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)
Exemplo n.º 13
0
    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()
Exemplo n.º 20
0
    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)
Exemplo n.º 22
0
    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.