Example #1
0
class AptCacheTests(TestCase):
    """
    Tests for :class:`pts.core.utils.packages.AptCache`.
    """
    @staticmethod
    def stub_acquire(source_records, dest_dir, debian_dir_only, content):
        # Create a file in the destination directory
        file_name = 'temp'
        file_path = os.path.join(dest_dir, file_name)
        # Create a file of the given size
        with open(file_path, 'wb') as f:
            f.write(content)
        return None, 'ekrem'

    def create_cache(self):
        """
        Helper method which creates an :class:`pts.core.utils.packages.AptCache`
        instance which is used for testing. Some of its methods are replaced by
        mocks and stubs to avoid HTTP calls.
        """
        self.cache = AptCache()
        self.cache._get_apt_source_records = mock.MagicMock()
        self.cache._get_format = mock.MagicMock(return_value='1.0')
        self.cache._extract_dpkg_source = mock.MagicMock()
        self.cached_files = []
        self.cache._get_all_cached_files = mock.MagicMock(
            return_value=self.cached_files)
        self.cache._match_index_file_to_repository = mock.MagicMock()

    def set_stub_acquire_content(self, content):
        """
        Helper method which sets the content of a file which is created by the
        cache instance when retrieve_source is called.
        """
        self.cache._apt_acquire_package = mock.MagicMock(side_effect=curry(
            AptCacheTests.stub_acquire, content=content))

    def set_stub_cached_files_for_repository(self, repository, files):
        """
        Helper method adds the given list of files to the stub list of cached
        files for a given repository.

        :param repository: The repository to which these files are associated.
        :type repository: :class:`Repository <pts.core.models.Repository>`
        :param files: List of cached file names. The function uses the list to
            build the stub by prefixing the names with expected repository
            identifiers.
        """
        # Build the prefix from the repository's URI and suite
        base_uri = repository.uri.rstrip('/')
        if base_uri.startswith('http://'):
            base_uri = base_uri[7:]
        prefix = base_uri + '/' + repository.suite + '/'
        prefix = prefix.replace('/', '_')
        for file_name in files:
            self.cached_files.append(prefix + file_name)
        self.cache._match_index_file_to_repository.return_value = repository

    def assert_cache_size_equal(self, size):
        self.assertEqual(size, self.cache.cache_size)

    def test_cache_size_increase_after_acquire(self):
        """
        Tests that the cache correctly increases its size after acquiring new
        files.
        """
        with make_temp_directory('-pts-cache') as cache_directory:
            with self.settings(
                    PTS_CACHE_DIRECTORY=cache_directory,
                    PTS_APT_CACHE_MAX_SIZE=10):
                self.create_cache()
                # Sanity check: old size is 0 as nothing was ever cached in the
                # brand new directory
                self.assert_cache_size_equal(0)
                content = b'a' * 5  # 5 bytes
                self.set_stub_acquire_content(content)

                self.cache.retrieve_source('dummy-package', '1.0.0')

                self.assert_cache_size_equal(5)

    def test_cache_multiple_insert_no_remove(self):
        """
        Tests that the cache does not remove packages unless the size limit is
        exceeded.
        """
        with make_temp_directory('-pts-cache') as cache_directory:
            with self.settings(
                    PTS_CACHE_DIRECTORY=cache_directory,
                    PTS_APT_CACHE_MAX_SIZE=10):
                self.create_cache()
                # Sanity check: old size is 0 as nothing was ever cached in the
                # brand new directory
                self.assert_cache_size_equal(0)
                content = b'a' * 5  # 5 bytes
                self.set_stub_acquire_content(content)
                # Add one file.
                self.cache.retrieve_source('dummy-package', '1.0.0')
                self.assert_cache_size_equal(5)
                # Same content in another file
                self.set_stub_acquire_content(content)

                self.cache.retrieve_source('package', '1.0.0')

                # Both files are now saved.
                self.assert_cache_size_equal(10)

    def test_clear_cache(self):
        """
        Tests that the cache removes packages when it exceeds its allocated
        size.
        """
        with make_temp_directory('-pts-cache') as cache_directory:
            with self.settings(
                    PTS_CACHE_DIRECTORY=cache_directory,
                    PTS_APT_CACHE_MAX_SIZE=10):
                self.create_cache()
                # Sanity check: old size is 0 as nothing was ever cached in the
                # brand new directory
                self.assert_cache_size_equal(0)
                initial_content = b'a' * 11
                self.set_stub_acquire_content(initial_content)
                # Set initial source content
                self.cache.retrieve_source('dummy-package', '1.0.0')
                self.assert_cache_size_equal(11)
                content = b'a' * 7
                self.set_stub_acquire_content(content)

                self.cache.retrieve_source('package', '1.0.0')

                # Only the second content is found in the package
                self.assert_cache_size_equal(7)

    def test_get_sources_for_repository(self):
        """
        Tests that the cache correctly returns a list of cached Sources files
        for a given repository.
        """
        with make_temp_directory('-pts-cache') as cache_directory:
            with self.settings(PTS_CACHE_DIRECTORY=cache_directory):
                self.create_cache()
                repository = Repository.objects.create(
                    name='stable',
                    shorthand='stable',
                    uri='http://cdn.debian.net/debian/dists',
                    suite='stable')
                expected_source_files = [
                    'main_source_Sources',
                    'contrib_source_Sources',
                ]
                files = expected_source_files + [
                    'Release',
                    'main_binary-amd64_Packages',
                ]
                self.set_stub_cached_files_for_repository(repository, files)

                sources = self.cache.get_sources_files_for_repository(repository)

                self.assertEqual(len(expected_source_files), len(sources))
                for expected_source, returned_source in zip(
                        expected_source_files, sources):
                    self.assertTrue(returned_source.endswith(expected_source))

    def test_get_packages_for_repository(self):
        """
        Tests that the cache correctly returns a list of cached Packages files
        for a given repository.
        """
        with make_temp_directory('-pts-cache') as cache_directory:
            with self.settings(PTS_CACHE_DIRECTORY=cache_directory):
                self.create_cache()
                repository = Repository.objects.create(
                    name='stable',
                    shorthand='stable',
                    uri='http://cdn.debian.net/debian/dists',
                    suite='stable')
                expected_packages_files = [
                    'main_binary-amd64_Packages',
                    'main_binary-i386_Packages',
                ]
                files = expected_packages_files + [
                    'Release',
                    'main_source_Sources',
                ]
                self.set_stub_cached_files_for_repository(repository, files)

                packages = self.cache.get_packages_files_for_repository(repository)

                self.assertEqual(len(expected_packages_files), len(packages))
                for expected, returned in zip(
                        expected_packages_files, packages):
                    self.assertTrue(returned.endswith(expected))