def _make_connection(self): from google.cloud.spanner_dbapi import Connection from google.cloud.spanner_v1.instance import Instance # We don't need a real Client object to test the constructor instance = Instance(self.INSTANCE, client=None) database = instance.database(self.DATABASE) return Connection(instance, database)
def test_reload_success(self): from google.cloud.spanner_admin_instance_v1 import Instance client = _Client(self.PROJECT) instance_pb = Instance( name=self.INSTANCE_NAME, config=self.CONFIG_NAME, display_name=self.DISPLAY_NAME, node_count=self.NODE_COUNT, labels=self.LABELS, ) api = client.instance_admin_api = _FauxInstanceAdminAPI( _get_instance_response=instance_pb) instance = self._make_one(self.INSTANCE_ID, client) instance.reload() self.assertEqual(instance.configuration_name, self.CONFIG_NAME) self.assertEqual(instance.node_count, self.NODE_COUNT) self.assertEqual(instance.display_name, self.DISPLAY_NAME) self.assertEqual(instance.labels, self.LABELS) name, metadata = api._got_instance self.assertEqual(name, self.INSTANCE_NAME) self.assertEqual(metadata, [("google-cloud-resource-prefix", instance.name)])
def instance( self, instance_id, configuration_name=None, display_name=None, node_count=DEFAULT_NODE_COUNT, ): """Factory to create a instance associated with this client. :type instance_id: str :param instance_id: The ID of the instance. :type configuration_name: string :param configuration_name: (Optional) Name of the instance configuration used to set up the instance's cluster, in the form: ``projects/<project>/instanceConfigs/<config>``. **Required** for instances which do not yet exist. :type display_name: str :param display_name: (Optional) The display name for the instance in the Cloud Console UI. (Must be between 4 and 30 characters.) If this value is not set in the constructor, will fall back to the instance ID. :type node_count: int :param node_count: (Optional) The number of nodes in the instance's cluster; used to set up the instance's cluster. :rtype: :class:`~google.cloud.spanner_v1.instance.Instance` :returns: an instance owned by this client. """ return Instance(instance_id, self, configuration_name, node_count, display_name)
def setUpModule(): if USE_EMULATOR: from google.auth.credentials import AnonymousCredentials emulator_project = os.getenv("GCLOUD_PROJECT", "emulator-test-project") Config.CLIENT = Client(project=emulator_project, credentials=AnonymousCredentials()) else: Config.CLIENT = Client() retry = RetryErrors(exceptions.ServiceUnavailable) configs = list(retry(Config.CLIENT.list_instance_configs)()) instances = retry(_list_instances)() EXISTING_INSTANCES[:] = instances # Delete test instances that are older than an hour. cutoff = int(time.time()) - 1 * 60 * 60 for instance_pb in Config.CLIENT.list_instances( "labels.python-spanner-dbapi-systests:true"): instance = Instance.from_pb(instance_pb, Config.CLIENT) if "created" not in instance.labels: continue create_time = int(instance.labels["created"]) if create_time > cutoff: continue # Instance cannot be deleted while backups exist. for backup_pb in instance.list_backups(): backup = Backup.from_pb(backup_pb, instance) backup.delete() instance.delete() if CREATE_INSTANCE: if not USE_EMULATOR: # Defend against back-end returning configs for regions we aren't # actually allowed to use. configs = [config for config in configs if "-us-" in config.name] if not configs: raise ValueError("List instance configs failed in module set up.") Config.INSTANCE_CONFIG = configs[0] config_name = configs[0].name create_time = str(int(time.time())) labels = { "python-spanner-dbapi-systests": "true", "created": create_time } Config.INSTANCE = Config.CLIENT.instance(INSTANCE_ID, config_name, labels=labels) created_op = Config.INSTANCE.create() created_op.result( SPANNER_OPERATION_TIMEOUT_IN_SECONDS) # block until completion else: Config.INSTANCE = Config.CLIENT.instance(INSTANCE_ID) Config.INSTANCE.reload()
def test_from_pb_bad_instance_name(self): from google.cloud.spanner_admin_instance_v1 import Instance instance_name = "INCORRECT_FORMAT" instance_pb = Instance(name=instance_name) klass = self._getTargetClass() with self.assertRaises(ValueError): klass.from_pb(instance_pb, None)
def test__update_from_pb_no_display_name(self): from google.cloud.spanner_admin_instance_v1 import Instance instance_pb = Instance() instance = self._make_one(None, None, None, None) self.assertEqual(instance.display_name, None) with self.assertRaises(ValueError): instance._update_from_pb(instance_pb) self.assertEqual(instance.display_name, None)
def test__update_from_pb_success(self): from google.cloud.spanner_admin_instance_v1 import Instance display_name = "display_name" instance_pb = Instance(display_name=display_name) instance = self._make_one(None, None, None, None) self.assertEqual(instance.display_name, None) instance._update_from_pb(instance_pb) self.assertEqual(instance.display_name, display_name)
def instance( self, instance_id, configuration_name=None, display_name=None, node_count=None, labels=None, processing_units=None, ): """Factory to create a instance associated with this client. :type instance_id: str :param instance_id: The ID of the instance. :type configuration_name: string :param configuration_name: (Optional) Name of the instance configuration used to set up the instance's cluster, in the form: ``projects/<project>/instanceConfigs/`` ``<config>``. **Required** for instances which do not yet exist. :type display_name: str :param display_name: (Optional) The display name for the instance in the Cloud Console UI. (Must be between 4 and 30 characters.) If this value is not set in the constructor, will fall back to the instance ID. :type node_count: int :param node_count: (Optional) The number of nodes in the instance's cluster; used to set up the instance's cluster. :type processing_units: int :param processing_units: (Optional) The number of processing units allocated to this instance. :type labels: dict (str -> str) or None :param labels: (Optional) User-assigned labels for this instance. :rtype: :class:`~google.cloud.spanner_v1.instance.Instance` :returns: an instance owned by this client. """ return Instance( instance_id, self, configuration_name, node_count, display_name, self._emulator_host, labels, processing_units, )
def test_from_pb_project_mistmatch(self): from google.cloud.spanner_admin_instance_v1 import Instance ALT_PROJECT = "ALT_PROJECT" client = _Client(project=ALT_PROJECT) self.assertNotEqual(self.PROJECT, ALT_PROJECT) instance_pb = Instance(name=self.INSTANCE_NAME) klass = self._getTargetClass() with self.assertRaises(ValueError): klass.from_pb(instance_pb, client)
def _item_to_instance(self, iterator, instance_pb): """Convert an instance protobuf to the native object. :type iterator: :class:`~google.api_core.page_iterator.Iterator` :param iterator: The iterator that is currently in use. :type instance_pb: :class:`~google.spanner.admin.instance.v1.Instance` :param instance_pb: An instance returned from the API. :rtype: :class:`~google.cloud.spanner_v1.instance.Instance` :returns: The next instance in the page. """ return Instance.from_pb(instance_pb, self)
def cleanup_old_instances(spanner_client): # Delete test instances that are older than an hour. cutoff = int(time.time()) - 1 * 60 * 60 instance_pbs = spanner_client.list_instances( "labels.cloud_spanner_samples:true") for instance_pb in instance_pbs: instance = Instance.from_pb(instance_pb, spanner_client) if "created" not in instance.labels: continue create_time = int(instance.labels["created"]) if create_time > cutoff: continue for backup_pb in instance.list_backups(): backup = Backup.from_pb(backup_pb, instance) backup.delete() instance.delete()
def test_from_pb_success(self): from google.cloud.spanner_admin_instance_v1 import Instance client = _Client(project=self.PROJECT) instance_pb = Instance( name=self.INSTANCE_NAME, config=self.CONFIG_NAME, display_name=self.INSTANCE_ID, labels=self.LABELS, ) klass = self._getTargetClass() instance = klass.from_pb(instance_pb, client) self.assertIsInstance(instance, klass) self.assertEqual(instance._client, client) self.assertEqual(instance.instance_id, self.INSTANCE_ID) self.assertEqual(instance.configuration_name, self.CONFIG_NAME) self.assertEqual(instance.labels, self.LABELS)
def delete_stale_test_instances(): """Delete test instances that are older than four hours.""" cutoff = int(time.time()) - 4 * 60 * 60 instances_pbs = CLIENT.list_instances( "labels.python-spanner-sqlalchemy-systest:true") for instance_pb in instances_pbs: instance = Instance.from_pb(instance_pb, CLIENT) if "created" not in instance.labels: continue create_time = int(instance.labels["created"]) if create_time > cutoff: continue # Backups are not used in sqlalchemy dialect test, # therefore instance can just be deleted. try: instance.delete() time.sleep(5) # Sleep for 5 seconds to give time for cooldown. except ResourceExhausted: print( "Unable to drop stale instance '{}'. May need manual delete.". format(instance.instance_id))
def _make_connection(self): # we don't need real Client object to test the constructor instance = Instance(self.instance_name, client=None) database = instance.database(self.database_name) return Connection(instance, database)