class TestRackspaceCtrl(unittest.TestCase): def setUp(self): # prefix to identify created objects self.object_prefix = "int_test_" self.prefix_length = len(self.object_prefix) self.ctrl = RackspaceCtrl(self.username, self.api_key, "http://foo.bar:8888") self.ctrl.authenticate() self.ctrl.set_region("ord") self.gns3_image = None self.ctrl.GNS3_CONTAINER_NAME = "TEST_GNS3" def tearDown(self): self._remove_instances() self._remove_key_pairs() if self.gns3_image is not None: self.ctrl.driver.ex_delete_image(self.gns3_image) def _remove_instances(self): """ Remove any instances that were created. """ for instance in self.ctrl.driver.list_nodes(): if instance.name[0 : self.prefix_length] == self.object_prefix: self.ctrl.driver.destroy_node(instance) def _delete_container(self): try: container = self.ctrl.storage_driver.get_container(self.ctrl.GNS3_CONTAINER_NAME) for o in container.iterate_objects(): o.delete() container.delete() except ContainerDoesNotExistError: pass def _remove_key_pairs(self): """ Remove any key pairs that were created. """ for key_pair in self.ctrl.driver.list_key_pairs(): if key_pair.name[0 : self.prefix_length] == self.object_prefix: self.ctrl.driver.delete_key_pair(key_pair) def test_authenticate_valid_user(self): """ Test authentication with a valid user and api key. """ ctrl = RackspaceCtrl(self.username, self.api_key, "http://foo.bar:8888") auth_result = ctrl.authenticate() self.assertEqual(auth_result, True) self.assertIsNotNone(ctrl.token) def test_authenticate_empty_user(self): """ Ensure authentication with empty string as username fails. """ ctrl = RackspaceCtrl("", self.api_key, "http://foo.bar:8888") auth_result = ctrl.authenticate() self.assertEqual(auth_result, False) self.assertIsNone(ctrl.token) def test_authenticate_empty_apikey(self): """ Ensure authentication with empty string as api_key fails. """ ctrl = RackspaceCtrl(self.username, "", "http://foo.bar:8888") auth_result = ctrl.authenticate() self.assertEqual(auth_result, False) self.assertIsNone(ctrl.token) def test_authenticate_invalid_user(self): """ Ensure authentication with invalid user credentials fails. """ ctrl = RackspaceCtrl("invalid_user", "invalid_api_key", "http://foo.bar:8888") auth_result = ctrl.authenticate() self.assertEqual(auth_result, False) self.assertIsNone(ctrl.token) def test_set_region(self): """ Ensure that set_region sets 'region' and 'driver'. """ ctrl = RackspaceCtrl(self.username, self.api_key, "http://foo.bar:8888") ctrl.authenticate() result = ctrl.set_region("iad") self.assertEqual(result, True) self.assertEqual(ctrl.region, "iad") self.assertIsNotNone(ctrl.driver) def test_set_invalid_region(self): """ Ensure that calling 'set_region' with an invalid param fails. """ ctrl = RackspaceCtrl(self.username, self.api_key, "http://foo.bar:8888") ctrl.authenticate() result = self.ctrl.set_region("invalid") self.assertEqual(result, False) self.assertIsNone(ctrl.region) self.assertIsNone(ctrl.driver) def test_create_instance(self): """ Test creating an instance. """ name = "%screate_instance" % self.object_prefix image = self.ctrl.driver.list_images()[0] size = self.ctrl.driver.list_sizes()[0] key_pair = self.ctrl.create_key_pair(name) instance = self.ctrl.create_instance(name, size, image, key_pair) if self.run_instances: self.ctrl.driver.wait_until_running([instance]) self.assertIsInstance(instance, Node) def test_delete_instance(self): """ Test deleting an instance. """ name = "%sdelete_instances" % self.object_prefix image = self.ctrl.driver.list_images()[0] size = self.ctrl.driver.list_sizes()[0] key_pair = self.ctrl.create_key_pair(name) instance = self.ctrl.create_instance(name, size, image, key_pair) if self.run_instances: self.ctrl.driver.wait_until_running([instance]) response = self.ctrl.delete_instance(instance) self.assertEqual(response, True) def test_delete_invalid_instance_id(self): fake_instance = StubObject(id="invalid_id") self.assertRaises(ItemNotFound, self.ctrl.delete_instance, fake_instance) def test_create_key_pair(self): """ Test creating a key pair. """ name = "%screate_key_pair" % self.object_prefix key_pair = self.ctrl.create_key_pair(name) self.assertIsInstance(key_pair, KeyPair) response = self.ctrl.delete_key_pair(key_pair) self.assertEqual(response, True) def test_create_key_pair_existing_name(self): """ Test creating a key pair with an existing name. """ name = "%screate_key_pair_existing_name" % self.object_prefix # Create the first instance self.ctrl.create_key_pair(name) self.assertRaises(KeyPairExists, self.ctrl.create_key_pair, name) def test_delete_key_pair(self): """ Test deleting a key pair. """ name = "%sdelete_key_pair" % self.object_prefix key_pair = self.ctrl.create_key_pair(name) result = self.ctrl.delete_key_pair(key_pair) self.assertEqual(result, True) def test_delete_nonexistant_key_pair(self): """ Test deleting a key pair that doesn't exist. """ fake_key_pair = StubObject(name="invalid_name") self.assertRaises(ItemNotFound, self.ctrl.delete_key_pair, fake_key_pair) def test_list_regions(self): """ Ensure that list_regions returns the correct result. """ regions = self.ctrl.list_regions() expected_regions = [{"IAD": "iad"}, {"DFW": "dfw"}, {"SYD": "syd"}, {"ORD": "ord"}, {"HKG": "hkg"}] self.assertCountEqual(regions, expected_regions) def test_list_instances(self): name = "%slist_instances" % self.object_prefix image = self.ctrl.driver.list_images()[0] size = self.ctrl.driver.list_sizes()[0] key_pair = self.ctrl.create_key_pair(name) instance = self.ctrl.create_instance(name, size, image, key_pair) if self.run_instances: self.ctrl.driver.wait_until_running([instance]) instances = self.ctrl.list_instances() self.assertIsInstance(instances, list) self.assertIsInstance(instances[0], Node) def test_list_sizes(self): sizes = self.ctrl.list_sizes() self.assertIsInstance(sizes, list) self.assertIsInstance(sizes[0], NodeSize) def test_token_parsed(self): """ Ensure that the token is set. """ self.assertIsNotNone(self.ctrl.token) def test__get_shared_image_not_found(self): self.assertRaises(ItemNotFound, self.ctrl._get_shared_images, "user_foo", "IAD", "foo_ver") def test__get_shared_image(self): name = "%s_get_shared_image" % self.object_prefix images = self.ctrl.driver.list_images() # use the smallest image available on Rackspace image = [i for i in images if "boot.rackspace.com" in i.name][0] size = self.ctrl.driver.list_sizes()[0] key_pair = self.ctrl.create_key_pair(name) print("Creating an instance...") instance = self.ctrl.create_instance(name, size, image, key_pair) # we cannot create images until the build is over self.ctrl.driver.wait_until_running([instance]) print("Instance up and running.") print("Creating an image...") gns3_image1 = self.ctrl.driver.ex_save_image(instance, "gns3_3.0a", metadata=None) # wait until image is active or gns3-ias will ignore it while self.ctrl.driver.ex_get_image(gns3_image1.id).extra["status"] != "ACTIVE": time.sleep(2) print("Image created.") # wait to avoid Exception: 409 Conflict Cannot 'createImage' while instance is in task_state image_uploading self.ctrl.driver.wait_until_running([instance]) print("Creating another image...") gns3_image2 = self.ctrl.driver.ex_save_image(instance, "gns3_3.0b", metadata=None) # wait until image is active or gns3-ias will ignore it while self.ctrl.driver.ex_get_image(gns3_image2.id).extra["status"] != "ACTIVE": time.sleep(2) print("Image created.") print("Getting shared images...") r_images = self.ctrl._get_shared_images("user_foo", "ORD", "3.0") self.assertTrue("image_id" in r_images[0]) self.assertTrue("image_id" in r_images[1]) self.assertTrue("member_id" in r_images[0]) self.assertTrue("member_id" in r_images[1]) self.assertTrue("status" in r_images[0]) self.assertTrue("status" in r_images[1]) self.assertEqual(r_images[0]["status"], "pending") self.assertEqual(r_images[1]["status"], "pending") print("Done.") print("Getting shared images...") r_images2 = self.ctrl._get_shared_images("user_foo", "ORD", "3.0") self.assertTrue("image_id" in r_images2[0]) self.assertTrue("image_id" in r_images2[1]) self.assertEqual(r_images[0]["image_id"], r_images2[0]["image_id"]) self.assertEqual(r_images[1]["image_id"], r_images2[1]["image_id"]) self.assertTrue("member_id" in r_images2[0]) self.assertTrue("member_id" in r_images2[1]) self.assertEqual(r_images[0]["member_id"], r_images2[0]["member_id"]) self.assertEqual(r_images[1]["member_id"], r_images2[1]["member_id"]) self.assertTrue("status" in r_images2[0]) self.assertTrue("status" in r_images2[1]) self.assertEqual(r_images2[0]["status"], "ALREADYREQUESTED") self.assertEqual(r_images2[1]["status"], "ALREADYREQUESTED") print("Done.") def test_upload_file(self): try: test_data = "abcdefg" test_file = tempfile.NamedTemporaryFile(mode="w") with test_file.file as f: f.write(test_data) return_value = self.ctrl.upload_file(test_file.name, "test_folder/test_file.txt") container = self.ctrl.storage_driver.get_container(self.ctrl.GNS3_CONTAINER_NAME) file_object = container.get_object("test_folder/test_file.txt") hash_object = container.get_object("test_folder/test_file.txt.md5") cloud_file_hash = "" for chunk in hash_object.as_stream(): cloud_file_hash += chunk.decode("utf8") cloud_file_contents = "" for chunk in file_object.as_stream(): cloud_file_contents += chunk.decode("utf8") self.assertEqual(cloud_file_hash, hashlib.md5(test_data.encode("utf8")).hexdigest()) self.assertEqual(cloud_file_contents, test_data) self.assertEqual(return_value, True) finally: self._delete_container() def test_list_projects(self): container = self.ctrl.storage_driver.create_container(self.ctrl.GNS3_CONTAINER_NAME) try: container.upload_object_via_stream(StringIO("abcd"), "projects/project1.gns3.zip") container.upload_object_via_stream(StringIO("abcd"), "projects/project1.gns3.zip.md5") container.upload_object_via_stream(StringIO("abcd"), "projects/project2.gns3.zip") container.upload_object_via_stream(StringIO("abcd"), "some_file.txt") container.upload_object_via_stream(StringIO("abcd"), "some_file2.zip") projects = self.ctrl.list_projects() self.assertDictEqual( projects, {"project1.gns3": "projects/project1.gns3.zip", "project2.gns3": "projects/project2.gns3.zip"} ) finally: self._delete_container() def test_download_file(self): container = self.ctrl.storage_driver.create_container(self.ctrl.GNS3_CONTAINER_NAME) try: test_data = b"abcdef" container.upload_object_via_stream(BytesIO(test_data), "projects/project1.gns3.zip") downloaded_data = self.ctrl.download_file("projects/project1.gns3.zip") self.assertEqual(downloaded_data.read(), test_data) finally: self._delete_container() def test_download_file__to_filesystem(self): container = self.ctrl.storage_driver.create_container(self.ctrl.GNS3_CONTAINER_NAME) try: test_data = b"abcd" container.upload_object_via_stream(BytesIO(test_data), "projects/project1.gns3.zip") self.ctrl.download_file("projects/project1.gns3.zip", "downloaded_file.zip") with open("downloaded_file.zip", "rb") as f: self.assertEqual(f.read(), test_data) finally: self._delete_container() os.remove("downloaded_file.zip") def test_delete_file(self): container = self.ctrl.storage_driver.create_container(self.ctrl.GNS3_CONTAINER_NAME) try: container.upload_object_via_stream(StringIO("abcde"), "projects/project1.gns3.zip") container.upload_object_via_stream(StringIO("1234"), "projects/project1.gns3.zip.md5") self.ctrl.delete_file("projects/project1.gns3.zip") self.assertRaises(ObjectDoesNotExistError, container.get_object, "projects/project1.gns3.zip") self.assertRaises(ObjectDoesNotExistError, container.get_object, "projects/project1.gns3.zip.md5") finally: self._delete_container()
class TestRackspaceCtrl(unittest.TestCase): def setUp(self): """ Set up the objects used by most of the tests. """ self.ctrl = RackspaceCtrl("valid_user", "valid_api_key", "http://foo.bar:8888") self.ctrl.post_fn = stub_rackspace_identity_post self.driver_cls = MockLibCloudDriver def test_authenticate_valid_user(self): """ Test authentication with a valid user and api key. """ auth_result = self.ctrl.authenticate() self.assertEqual(auth_result, True) self.assertIsNotNone(self.ctrl.token) def test_authenticate_empty_user(self): """ Ensure authentication with empty string as username fails. """ ctrl = RackspaceCtrl("", "valid_api_key", "http://foo.bar:8888") ctrl.post_fn = stub_rackspace_identity_post auth_result = ctrl.authenticate() self.assertEqual(auth_result, False) self.assertIsNone(ctrl.token) def test_authenticate_empty_apikey(self): """ Ensure authentication with empty string as api_key fails. """ ctrl = RackspaceCtrl("valid_user", "", "http://foo.bar:8888") ctrl.post_fn = stub_rackspace_identity_post auth_result = ctrl.authenticate() self.assertEqual(auth_result, False) self.assertIsNone(ctrl.token) def test_authenticate_invalid_user(self): """ Ensure authentication with invalid user credentials fails. """ ctrl = RackspaceCtrl("invalid_user", "invalid_api_key", "http://foo.bar:8888") ctrl.post_fn = stub_rackspace_identity_post auth_result = ctrl.authenticate() self.assertEqual(auth_result, False) self.assertIsNone(ctrl.token) def test_list_regions(self): """ Ensure that list_regions returns the correct result. """ self.ctrl.authenticate() regions = self.ctrl.list_regions() expected_regions = [{"IAD": "iad"}, {"DFW": "dfw"}, {"SYD": "syd"}, {"ORD": "ord"}] self.assertCountEqual(regions, expected_regions) def test_set_region(self): """ Ensure that set_region sets 'region' and 'driver'. """ self.ctrl.authenticate() result = self.ctrl.set_region("iad") self.assertEqual(result, True) self.assertEqual(self.ctrl.region, "iad") self.assertIsNotNone(self.ctrl.driver) def test_set_invalid_region(self): """ Ensure that calling 'set_region' with an invalid param fails. """ self.ctrl.authenticate() result = self.ctrl.set_region("invalid") self.assertEqual(result, False) self.assertIsNone(self.ctrl.region) self.assertIsNone(self.ctrl.driver) def test_token_parsed(self): """ Ensure that the token is set. """ ctrl = RackspaceCtrl("valid_user", "valid_api_key", "http://foo.bar:8888") ctrl.post_fn = stub_rackspace_identity_post ctrl.authenticate() self.assertEqual("abcdefgh0123456789", ctrl.token) def test_upload_file(self): self.ctrl.storage_driver = mock.MagicMock() mock_container = mock.MagicMock() mock_container.list_objects = mock.MagicMock(return_value=[]) self.ctrl.storage_driver.create_container = mock.MagicMock(return_value=mock_container) test_data = b"abcdef" test_data_hash = hashlib.md5(test_data).hexdigest() test_file = tempfile.NamedTemporaryFile() with test_file.file as f: f.write(test_data) return_value = self.ctrl.upload_file(test_file.name, "test_folder/test.txt") upload_file_args = self.ctrl.storage_driver.upload_object_via_stream.call_args_list[0] upload_hash_args = self.ctrl.storage_driver.upload_object_via_stream.call_args_list[1] self.assertEqual(upload_file_args[0][2], "test_folder/test.txt") self.assertEqual(upload_hash_args[0][2], "test_folder/test.txt.md5") self.assertEqual(upload_file_args[0][0].name, test_file.name) self.assertEqual(upload_hash_args[0][0].read(), test_data_hash) self.assertEqual(return_value, True) def test_upload_file__exists(self): test_data = b"abcdef" test_data_hash = hashlib.md5(test_data).hexdigest() test_file = tempfile.NamedTemporaryFile() with test_file.file as f: f.write(test_data) self.ctrl.storage_driver = mock.MagicMock() mock_container = mock.MagicMock() mock_container.list_objects = mock.MagicMock( return_value=[MockStorageObject("test_folder/test.txt"), MockStorageObject("test_folder/test.txt.md5")] ) self.ctrl.storage_driver.create_container = mock.MagicMock(return_value=mock_container) mock_container.get_object = mock.MagicMock(return_value=MockStorageObject("", bytes(test_data_hash, "utf8"))) return_value = self.ctrl.upload_file(test_file.name, "test_folder/test.txt") self.assertFalse(self.ctrl.storage_driver.upload_object_via_stream.called) self.assertEqual(return_value, False) def test_download_file__exists__same_hash(self): test_data = b"abcdefghi" test_data_hash = hashlib.md5(test_data).hexdigest() test_file = tempfile.NamedTemporaryFile() with test_file.file as f: f.write(test_data) self.ctrl.storage_driver = mock.MagicMock() mock_container = mock.MagicMock() self.ctrl.storage_driver.get_container = mock.MagicMock(return_value=mock_container) file_object = MockStorageObject("test_file.txt") file_object.download = mock.MagicMock() file_hash_object = MockStorageObject("test_file.txt", bytes(test_data_hash, "utf8")) mock_container.get_object = lambda name: {"test_file.txt": file_object, "test_file.txt.md5": file_hash_object}[ name ] self.ctrl.download_file("test_file.txt", test_file.name) self.assertFalse(file_object.download.called) def test_download_file__exists__different_hash(self): test_data = b"abcdefghij" test_data_hash = "some_garbage_hash" test_file = tempfile.NamedTemporaryFile() with test_file.file as f: f.write(test_data) self.ctrl.storage_driver = mock.MagicMock() mock_container = mock.MagicMock() self.ctrl.storage_driver.get_container = mock.MagicMock(return_value=mock_container) file_object = MockStorageObject("test_file.txt") file_object.download = mock.MagicMock() file_hash_object = MockStorageObject("test_file.txt", bytes(test_data_hash, "utf8")) mock_container.get_object = lambda name: {"test_file.txt": file_object, "test_file.txt.md5": file_hash_object}[ name ] self.ctrl.download_file("test_file.txt", test_file.name) file_object.download.assert_called_once_with(test_file.name) def test_find_storage_image_names(self): self.ctrl.storage_driver = mock.MagicMock() mock_container = mock.MagicMock() self.ctrl.storage_driver.get_container = mock.MagicMock(return_value=mock_container) mock_container.list_objects = mock.MagicMock( return_value=[ MockStorageObject("images/IOS/test_image_1.image"), MockStorageObject("images/IOS/test_image_1.image.md5"), MockStorageObject("images/IOS/test_image_2.img"), MockStorageObject("images/IOS/test_image_2.img.md5"), MockStorageObject("images/IOS/test_image_3.img"), MockStorageObject("projects/project1.zip"), MockStorageObject("test_image_1.image"), ] ) image_names = self.ctrl.find_storage_image_names(["test_image_1.image", "test_image_2.img"]) self.assertDictEqual( image_names, {"test_image_1.image": "images/IOS/test_image_1.image", "test_image_2.img": "images/IOS/test_image_2.img"}, ) def test_find_storage_image_names__missing(self): self.ctrl.storage_driver = mock.MagicMock() mock_container = mock.MagicMock() self.ctrl.storage_driver.get_container = mock.MagicMock(return_value=mock_container) mock_container.list_objects = mock.MagicMock( return_value=[ MockStorageObject("images/IOS/test_image_1.image"), MockStorageObject("images/IOS/test_image_1.image.md5"), MockStorageObject("images/IOS/test_image_2.img.md5"), MockStorageObject("projects/project1.zip"), MockStorageObject("test_image_1.image"), ] ) self.assertRaises(Exception, self.ctrl.find_storage_image_names, ["test_image_1.image", "test_image_2.img"])