class ImageSweeperTouchTimestampTestCase(unittest.TestCase): DATASTORE_ID = "DS01" BASE_TEMP_DIR = "image_sweeper" IMAGE_TIMESTAMP_FILENAME = EsxImageManager.IMAGE_TIMESTAMP_FILE_NAME IMAGE_TOMBSTONE_FILENAME = EsxImageManager.IMAGE_TOMBSTONE_FILE_NAME def setUp(self): self.test_dir = os.path.join(tempfile.mkdtemp(), self.BASE_TEMP_DIR) services.register(ServiceName.AGENT_CONFIG, MagicMock()) self.image_manager = EsxImageManager(MagicMock(), MagicMock()) self.vm_manager = MagicMock() self.image_sweeper = DatastoreImageSweeper(self.image_manager, self.DATASTORE_ID) self.image_sweeper._task_runner = MagicMock() self.image_sweeper._task_runner.is_stopped.return_value = False self.delete_count = 0 # Create various image directories and empty vmdks dir0 = os.path.join(self.test_dir, self.DATASTORE_ID, "images/im") self.dir0 = dir0 # Image dir with correct timestamp file image_id_1 = str(uuid.uuid4()) dir1 = self.create_dir(image_id_1) open(os.path.join( dir1, self.IMAGE_TIMESTAMP_FILENAME), 'w').close() # Image dir without the correct timestamp file image_id_2 = str(uuid.uuid4()) dir2 = self.create_dir(image_id_2) # Image dir with correct timestamp file # and with tombstone file image_id_3 = str(uuid.uuid4()) dir3 = self.create_dir(image_id_3) open(os.path.join( dir3, self.IMAGE_TIMESTAMP_FILENAME), 'w').close() open(os.path.join( dir3, self.IMAGE_TOMBSTONE_FILENAME), 'w').close() self.image_ids = ["", image_id_1, image_id_2, image_id_3] self.image_dirs = ["", dir1, dir2, dir3] def tearDown(self): shutil.rmtree(self.test_dir, True) @parameterized.expand([ # timestamp_exists, tombstone_exists (True, False), (True, True), (False, False) ]) # The os_vmdk_path method is defined in vm_config.py # but it is imported in esx/image_manager.py, that is # the instance we need to patch @patch("host.hypervisor.esx.image_manager.os_vmdk_path") def test_touch_timestamp_file(self, timestamp_exists, tombstone_exists, os_vmdk_path): if tombstone_exists: image_index = 3 exception_class = type(InvalidImageState()) elif not timestamp_exists: image_index = 2 exception_class = type(OSError()) else: image_index = 1 exception_class = None image_id = self.image_ids[image_index] image_dir = self.image_dirs[image_index] os_vmdk_path.side_effect = self.patched_os_vmdk_path timestamp_filename_path = \ os.path.join(image_dir, self.IMAGE_TIMESTAMP_FILENAME) pre_mod_time = 0 if timestamp_exists: # save mod time on the image timestamp file pre_mod_time = os.path.getmtime(timestamp_filename_path) try: time.sleep(1) self.image_manager.\ touch_image_timestamp(self.DATASTORE_ID, image_id) assert_that(exception_class is None) # check new timestamp post_mod_time = os.path.getmtime(timestamp_filename_path) assert_that((post_mod_time > pre_mod_time) is True) except Exception as ex: assert_that((type(ex) == exception_class) is True) @patch("host.hypervisor.esx.image_manager.os_vmdk_path") def test_create_tombstone_file(self, os_vmdk_path): image_index = 1 image_id = self.image_ids[image_index] image_dir = self.image_dirs[image_index] os_vmdk_path.side_effect = self.patched_os_vmdk_path tombstone_filename_path = \ os.path.join(image_dir, self.IMAGE_TOMBSTONE_FILENAME) self.image_manager.create_image_tombstone(self.DATASTORE_ID, image_id) # check tombstone exists exists = os.path.exists(tombstone_filename_path) assert_that(exists is True) def patched_os_vmdk_path(self, datastore, disk_id, folder): folder = self.dir0 ret = os_vmdk_path(datastore, disk_id, folder) return ret def create_dir(self, image_id): dirname = os.path.join(self.dir0, _disk_path(image_id)) os.makedirs(dirname) return dirname
class ImageSweeperTouchTimestampTestCase(unittest.TestCase): DATASTORE_ID = "DS01" BASE_TEMP_DIR = "image_sweeper" IMAGE_TIMESTAMP_FILENAME = EsxImageManager.IMAGE_TIMESTAMP_FILE_NAME IMAGE_TOMBSTONE_FILENAME = EsxImageManager.IMAGE_TOMBSTONE_FILE_NAME def setUp(self): self.test_dir = os.path.join(tempfile.mkdtemp(), self.BASE_TEMP_DIR) services.register(ServiceName.AGENT_CONFIG, MagicMock()) self.image_manager = EsxImageManager(MagicMock(), MagicMock()) self.vm_manager = MagicMock() self.image_sweeper = DatastoreImageSweeper(self.image_manager, self.DATASTORE_ID) self.image_sweeper._task_runner = MagicMock() self.image_sweeper._task_runner.is_stopped.return_value = False self.delete_count = 0 # Create various image directories and empty vmdks dir0 = os.path.join(self.test_dir, self.DATASTORE_ID, "images/im") self.dir0 = dir0 # Image dir with correct timestamp file image_id_1 = str(uuid.uuid4()) dir1 = self.create_dir(image_id_1) open(os.path.join(dir1, self.IMAGE_TIMESTAMP_FILENAME), 'w').close() # Image dir without the correct timestamp file image_id_2 = str(uuid.uuid4()) dir2 = self.create_dir(image_id_2) # Image dir with correct timestamp file # and with tombstone file image_id_3 = str(uuid.uuid4()) dir3 = self.create_dir(image_id_3) open(os.path.join(dir3, self.IMAGE_TIMESTAMP_FILENAME), 'w').close() open(os.path.join(dir3, self.IMAGE_TOMBSTONE_FILENAME), 'w').close() self.image_ids = ["", image_id_1, image_id_2, image_id_3] self.image_dirs = ["", dir1, dir2, dir3] def tearDown(self): shutil.rmtree(self.test_dir, True) @parameterized.expand([ # timestamp_exists, tombstone_exists (True, False), (True, True), (False, False) ]) # The os_vmdk_path method is defined in vm_config.py # but it is imported in esx/image_manager.py, that is # the instance we need to patch @patch("host.hypervisor.esx.image_manager.os_vmdk_path") def test_touch_timestamp_file(self, timestamp_exists, tombstone_exists, os_vmdk_path): if tombstone_exists: image_index = 3 exception_class = type(InvalidImageState()) elif not timestamp_exists: image_index = 2 exception_class = type(OSError()) else: image_index = 1 exception_class = None image_id = self.image_ids[image_index] image_dir = self.image_dirs[image_index] os_vmdk_path.side_effect = self.patched_os_vmdk_path timestamp_filename_path = \ os.path.join(image_dir, self.IMAGE_TIMESTAMP_FILENAME) pre_mod_time = 0 if timestamp_exists: # save mod time on the image timestamp file pre_mod_time = os.path.getmtime(timestamp_filename_path) try: time.sleep(1) self.image_manager.\ touch_image_timestamp(self.DATASTORE_ID, image_id) assert_that(exception_class is None) # check new timestamp post_mod_time = os.path.getmtime(timestamp_filename_path) assert_that((post_mod_time > pre_mod_time) is True) except Exception as ex: assert_that((type(ex) == exception_class) is True) @patch("host.hypervisor.esx.image_manager.os_vmdk_path") def test_create_tombstone_file(self, os_vmdk_path): image_index = 1 image_id = self.image_ids[image_index] image_dir = self.image_dirs[image_index] os_vmdk_path.side_effect = self.patched_os_vmdk_path tombstone_filename_path = \ os.path.join(image_dir, self.IMAGE_TOMBSTONE_FILENAME) self.image_manager.create_image_tombstone(self.DATASTORE_ID, image_id) # check tombstone exists exists = os.path.exists(tombstone_filename_path) assert_that(exists is True) def patched_os_vmdk_path(self, datastore, disk_id, folder): folder = self.dir0 ret = os_vmdk_path(datastore, disk_id, folder) return ret def create_dir(self, image_id): dirname = os.path.join(self.dir0, _disk_path(image_id)) os.makedirs(dirname) return dirname