def test_export_plugins_regroup_plugins_in_one_file(self): version_definition = VersionDefinition( version="1.0", signatures=[Signature(path="file")]) plugin0_version_list = VersionList(key="plugin0", producer="unittest", versions=[version_definition]) plugin1_version_list = VersionList(key="plugin1", producer="unittest", versions=[version_definition]) self.exporter._list_keys = MagicMock() self.exporter._list_keys.return_value = ["plugin0", "plugin1"] self.storage.version_list = [ plugin0_version_list, plugin1_version_list ] self.exporter.export_plugins(export_path="path") args, kwargs = self.exporter._dump.call_args plugins = args[1] schema = args[2] self.assertIsInstance(schema, FileListGroupSchema) self.assertEqual(plugins.key, "plugins") self.assertEqual(plugins.producer, "Vane2Export") self.assert_object_with_attribute_value_in_container( "key", "plugin0", plugins.file_lists) self.assert_object_with_attribute_value_in_container( "producer", "Vane2Export", plugins.file_lists) self.assert_object_with_attribute_value_in_container( "key", "plugin1", plugins.file_lists)
async def test_skip_loaded_versions(self, fake_future): workspace = MagicMock() workspace.list_versions.return_value = fake_future( ["1.0", "10.1", "2.0"]) hasher = RepositoryHasher(storage=MagicMock(), hasher=MagicMock()) hasher.collect_for_version = MagicMock() hasher.collect_for_version.return_value = fake_future([ Signature(path="wp-content/plugins/a-plugin/readme.txt", hash="12345") ]) stored = VersionList(producer="RepositoryHasher", key="plugins/a-plugin") stored.get_version("1.0", create_missing=True) stored.get_version("2.0", create_missing=True) hasher.storage.read_versions.return_value = stored await hasher.collect_for_workspace( "plugins/a-plugin", workspace, prefix="wp-content/plugins/a-plugin") hasher.storage.read_versions.assert_called_with("plugins/a-plugin") hasher.collect_for_version.assert_called_once_with( workspace, "10.1", prefix="wp-content/plugins/a-plugin")
def test_get_hash_algo_raise_value_error_if_not_all_signature_use_same_algo(self): version_list = VersionList(key="key", producer="producer") for i in range(5): version = version_list.get_version("1.%d" % i, create_missing=True) version.add_signature("file0", hash="123", algo="SHA512") version.add_signature("file1", hash="123", algo="md5") with self.assertRaises(ValueError): self.version_builder._get_hash_algo(version_list)
def test_get_hash_algo_return_algo_used_by_all_signatures_in_version_list(self): version_list = VersionList(key="key", producer="producer") for i in range(5): version = version_list.get_version("1.%d" % i, create_missing=True) version.add_signature("file0", hash="123", algo="SHA512") version.add_signature("file1", hash="123", algo="SHA512") algo = self.version_builder._get_hash_algo(version_list) self.assertEqual(algo, "SHA512")
def test_update_file_list_set_versions_in_order_when_adding_versions_to_signature(self): self.version_builder._shrink_version_list = MagicMock() version_list = VersionList(key="key", producer="producer") version0 = version_list.get_version(version="1.0", create_missing=True) version0.add_signature("file", "hash") version1 = version_list.get_version(version="1.1", create_missing=True) version1.add_signature("file", "hash") file_list = self.version_builder.create_file_list_from_version_list(version_list, 50) version2 = version_list.get_version("1.2", create_missing=True) version2.add_signature("file", "hash") self.version_builder.update_file_list(file_list, version_list, 50) self.assertEqual(file_list.files[0].signatures[0].versions, ["1.0", "1.1", "1.2"])
def test_keep_most_common_differences_between_versions_use_most_common_files_if_too_many_diff_with_same_count(self): diff_1_0 = {"file0", "file1", "file3", "file4"} # file3-4 will be kept diff_1_1 = {"file2", "file5", "file6"} # file5-6 will be kept diff_1_2 = {"file7", "file8", "file9"} # file 7-8 will be kept diff_1_3 = {"file7", "file8"} differences_between_versions = {"1.0": diff_1_0, "1.1": diff_1_1, "1.2": diff_1_2, "1.3": diff_1_3} version0 = VersionDefinition(version="1.0") version1 = VersionDefinition(version="1.1") version2 = VersionDefinition(version="1.2") version3 = VersionDefinition(version="1.3") for i in range(0, 5): version0.add_signature(path="file%d" % i, hash=i) for i in range(2, 7): version1.add_signature(path="file%d" % i, hash=i) for i in range(4, 10): version2.add_signature(path="file%d" % i, hash=i) version3.add_signature(path="file%d" % i, hash=i) # file count: # file0, file1: 1 # file2, file3, file7, file8, file9: 2 # file5, file6: 3 # file4: 4 version_list = VersionList(key="key", producer="producer", versions=[version0, version1, version2, version3]) self.version_builder.version_list = version_list self.version_builder.files_per_version = 2 self.version_builder._keep_most_common_differences_between_versions(differences_between_versions) self.assertEqual(differences_between_versions["1.0"], {"file3", "file4"}) self.assertEqual(differences_between_versions["1.1"], {"file5", "file6"}) self.assertEqual(differences_between_versions["1.2"], {"file7", "file8"}) self.assertEqual(differences_between_versions["1.3"], {"file7", "file8"})
def test_update_file_list(self): signature0 = Signature(path="file", hash="12345") signature1 = Signature(path="readme", hash="54321") signature2 = Signature(path="readme", hash="56789") version0 = VersionDefinition(version="1.0", signatures=[signature0, signature1]) version1 = VersionDefinition(version="1.1", signatures=[signature0, signature1]) version2 = VersionDefinition(version="1.2", signatures=[signature0, signature2]) version_list = VersionList(producer="producer", key="key", versions=[version0, version1]) file_list = self.version_builder.create_file_list_from_version_list(version_list) version_list.versions.append(version2) self.version_builder.update_file_list(file_list, version_list) file = [file for file in file_list.files if file.path == "file"][0] self.assertEqual(file.path, "file") self.assertEqual(len(file.signatures), 1) self.assertEqual(file.signatures[0].hash, "12345") self.assertEqual(len(file.signatures[0].versions), 3) readme = [file for file in file_list.files if file.path == "readme"][0] self.assertEqual(readme.path, "readme") self.assertEqual(len(readme.signatures), 2) self.assertEqual(readme.signatures[0].hash, "54321") self.assertEqual(len(readme.signatures[0].versions), 2) self.assertIn("1.0", readme.signatures[0].versions) self.assertIn("1.1", readme.signatures[0].versions) self.assertEqual(readme.signatures[1].hash, "56789") self.assertEqual(readme.signatures[1].versions, ["1.2"])
def test_get_differences_between_versions_return_all_files_that_differ_or_are_added_between_versions(self): version0 = VersionDefinition(version="1.0") version1 = VersionDefinition(version="1.1") version2 = VersionDefinition(version="1.2") for i in range(0, 5): # All versions are equal same_signature = Signature(path="file%d" % i, hash=str(i)) version0.signatures.append(same_signature) version1.signatures.append(same_signature) version2.signatures.append(same_signature) for i in range(5, 10): # 5 diff between each version version0.add_signature(path="file%d" % i, hash=str(i)) version1.add_signature(path="file%d" % i, hash="A%d" % i) version2.add_signature(path="file%d" % i, hash="B%d" % i) for i in range(10, 15): # 10 diff between 1.0 and 1.1 version0.add_signature(path="file%d" % i, hash=str(i)) version1.add_signature(path="file%d" % i, hash="A%d" % i) version2.add_signature(path="file%d" % i, hash="A%d" % i) for i in range(15, 20): # 10 diff between 1.1 and 1.2 version0.add_signature(path="file%d" % i, hash=str(i)) version1.add_signature(path="file%d" % i, hash=str(i)) version2.add_signature(path="file%d" % i, hash="A%d" % i) for i in range(20, 25): # 15 diff between 1.1 and 1.2 version2.add_signature(path="file%d" % i, hash=str(i)) version_list = VersionList(producer="producer", key="key", versions=[version0, version1, version2]) self.version_builder.version_list = version_list diff_list = self.version_builder._get_differences_between_versions() self.assertEqual(len(diff_list["1.1"]), 10) self.assertEqual(len(diff_list["1.2"]), 15)
def test_update_hashes(self): version_list = VersionList(key="wordpress", producer="Test") v392 = version_list.get_version("3.9.2", create_missing=True) v392.add_signature("readme.html", "1234") v392.add_signature("randomfile", "1234") v466 = version_list.get_version("4.6.6", create_missing=True) v466.add_signature("readme.html", "12345") self.rebuild.update(version_list) self.assertEqual( self.rebuild.get_hash("readme.html", "3.9.2").attrib["sha256"], "1234") self.assertEqual( self.rebuild.get_hash("readme.html", "4.6.6").attrib["sha256"], "12345")
def test_create_file_list_from_version_list_return_none_if_no_signature_in_version_definitions(self): version0 = VersionDefinition(version="1.0") version1 = VersionDefinition(version="1.1") version2 = VersionDefinition(version="1.2") version_list = VersionList(producer="producer", key="key", versions=[version0, version1, version2]) file_list = self.version_builder.create_file_list_from_version_list(version_list) self.assertIsNone(file_list)
def test_create_file_list_from_version_list_shrink_version_list_if_too_many_files_per_version(self): self.version_builder._shrink_version_list = MagicMock() self.version_builder._is_version_list_empty = MagicMock(return_value=False) signatures = [Signature(path=str(i), hash=i) for i in range(0, 100)] version_list = VersionList(key="key", producer="producer", versions=[VersionDefinition(version="1.0", signatures=signatures)]) self.version_builder.create_file_list_from_version_list(version_list, 50) self.version_builder._shrink_version_list.assert_called_once_with()
def test_shrink_version_list_choose_files_arbitrarily_if_only_one_version_and_more_files_than_max(self): version = VersionDefinition(version="1.0") for i in range(0, 15): version.add_signature(path="file%d" % i, hash=str(i)) version_list = VersionList(producer="producer", key="key", versions=[version]) self.version_builder.version_list = version_list self.version_builder.files_per_version = 10 self.version_builder._shrink_version_list() self.assertEqual(len(version_list.versions[0].signatures), 10)
def test_export_themes_ignore_themes_with_empty_versions_file(self): theme_version_list = VersionList(key="my-theme", producer="unittest") self.exporter._list_keys = MagicMock() self.exporter._list_keys.return_value = ["my-theme"] self.storage.version_list = [theme_version_list] self.exporter.export_themes("path") args, kwargs = self.exporter._dump.call_args themes = args[1] self.assertEqual(len(themes.file_lists), 0)
def test_get_differences_between_versions_set_all_files_as_diff_for_first_version(self): version0 = VersionDefinition(version="1.0") version1 = VersionDefinition(version="1.1") for i in range(0, 5): version0.add_signature(path="file%d" % i, hash=str(i)) version_list = VersionList(producer="producer", key="key", versions=[version0, version1]) self.version_builder.version_list = version_list self.version_builder.files_per_version = 14 diff_list = self.version_builder._get_differences_between_versions() self.assertEqual(len(diff_list["1.0"]), 5)
async def test_brand_new_file(self, fake_future): workspace = MagicMock() workspace.list_versions.return_value = fake_future( ["1.0", "10.1", "2.0"]) hasher = RepositoryHasher(storage=MagicMock(), hasher=MagicMock()) hasher.collect_for_version = MagicMock() hasher.collect_for_version.return_value = fake_future([ Signature(path="wp-content/plugins/a-plugin/readme.txt", hash="12345") ]) hasher.storage.read_versions.side_effect = FileNotFoundError() await hasher.collect_for_workspace( "plugins/a-plugin", workspace, prefix="wp-content/plugins/a-plugin") hasher.storage.read_versions.assert_called_with("plugins/a-plugin") hasher.collect_for_version.assert_has_calls([ call(workspace, "1.0", prefix="wp-content/plugins/a-plugin"), call(workspace, "2.0", prefix="wp-content/plugins/a-plugin"), call(workspace, "10.1", prefix="wp-content/plugins/a-plugin"), ], any_order=False) expect = VersionList(producer="RepositoryHasher", key="plugins/a-plugin") v1 = expect.get_version("1.0", create_missing=True) v1.add_signature("wp-content/plugins/a-plugin/readme.txt", hash="12345") v2 = expect.get_version("2.0", create_missing=True) v2.add_signature("wp-content/plugins/a-plugin/readme.txt", hash="12345") v10 = expect.get_version("10.1", create_missing=True) v10.add_signature("wp-content/plugins/a-plugin/readme.txt", hash="12345") hasher.storage.write_versions.assert_called_with(expect)
def test_exclude_files_removes_files_beginning_with_branches(self): signature0 = Signature(path="wp-content/plugins/my-plugin/branches/file0", hash="1") signature1 = Signature(path="wp-content/plugins/my-plugin/file1", hash="2") signature2 = Signature(path="wp-content/plugins/my-plugin/file2", hash="3") signature3 = Signature(path="wp-content/plugins/my-plugin/branches/file3", hash="4") version = VersionDefinition(version="1.2", signatures=[signature0, signature1, signature2, signature3]) version_list = VersionList(producer="producer", key="plugins/my-plugin", versions=[version]) self.version_builder.version_list = version_list self.version_builder._exclude_files() self.assertEqual(len(version.signatures), 2) self.assertIn(signature1, version.signatures) self.assertIn(signature2, version.signatures)
def test_update_file_list_keep_file_order_and_append_new_file_at_end(self): self.version_builder._shrink_version_list = MagicMock() signature0 = Signature(path="path/to/files/abc.html", hash="12345") signature1 = Signature(path="path/to/files/file.js", hash="12345") signature2 = Signature(path="path/to/files/js/file.js", hash="12345") signature3 = Signature(path="path/to/files/readme.txt", hash="12345") signature4 = Signature(path="path/to/files/style/color.css", hash="12345") signature5 = Signature(path="path/to/files/style/style.css", hash="12345") signature6 = Signature(path="path/to/files/style/color.css", hash="23456") signature7 = Signature(path="path/to/files/readme.txt", hash="23456") signatures = [signature0, signature1, signature2, signature3, signature4] version_list = VersionList(key="key", producer="producer", versions=[VersionDefinition(version="1.0", signatures=signatures)]) file_list = self.version_builder.create_file_list_from_version_list(version_list, 50) initial_file_order = [file.path for file in file_list.files] version = version_list.get_version("1.1", create_missing=True) version.signatures = [signature5, signature6, signature7] self.version_builder.update_file_list(file_list, version_list, 50) for i in range(len(initial_file_order)): self.assertEqual(file_list.files[i].path, initial_file_order[i]) self.assertEqual(signature5.path, file_list.files[-1].path)
def test_shrink_version_list_keep_max_files_from_most_common_files_if_no_changes_between_version(self): version0 = VersionDefinition(version="1.0") version1 = VersionDefinition(version="1.1") for i in range(0, 10): # All versions are equal same_signature = Signature(path="file%d" % i, hash=str(i)) version0.signatures.append(same_signature) version1.signatures.append(same_signature) version_list = VersionList(producer="producer", key="key", versions=[version0, version1]) self.version_builder.version_list = version_list self.version_builder.files_per_version = 10 self.version_builder._shrink_version_list() self.assertEqual(len(version0.signatures), 10) for i in range(0, 10): self.assertIn("file%d" % i, [signature.path for signature in version0.signatures])
async def test_collect_for_workspace_do_not_write_versions_if_empty_signatures( self): hasher = RepositoryHasher(storage=MagicMock(), hasher=Hasher("SHA256")) hasher.collect_for_version = make_mocked_coro(return_value=[]) hasher.get_version_list = MagicMock(return_value=VersionList( key="plugins/plugin-key", producer="unittest", versions=[VersionDefinition(version="1.0")])) workspace = MagicMock() workspace.list_versions = make_mocked_coro(return_value=["1.2"]) hasher.storage.write_versions = MagicMock() await hasher.collect_for_workspace("plugins/plugin-key", workspace) hasher.collect_for_version.assert_called_once_with(workspace, "1.2", prefix="") hasher.storage.write_versions.assert_not_called()
def test_export_wordpress_dump_wordpress_versions(self): versions = [ VersionDefinition( version="1.0", signatures=[Signature(path="file.html", hash="a1b2c3")]), VersionDefinition(version="2.0", signatures=[ Signature(path="file.html", hash="d4e5f6"), Signature(path="style.css", hash="12345") ]) ] wordpress_version_list = VersionList(key="wordpress", producer="unittest", versions=versions) self.exporter._list_keys = MagicMock() self.exporter._list_keys.return_value = ["wordpress"] self.storage.version_list = [wordpress_version_list] self.exporter.export_wordpress("path") args, kwargs = self.exporter._dump.call_args file_name = args[0] wordpress_file_list = args[1] schema = args[2] self.assertEqual(file_name, "path/vane2_wordpress_versions.json") self.assertIsInstance(schema, FileListSchema) self.assertEqual(wordpress_file_list.key, "wordpress") self.assert_object_with_attribute_value_in_container( "path", "file.html", wordpress_file_list.files) self.assert_object_with_attribute_value_in_container( "path", "style.css", wordpress_file_list.files) path_file = self.get_object_with_attribute_value_in_container( "path", "file.html", wordpress_file_list.files) style_file = self.get_object_with_attribute_value_in_container( "path", "style.css", wordpress_file_list.files) path_version1_signature = self.get_object_with_attribute_value_in_container( "hash", "a1b2c3", path_file.signatures) path_version2_signature = self.get_object_with_attribute_value_in_container( "hash", "d4e5f6", path_file.signatures) style_signature = style_file.signatures[0] self.assertEqual(path_version1_signature.versions, ["1.0"]) self.assertEqual(path_version2_signature.versions, ["2.0"]) self.assertEqual(style_signature.versions, ["2.0"])
def test_get_file_paths_from_version_list(self): signature0 = Signature(path="file0", hash="1") signature1 = Signature(path="file1", hash="2") signature2 = Signature(path="file2", hash="3") signature3 = Signature(path="file3", hash="4") signature4 = Signature(path="file0", hash="5") version0 = VersionDefinition(version="1.0", signatures=[signature0, signature1, signature2]) version1 = VersionDefinition(version="1.1", signatures=[signature0, signature1, signature3]) version2 = VersionDefinition(version="1.2", signatures=[signature4, signature2]) version_list = VersionList(producer="producer", key="key", versions=[version0, version1, version2]) self.version_builder.version_list = version_list file_paths = self.version_builder._get_file_paths_from_version_list() self.assertEqual(len(file_paths), 4) self.assertIn("file0", file_paths) self.assertIn("file1", file_paths) self.assertIn("file2", file_paths) self.assertIn("file3", file_paths)
def test_export_plugins_create_file_list_from_version_list_for_plugin( self): versions = [ VersionDefinition( version="1.0", signatures=[Signature(path="file.html", hash="a1b2c3")]), VersionDefinition(version="2.0", signatures=[ Signature(path="file.html", hash="d4e5f6"), Signature(path="style.css", hash="12345") ]) ] plugin_version_list = VersionList(key="my-plugin", producer="unittest", versions=versions) self.exporter._list_keys = MagicMock() self.exporter._list_keys.return_value = ["my-plugin"] self.storage.version_list = [plugin_version_list] self.exporter.export_plugins("path") args, kwargs = self.exporter._dump.call_args plugins = args[1] plugin = plugins.file_lists[0] self.assertEqual(plugin.key, "my-plugin") self.assert_object_with_attribute_value_in_container( "path", "file.html", plugin.files) self.assert_object_with_attribute_value_in_container( "path", "style.css", plugin.files) path_file = self.get_object_with_attribute_value_in_container( "path", "file.html", plugin.files) style_file = self.get_object_with_attribute_value_in_container( "path", "style.css", plugin.files) path_version1_signature = self.get_object_with_attribute_value_in_container( "hash", "a1b2c3", path_file.signatures) path_version2_signature = self.get_object_with_attribute_value_in_container( "hash", "d4e5f6", path_file.signatures) style_signature = style_file.signatures[0] self.assertEqual(path_version1_signature.versions, ["1.0"]) self.assertEqual(path_version2_signature.versions, ["2.0"]) self.assertEqual(style_signature.versions, ["2.0"])
def test_create_file_from_version_list_regroup_all_versions_with_equal_hash_for_file_in_same_file_signature(self): signature0 = Signature(path="file", hash="12345") signature1 = Signature(path="readme", hash="54321") version0 = VersionDefinition(version="1.0", signatures=[signature0, signature1]) version1 = VersionDefinition(version="1.1", signatures=[signature0, signature1]) version2 = VersionDefinition(version="1.2", signatures=[signature0, signature1]) version_list = VersionList(producer="producer", key="key", versions=[version0, version1, version2]) self.version_builder.version_list = version_list file0 = self.version_builder._create_file_from_version_list("file") file1 = self.version_builder._create_file_from_version_list("readme") file_signature0 = file0.signatures[0] file_signature1 = file1.signatures[0] self.assertEqual(len(file0.signatures), 1) self.assertEqual(len(file1.signatures), 1) self.assertEqual(file_signature0.hash, signature0.hash) self.assertEqual(file_signature1.hash, signature1.hash) versions = [version.version for version in version_list.versions] self.assertTrue(all(version in versions for version in file_signature0.versions)) self.assertTrue(all(version in versions for version in file_signature1.versions))
def test_shrink_version_list_use_the_same_files_for_all_versions(self): version0 = VersionDefinition(version="1.0") version1 = VersionDefinition(version="1.1") version2 = VersionDefinition(version="1.2") identity_files = set() for i in range(0, 5): # Files common to all the version version0.add_signature(path="file%d" % i, hash=str(i)) version1.add_signature(path="file%d" % i, hash=str(i)) version2.add_signature(path="file%d" % i, hash=str(i)) for i in range(5, 10): # Files changing in all versions version0.add_signature(path="file%d" % i, hash='A') version1.add_signature(path="file%d" % i, hash='B') version2.add_signature(path="file%d" % i, hash='C') identity_files.add("file%d" % i) for i in range(10, 15): # Files changing in version 1.1 version1.add_signature(path="file%d" % i, hash='B') version2.add_signature(path="file%d" % i, hash='B') identity_files.add("file%d" % i) for i in range(15, 17): # Files only in version 1.2 version2.add_signature(path="file%d" % i, hash="hash") identity_files.add("file%d" % i) version_list = VersionList(producer="producer", key="key", versions=[version0, version1, version2]) self.version_builder.version_list = version_list self.version_builder.files_per_version = 10 self.version_builder._shrink_version_list() self.assertEqual(10, len(version0.signatures)) # Only 10 files for version 1.0, so they are all kept self.assertEqual(15, len(version1.signatures)) # 10 files are changing in 1.1 + 5 files already kept by 1.0 but no changing in 1.1 self.assertEqual(17, len(version2.signatures)) # 7 files changing in 1.2 + 5 from 1.1 + 5 from 1.0 version0_files = [signature.path for signature in version0.signatures] version1_files = [signature.path for signature in version1.signatures] version2_files = [signature.path for signature in version2.signatures] for i in range(0, 10): self.assertIn("file%d" % i, version0_files) for i in range(0, 15): self.assertIn("file%d" % i, version1_files) for i in range(0, 17): self.assertIn("file%d" % i, version2_files)
def test_shrink_version_list_use_common_files_if_not_enough_diff_per_between_versions(self): version0 = VersionDefinition(version="1.0") version1 = VersionDefinition(version="1.1") version2 = VersionDefinition(version="1.2") for i in range(0, 15): version0.add_signature(path="file%d" % i, hash=str(i)) version1.add_signature(path="file%d" % i, hash=str(i)) for i in range(0, 4): version2.add_signature(path="file%d" % (i + 15), hash=str(i)) version2.add_signature(path="file%d" % i, hash="hash") for i in range(4, 8): version2.add_signature(path="file%d" % i, hash=str(i)) version1.add_signature(path="fileA", hash="unique_hash") # file0-7 are the most common files # file0-3 and file15-18 are diff for 1.2 (8 diff) # fileA is the diff for 1.1 # file0-7, file15-18 and fileA are always kept, plus 2 files randomly choose from file6-14 (equally common in diff): 15 files total version_list = VersionList(producer="producer", key="key", versions=[version0, version1, version2]) self.version_builder.version_list = version_list self.version_builder.files_per_version = 10 self.version_builder._shrink_version_list() file_paths = self.version_builder._get_file_paths_from_version_list() self.assertEqual(len(file_paths), 15) self.assertEqual(len(version0.signatures), 10) self.assertEqual(len(version1.signatures), 11) self.assertEqual(len(version2.signatures), 12) self.assertIn("fileA", file_paths) for i in range(0, 8): self.assertIn("file%d" % i, file_paths) for i in range(15, 19): self.assertIn("file%d" % i, file_paths) self.assertEqual(len(file_paths & set("file%d" % i for i in range(8, 15))), 2) # check that 2 files are arbitrarily kept from these files.