|
25 | 25 | # Import Integration Libraries |
26 | 26 | # base - contains all resources as entities and defines create, delete, list operations on them |
27 | 27 | from marvin.lib.base import Account, DiskOffering, ServiceOffering, Snapshot, StoragePool, Template, User, \ |
28 | | - VirtualMachine, Volume |
| 28 | + VirtualMachine, VmSnapshot, Volume |
29 | 29 |
|
30 | 30 | # common - commonly used methods for all tests are listed here |
31 | 31 | from marvin.lib.common import get_domain, get_template, get_zone, list_clusters, list_hosts, list_virtual_machines, \ |
@@ -887,8 +887,94 @@ def test_08_delete_volume_was_attached(self): |
887 | 887 | "Check volume was deleted" |
888 | 888 | ) |
889 | 889 |
|
| 890 | + @attr(tags=['basic'], required_hardware=False) |
| 891 | + def test_09_create_snapshot(self): |
| 892 | + """Create snapshot of root disk""" |
| 893 | + self.virtual_machine.stop(self.apiClient) |
| 894 | + |
| 895 | + volume = list_volumes( |
| 896 | + self.apiClient, |
| 897 | + virtualmachineid = self.virtual_machine.id, |
| 898 | + type = "ROOT", |
| 899 | + listall = True, |
| 900 | + ) |
| 901 | + snapshot = Snapshot.create( |
| 902 | + self.apiClient, |
| 903 | + volume_id = volume[0].id, |
| 904 | + account=self.account.name, |
| 905 | + domainid=self.domain.id, |
| 906 | + ) |
| 907 | + |
| 908 | + self.assertIsNotNone(snapshot, "Could not create snapshot") |
| 909 | + |
| 910 | + snapshot.delete(self.apiClient) |
| 911 | + |
| 912 | + @attr(tags=['basic'], required_hardware=False) |
| 913 | + def test_10_create_template_from_snapshot(self): |
| 914 | + """ |
| 915 | + Create a template from a snapshot and start an instance from it |
| 916 | + """ |
| 917 | + self.virtual_machine.stop(self.apiClient) |
| 918 | + |
| 919 | + volume = list_volumes( |
| 920 | + self.apiClient, |
| 921 | + virtualmachineid = self.virtual_machine.id, |
| 922 | + type = "ROOT", |
| 923 | + listall = True, |
| 924 | + ) |
| 925 | + snapshot = Snapshot.create( |
| 926 | + self.apiClient, |
| 927 | + volume_id=volume[0].id, |
| 928 | + account=self.account.name, |
| 929 | + domainid=self.domain.id, |
| 930 | + ) |
| 931 | + self.cleanup.append(snapshot) |
| 932 | + |
| 933 | + self.assertIsNotNone(snapshot, "Could not create snapshot") |
| 934 | + |
| 935 | + services = { |
| 936 | + "displaytext": "IntegrationTestTemplate", |
| 937 | + "name": "int-test-template", |
| 938 | + "ostypeid": self.template.ostypeid, |
| 939 | + "ispublic": "true" |
| 940 | + } |
| 941 | + |
| 942 | + custom_template = Template.create_from_snapshot( |
| 943 | + self.apiClient, |
| 944 | + snapshot, |
| 945 | + services, |
| 946 | + ) |
| 947 | + self.cleanup.append(custom_template) |
| 948 | + |
| 949 | + # create VM from custom template |
| 950 | + test_virtual_machine = VirtualMachine.create( |
| 951 | + self.apiClient, |
| 952 | + self.testdata[TestData.virtualMachine2], |
| 953 | + accountid=self.account.name, |
| 954 | + zoneid=self.zone.id, |
| 955 | + serviceofferingid=self.compute_offering.id, |
| 956 | + templateid=custom_template.id, |
| 957 | + domainid=self.domain.id, |
| 958 | + startvm=False, |
| 959 | + mode='basic', |
| 960 | + ) |
| 961 | + self.cleanup.append(test_virtual_machine) |
| 962 | + |
| 963 | + TestLinstorVolumes._start_vm(test_virtual_machine) |
| 964 | + |
| 965 | + test_virtual_machine.stop(self.apiClient) |
| 966 | + |
| 967 | + test_virtual_machine.delete(self.apiClient, True) |
| 968 | + self.cleanup.remove(test_virtual_machine) |
| 969 | + |
| 970 | + custom_template.delete(self.apiClient) |
| 971 | + self.cleanup.remove(custom_template) |
| 972 | + snapshot.delete(self.apiClient) |
| 973 | + self.cleanup.remove(snapshot) |
| 974 | + |
| 975 | + |
890 | 976 | @attr(tags=['advanced', 'migration'], required_hardware=False) |
891 | | - def test_09_migrate_volume_to_same_instance_pool(self): |
| 977 | + def test_11_migrate_volume_to_same_instance_pool(self): |
892 | 978 | """Migrate volume to the same instance pool""" |
893 | 979 |
|
894 | 980 | if not self.testdata[TestData.migrationTests]: |
@@ -1020,7 +1106,7 @@ def test_09_migrate_volume_to_same_instance_pool(self): |
1020 | 1106 | test_virtual_machine.delete(self.apiClient, True) |
1021 | 1107 |
|
1022 | 1108 | @attr(tags=['advanced', 'migration'], required_hardware=False) |
1023 | | - def test_10_migrate_volume_to_distinct_instance_pool(self): |
| 1109 | + def test_12_migrate_volume_to_distinct_instance_pool(self): |
1024 | 1110 | """Migrate volume to distinct instance pool""" |
1025 | 1111 |
|
1026 | 1112 | if not self.testdata[TestData.migrationTests]: |
@@ -1151,6 +1237,132 @@ def test_10_migrate_volume_to_distinct_instance_pool(self): |
1151 | 1237 |
|
1152 | 1238 | test_virtual_machine.delete(self.apiClient, True) |
1153 | 1239 |
|
| 1240 | + @attr(tags=["basic"], required_hardware=False) |
| 1241 | + def test_13_create_vm_snapshots(self): |
| 1242 | + """Test to create VM snapshots |
| 1243 | + """ |
| 1244 | + vm = TestLinstorVolumes._start_vm(self.virtual_machine) |
| 1245 | + |
| 1246 | + try: |
| 1247 | + # Login to VM and write data to file system |
| 1248 | + self.debug("virt: {}".format(vm)) |
| 1249 | + ssh_client = self.virtual_machine.get_ssh_client(vm.ipaddress, retries=5) |
| 1250 | + ssh_client.execute("echo 'hello world' > testfile") |
| 1251 | + ssh_client.execute("sync") |
| 1252 | + except Exception as exc: |
| 1253 | + self.fail("SSH failed for Virtual machine {}: {}".format(self.virtual_machine.ssh_ip, exc)) |
| 1254 | + |
| 1255 | + time.sleep(10) |
| 1256 | + memory_snapshot = False |
| 1257 | + vm_snapshot = VmSnapshot.create( |
| 1258 | + self.apiClient, |
| 1259 | + self.virtual_machine.id, |
| 1260 | + memory_snapshot, |
| 1261 | + "VMSnapshot1", |
| 1262 | + "test snapshot" |
| 1263 | + ) |
| 1264 | + self.assertEqual( |
| 1265 | + vm_snapshot.state, |
| 1266 | + "Ready", |
| 1267 | + "Check the snapshot of vm is ready!" |
| 1268 | + ) |
| 1269 | + |
| 1270 | + @attr(tags=["basic"], required_hardware=False) |
| 1271 | + def test_14_revert_vm_snapshots(self): |
| 1272 | + """Test to revert VM snapshots |
| 1273 | + """ |
| 1274 | + |
| 1275 | + result = None |
| 1276 | + try: |
| 1277 | + ssh_client = self.virtual_machine.get_ssh_client(reconnect=True) |
| 1278 | + result = ssh_client.execute("rm -rf testfile") |
| 1279 | + except Exception as exc: |
| 1280 | + self.fail("SSH failed for Virtual machine %s: %s".format(self.virtual_machine.ipaddress, exc)) |
| 1281 | + |
| 1282 | + if result is not None and "No such file or directory" in str(result): |
| 1283 | + self.fail("testfile not deleted") |
| 1284 | + |
| 1285 | + time.sleep(5) |
| 1286 | + |
| 1287 | + list_snapshot_response = VmSnapshot.list( |
| 1288 | + self.apiClient, |
| 1289 | + virtualmachineid=self.virtual_machine.id, |
| 1290 | + listall=True) |
| 1291 | + |
| 1292 | + self.assertEqual( |
| 1293 | + isinstance(list_snapshot_response, list), |
| 1294 | + True, |
| 1295 | + "Check list response returns a valid list" |
| 1296 | + ) |
| 1297 | + self.assertNotEqual( |
| 1298 | + list_snapshot_response, |
| 1299 | + None, |
| 1300 | + "Check if snapshot exists in ListSnapshot" |
| 1301 | + ) |
| 1302 | + |
| 1303 | + self.assertEqual( |
| 1304 | + list_snapshot_response[0].state, |
| 1305 | + "Ready", |
| 1306 | + "Check the snapshot of vm is ready!" |
| 1307 | + ) |
| 1308 | + |
| 1309 | + self.virtual_machine.stop(self.apiClient, forced=True) |
| 1310 | + |
| 1311 | + VmSnapshot.revertToSnapshot( |
| 1312 | + self.apiClient, |
| 1313 | + list_snapshot_response[0].id |
| 1314 | + ) |
| 1315 | + |
| 1316 | + TestLinstorVolumes._start_vm(self.virtual_machine) |
| 1317 | + |
| 1318 | + try: |
| 1319 | + ssh_client = self.virtual_machine.get_ssh_client(reconnect=True) |
| 1320 | + |
| 1321 | + result = ssh_client.execute("cat testfile") |
| 1322 | + |
| 1323 | + except Exception as exc: |
| 1324 | + self.fail("SSH failed for Virtual machine {}: {}".format(self.virtual_machine.ipaddress, exc)) |
| 1325 | + |
| 1326 | + self.assertEqual( |
| 1327 | + "hello world", |
| 1328 | + result[0], |
| 1329 | + "Check the content is the same as originally written" |
| 1330 | + ) |
| 1331 | + |
| 1332 | + @attr(tags=["basic"], required_hardware=False) |
| 1333 | + def test_15_delete_vm_snapshots(self): |
| 1334 | + """Test to delete vm snapshots |
| 1335 | + """ |
| 1336 | + |
| 1337 | + list_snapshot_response = VmSnapshot.list( |
| 1338 | + self.apiClient, |
| 1339 | + virtualmachineid=self.virtual_machine.id, |
| 1340 | + listall=True) |
| 1341 | + |
| 1342 | + self.assertEqual( |
| 1343 | + isinstance(list_snapshot_response, list), |
| 1344 | + True, |
| 1345 | + "Check list response returns a valid list" |
| 1346 | + ) |
| 1347 | + self.assertNotEqual( |
| 1348 | + list_snapshot_response, |
| 1349 | + None, |
| 1350 | + "Check if snapshot exists in ListSnapshot" |
| 1351 | + ) |
| 1352 | + VmSnapshot.deleteVMSnapshot( |
| 1353 | + self.apiClient, |
| 1354 | + list_snapshot_response[0].id) |
| 1355 | + |
| 1356 | + time.sleep(5) |
| 1357 | + |
| 1358 | + list_snapshot_response = VmSnapshot.list( |
| 1359 | + self.apiClient, |
| 1360 | + virtualmachineid=self.virtual_machine.id, |
| 1361 | + listall=False) |
| 1362 | + self.debug('list_snapshot_response -------------------- {}'.format(list_snapshot_response)) |
| 1363 | + |
| 1364 | + self.assertIsNone(list_snapshot_response, "snapshot is already deleted") |
| 1365 | + |
1154 | 1366 | def _create_vm_using_template_and_destroy_vm(self, template): |
1155 | 1367 | vm_name = "VM-%d" % random.randint(0, 100) |
1156 | 1368 |
|
|
0 commit comments