+ def test_create_raises_but_actually_succeeded(self):
+ arv_node = testutil.arvados_node_mock(1, hostname=None)
+ driver = self.new_driver()
+ nodelist = [testutil.cloud_node_mock(1)]
+ nodelist[0].name = 'compute-000000000000001-zzzzz'
+ self.driver_mock().list_nodes.return_value = nodelist
+ self.driver_mock().create_node.side_effect = IOError
+ n = driver.create_node(testutil.MockSize(1), arv_node)
+ self.assertEqual('compute-000000000000001-zzzzz', n.name)
+
+ def test_create_sets_default_hostname(self):
+ driver = self.new_driver()
+ driver.create_node(testutil.MockSize(1),
+ testutil.arvados_node_mock(254, hostname=None))
+ create_kwargs = self.driver_mock().create_node.call_args[1]
+ self.assertEqual('compute-0000000000000fe-zzzzz',
+ create_kwargs.get('name'))
+ self.assertEqual('dynamic.compute.zzzzz.arvadosapi.com',
+ create_kwargs.get('ex_metadata', {}).get('hostname'))
+
+ def test_create_tags_from_list_tags(self):
+ driver = self.new_driver(list_kwargs={'tags': 'testA, testB'})
+ driver.create_node(testutil.MockSize(1), testutil.arvados_node_mock())
+ self.assertEqual(['testA', 'testB'],
+ self.driver_mock().create_node.call_args[1]['ex_tags'])
+
+ def test_create_with_two_disks_attached(self):
+ driver = self.new_driver(create_kwargs={'image': 'testimage'})
+ driver.create_node(testutil.MockSize(1), testutil.arvados_node_mock())
+ create_disks = self.driver_mock().create_node.call_args[1].get(
+ 'ex_disks_gce_struct', [])
+ self.assertEqual(2, len(create_disks))
+ self.assertTrue(create_disks[0].get('autoDelete'))
+ self.assertTrue(create_disks[0].get('boot'))
+ self.assertEqual('PERSISTENT', create_disks[0].get('type'))
+ init_params = create_disks[0].get('initializeParams', {})
+ self.assertEqual('pd-standard-link', init_params.get('diskType'))
+ self.assertEqual('image-link', init_params.get('sourceImage'))
+ # Our node images expect the SSD to be named `tmp` to find and mount it.
+ self.assertEqual('tmp', create_disks[1].get('deviceName'))
+ self.assertTrue(create_disks[1].get('autoDelete'))
+ self.assertFalse(create_disks[1].get('boot', 'unset'))
+ self.assertEqual('SCRATCH', create_disks[1].get('type'))
+ init_params = create_disks[1].get('initializeParams', {})
+ self.assertEqual('local-ssd-link', init_params.get('diskType'))
+
+ def test_list_nodes_requires_tags_match(self):
+ # A node matches if our list tags are a subset of the node's tags.
+ # Test behavior with no tags, no match, partial matches, different
+ # order, and strict supersets.
+ cloud_mocks = [
+ testutil.cloud_node_mock(node_num, tags=tag_set)
+ for node_num, tag_set in enumerate(
+ [[], ['bad'], ['good'], ['great'], ['great', 'ok'],
+ ['great', 'good'], ['good', 'fantastic', 'great']])]
+ cloud_mocks.append(testutil.cloud_node_mock())
+ self.driver_mock().list_nodes.return_value = cloud_mocks
+ driver = self.new_driver(list_kwargs={'tags': 'good, great'})
+ self.assertItemsEqual(['5', '6'], [n.id for n in driver.list_nodes()])
+
+ def build_gce_metadata(self, metadata_dict):
+ # Convert a plain metadata dictionary to the GCE data structure.
+ return {
+ 'kind': 'compute#metadata',
+ 'fingerprint': 'testprint',
+ 'items': [{'key': key, 'value': metadata_dict[key]}
+ for key in metadata_dict],
+ }
+
+ def check_sync_node_updates_hostname_tag(self, plain_metadata):
+ start_metadata = self.build_gce_metadata(plain_metadata)