diff --git a/bigquery/docs/reference.rst b/bigquery/docs/reference.rst index e01443808795..a0fc0e1ead70 100644 --- a/bigquery/docs/reference.rst +++ b/bigquery/docs/reference.rst @@ -88,7 +88,6 @@ Table table.TableReference table.Row table.RowIterator - table.EncryptionConfiguration table.TimePartitioning table.TimePartitioningType @@ -173,6 +172,13 @@ Enums enums.StandardSqlDataTypes +Encryption Configuration +======================== + +.. autosummary:: + :toctree: generated + + encryption_configuration.EncryptionConfiguration Additional Types ================ diff --git a/bigquery/google/cloud/bigquery/__init__.py b/bigquery/google/cloud/bigquery/__init__.py index bda8c5611435..da13375365e9 100644 --- a/bigquery/google/cloud/bigquery/__init__.py +++ b/bigquery/google/cloud/bigquery/__init__.py @@ -73,12 +73,12 @@ from google.cloud.bigquery.routine import RoutineArgument from google.cloud.bigquery.routine import RoutineReference from google.cloud.bigquery.schema import SchemaField -from google.cloud.bigquery.table import EncryptionConfiguration from google.cloud.bigquery.table import Table from google.cloud.bigquery.table import TableReference from google.cloud.bigquery.table import Row from google.cloud.bigquery.table import TimePartitioningType from google.cloud.bigquery.table import TimePartitioning +from google.cloud.bigquery.encryption_configuration import EncryptionConfiguration __all__ = [ "__version__", @@ -94,7 +94,6 @@ "DatasetReference", "AccessEntry", # Tables - "EncryptionConfiguration", "Table", "TableReference", "Row", @@ -136,6 +135,8 @@ "StandardSqlDataTypes", "SourceFormat", "WriteDisposition", + # EncryptionConfiguration + "EncryptionConfiguration", ] diff --git a/bigquery/google/cloud/bigquery/encryption_configuration.py b/bigquery/google/cloud/bigquery/encryption_configuration.py new file mode 100644 index 000000000000..ba04ae2c45a7 --- /dev/null +++ b/bigquery/google/cloud/bigquery/encryption_configuration.py @@ -0,0 +1,84 @@ +# Copyright 2015 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Define class for the custom encryption configuration.""" + +import copy + + +class EncryptionConfiguration(object): + """Custom encryption configuration (e.g., Cloud KMS keys). + + Args: + kms_key_name (str): resource ID of Cloud KMS key used for encryption + """ + + def __init__(self, kms_key_name=None): + self._properties = {} + if kms_key_name is not None: + self._properties["kmsKeyName"] = kms_key_name + + @property + def kms_key_name(self): + """str: Resource ID of Cloud KMS key + + Resource ID of Cloud KMS key or :data:`None` if using default + encryption. + """ + return self._properties.get("kmsKeyName") + + @kms_key_name.setter + def kms_key_name(self, value): + self._properties["kmsKeyName"] = value + + @classmethod + def from_api_repr(cls, resource): + """Construct an encryption configuration from its API representation + + Args: + resource (Dict[str, object]): + An encryption configuration representation as returned from + the API. + + Returns: + google.cloud.bigquery.table.EncryptionConfiguration: + An encryption configuration parsed from ``resource``. + """ + config = cls() + config._properties = copy.deepcopy(resource) + return config + + def to_api_repr(self): + """Construct the API resource representation of this encryption + configuration. + + Returns: + Dict[str, object]: + Encryption configuration as represented as an API resource + """ + return copy.deepcopy(self._properties) + + def __eq__(self, other): + if not isinstance(other, EncryptionConfiguration): + return NotImplemented + return self.kms_key_name == other.kms_key_name + + def __ne__(self, other): + return not self == other + + def __hash__(self): + return hash(self.kms_key_name) + + def __repr__(self): + return "EncryptionConfiguration({})".format(self.kms_key_name) diff --git a/bigquery/google/cloud/bigquery/job.py b/bigquery/google/cloud/bigquery/job.py index ccbab8b5eb44..0504aca6e686 100644 --- a/bigquery/google/cloud/bigquery/job.py +++ b/bigquery/google/cloud/bigquery/job.py @@ -37,12 +37,12 @@ from google.cloud.bigquery.routine import RoutineReference from google.cloud.bigquery.schema import SchemaField from google.cloud.bigquery.table import _EmptyRowIterator -from google.cloud.bigquery.table import EncryptionConfiguration from google.cloud.bigquery.table import _table_arg_to_table_ref from google.cloud.bigquery.table import TableReference from google.cloud.bigquery.table import Table from google.cloud.bigquery.table import TimePartitioning from google.cloud.bigquery import _helpers +from google.cloud.bigquery.encryption_configuration import EncryptionConfiguration _DONE_STATE = "DONE" _STOPPED_REASON = "stopped" @@ -1006,7 +1006,7 @@ def create_disposition(self, value): @property def destination_encryption_configuration(self): - """google.cloud.bigquery.table.EncryptionConfiguration: Custom + """google.cloud.bigquery.encryption_configuration.EncryptionConfiguration: Custom encryption configuration for the destination table. Custom encryption configuration (e.g., Cloud KMS keys) or :data:`None` @@ -1400,7 +1400,7 @@ def schema(self): @property def destination_encryption_configuration(self): - """google.cloud.bigquery.table.EncryptionConfiguration: Custom + """google.cloud.bigquery.encryption_configuration.EncryptionConfiguration: Custom encryption configuration for the destination table. Custom encryption configuration (e.g., Cloud KMS keys) @@ -1604,7 +1604,7 @@ def write_disposition(self, value): @property def destination_encryption_configuration(self): - """google.cloud.bigquery.table.EncryptionConfiguration: Custom + """google.cloud.bigquery.encryption_configuration.EncryptionConfiguration: Custom encryption configuration for the destination table. Custom encryption configuration (e.g., Cloud KMS keys) or :data:`None` @@ -1675,7 +1675,7 @@ def write_disposition(self): @property def destination_encryption_configuration(self): - """google.cloud.bigquery.table.EncryptionConfiguration: Custom + """google.cloud.bigquery.encryption_configuration.EncryptionConfiguration: Custom encryption configuration for the destination table. Custom encryption configuration (e.g., Cloud KMS keys) or :data:`None` @@ -2007,7 +2007,7 @@ def __init__(self, **kwargs): @property def destination_encryption_configuration(self): - """google.cloud.bigquery.table.EncryptionConfiguration: Custom + """google.cloud.bigquery.encryption_configuration.EncryptionConfiguration: Custom encryption configuration for the destination table. Custom encryption configuration (e.g., Cloud KMS keys) or :data:`None` @@ -2426,7 +2426,7 @@ def destination(self): @property def destination_encryption_configuration(self): - """google.cloud.bigquery.table.EncryptionConfiguration: Custom + """google.cloud.bigquery.encryption_configuration.EncryptionConfiguration: Custom encryption configuration for the destination table. Custom encryption configuration (e.g., Cloud KMS keys) or :data:`None` diff --git a/bigquery/google/cloud/bigquery/model.py b/bigquery/google/cloud/bigquery/model.py index 4049a9232467..b461e44201fb 100644 --- a/bigquery/google/cloud/bigquery/model.py +++ b/bigquery/google/cloud/bigquery/model.py @@ -25,6 +25,7 @@ from google.api_core import datetime_helpers from google.cloud.bigquery import _helpers from google.cloud.bigquery_v2 import types +from google.cloud.bigquery.encryption_configuration import EncryptionConfiguration class Model(object): @@ -51,6 +52,7 @@ class Model(object): # have an exhaustive list of all mutable properties. "labels": "labels", "description": "description", + "encryption_configuration": "encryptionConfiguration", } def __init__(self, model_ref): @@ -256,6 +258,30 @@ def labels(self, value): value = {} self._properties["labels"] = value + @property + def encryption_configuration(self): + """google.cloud.bigquery.encryption_configuration.EncryptionConfiguration: Custom + encryption configuration for the model. + + Custom encryption configuration (e.g., Cloud KMS keys) or :data:`None` + if using default encryption. + + See `protecting data with Cloud KMS keys + `_ + in the BigQuery documentation. + """ + prop = self._properties.get("encryptionConfiguration") + if prop: + prop = EncryptionConfiguration.from_api_repr(prop) + return prop + + @encryption_configuration.setter + def encryption_configuration(self, value): + api_repr = value + if value: + api_repr = value.to_api_repr() + self._properties["encryptionConfiguration"] = api_repr + @classmethod def from_api_repr(cls, resource): """Factory: construct a model resource given its API representation diff --git a/bigquery/google/cloud/bigquery/table.py b/bigquery/google/cloud/bigquery/table.py index 71fc9ef945d4..87923665c1aa 100644 --- a/bigquery/google/cloud/bigquery/table.py +++ b/bigquery/google/cloud/bigquery/table.py @@ -55,6 +55,7 @@ from google.cloud.bigquery.schema import _build_schema_resource from google.cloud.bigquery.schema import _parse_schema_resource from google.cloud.bigquery.external_config import ExternalConfig +from google.cloud.bigquery.encryption_configuration import EncryptionConfiguration _LOGGER = logging.getLogger(__name__) @@ -113,73 +114,6 @@ def _view_use_legacy_sql_getter(table): return True -class EncryptionConfiguration(object): - """Custom encryption configuration (e.g., Cloud KMS keys). - - Args: - kms_key_name (str): resource ID of Cloud KMS key used for encryption - """ - - def __init__(self, kms_key_name=None): - self._properties = {} - if kms_key_name is not None: - self._properties["kmsKeyName"] = kms_key_name - - @property - def kms_key_name(self): - """str: Resource ID of Cloud KMS key - - Resource ID of Cloud KMS key or :data:`None` if using default - encryption. - """ - return self._properties.get("kmsKeyName") - - @kms_key_name.setter - def kms_key_name(self, value): - self._properties["kmsKeyName"] = value - - @classmethod - def from_api_repr(cls, resource): - """Construct an encryption configuration from its API representation - - Args: - resource (Dict[str, object]): - An encryption configuration representation as returned from - the API. - - Returns: - google.cloud.bigquery.table.EncryptionConfiguration: - An encryption configuration parsed from ``resource``. - """ - config = cls() - config._properties = copy.deepcopy(resource) - return config - - def to_api_repr(self): - """Construct the API resource representation of this encryption - configuration. - - Returns: - Dict[str, object]: - Encryption configuration as represented as an API resource - """ - return copy.deepcopy(self._properties) - - def __eq__(self, other): - if not isinstance(other, EncryptionConfiguration): - return NotImplemented - return self.kms_key_name == other.kms_key_name - - def __ne__(self, other): - return not self == other - - def __hash__(self): - return hash(self.kms_key_name) - - def __repr__(self): - return "EncryptionConfiguration({})".format(self.kms_key_name) - - class TableReference(object): """TableReferences are pointers to tables. @@ -469,7 +403,7 @@ def labels(self, value): @property def encryption_configuration(self): - """google.cloud.bigquery.table.EncryptionConfiguration: Custom + """google.cloud.bigquery.encryption_configuration.EncryptionConfiguration: Custom encryption configuration for the table. Custom encryption configuration (e.g., Cloud KMS keys) or :data:`None` diff --git a/bigquery/tests/unit/model/test_model.py b/bigquery/tests/unit/model/test_model.py index b6d9756e15fe..bbb93ef9e897 100644 --- a/bigquery/tests/unit/model/test_model.py +++ b/bigquery/tests/unit/model/test_model.py @@ -21,6 +21,8 @@ import google.cloud._helpers from google.cloud.bigquery_v2.gapic import enums +KMS_KEY_NAME = "projects/1/locations/us/keyRings/1/cryptoKeys/1" + @pytest.fixture def target_class(): @@ -99,6 +101,7 @@ def test_from_api_repr(target_class): }, ], "featureColumns": [], + "encryptionConfiguration": {"kmsKeyName": KMS_KEY_NAME}, } got = target_class.from_api_repr(resource) @@ -116,6 +119,7 @@ def test_from_api_repr(target_class): assert got.friendly_name == u"A friendly name." assert got.model_type == enums.Model.ModelType.LOGISTIC_REGRESSION assert got.labels == {"greeting": u"こんにちは"} + assert got.encryption_configuration.kms_key_name == KMS_KEY_NAME assert got.training_runs[0].training_options.initial_learn_rate == 1.0 assert ( got.training_runs[0] @@ -160,6 +164,7 @@ def test_from_api_repr_w_minimal_resource(target_class): assert got.friendly_name is None assert got.model_type == enums.Model.ModelType.MODEL_TYPE_UNSPECIFIED assert got.labels == {} + assert got.encryption_configuration is None assert len(got.training_runs) == 0 assert len(got.feature_columns) == 0 assert len(got.label_columns) == 0 @@ -229,6 +234,17 @@ def test_from_api_repr_w_unknown_fields(target_class): ["labels"], {"labels": {"a-label": "a-value"}}, ), + ( + { + "friendlyName": "hello", + "description": "world", + "expirationTime": None, + "labels": {"a-label": "a-value"}, + "encryptionConfiguration": {"kmsKeyName": KMS_KEY_NAME}, + }, + ["encryptionConfiguration"], + {"encryptionConfiguration": {"kmsKeyName": KMS_KEY_NAME}}, + ), ], ) def test_build_resource(object_under_test, resource, filter_fields, expected): @@ -283,6 +299,18 @@ def test_replace_labels(object_under_test): assert object_under_test.labels == {} +def test_set_encryption_configuration(object_under_test): + from google.cloud.bigquery.encryption_configuration import EncryptionConfiguration + + assert not object_under_test.encryption_configuration + object_under_test.encryption_configuration = EncryptionConfiguration( + kms_key_name=KMS_KEY_NAME + ) + assert object_under_test.encryption_configuration.kms_key_name == KMS_KEY_NAME + object_under_test.encryption_configuration = None + assert not object_under_test.encryption_configuration + + def test_repr(target_class): model = target_class("my-proj.my_dset.my_model") got = repr(model) diff --git a/bigquery/tests/unit/test_client.py b/bigquery/tests/unit/test_client.py index ea4b114358a9..aa06e2ec4f0c 100644 --- a/bigquery/tests/unit/test_client.py +++ b/bigquery/tests/unit/test_client.py @@ -81,7 +81,7 @@ class TestClient(unittest.TestCase): TABLE_ID = "TABLE_ID" MODEL_ID = "MODEL_ID" TABLE_REF = DatasetReference(PROJECT, DS_ID).table(TABLE_ID) - KMS_KEY_NAME = "projects/1/locations/global/keyRings/1/cryptoKeys/1" + KMS_KEY_NAME = "projects/1/locations/us/keyRings/1/cryptoKeys/1" LOCATION = "us-central" @staticmethod @@ -1074,7 +1074,9 @@ def test_create_table_w_custom_property(self): self.assertEqual(got.table_id, self.TABLE_ID) def test_create_table_w_encryption_configuration(self): - from google.cloud.bigquery.table import EncryptionConfiguration + from google.cloud.bigquery.encryption_configuration import ( + EncryptionConfiguration, + ) from google.cloud.bigquery.table import Table path = "projects/%s/datasets/%s/tables" % (self.PROJECT, self.DS_ID) diff --git a/bigquery/tests/unit/test_encryption_configuration.py b/bigquery/tests/unit/test_encryption_configuration.py new file mode 100644 index 000000000000..f432a903b4cc --- /dev/null +++ b/bigquery/tests/unit/test_encryption_configuration.py @@ -0,0 +1,111 @@ +# Copyright 2015 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import unittest +import mock + + +class TestEncryptionConfiguration(unittest.TestCase): + KMS_KEY_NAME = "projects/1/locations/us/keyRings/1/cryptoKeys/1" + + @staticmethod + def _get_target_class(): + from google.cloud.bigquery.encryption_configuration import ( + EncryptionConfiguration, + ) + + return EncryptionConfiguration + + def _make_one(self, *args, **kw): + return self._get_target_class()(*args, **kw) + + def test_ctor_defaults(self): + encryption_config = self._make_one() + self.assertIsNone(encryption_config.kms_key_name) + + def test_ctor_with_key(self): + encryption_config = self._make_one(kms_key_name=self.KMS_KEY_NAME) + self.assertEqual(encryption_config.kms_key_name, self.KMS_KEY_NAME) + + def test_kms_key_name_setter(self): + encryption_config = self._make_one() + self.assertIsNone(encryption_config.kms_key_name) + encryption_config.kms_key_name = self.KMS_KEY_NAME + self.assertEqual(encryption_config.kms_key_name, self.KMS_KEY_NAME) + encryption_config.kms_key_name = None + self.assertIsNone(encryption_config.kms_key_name) + + def test_from_api_repr(self): + RESOURCE = {"kmsKeyName": self.KMS_KEY_NAME} + klass = self._get_target_class() + encryption_config = klass.from_api_repr(RESOURCE) + self.assertEqual(encryption_config.kms_key_name, self.KMS_KEY_NAME) + + def test_to_api_repr(self): + encryption_config = self._make_one(kms_key_name=self.KMS_KEY_NAME) + resource = encryption_config.to_api_repr() + self.assertEqual(resource, {"kmsKeyName": self.KMS_KEY_NAME}) + + def test___eq___wrong_type(self): + encryption_config = self._make_one() + other = object() + self.assertNotEqual(encryption_config, other) + self.assertEqual(encryption_config, mock.ANY) + + def test___eq___kms_key_name_mismatch(self): + encryption_config = self._make_one() + other = self._make_one(self.KMS_KEY_NAME) + self.assertNotEqual(encryption_config, other) + + def test___eq___hit(self): + encryption_config = self._make_one(self.KMS_KEY_NAME) + other = self._make_one(self.KMS_KEY_NAME) + self.assertEqual(encryption_config, other) + + def test___ne___wrong_type(self): + encryption_config = self._make_one() + other = object() + self.assertNotEqual(encryption_config, other) + self.assertEqual(encryption_config, mock.ANY) + + def test___ne___same_value(self): + encryption_config1 = self._make_one(self.KMS_KEY_NAME) + encryption_config2 = self._make_one(self.KMS_KEY_NAME) + # unittest ``assertEqual`` uses ``==`` not ``!=``. + comparison_val = encryption_config1 != encryption_config2 + self.assertFalse(comparison_val) + + def test___ne___different_values(self): + encryption_config1 = self._make_one() + encryption_config2 = self._make_one(self.KMS_KEY_NAME) + self.assertNotEqual(encryption_config1, encryption_config2) + + def test___hash__set_equality(self): + encryption_config1 = self._make_one(self.KMS_KEY_NAME) + encryption_config2 = self._make_one(self.KMS_KEY_NAME) + set_one = {encryption_config1, encryption_config2} + set_two = {encryption_config1, encryption_config2} + self.assertEqual(set_one, set_two) + + def test___hash__not_equals(self): + encryption_config1 = self._make_one() + encryption_config2 = self._make_one(self.KMS_KEY_NAME) + set_one = {encryption_config1} + set_two = {encryption_config2} + self.assertNotEqual(set_one, set_two) + + def test___repr__(self): + encryption_config = self._make_one(self.KMS_KEY_NAME) + expected = "EncryptionConfiguration({})".format(self.KMS_KEY_NAME) + self.assertEqual(repr(encryption_config), expected) diff --git a/bigquery/tests/unit/test_job.py b/bigquery/tests/unit/test_job.py index b34184f00cd9..bc62879017b1 100644 --- a/bigquery/tests/unit/test_job.py +++ b/bigquery/tests/unit/test_job.py @@ -1030,7 +1030,7 @@ class _Base(object): TABLE_ID = "table_id" TABLE_REF = TableReference(DS_REF, TABLE_ID) JOB_ID = "JOB_ID" - KMS_KEY_NAME = "projects/1/locations/global/keyRings/1/cryptoKeys/1" + KMS_KEY_NAME = "projects/1/locations/us/keyRings/1/cryptoKeys/1" def _make_one(self, *args, **kw): return self._get_target_class()(*args, **kw) @@ -1229,7 +1229,9 @@ def test_destination_encryption_configuration_missing(self): self.assertIsNone(config.destination_encryption_configuration) def test_destination_encryption_configuration_hit(self): - from google.cloud.bigquery.table import EncryptionConfiguration + from google.cloud.bigquery.encryption_configuration import ( + EncryptionConfiguration, + ) kms_key_name = "kms-key-name" encryption_configuration = EncryptionConfiguration(kms_key_name) @@ -1242,7 +1244,9 @@ def test_destination_encryption_configuration_hit(self): ) def test_destination_encryption_configuration_setter(self): - from google.cloud.bigquery.table import EncryptionConfiguration + from google.cloud.bigquery.encryption_configuration import ( + EncryptionConfiguration, + ) kms_key_name = "kms-key-name" encryption_configuration = EncryptionConfiguration(kms_key_name) @@ -2439,7 +2443,9 @@ def test_ctor_w_properties(self): self.assertEqual(config.write_disposition, write_disposition) def test_to_api_repr_with_encryption(self): - from google.cloud.bigquery.table import EncryptionConfiguration + from google.cloud.bigquery.encryption_configuration import ( + EncryptionConfiguration, + ) config = self._make_one() config.destination_encryption_configuration = EncryptionConfiguration( @@ -3364,7 +3370,9 @@ def test_to_api_repr_normal(self): self.assertEqual(resource["someNewProperty"], "Woohoo, alpha stuff.") def test_to_api_repr_with_encryption(self): - from google.cloud.bigquery.table import EncryptionConfiguration + from google.cloud.bigquery.encryption_configuration import ( + EncryptionConfiguration, + ) config = self._make_one() config.destination_encryption_configuration = EncryptionConfiguration( diff --git a/bigquery/tests/unit/test_table.py b/bigquery/tests/unit/test_table.py index 562bcf6b4e7d..c68b52f00bd6 100644 --- a/bigquery/tests/unit/test_table.py +++ b/bigquery/tests/unit/test_table.py @@ -71,7 +71,7 @@ def _verifySchema(self, schema, resource): class TestEncryptionConfiguration(unittest.TestCase): - KMS_KEY_NAME = "projects/1/locations/global/keyRings/1/cryptoKeys/1" + KMS_KEY_NAME = "projects/1/locations/us/keyRings/1/cryptoKeys/1" @staticmethod def _get_target_class(): @@ -90,78 +90,6 @@ def test_ctor_with_key(self): encryption_config = self._make_one(kms_key_name=self.KMS_KEY_NAME) self.assertEqual(encryption_config.kms_key_name, self.KMS_KEY_NAME) - def test_kms_key_name_setter(self): - encryption_config = self._make_one() - self.assertIsNone(encryption_config.kms_key_name) - encryption_config.kms_key_name = self.KMS_KEY_NAME - self.assertEqual(encryption_config.kms_key_name, self.KMS_KEY_NAME) - encryption_config.kms_key_name = None - self.assertIsNone(encryption_config.kms_key_name) - - def test_from_api_repr(self): - RESOURCE = {"kmsKeyName": self.KMS_KEY_NAME} - klass = self._get_target_class() - encryption_config = klass.from_api_repr(RESOURCE) - self.assertEqual(encryption_config.kms_key_name, self.KMS_KEY_NAME) - - def test_to_api_repr(self): - encryption_config = self._make_one(kms_key_name=self.KMS_KEY_NAME) - resource = encryption_config.to_api_repr() - self.assertEqual(resource, {"kmsKeyName": self.KMS_KEY_NAME}) - - def test___eq___wrong_type(self): - encryption_config = self._make_one() - other = object() - self.assertNotEqual(encryption_config, other) - self.assertEqual(encryption_config, mock.ANY) - - def test___eq___kms_key_name_mismatch(self): - encryption_config = self._make_one() - other = self._make_one(self.KMS_KEY_NAME) - self.assertNotEqual(encryption_config, other) - - def test___eq___hit(self): - encryption_config = self._make_one(self.KMS_KEY_NAME) - other = self._make_one(self.KMS_KEY_NAME) - self.assertEqual(encryption_config, other) - - def test___ne___wrong_type(self): - encryption_config = self._make_one() - other = object() - self.assertNotEqual(encryption_config, other) - self.assertEqual(encryption_config, mock.ANY) - - def test___ne___same_value(self): - encryption_config1 = self._make_one(self.KMS_KEY_NAME) - encryption_config2 = self._make_one(self.KMS_KEY_NAME) - # unittest ``assertEqual`` uses ``==`` not ``!=``. - comparison_val = encryption_config1 != encryption_config2 - self.assertFalse(comparison_val) - - def test___ne___different_values(self): - encryption_config1 = self._make_one() - encryption_config2 = self._make_one(self.KMS_KEY_NAME) - self.assertNotEqual(encryption_config1, encryption_config2) - - def test___hash__set_equality(self): - encryption_config1 = self._make_one(self.KMS_KEY_NAME) - encryption_config2 = self._make_one(self.KMS_KEY_NAME) - set_one = {encryption_config1, encryption_config2} - set_two = {encryption_config1, encryption_config2} - self.assertEqual(set_one, set_two) - - def test___hash__not_equals(self): - encryption_config1 = self._make_one() - encryption_config2 = self._make_one(self.KMS_KEY_NAME) - set_one = {encryption_config1} - set_two = {encryption_config2} - self.assertNotEqual(set_one, set_two) - - def test___repr__(self): - encryption_config = self._make_one(self.KMS_KEY_NAME) - expected = "EncryptionConfiguration({})".format(self.KMS_KEY_NAME) - self.assertEqual(repr(encryption_config), expected) - class TestTableReference(unittest.TestCase): @staticmethod @@ -339,7 +267,7 @@ class TestTable(unittest.TestCase, _SchemaBase): PROJECT = "prahj-ekt" DS_ID = "dataset-name" TABLE_NAME = "table-name" - KMS_KEY_NAME = "projects/1/locations/global/keyRings/1/cryptoKeys/1" + KMS_KEY_NAME = "projects/1/locations/us/keyRings/1/cryptoKeys/1" @staticmethod def _get_target_class(): @@ -1118,6 +1046,10 @@ def test_clustering_fields_setter_w_none_noop(self): self.assertFalse("clustering" in table._properties) def test_encryption_configuration_setter(self): + # Previously, the EncryptionConfiguration class was in the table module, not the + # encryption_configuration module. It was moved to support models encryption. + # This test import from the table module to ensure that the previous location + # continues to function as an alias. from google.cloud.bigquery.table import EncryptionConfiguration dataset = DatasetReference(self.PROJECT, self.DS_ID)