Ejemplo n.º 1
0
    def test_validate_invalid_name_full_validation_true(self):
        """
        Due to a bug[0], we don't want to allow an ISO named PULP_MANIFEST. This test asserts that
        the name is validated when full_validation is set to True.

        [0] https://bugzilla.redhat.com/show_bug.cgi?id=973678
        """
        name = 'PULP_MANIFEST'
        destination = os.path.join(self.temp_dir, name)
        with open(destination, 'w') as test_file:
            test_file.write(
                "I heard there was this band called 1023MB, they haven't got any gigs yet.")
        unit = mock.MagicMock()
        unit.storage_path = destination
        iso = models.ISO(name, 73,
                         '36891c265290bf4610b488a8eb884d32a29fd17bb9886d899e75f4cf29d3f464',
                         unit)

        # This should raise a ValueError with an appropriate error message
        try:
            # We'll set full_validation to True for this test
            iso.validate(full_validation=True)
            self.fail('A ValueError should have been raised, but it was not.')
        except ValueError, e:
            self.assertEqual(
                str(e), 'An ISO may not be named PULP_MANIFEST, as it conflicts with the name of '
                        'the manifest during publishing.')
Ejemplo n.º 2
0
    def test_download_succeeded(self, download_failed):
        destination = os.path.join(self.temp_dir, 'test.txt')
        with open(destination, 'w') as test_file:
            test_file.write(
                'Descartes walks into a bar and sits down, the bartender walks up to him and says '
                '"You, my '
                'man, look like you need a stiff drink." Descartes considers this, and shakes his '
                'head "No, '
                'I don\'t think-" and ceases to exist.')
        unit = MagicMock()
        unit.storage_path = destination
        iso = models.ISO(
            'test.txt', 217,
            'a1552efee6f04012bc7e1f3e02c00c6177b08217cead958c47ec83cb8f97f835',
            unit)
        iso.url = 'http://fake.com'
        report = DownloadReport(iso.url, destination, iso)

        # Simulate having downloaded the whole file
        iso.bytes_downloaded = iso.size
        report.bytes_downloaded = iso.size
        self.iso_sync_run.progress_report._state = SyncProgressReport.STATE_ISOS_IN_PROGRESS

        self.iso_sync_run.download_succeeded(report)

        # The sync conduit should have been called to save the unit
        self.sync_conduit.save_unit.assert_any_call(unit)
        # The download should not fail
        self.assertEqual(download_failed.call_count, 0)
Ejemplo n.º 3
0
    def test_validate_wrong_size_full_validation_true(self):
        """
        Assert that validate() raises a ValueError when given an incorrect size and full_validation
        is True (default).
        """
        destination = os.path.join(self.temp_dir, 'test.txt')
        try:
            test_file = open(destination, 'w')
            test_file.write(
                "Hey girl, what's your sine? It must be math.pi/2 because you're the 1."
            )
        finally:
            test_file.close()
        unit = mock.MagicMock()
        unit.storage_path = destination
        iso = models.ISO(
            'test.txt', math.pi,
            '2b046422425d6f01a920278c55d8842a8989bacaea05b29d1d2082fae91c6041',
            unit)

        # This should raise a ValueError with an appropriate error message
        try:
            iso.validate()
            self.fail('A ValueError should have been raised, but it was not.')
        except ValueError, e:
            self.assertEqual(
                str(e),
                'Downloading <test.txt> failed validation. The manifest specified that the '
                'file should be 3.14159265359 bytes, but the downloaded file is 70 bytes.'
            )
Ejemplo n.º 4
0
    def test_validate_wrong_checksum_full_validation_true(self):
        """
        Assert that validate() raises a ValueError when the checksum is not correct and
        full_validation is True (default).
        """
        destination = os.path.join(self.temp_dir, 'test.txt')
        try:
            test_file = open(destination, 'w')
            test_file.write(
                'Two chemists walk into a bar, the first one says "I\'ll have some H2O." to '
                'which the other adds "I\'ll have some H2O, too." The second chemist died.'
            )
        finally:
            test_file.close()
        unit = mock.MagicMock()
        unit.storage_path = destination
        iso = models.ISO('test.txt', 146, 'terrible_pun', unit)

        # This should raise a ValueError with an appropriate error message
        try:
            iso.validate()
            self.fail('A ValueError should have been raised, but it was not.')
        except ValueError, e:
            self.assertEqual(
                str(e),
                'Downloading <test.txt> failed checksum validation. The manifest specified the '
                'checksum to be terrible_pun, but it was '
                'dfec884065223f24c3ef333d4c7dcc0eb785a683cfada51ce071410b32a905e8.'
            )
Ejemplo n.º 5
0
    def test_download_succeeded_fails_checksum(self, download_failed):
        """
        This test verifies that download_succeeded does the right thing if the checksum fails. Note
        that we are also implicitly testing that the default behavior is to validate downloads by
        not setting it in this test. There are two other tests that verify that setting the boolean
        explicitly is honored.
        """
        self.config.override_config[importer_constants.KEY_VALIDATE] = True

        iso_sync_run = ISOSyncRun(self.sync_conduit, self.config)

        destination = os.path.join(self.temp_dir, 'test.txt')
        with open(destination, 'w') as test_file:
            test_file.write('Boring test data.')
        unit = MagicMock()
        unit.storage_path = destination
        iso = models.ISO('test.txt', 114, 'wrong checksum', unit)
        iso.url = 'http://fake.com'
        report = DownloadReport(iso.url, destination, iso)

        # Let's fake having downloaded the whole file
        iso.bytes_downloaded = iso.size
        report.bytes_downloaded = iso.size
        iso_sync_run.progress_report._state = SyncProgressReport.STATE_ISOS_IN_PROGRESS

        iso_sync_run.download_succeeded(report)

        # Because we fail validation, the save_unit step will not be called
        self.assertEqual(self.sync_conduit.save_unit.call_count, 0)
        # The download should be marked failed
        self.assertEqual(download_failed.call_count, 1)
        download_failed.assert_called_once_with(report)
Ejemplo n.º 6
0
    def test_save_unit(self):
        unit = mock.MagicMock()
        iso = models.ISO('name', 42, 'checksum', unit)
        conduit = mock.MagicMock()

        iso.save_unit(conduit)

        conduit.save_unit.assert_called_once_with(unit)
Ejemplo n.º 7
0
    def test___init__(self):
        """
        Make sure __init__() sets all the proper attributes.
        """
        iso = models.ISO('name', 42, 'checksum')

        self.assertEqual(iso.name, 'name')
        self.assertEqual(iso.size, 42)
        self.assertEqual(iso.checksum, 'checksum')
        self.assertEqual(iso._unit, None)
Ejemplo n.º 8
0
    def test_storage_path(self):
        """
        Make sure the storage_path() method returns the underlying Unit's storage_path attribute.
        """
        unit = mock.MagicMock()
        unit.storage_path = '/some/path'
        iso = models.ISO('name', 42, 'checksum', unit)

        storage_path = iso.storage_path

        self.assertEqual(storage_path, unit.storage_path)
Ejemplo n.º 9
0
    def test_download_failed_during_iso_download(self, _logger):
        self.iso_sync_run.progress_report._state = SyncProgressReport.STATE_ISOS_IN_PROGRESS
        url = 'http://www.theonion.com/articles/american-airlines-us-airways-merge-to-form' \
              '-worlds,31302/'
        iso = models.ISO('test.txt', 217,
                         'a1552efee6f04012bc7e1f3e02c00c6177b08217cead958c47ec83cb8f97f835')
        report = DownloadReport(url, '/fake/destination', iso)
        report.error_msg = 'uh oh'

        self.iso_sync_run.download_failed(report)

        self.assertEqual(_logger.error.call_count, 1)
        log_msg = _logger.error.mock_calls[0][1][0]
        self.assertTrue('uh oh' in log_msg)
Ejemplo n.º 10
0
    def test_validate_wrong_size_full_validation_false(self):
        """
        Assert that validate() does not raise a ValueError when given an incorrect size and
        full_validation is False.
        """
        destination = os.path.join(self.temp_dir, 'test.txt')
        with open(destination, 'w') as test_file:
            test_file.write(
                "Hey girl, what's your sine? It must be math.pi/2 because you're the 1.")
        unit = mock.MagicMock()
        unit.storage_path = destination
        iso = models.ISO('test.txt', math.pi,
                         '2b046422425d6f01a920278c55d8842a8989bacaea05b29d1d2082fae91c6041', unit)

        # This should not raise an Exception because full_validation is set to False
        iso.validate(full_validation=False)
Ejemplo n.º 11
0
    def test_validate_wrong_checksum_full_validation_false(self):
        """
        Assert that validate() does not raise a ValueError when the checksum is not correct and
        full_validation is False.
        """
        destination = os.path.join(self.temp_dir, 'test.txt')
        with open(destination, 'w') as test_file:
            test_file.write(
                'Two chemists walk into a bar, the first one says "I\'ll have some H2O." to '
                'which the other adds "I\'ll have some H2O, too." The second chemist died.')
        unit = mock.MagicMock()
        unit.storage_path = destination
        iso = models.ISO('test.txt', 146, 'terrible_pun', unit)

        # This should not raise a ValueError since full_validation is False
        iso.validate(full_validation=False)
Ejemplo n.º 12
0
    def test_init_unit(self):
        """
        Assert correct behavior from the init_unit() method.
        """
        unit = mock.MagicMock()
        conduit = mock.MagicMock()
        conduit.init_unit = mock.MagicMock(return_value=unit)
        iso = models.ISO('name', 42, 'checksum')

        iso.init_unit(conduit)

        self.assertEqual(iso._unit, unit)
        expected_relative_path = os.path.join('name', 'checksum', '42', 'name')
        conduit.init_unit.assert_called_once_with(
            ids.TYPE_ID_ISO, {'name': 'name', 'size': 42, 'checksum': 'checksum'}, {},
            expected_relative_path)
Ejemplo n.º 13
0
    def upload_unit(self, transfer_repo, type_id, unit_key, metadata,
                    file_path, conduit, config):
        """
        Handles the creation and association of an ISO.

        :param repo: The repository to import the package into
        :type  repo: pulp.server.db.model.Repository

        :param type_id: The type_id of the package being uploaded
        :type  type_id: str

        :param unit_key: A dictionary of fields to overwrite introspected field values
        :type  unit_key: dict

        :param metadata: A dictionary of fields to overwrite introspected field values, or None
        :type  metadata: dict or None

        :param file_path: The path to the uploaded package
        :type  file_path: str

        :param conduit: provides access to relevant Pulp functionality
        :type  conduit: pulp.plugins.conduits.upload.UploadConduit

        :param config: plugin configuration for the repository
        :type  config: pulp.plugins.config.PluginCallConfiguration
        """
        qs = models.ISO.objects.filter(**unit_key)
        if qs:
            # iso with this key already exists, use it
            iso = qs.first()
        else:
            # this is a new ISO, create it
            iso = models.ISO(**unit_key)

        validate = config.get_boolean(importer_constants.KEY_VALIDATE)
        validate = validate if validate is not None else constants.CONFIG_VALIDATE_DEFAULT
        try:
            # Let's validate the ISO. This will raise a
            # ValueError if the ISO does not validate correctly.
            iso.validate_iso(file_path, full_validation=validate)
        except ValueError, e:
            return {
                'success_flag': False,
                'summary': e.message,
                'details': None
            }
Ejemplo n.º 14
0
    def upload_unit(self, repo, type_id, unit_key, metadata, file_path, conduit, config):
        """
        See super(self.__class__, self).upload_unit() for the docblock explaining this method. In
        short, it handles ISO uploads.
        """
        iso = models.ISO(unit_key['name'], unit_key['size'], unit_key['checksum'])
        iso.init_unit(conduit)

        shutil.move(file_path, iso.storage_path)
        validate = config.get_boolean(importer_constants.KEY_VALIDATE)
        validate = validate if validate is not None else constants.CONFIG_VALIDATE_DEFAULT
        try:
            # Let's validate the ISO. This will raise a
            # ValueError if the ISO does not validate correctly.
            iso.validate(full_validation=validate)
        except ValueError, e:
            # If validation raises a ValueError, we should delete the file and raise
            os.remove(iso.storage_path)
            return {'success_flag': False, 'summary': e.message, 'details': None}
Ejemplo n.º 15
0
    def test_validate(self):
        """
        Assert that validate() raises no Exception when passed correct data.
        """
        destination = os.path.join(self.temp_dir, 'test.txt')
        try:
            test_file = open(destination, 'w')
            test_file.write(
                "I heard there was this band called 1023MB, they haven't got any gigs yet.")
        finally:
            test_file.close()
        unit = mock.MagicMock()
        unit.storage_path = destination
        iso = models.ISO('test.txt', 73,
                         '36891c265290bf4610b488a8eb884d32a29fd17bb9886d899e75f4cf29d3f464',
                         unit)

        # This should validate, i.e., should not raise any Exception
        iso.validate()
Ejemplo n.º 16
0
    def test_download_succeeded_honors_validate_units_set_false(
            self, download_failed):
        """
        We have a setting that makes download validation optional. This test ensures that
        download_succeeded()
        honors that setting.
        """
        # In this config, we will set validate_units to False, which should make our
        # "wrong_checksum" OK
        config = importer_mocks.get_basic_config(
            **{
                importer_constants.KEY_FEED: 'http://fake.com/iso_feed/',
                importer_constants.KEY_VALIDATE: False
            })

        iso_sync_run = ISOSyncRun(self.sync_conduit, config)

        destination = os.path.join(self.temp_dir, 'test.iso')
        with open(destination, 'w') as test_iso:
            test_iso.write(
                'What happens when you combine a mosquito with a mountain climber? Nothing. You '
                'can\'t cross a vector with a scalar.')
        unit = MagicMock()
        unit.storage_path = destination
        iso = models.ISO('test.txt', 114, 'wrong checksum', unit)
        iso.url = 'http://fake.com'
        report = DownloadReport(iso.url, destination, iso)

        # Let's fake having downloaded the whole file
        iso.bytes_downloaded = iso.size
        report.bytes_downloaded = iso.size
        iso_sync_run.progress_report._state = SyncProgressReport.STATE_ISOS_IN_PROGRESS

        iso_sync_run.download_succeeded(report)

        # The sync conduit should have been called to save the unit
        self.sync_conduit.save_unit.assert_any_call(unit)
        # The download should not fail
        self.assertEqual(download_failed.call_count, 0)
Ejemplo n.º 17
0
    def test_download_succeeded_honors_validate_units_set_true(
            self, download_failed):
        """
        We have a setting that makes download validation optional. This test ensures that
        download_succeeded()
        honors that setting.
        """
        # In this config, we will set validate_units to False, which should make our
        # "wrong_checksum" OK
        config = importer_mocks.get_basic_config(
            **{
                importer_constants.KEY_FEED: 'http://fake.com/iso_feed/',
                importer_constants.KEY_VALIDATE: True
            })

        iso_sync_run = ISOSyncRun(self.sync_conduit, config)

        destination = os.path.join(self.temp_dir, 'test.txt')
        with open(destination, 'w') as test_file:
            test_file.write('Boring test data.')
        unit = MagicMock()
        unit.storage_path = destination
        iso = models.ISO('test.txt', 114, 'wrong checksum', unit)
        iso.url = 'http://fake.com'
        report = DownloadReport(iso.url, destination, iso)

        # Let's fake having downloaded the whole file
        iso.bytes_downloaded = iso.size
        report.bytes_downloaded = iso.size
        iso_sync_run.progress_report._state = SyncProgressReport.STATE_ISOS_IN_PROGRESS

        iso_sync_run.download_succeeded(report)

        # Because we fail validation, the save_unit step will not be called
        self.assertEqual(self.sync_conduit.save_unit.call_count, 0)
        # The download should be marked failed
        self.assertEqual(download_failed.call_count, 1)
        download_failed.assert_called_once_with(report)