Add test coverage for x509.CertificateBuilder
diff --git a/tests/test_x509.py b/tests/test_x509.py
index 91b4f2b..16d040f 100644
--- a/tests/test_x509.py
+++ b/tests/test_x509.py
@@ -820,6 +820,139 @@
         assert basic_constraints.value.path_length is None
 
 
+class TestCertificateBuilder(object):
+    def test_version_must_be_a_version_type(self):
+        builder = x509.CertificateBuilder()
+
+        with pytest.raises(TypeError):
+            builder.version("v1")
+
+    def test_version_may_only_be_set_once(self):
+        builder = x509.CertificateBuilder().version(
+            x509.Version.v3
+        )
+
+        with pytest.raises(ValueError):
+            builder.version(x509.Version.v1)
+
+    def test_issuer_name_must_be_a_name_type(self):
+        builder = x509.CertificateBuilder()
+
+        with pytest.raises(TypeError):
+            builder.issuer_name("subject")
+
+        with pytest.raises(TypeError):
+            builder.issuer_name(object)
+
+    def test_issuer_name_may_only_be_set_once(self):
+        name = x509.Name([
+            x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US'),
+            x509.NameAttribute(x509.OID_STATE_OR_PROVINCE_NAME, u'Texas'),
+            x509.NameAttribute(x509.OID_LOCALITY_NAME, u'Austin'),
+            x509.NameAttribute(x509.OID_ORGANIZATION_NAME, u'PyCA'),
+            x509.NameAttribute(x509.OID_COMMON_NAME, u'cryptography.io'),
+        ])
+        builder = x509.CertificateBuilder().issuer_name(name)
+
+        with pytest.raises(ValueError):
+            builder.issuer_name(name)
+
+    def test_subject_name_must_be_a_name_type(self):
+        builder = x509.CertificateBuilder()
+
+        with pytest.raises(TypeError):
+            builder.subject_name("subject")
+
+        with pytest.raises(TypeError):
+            builder.subject_name(object)
+
+    def test_subject_name_may_only_be_set_once(self):
+        name = x509.Name([
+            x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US'),
+            x509.NameAttribute(x509.OID_STATE_OR_PROVINCE_NAME, u'Texas'),
+            x509.NameAttribute(x509.OID_LOCALITY_NAME, u'Austin'),
+            x509.NameAttribute(x509.OID_ORGANIZATION_NAME, u'PyCA'),
+            x509.NameAttribute(x509.OID_COMMON_NAME, u'cryptography.io'),
+        ])
+        builder = x509.CertificateBuilder().subject_name(name)
+
+        with pytest.raises(ValueError):
+            builder.subject_name(name)
+
+    @pytest.mark.requires_backend_interface(interface=RSABackend)
+    @pytest.mark.requires_backend_interface(interface=X509Backend)
+    def test_public_key_must_be_public_key(self, backend):
+        private_key = RSA_KEY_2048.private_key(backend)
+        builder = x509.CertificateBuilder()
+
+        with pytest.raises(TypeError):
+            builder.public_key(private_key)
+
+    @pytest.mark.requires_backend_interface(interface=RSABackend)
+    @pytest.mark.requires_backend_interface(interface=X509Backend)
+    def test_public_key_may_only_be_set_once(self, backend):
+        private_key = RSA_KEY_2048.private_key(backend)
+        public_key = private_key.public_key()
+        builder = x509.CertificateBuilder().public_key(public_key)
+
+        with pytest.raises(ValueError):
+            builder.public_key(public_key)
+
+    def test_serial_number_must_be_an_integer_type(self):
+        with pytest.raises(TypeError):
+            x509.CertificateBuilder().serial_number(10.0)
+
+    def test_serial_number_may_only_be_set_once(self):
+        builder = x509.CertificateBuilder().serial_number(10)
+
+        with pytest.raises(ValueError):
+            builder.serial_number(20)
+
+    def test_invalid_not_valid_after(self):
+        with pytest.raises(TypeError):
+            x509.CertificateBuilder().not_valid_after(104204304504)
+
+        with pytest.raises(TypeError):
+            x509.CertificateBuilder().not_valid_after(datetime.time())
+
+    def test_not_valid_after_may_only_be_set_once(self):
+        builder = x509.CertificateBuilder().not_valid_after(
+            datetime.datetime.now()
+        )
+
+        with pytest.raises(ValueError):
+            builder.not_valid_after(
+                datetime.datetime.now()
+            )
+
+    def test_invalid_not_valid_before(self):
+        with pytest.raises(TypeError):
+            x509.CertificateBuilder().not_valid_before(104204304504)
+
+        with pytest.raises(TypeError):
+            x509.CertificateBuilder().not_valid_before(datetime.time())
+
+    def test_not_valid_before_may_only_be_set_once(self):
+        builder = x509.CertificateBuilder().not_valid_before(
+            datetime.datetime.now()
+        )
+
+        with pytest.raises(ValueError):
+            builder.not_valid_before(
+                datetime.datetime.now()
+            )
+
+    def test_add_extension_checks_for_duplicates(self):
+        builder = x509.CertificateBuilder().add_extension(
+            x509.BasicConstraints(ca=False, path_length=None), True,
+        )
+
+        with pytest.raises(ValueError):
+            builder.add_extension(
+                x509.BasicConstraints(ca=False, path_length=None), True,
+            )
+
+
 @pytest.mark.requires_backend_interface(interface=X509Backend)
 class TestCertificateSigningRequestBuilder(object):
     @pytest.mark.requires_backend_interface(interface=RSABackend)