def test_publish(self): """Instances can be published.""" self.add_rule( { "text": json.dumps( { "type": "sync", "metadata": { "id": "operation-abc", "metadata": { "fingerprint": ( "e3b0c44298fc1c149afbf4c8996fb92427" "ae41e4649b934ca495991b7852b855" ) }, }, } ), "method": "GET", "url": r"^http://pylxd.test/1.0/operations/operation-abc$", } ) an_instance = models.Instance(self.client, name="an-instance") # Hack to get around mocked data an_instance.type = "container" image = an_instance.publish(wait=True) self.assertEqual( "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", image.fingerprint, )
def test_publish(self): """Instances can be published.""" self.add_rule({ 'text': json.dumps({ 'type': 'sync', 'metadata': { 'id': 'operation-abc', 'metadata': { 'fingerprint': ('e3b0c44298fc1c149afbf4c8996fb92427' 'ae41e4649b934ca495991b7852b855') } } }), 'method': 'GET', 'url': r'^http://pylxd.test/1.0/operations/operation-abc$', }) an_instance = models.Instance( self.client, name='an-instance') # Hack to get around mocked data an_instance.type = 'container' image = an_instance.publish(wait=True) self.assertEqual( 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', image.fingerprint)
def test_rename(self): an_instance = models.Instance( self.client, name='an-instance') an_instance.rename('an-renamed-instance', wait=True) self.assertEqual('an-renamed-instance', an_instance.name)
def test_fetch(self): """A sync updates the properties of a instance.""" an_instance = models.Instance(self.client, name="an-instance") an_instance.sync() self.assertTrue(an_instance.ephemeral)
def test_raw_interactive_execute_string(self): """A command passed as string raises a TypeError.""" an_instance = models.Instance(self.client, name="an-instance") self.assertRaises( TypeError, an_instance.raw_interactive_execute, "apt-get update" )
def test_delete(self): """A instance is deleted.""" # XXX: rockstar (21 May 2016) - This just executes # a code path. There should be an assertion here, but # it's not clear how to assert that, just yet. an_instance = models.Instance(self.client, name="an-instance") an_instance.delete(wait=True)
def test_raw_interactive_execute(self): an_instance = models.Instance(self.client, name="an-instance") result = an_instance.raw_interactive_execute(["/bin/bash"]) self.assertEqual(result["ws"], "/1.0/operations/operation-abc/websocket?secret=abc") self.assertEqual(result["control"], "/1.0/operations/operation-abc/websocket?secret=jkl")
def test_raw_interactive_execute(self): an_instance = models.Instance(self.client, name='an-instance') result = an_instance.raw_interactive_execute(['/bin/bash']) self.assertEqual(result['ws'], '/1.0/operations/operation-abc/websocket?secret=abc') self.assertEqual(result['control'], '/1.0/operations/operation-abc/websocket?secret=jkl')
def test_migrate(self): """A instance is migrated.""" from pylxd.client import Client client2 = Client(endpoint="http://pylxd2.test") an_instance = models.Instance(self.client, name="an-instance") an_migrated_instance = an_instance.migrate(client2) self.assertEqual("an-instance", an_migrated_instance.name) self.assertEqual(client2, an_migrated_instance.client)
def test_raw_interactive_execute_options(self): """It's possible to pass user, group and cwd arguments to an execute command.""" an_instance = models.Instance(self.client, name="an-instance") result = an_instance.raw_interactive_execute(["/bin/bash"], user="******", group="group", cwd="/some/path") self.assertEqual(result["ws"], "/1.0/operations/operation-abc/websocket?secret=abc") self.assertEqual(result["control"], "/1.0/operations/operation-abc/websocket?secret=jkl")
def test_execute_with_env(self, _CommandWebsocketClient, _StdinWebsocket): """A command is executed on a instance with custom env variables.""" fake_websocket = mock.Mock() fake_websocket.data = "test\n" _StdinWebsocket.return_value = fake_websocket _CommandWebsocketClient.return_value = fake_websocket an_instance = models.Instance(self.client, name="an-instance") result = an_instance.execute(["echo", "test"], environment={"DISPLAY": ":1"}) self.assertEqual(0, result.exit_code) self.assertEqual("test\n", result.stdout)
def test_execute(self, _CommandWebsocketClient, _StdinWebsocket): """A command is executed on a instance.""" fake_websocket = mock.Mock() fake_websocket.data = "test\n" _StdinWebsocket.return_value = fake_websocket _CommandWebsocketClient.return_value = fake_websocket an_instance = models.Instance(self.client, name="an-instance") result = an_instance.execute(["echo", "test"]) self.assertEqual(0, result.exit_code) self.assertEqual("test\n", result.stdout)
def test_execute(self, _CommandWebsocketClient, _StdinWebsocket): """A command is executed on a instance.""" fake_websocket = mock.Mock() fake_websocket.data = 'test\n' _StdinWebsocket.return_value = fake_websocket _CommandWebsocketClient.return_value = fake_websocket an_instance = models.Instance( self.client, name='an-instance') result = an_instance.execute(['echo', 'test']) self.assertEqual(0, result.exit_code) self.assertEqual('test\n', result.stdout)
def test_execute_no_ws4py(self): """If ws4py is not installed, ValueError is raised.""" from pylxd.models import instance old_installed = instance._ws4py_installed instance._ws4py_installed = False def cleanup(): instance._ws4py_installed = old_installed self.addCleanup(cleanup) an_instance = models.Instance( self.client, name='an-instance') self.assertRaises(ValueError, an_instance.execute, ['echo', 'test'])
def test_migrate_local_client(self, get): """Migration from local clients is not supported.""" # Mock out the _APINode for the local instance. response = mock.Mock() response.json.return_value = {"metadata": {"fake": "response"}} response.status_code = 200 get.return_value = response from pylxd.client import Client client2 = Client(endpoint="http+unix://pylxd2.test") an_instance = models.Instance(client2, name="an-instance") self.assertRaises(ValueError, an_instance.migrate, self.client)
def test_update(self): """A instance is updated.""" an_instance = models.Instance(self.client, name="an-instance") an_instance.architecture = 1 an_instance.config = {} an_instance.created_at = 1 an_instance.devices = {} an_instance.ephemeral = 1 an_instance.expanded_config = {} an_instance.expanded_devices = {} an_instance.profiles = 1 an_instance.status = 1 an_instance.save(wait=True) self.assertTrue(an_instance.ephemeral)
def test_migrate_exception_error(self, generate_migration_data): """LXDAPIException is raised in case of migration failure""" from pylxd.client import Client from pylxd.exceptions import LXDAPIException def generate_exception(*args, **kwargs): response = mock.Mock() response.status_code = 400 raise LXDAPIException(response) generate_migration_data.side_effect = generate_exception an_instance = models.Instance(self.client, name="an-instance") client2 = Client(endpoint="http://pylxd2.test") self.assertRaises(LXDAPIException, an_instance.migrate, client2)
def test_fetch_error(self): """LXDAPIException is raised on error.""" def not_found(request, context): context.status_code = 500 return json.dumps({ 'type': 'error', 'error': 'An bad error', 'error_code': 500}) self.add_rule({ 'text': not_found, 'method': 'GET', 'url': r'^http://pylxd.test/1.0/instances/an-missing-instance$', }) an_instance = models.Instance( self.client, name='an-missing-instance') self.assertRaises(exceptions.LXDAPIException, an_instance.sync)
def test_fetch_error(self): """LXDAPIException is raised on error.""" def not_found(request, context): context.status_code = 500 return json.dumps( {"type": "error", "error": "An bad error", "error_code": 500} ) self.add_rule( { "text": not_found, "method": "GET", "url": r"^http://pylxd.test/1.0/instances/an-missing-instance$", } ) an_instance = models.Instance(self.client, name="an-missing-instance") self.assertRaises(exceptions.LXDAPIException, an_instance.sync)
def test_migrate_exception_running(self, generate_migration_data): """Migrated instance already running on destination""" from pylxd.client import Client from pylxd.exceptions import LXDAPIException client2 = Client(endpoint="http://pylxd2.test") an_instance = models.Instance(self.client, name="an-instance") an_instance.status_code = 103 def generate_exception(*args, **kwargs): response = mock.Mock() response.status_code = 103 raise LXDAPIException(response) generate_migration_data.side_effect = generate_exception an_migrated_instance = an_instance.migrate(client2, live=True) self.assertEqual("an-instance", an_migrated_instance.name) self.assertEqual(client2, an_migrated_instance.client) generate_migration_data.assert_called_once_with(True)
def test_restore_snapshot(self): """Snapshots can be restored""" an_instance = models.Instance(self.client, name="an-instance") an_instance.restore_snapshot("thing")
def test_execute_string(self): """A command passed as string raises a TypeError.""" an_instance = models.Instance( self.client, name='an-instance') self.assertRaises(TypeError, an_instance.execute, 'apt-get update')
def test_rename(self): an_instance = models.Instance(self.client, name="an-instance") an_instance.rename("an-renamed-instance", wait=True) self.assertEqual("an-renamed-instance", an_instance.name)