예제 #1
0
    def test_validate_config(self):
        """
        We already have a seperate test module for config validation, but we can get 100% test
        coverage with
        this!
        """
        config = importer_mocks.get_basic_config(
            **{
                importer_constants.KEY_FEED: "http://test.com/feed",
                importer_constants.KEY_MAX_SPEED: 128.8
            })
        # We'll pass None for the parameters that don't get used by validate_config
        status, error_message = self.iso_importer.validate_config(None, config)
        self.assertTrue(status)
        self.assertEqual(error_message, None)

        config = importer_mocks.get_basic_config(
            **{
                importer_constants.KEY_FEED: "http://test.com/feed",
                importer_constants.KEY_MAX_SPEED: -42
            })
        status, error_message = self.iso_importer.validate_config(None, config)
        self.assertFalse(status)
        self.assertEqual(
            error_message,
            'The configuration parameter <max_speed> must be set to a positive '
            'numerical value, but is currently set to <-42.0>.')
예제 #2
0
    def test__init___ssl_validation(self):
        """
        Make sure the SSL validation is on by default.
        """
        # It should default to True
        config = importer_mocks.get_basic_config(
            **{importer_constants.KEY_FEED: 'http://fake.com/iso_feed/'})
        iso_sync_run = ISOSyncRun(self.sync_conduit, config)
        self.assertEqual(iso_sync_run.downloader.config.ssl_validation, True)

        # It should be possible to explicitly set it to False
        config = importer_mocks.get_basic_config(
            **{
                importer_constants.KEY_FEED: 'http://fake.com/iso_feed/',
                importer_constants.KEY_SSL_VALIDATION: False
            })
        iso_sync_run = ISOSyncRun(self.sync_conduit, config)
        self.assertEqual(iso_sync_run.downloader.config.ssl_validation, False)

        # It should be possible to explicitly set it to True
        config = importer_mocks.get_basic_config(
            **{
                importer_constants.KEY_FEED: 'http://fake.com/iso_feed/',
                importer_constants.KEY_SSL_VALIDATION: True
            })
        iso_sync_run = ISOSyncRun(self.sync_conduit, config)
        self.assertEqual(iso_sync_run.downloader.config.ssl_validation, True)
예제 #3
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)
예제 #4
0
 def test_validate(self):
     config = importer_mocks.get_basic_config(
         **{importer_constants.KEY_PROXY_HOST: 'http://fake.com/',
            importer_constants.KEY_FEED: 'http://test.com'})
     status, error_message = configuration.validate(config)
     self.assertTrue(status is True)
     self.assertEqual(error_message, None)
예제 #5
0
    def test_upload_unit_validate_unset(self, remove, validate):
        """
        Assert correct behavior from upload_unit() when the validation setting is not set. This
        should default to validating the upload.
        """
        # Set up the test
        file_data = "This is a file.\n"
        working_dir = os.path.join(self.temp_dir, "working")
        os.mkdir(working_dir)
        pkg_dir = os.path.join(self.temp_dir, "content")
        os.mkdir(pkg_dir)
        repo = mock.MagicMock(spec=Repository)
        repo.working_dir = working_dir
        # Set the checksum incorrect. The upload should be unsuccessful since the default is to
        # validate
        unit_key = {"name": "test.iso", "size": 16, "checksum": "Wrong"}
        metadata = {}
        temp_file_location = os.path.join(self.temp_dir, "test.iso")
        with open(temp_file_location, "w") as temp_file:
            temp_file.write(file_data)
        sync_conduit = importer_mocks.get_sync_conduit(pkg_dir=pkg_dir)
        # validate isn't set, so default should happen
        config = importer_mocks.get_basic_config()

        # Run the upload. This should report a failure
        report = self.iso_importer.upload_unit(
            repo, ids.TYPE_ID_ISO, unit_key, metadata, temp_file_location, sync_conduit, config
        )

        self.assertEqual(report["success_flag"], False)
        self.assertEqual(
            report["summary"],
            (
                "Downloading <test.iso> failed checksum validation. The manifest specified the "
                "checksum to be Wrong, but it was "
                "f02d5a72cd2d57fa802840a76b44c6c6920a8b8e6b90b20e26c03876275069e0."
            ),
        )

        # The conduit's init_unit method should have been called
        expected_rel_path = os.path.join(
            unit_key["name"], unit_key["checksum"], str(unit_key["size"]), unit_key["name"]
        )
        modified_metadata = metadata.copy()
        modified_metadata[server_constants.PULP_USER_METADATA_FIELDNAME] = {}
        sync_conduit.init_unit.assert_called_once_with(ids.TYPE_ID_ISO, unit_key, modified_metadata, expected_rel_path)

        # The file should have been moved to its final destination
        self.assertFalse(os.path.exists(temp_file_location))
        would_be_destination = os.path.join(pkg_dir, expected_rel_path)
        self.assertFalse(os.path.exists(would_be_destination))
        # The file should have been removed
        remove.assert_called_once_with(would_be_destination)

        # validate() should have been called with the full_validation=True flag
        iso = validate.mock_calls[0][1][0]
        validate.assert_called_once_with(iso, full_validation=True)

        # The conduit's save_unit method should have been called
        self.assertEqual(sync_conduit.save_unit.call_count, 0)
예제 #6
0
 def test_required_when_other_parameters_are_present(self):
     for parameters in [
         {
             importer_constants.KEY_PROXY_PASS: "******",
             importer_constants.KEY_PROXY_USER: "******",
             importer_constants.KEY_FEED: "http://fake.com",
         },
         {importer_constants.KEY_PROXY_PORT: "3037", importer_constants.KEY_FEED: "http://fake.com"},
     ]:
         # Each of the above configurations should cause the validator to complain about the
         # proxy_url
         # missing
         config = importer_mocks.get_basic_config(**parameters)
         status, error_message = configuration.validate(config)
         self.assertTrue(status is False)
         expected_message = (
             "The configuration parameter <%(proxy_host)s> is required when any of the "
             "following "
             "other parameters are defined: %(proxy_pass)s, %(proxy_port)s, %(proxy_user)s."
         )
         expected_message = expected_message % {
             "proxy_pass": importer_constants.KEY_PROXY_PASS,
             "proxy_user": importer_constants.KEY_PROXY_USER,
             "proxy_port": importer_constants.KEY_PROXY_PORT,
             "proxy_host": importer_constants.KEY_PROXY_HOST,
         }
         self.assertEqual(error_message, expected_message)
예제 #7
0
 def test_valid_config(self):
     config = importer_mocks.get_basic_config(
         **{importer_constants.KEY_UNITS_REMOVE_MISSING: True, importer_constants.KEY_FEED: "http://feed.com"}
     )
     status, error_message = configuration.validate(config)
     self.assertTrue(status is True)
     self.assertEqual(error_message, None)
예제 #8
0
 def test_string_true(self):
     config = importer_mocks.get_basic_config(
         **{importer_constants.KEY_VALIDATE: "true", importer_constants.KEY_FEED: "http://feed.com"}
     )
     status, error_message = configuration.validate(config)
     self.assertTrue(status is True)
     self.assertEqual(error_message, None)
 def test_required_when_other_parameters_are_present(self):
     for parameters in [
         {importer_constants.KEY_MAX_SPEED: '1024'}, {importer_constants.KEY_MAX_DOWNLOADS: 2},
         {importer_constants.KEY_PROXY_PASS: '******',
          importer_constants.KEY_PROXY_USER: '******',
          importer_constants.KEY_PROXY_HOST: 'http://test.com'},
         {importer_constants.KEY_PROXY_HOST: 'http://test.com', importer_constants.KEY_PROXY_PORT: '3037'},
         {importer_constants.KEY_PROXY_HOST: 'http://test.com'},
         {importer_constants.KEY_UNITS_REMOVE_MISSING: True},
         {importer_constants.KEY_SSL_CA_CERT: 'cert'},
         {importer_constants.KEY_SSL_CLIENT_CERT: 'cert'},
         {importer_constants.KEY_SSL_CLIENT_CERT: 'cert', importer_constants.KEY_SSL_CLIENT_KEY: 'key'},
         {importer_constants.KEY_VALIDATE: True}]:
             # Each of the above configurations should cause the validator to complain about the feed_url
             # missing
             config = importer_mocks.get_basic_config(**parameters)
             status, error_message = configuration.validate(config)
             self.assertTrue(status is False)
             self.assertEqual(
                 error_message,
                 'The configuration parameter <%(feed)s> is required when any of the following other '
                 'parameters are defined: %(max_speed)s, %(num_threads)s, %(proxy_pass)s, %(proxy_port)s, '
                 '%(proxy_host)s, %(proxy_user)s, %(remove_missing_units)s, %(ssl_ca_cert)s, '
                 '%(ssl_client_cert)s, %(ssl_client_key)s, %(validate_units)s.' % {
                     'feed': importer_constants.KEY_FEED, 'max_speed': importer_constants.KEY_MAX_SPEED,
                     'num_threads': importer_constants.KEY_MAX_DOWNLOADS,
                     'proxy_pass': importer_constants.KEY_PROXY_PASS,
                     'proxy_port': importer_constants.KEY_PROXY_PORT,
                     'proxy_host': importer_constants.KEY_PROXY_HOST,
                     'proxy_user': importer_constants.KEY_PROXY_USER,
                     'remove_missing_units': importer_constants.KEY_UNITS_REMOVE_MISSING,
                     'ssl_ca_cert': importer_constants.KEY_SSL_CA_CERT,
                     'ssl_client_cert': importer_constants.KEY_SSL_CLIENT_CERT,
                     'ssl_client_key': importer_constants.KEY_SSL_CLIENT_KEY,
                     'validate_units': importer_constants.KEY_VALIDATE})
 def test_client_key_requires_client_cert(self):
     config = importer_mocks.get_basic_config(**{importer_constants.KEY_SSL_CLIENT_KEY: 'Client Key!',
                                                 importer_constants.KEY_FEED: 'http://test.com'})
     status, error_message = configuration.validate(config)
     self.assertTrue(status is False)
     self.assertEqual(error_message, 'The configuration parameter <ssl_client_key> requires the '
                                     '<ssl_client_cert> parameter to also be set.')
예제 #11
0
 def test_validate(self):
     config = importer_mocks.get_basic_config(
         **{importer_constants.KEY_MAX_SPEED: 1.0, importer_constants.KEY_FEED: "http://test.com"}
     )
     status, error_message = configuration.validate(config)
     self.assertTrue(status is True)
     self.assertEqual(error_message, None)
 def test_invalid_config(self):
     config = importer_mocks.get_basic_config(**{importer_constants.KEY_MAX_SPEED: -1.0,
                                                 importer_constants.KEY_FEED: 'http://test.com'})
     status, error_message = configuration.validate(config)
     self.assertTrue(status is False)
     self.assertEqual(error_message, 'The configuration parameter <max_speed> must be set to a positive '
                                     'numerical value, but is currently set to <-1.0>.')
 def test_validate_str(self):
     parameters = {importer_constants.KEY_PROXY_PORT: '3128', importer_constants.KEY_PROXY_HOST: 'http://test.com',
                   importer_constants.KEY_FEED: 'http://test.com'}
     config = importer_mocks.get_basic_config(**parameters)
     status, error_message = configuration.validate(config)
     self.assertTrue(status is True)
     self.assertEqual(error_message, None)
예제 #14
0
 def test_required_when_other_parameters_are_present(self):
     for parameters in [{
             importer_constants.KEY_PROXY_PASS: '******',
             importer_constants.KEY_PROXY_USER: '******',
             importer_constants.KEY_FEED: 'http://fake.com'
     }, {
             importer_constants.KEY_PROXY_PORT: '3037',
             importer_constants.KEY_FEED: 'http://fake.com'
     }]:
         # Each of the above configurations should cause the validator to complain about the
         # proxy_url
         # missing
         config = importer_mocks.get_basic_config(**parameters)
         status, error_message = configuration.validate(config)
         self.assertTrue(status is False)
         expected_message = (
             'The configuration parameter <%(proxy_host)s> is required when any of the '
             'following '
             'other parameters are defined: %(proxy_pass)s, %(proxy_port)s, %(proxy_user)s.'
         )
         expected_message = expected_message % {
             'proxy_pass': importer_constants.KEY_PROXY_PASS,
             'proxy_user': importer_constants.KEY_PROXY_USER,
             'proxy_port': importer_constants.KEY_PROXY_PORT,
             'proxy_host': importer_constants.KEY_PROXY_HOST
         }
         self.assertEqual(error_message, expected_message)
 def test_client_cert_is_non_string(self):
     config = importer_mocks.get_basic_config(**{importer_constants.KEY_SSL_CLIENT_CERT: 8,
                                                 importer_constants.KEY_FEED: 'http://test.com'})
     status, error_message = configuration.validate(config)
     self.assertTrue(status is False)
     self.assertEqual(error_message, "The configuration parameter <ssl_client_cert> should be a string, "
                                     "but it was <type 'int'>.")
 def test_password_is_non_string(self):
     parameters = {importer_constants.KEY_PROXY_PASS: 7, importer_constants.KEY_PROXY_USER: "******",
                   importer_constants.KEY_FEED: 'http://test.com'}
     config = importer_mocks.get_basic_config(**parameters)
     status, error_message = configuration.validate(config)
     self.assertTrue(status is False)
     self.assertEqual(error_message, "The configuration parameter <proxy_password> should be a string, "
                                     "but it was <type 'int'>.")
 def test_zero(self):
     parameters = {importer_constants.KEY_PROXY_PORT: 0, importer_constants.KEY_PROXY_HOST: 'http://test.com',
                   importer_constants.KEY_FEED: 'http://test.com'}
     config = importer_mocks.get_basic_config(**parameters)
     status, error_message = configuration.validate(config)
     self.assertTrue(status is False)
     self.assertEqual(error_message, 'The configuration parameter <proxy_port> must be set to a positive '
                                     'integer, but is currently set to <0>.')
 def test_validate(self):
     params = {importer_constants.KEY_PROXY_PASS: '******', importer_constants.KEY_PROXY_USER: '******',
               importer_constants.KEY_PROXY_HOST: 'http://fake.com/',
               importer_constants.KEY_FEED: 'http://test.com'}
     config = importer_mocks.get_basic_config(**params)
     status, error_message = configuration.validate(config)
     self.assertTrue(status is True)
     self.assertEqual(error_message, None)
예제 #19
0
 def test_invalid_config(self):
     config = importer_mocks.get_basic_config(
         **{importer_constants.KEY_FEED: 42})
     status, error_message = configuration.validate(config)
     self.assertTrue(status is False)
     self.assertEqual(
         error_message, '<%(feed)s> must be a string.' %
         {'feed': importer_constants.KEY_FEED})
예제 #20
0
    def setUp(self):
        config = {
            importer_constants.KEY_FEED: 'http://fake.com/iso_feed/',
            importer_constants.KEY_MAX_SPEED: 500.0,
            importer_constants.KEY_MAX_DOWNLOADS: 5,
            importer_constants.KEY_SSL_VALIDATION: False,
            importer_constants.KEY_SSL_CLIENT_CERT:
            "Trust me, I'm who I say I am.",
            importer_constants.KEY_SSL_CLIENT_KEY: "Secret Key",
            importer_constants.KEY_SSL_CA_CERT:
            "Uh, I guess that's the right server.",
            importer_constants.KEY_PROXY_HOST: 'proxy.com',
            importer_constants.KEY_PROXY_PORT: 1234,
            importer_constants.KEY_PROXY_USER: "******",
            importer_constants.KEY_PROXY_PASS: '******',
            importer_constants.KEY_VALIDATE: False,
        }

        self.config = importer_mocks.get_basic_config(**config)

        self.temp_dir = tempfile.mkdtemp()
        self.pkg_dir = os.path.join(self.temp_dir, 'content')
        os.mkdir(self.pkg_dir)

        # These checksums correspond to the checksums of the files that our curl mocks will
        # generate. Our curl mocks do not have a test4.iso, so that one is to test removal of
        # old ISOs during sync
        self.existing_units = [
            Unit(
                TYPE_ID_ISO, {
                    'name':
                    'test.iso',
                    'size':
                    16,
                    'checksum':
                    'f02d5a72cd2d57fa802840a76b44c6c6920a8b8e6b90b20e26c03876275069e0'
                }, {}, '/path/test.iso'),
            Unit(
                TYPE_ID_ISO, {
                    'name':
                    'test2.iso',
                    'size':
                    22,
                    'checksum':
                    'c7fbc0e821c0871805a99584c6a384533909f68a6bbe9a2a687d28d9f3b10c16'
                }, {}, '/path/test2.iso'),
            Unit(TYPE_ID_ISO, {
                'name': 'test4.iso',
                'size': 4,
                'checksum': 'sum4'
            }, {}, '/path/test4.iso')
        ]
        self.sync_conduit = importer_mocks.get_sync_conduit(
            pkg_dir=self.pkg_dir,
            existing_units=self.existing_units,
            pulp_units=self.existing_units)

        self.iso_sync_run = ISOSyncRun(self.sync_conduit, self.config)
예제 #21
0
    def test_upload_unit_validate_true_good_checksum(self):
        """
        Test behavior with good arguments.
        """
        # Set up the test
        file_data = 'This is a file.\n'
        working_dir = os.path.join(self.temp_dir, "working")
        os.mkdir(working_dir)
        pkg_dir = os.path.join(self.temp_dir, 'content')
        os.mkdir(pkg_dir)
        repo = mock.MagicMock(spec=Repository)
        repo.working_dir = working_dir
        unit_key = {
            'name':
            'test.iso',
            'size':
            16,
            'checksum':
            'f02d5a72cd2d57fa802840a76b44c6c6920a8b8e6b90b20e26c03876275069e0'
        }
        metadata = {}
        temp_file_location = os.path.join(self.temp_dir, 'test.iso')
        with open(temp_file_location, 'w') as temp_file:
            temp_file.write(file_data)
        sync_conduit = importer_mocks.get_sync_conduit(pkg_dir=pkg_dir)
        config = importer_mocks.get_basic_config(
            **{importer_constants.KEY_VALIDATE: 'true'})

        # Run the upload. This should be successful
        report = self.iso_importer.upload_unit(repo, ids.TYPE_ID_ISO, unit_key,
                                               metadata, temp_file_location,
                                               sync_conduit, config)

        self.assertEqual(report['success_flag'], True)
        self.assertEqual(report['summary'], None)
        # The conduit's init_unit method should have been called
        expected_rel_path = os.path.join(unit_key['name'],
                                         unit_key['checksum'],
                                         str(unit_key['size']),
                                         unit_key['name'])
        modified_metadata = metadata.copy()
        modified_metadata[server_constants.PULP_USER_METADATA_FIELDNAME] = {}
        sync_conduit.init_unit.assert_called_once_with(ids.TYPE_ID_ISO,
                                                       unit_key,
                                                       modified_metadata,
                                                       expected_rel_path)

        # The file should have been moved to its final destination
        self.assertFalse(os.path.exists(temp_file_location))
        expected_destination = os.path.join(pkg_dir, expected_rel_path)
        self.assertTrue(os.path.exists(expected_destination))
        with open(expected_destination) as iso_file:
            self.assertEqual(iso_file.read(), file_data)

        # The conduit's save_unit method should have been called
        self.assertEqual(sync_conduit.save_unit.call_count, 1)
        saved_unit = sync_conduit.save_unit.mock_calls[0][1][0]
        self.assertEqual(saved_unit.unit_key, unit_key)
 def test_url_is_non_string(self):
     config = importer_mocks.get_basic_config(**{importer_constants.KEY_PROXY_HOST: 7,
                                                 importer_constants.KEY_FEED: 'http://test.com'})
     status, error_message = configuration.validate(config)
     self.assertTrue(status is False)
     expected_message = ("The configuration parameter <%(proxy_host)s> should be a string, but it was "
                         "<type 'int'>.")
     expected_message = expected_message % {'proxy_host': importer_constants.KEY_PROXY_HOST}
     self.assertEqual(error_message, expected_message)
 def test_zero(self):
     config = importer_mocks.get_basic_config(**{importer_constants.KEY_MAX_DOWNLOADS: 0,
                                                 importer_constants.KEY_FEED: 'http://test.com'})
     status, error_message = configuration.validate(config)
     self.assertTrue(status is False)
     expected_message = ('The configuration parameter <%(num_threads)s> must be set to a positive '
                         'integer, but is currently set to <0>.')
     expected_message = expected_message % {'num_threads': importer_constants.KEY_MAX_DOWNLOADS}
     self.assertEqual(error_message, expected_message)
예제 #24
0
    def test_validate_config(self):
        """
        We already have a seperate test module for config validation, but we can get 100% test coverage with
        this!
        """
        config = importer_mocks.get_basic_config(
            **{importer_constants.KEY_FEED: "http://test.com/feed", importer_constants.KEY_MAX_SPEED: 128.8})
        # We'll pass None for the parameters that don't get used by validate_config
        status, error_message = self.iso_importer.validate_config(None, config)
        self.assertTrue(status)
        self.assertEqual(error_message, None)

        config = importer_mocks.get_basic_config(**{importer_constants.KEY_FEED: "http://test.com/feed",
                                                    importer_constants.KEY_MAX_SPEED: -42})
        status, error_message = self.iso_importer.validate_config(None, config)
        self.assertFalse(status)
        self.assertEqual(error_message, 'The configuration parameter <max_speed> must be set to a positive '
                                        'numerical value, but is currently set to <-42.0>.')
예제 #25
0
 def test_valid_config(self):
     config = importer_mocks.get_basic_config(
         **{
             importer_constants.KEY_UNITS_REMOVE_MISSING: True,
             importer_constants.KEY_FEED: 'http://feed.com'
         })
     status, error_message = configuration.validate(config)
     self.assertTrue(status is True)
     self.assertEqual(error_message, None)
예제 #26
0
 def test_invalid_config(self):
     config = importer_mocks.get_basic_config(**{importer_constants.KEY_VALIDATE: 1,
                                                 importer_constants.KEY_FEED: 'http://feed.com'})
     status, error_message = configuration.validate(config)
     self.assertTrue(status is False)
     expected_message = ('The configuration parameter <%(validate)s> may only be set to a '
                         'boolean value, but is currently set to <1>.')
     expected_message = expected_message % {'validate': importer_constants.KEY_VALIDATE}
     self.assertEqual(error_message, expected_message)
예제 #27
0
 def test_validate(self):
     config = importer_mocks.get_basic_config(
         **{
             importer_constants.KEY_MAX_SPEED: 1.0,
             importer_constants.KEY_FEED: 'http://test.com'
         })
     status, error_message = configuration.validate(config)
     self.assertTrue(status is True)
     self.assertEqual(error_message, None)
예제 #28
0
    def test_sync_no_feed(self):
        repo = mock.MagicMock(spec=Repository)
        pkg_dir = os.path.join(self.temp_dir, "content")
        sync_conduit = importer_mocks.get_sync_conduit(pkg_dir=pkg_dir)
        config = {importer_constants.KEY_FEED: None}
        config = importer_mocks.get_basic_config(**config)

        # Now run the sync
        self.assertRaises(ValueError, self.iso_importer.sync_repo, repo, sync_conduit, config)
예제 #29
0
 def test_string_true(self):
     config = importer_mocks.get_basic_config(
         **{
             importer_constants.KEY_VALIDATE: 'true',
             importer_constants.KEY_FEED: 'http://feed.com'
         })
     status, error_message = configuration.validate(config)
     self.assertTrue(status is True)
     self.assertEqual(error_message, None)
예제 #30
0
    def test_sync_no_feed(self):
        repo = mock.MagicMock(spec=Repository)
        pkg_dir = os.path.join(self.temp_dir, 'content')
        sync_conduit = importer_mocks.get_sync_conduit(pkg_dir=pkg_dir)
        config = {importer_constants.KEY_FEED: None}
        config = importer_mocks.get_basic_config(**config)

        # Now run the sync
        self.assertRaises(ValueError, self.iso_importer.sync_repo, repo, sync_conduit, config)
 def test_invalid_config(self):
     config = importer_mocks.get_basic_config(**{importer_constants.KEY_UNITS_REMOVE_MISSING: 'trizue',
                                                 importer_constants.KEY_FEED: 'http://feed.com'})
     status, error_message = configuration.validate(config)
     self.assertTrue(status is False)
     expected_message = ('The configuration parameter <%(remove_missing)s> may only be set to a '
                         'boolean value, but is currently set to <trizue>.')
     expected_message = expected_message % {'remove_missing': importer_constants.KEY_UNITS_REMOVE_MISSING}
     self.assertEqual(error_message, expected_message)
예제 #32
0
    def test_upload_unit_validate_unset(self, remove, validate):
        """
        Assert correct behavior from upload_unit() when the validation setting is not set. This
        should default to validating the upload.
        """
        # Set up the test
        file_data = 'This is a file.\n'
        working_dir = os.path.join(self.temp_dir, "working")
        os.mkdir(working_dir)
        pkg_dir = os.path.join(self.temp_dir, 'content')
        os.mkdir(pkg_dir)
        repo = mock.MagicMock(spec=Repository)
        repo.working_dir = working_dir
        # Set the checksum incorrect. The upload should be unsuccessful since the default is to
        # validate
        unit_key = {'name': 'test.iso', 'size': 16, 'checksum': 'Wrong'}
        metadata = {}
        temp_file_location = os.path.join(self.temp_dir, 'test.iso')
        with open(temp_file_location, 'w') as temp_file:
            temp_file.write(file_data)
        sync_conduit = importer_mocks.get_sync_conduit(pkg_dir=pkg_dir)
        # validate isn't set, so default should happen
        config = importer_mocks.get_basic_config()

        # Run the upload. This should report a failure
        report = self.iso_importer.upload_unit(repo, ids.TYPE_ID_ISO, unit_key, metadata,
                                               temp_file_location, sync_conduit, config)

        self.assertEqual(report['success_flag'], False)
        self.assertEqual(
            report['summary'],
            ('Downloading <test.iso> failed checksum validation. The manifest specified the '
             'checksum to be Wrong, but it was '
             'f02d5a72cd2d57fa802840a76b44c6c6920a8b8e6b90b20e26c03876275069e0.'))

        # The conduit's init_unit method should have been called
        expected_rel_path = os.path.join(unit_key['name'], unit_key['checksum'],
                                         str(unit_key['size']), unit_key['name'])
        modified_metadata = metadata.copy()
        modified_metadata[server_constants.PULP_USER_METADATA_FIELDNAME] = {}
        sync_conduit.init_unit.assert_called_once_with(ids.TYPE_ID_ISO, unit_key, modified_metadata,
                                                       expected_rel_path)

        # The file should have been moved to its final destination
        self.assertFalse(os.path.exists(temp_file_location))
        would_be_destination = os.path.join(pkg_dir, expected_rel_path)
        self.assertFalse(os.path.exists(would_be_destination))
        # The file should have been removed
        remove.assert_called_once_with(would_be_destination)

        # validate() should have been called with the full_validation=True flag
        iso = validate.mock_calls[0][1][0]
        validate.assert_called_once_with(iso, full_validation=True)

        # The conduit's save_unit method should have been called
        self.assertEqual(sync_conduit.save_unit.call_count, 0)
예제 #33
0
    def test_upload_unit_validate_false(self, validate):
        """
        Assert correct behavior from upload_unit() when the validation setting is False.
        """
        # Set up the test
        file_data = "This is a file.\n"
        working_dir = os.path.join(self.temp_dir, "working")
        os.mkdir(working_dir)
        pkg_dir = os.path.join(self.temp_dir, "content")
        os.mkdir(pkg_dir)
        repo = mock.MagicMock(spec=Repository)
        repo.working_dir = working_dir
        # Set the checksum incorrect. The upload should be successful no matter what since
        # validation will be set to False
        unit_key = {"name": "test.iso", "size": 16, "checksum": "Wrong"}
        metadata = {}
        temp_file_location = os.path.join(self.temp_dir, "test.iso")
        with open(temp_file_location, "w") as temp_file:
            temp_file.write(file_data)
        sync_conduit = importer_mocks.get_sync_conduit(pkg_dir=pkg_dir)
        config = importer_mocks.get_basic_config(**{importer_constants.KEY_VALIDATE: "false"})

        # Run the upload. This should be successful, since we have set validation off.
        report = self.iso_importer.upload_unit(
            repo, ids.TYPE_ID_ISO, unit_key, metadata, temp_file_location, sync_conduit, config
        )

        # The import should have been successful
        self.assertEqual(report["success_flag"], True)
        self.assertEqual(report["summary"], None)

        # The conduit's init_unit method should have been called
        expected_rel_path = os.path.join(
            unit_key["name"], unit_key["checksum"], str(unit_key["size"]), unit_key["name"]
        )
        modified_metadata = metadata.copy()
        modified_metadata[server_constants.PULP_USER_METADATA_FIELDNAME] = {}
        sync_conduit.init_unit.assert_called_once_with(ids.TYPE_ID_ISO, unit_key, modified_metadata, expected_rel_path)

        # The file should have been moved to its final destination
        self.assertFalse(os.path.exists(temp_file_location))
        expected_destination = os.path.join(pkg_dir, expected_rel_path)
        self.assertTrue(os.path.exists(expected_destination))
        with open(expected_destination) as iso_file:
            self.assertEqual(iso_file.read(), file_data)

        # validate() should still have been called, but with the full_validation=False flag
        # We need to get the ISO itself for our assertion, since it is technically the first
        # argument
        iso = validate.mock_calls[0][1][0]
        validate.assert_called_once_with(iso, full_validation=False)

        # The conduit's save_unit method should have been called
        self.assertEqual(sync_conduit.save_unit.call_count, 1)
        saved_unit = sync_conduit.save_unit.mock_calls[0][1][0]
        self.assertEqual(saved_unit.unit_key, unit_key)
예제 #34
0
 def test_validate(self):
     params = {
         importer_constants.KEY_SSL_CA_CERT: 'CA Certificate!',
         importer_constants.KEY_SSL_CLIENT_CERT: 'Client Certificate!',
         importer_constants.KEY_SSL_CLIENT_KEY: 'Client Key!',
         importer_constants.KEY_FEED: 'http://test.com'}
     config = importer_mocks.get_basic_config(**params)
     status, error_message = configuration.validate(config)
     self.assertTrue(status is True)
     self.assertEqual(error_message, None)
예제 #35
0
    def test_sync_calls_sync(self, mock_sync_run):
        repo = Repository("repo1")
        sync_conduit = importer_mocks.get_sync_conduit(pkg_dir="/a/b/c")
        config = importer_mocks.get_basic_config(**{importer_constants.KEY_FEED: "http://fake.com/iso_feed/"})

        self.iso_importer.sync_repo(repo, sync_conduit, config)

        # make sure the sync workflow is called with the right stuff
        mock_sync_run.assert_called_once_with(sync_conduit, config)
        mock_sync_run.return_value.perform_sync.assert_called_once_with()
예제 #36
0
 def test_validate_str(self):
     parameters = {
         importer_constants.KEY_PROXY_PORT: '3128',
         importer_constants.KEY_PROXY_HOST: 'http://test.com',
         importer_constants.KEY_FEED: 'http://test.com'
     }
     config = importer_mocks.get_basic_config(**parameters)
     status, error_message = configuration.validate(config)
     self.assertTrue(status is True)
     self.assertEqual(error_message, None)
예제 #37
0
    def test_upload_unit_validate_true_bad_checksum(self, remove, validate):
        """
        Test behavior with a bad checksum.
        """
        # Set up the test
        file_data = 'This is a file.\n'
        error_message = 'uh oh'
        validate.side_effect = ValueError(error_message)
        working_dir = os.path.join(self.temp_dir, "working")
        os.mkdir(working_dir)
        pkg_dir = os.path.join(self.temp_dir, 'content')
        os.mkdir(pkg_dir)
        repo = mock.MagicMock(spec=Repository)
        repo.working_dir = working_dir
        # Set the checksum incorrect. The upload should fail.
        unit_key = {'name': 'test.iso', 'size': 16, 'checksum': 'Wrong'}
        metadata = {}
        temp_file_location = os.path.join(self.temp_dir, 'test.iso')
        with open(temp_file_location, 'w') as temp_file:
            temp_file.write(file_data)
        sync_conduit = importer_mocks.get_sync_conduit(pkg_dir=pkg_dir)
        config = importer_mocks.get_basic_config(
            **{importer_constants.KEY_VALIDATE: 'true'})

        # Run the upload. This should fail due to the bad checksum
        report = self.iso_importer.upload_unit(repo, ids.TYPE_ID_ISO, unit_key,
                                               metadata, temp_file_location,
                                               sync_conduit, config)

        self.assertEqual(report['success_flag'], False)
        self.assertEqual(report['summary'], error_message)
        # The conduit's init_unit method should have been called
        expected_rel_path = os.path.join(unit_key['name'],
                                         unit_key['checksum'],
                                         str(unit_key['size']),
                                         unit_key['name'])
        modified_metadata = metadata.copy()
        modified_metadata[server_constants.PULP_USER_METADATA_FIELDNAME] = {}
        sync_conduit.init_unit.assert_called_once_with(ids.TYPE_ID_ISO,
                                                       unit_key,
                                                       modified_metadata,
                                                       expected_rel_path)

        # The file should have been deleted
        self.assertFalse(os.path.exists(temp_file_location))
        would_be_destination = os.path.join(pkg_dir, expected_rel_path)
        self.assertFalse(os.path.exists(would_be_destination))
        # The file should have been removed from there
        remove.assert_called_once_with(would_be_destination)

        # validate() should have been called with the full_validation=True flag
        validate.assert_called_once_with(full_validation=True)

        # The conduit's save_unit method should not have been called
        self.assertEqual(sync_conduit.save_unit.call_count, 0)
예제 #38
0
 def test_required_when_other_parameters_are_present(self):
     for parameters in [{
             importer_constants.KEY_MAX_SPEED: '1024'
     }, {
             importer_constants.KEY_MAX_DOWNLOADS: 2
     }, {
             importer_constants.KEY_PROXY_PASS: '******',
             importer_constants.KEY_PROXY_USER: '******',
             importer_constants.KEY_PROXY_HOST: 'http://test.com'
     }, {
             importer_constants.KEY_PROXY_HOST: 'http://test.com',
             importer_constants.KEY_PROXY_PORT: '3037'
     }, {
             importer_constants.KEY_PROXY_HOST: 'http://test.com'
     }, {
             importer_constants.KEY_UNITS_REMOVE_MISSING: True
     }, {
             importer_constants.KEY_SSL_CA_CERT: 'cert'
     }, {
             importer_constants.KEY_SSL_CLIENT_CERT: 'cert'
     }, {
             importer_constants.KEY_SSL_CLIENT_CERT: 'cert',
             importer_constants.KEY_SSL_CLIENT_KEY: 'key'
     }, {
             importer_constants.KEY_VALIDATE: True
     }]:
         # Each of the above configurations should cause the validator to complain about the
         # feed_url
         # missing
         config = importer_mocks.get_basic_config(**parameters)
         status, error_message = configuration.validate(config)
         self.assertTrue(status is False)
         self.assertEqual(
             error_message,
             'The configuration parameter <%(feed)s> is required when any of the following '
             'other '
             'parameters are defined: %(max_speed)s, %(num_threads)s, %(proxy_pass)s, '
             '%(proxy_port)s, '
             '%(proxy_host)s, %(proxy_user)s, %(remove_missing_units)s, %(ssl_ca_cert)s, '
             '%(ssl_client_cert)s, %(ssl_client_key)s, %(validate_units)s.'
             % {
                 'feed': importer_constants.KEY_FEED,
                 'max_speed': importer_constants.KEY_MAX_SPEED,
                 'num_threads': importer_constants.KEY_MAX_DOWNLOADS,
                 'proxy_pass': importer_constants.KEY_PROXY_PASS,
                 'proxy_port': importer_constants.KEY_PROXY_PORT,
                 'proxy_host': importer_constants.KEY_PROXY_HOST,
                 'proxy_user': importer_constants.KEY_PROXY_USER,
                 'remove_missing_units':
                 importer_constants.KEY_UNITS_REMOVE_MISSING,
                 'ssl_ca_cert': importer_constants.KEY_SSL_CA_CERT,
                 'ssl_client_cert': importer_constants.KEY_SSL_CLIENT_CERT,
                 'ssl_client_key': importer_constants.KEY_SSL_CLIENT_KEY,
                 'validate_units': importer_constants.KEY_VALIDATE
             })
예제 #39
0
    def test_upload_unit_validate_false(self, validate):
        """
        Assert correct behavior from upload_unit() when the validation setting is False.
        """
        # Set up the test
        file_data = 'This is a file.\n'
        working_dir = os.path.join(self.temp_dir, "working")
        os.mkdir(working_dir)
        pkg_dir = os.path.join(self.temp_dir, 'content')
        os.mkdir(pkg_dir)
        repo = mock.MagicMock(spec=Repository)
        repo.working_dir = working_dir
        # Set the checksum incorrect. The upload should be successful no matter what since
        # validation will be set to False
        unit_key = {'name': 'test.iso', 'size': 16, 'checksum': 'Wrong'}
        metadata = {}
        temp_file_location = os.path.join(self.temp_dir, 'test.iso')
        with open(temp_file_location, 'w') as temp_file:
            temp_file.write(file_data)
        sync_conduit = importer_mocks.get_sync_conduit(pkg_dir=pkg_dir)
        config = importer_mocks.get_basic_config(**{importer_constants.KEY_VALIDATE: 'false'})

        # Run the upload. This should be successful, since we have set validation off.
        report = self.iso_importer.upload_unit(repo, ids.TYPE_ID_ISO, unit_key, metadata,
                                               temp_file_location, sync_conduit, config)

        # The import should have been successful
        self.assertEqual(report['success_flag'], True)
        self.assertEqual(report['summary'], None)

        # The conduit's init_unit method should have been called
        expected_rel_path = os.path.join(unit_key['name'], unit_key['checksum'],
                                         str(unit_key['size']), unit_key['name'])
        modified_metadata = metadata.copy()
        modified_metadata[server_constants.PULP_USER_METADATA_FIELDNAME] = {}
        sync_conduit.init_unit.assert_called_once_with(ids.TYPE_ID_ISO, unit_key, modified_metadata,
                                                       expected_rel_path)

        # The file should have been moved to its final destination
        self.assertFalse(os.path.exists(temp_file_location))
        expected_destination = os.path.join(pkg_dir, expected_rel_path)
        self.assertTrue(os.path.exists(expected_destination))
        with open(expected_destination) as iso_file:
            self.assertEqual(iso_file.read(), file_data)

        # validate() should still have been called, but with the full_validation=False flag
        # We need to get the ISO itself for our assertion, since it is technically the first
        # argument
        iso = validate.mock_calls[0][1][0]
        validate.assert_called_once_with(iso, full_validation=False)

        # The conduit's save_unit method should have been called
        self.assertEqual(sync_conduit.save_unit.call_count, 1)
        saved_unit = sync_conduit.save_unit.mock_calls[0][1][0]
        self.assertEqual(saved_unit.unit_key, unit_key)
예제 #40
0
 def test_validate(self):
     params = {
         importer_constants.KEY_SSL_CA_CERT: 'CA Certificate!',
         importer_constants.KEY_SSL_CLIENT_CERT: 'Client Certificate!',
         importer_constants.KEY_SSL_CLIENT_KEY: 'Client Key!',
         importer_constants.KEY_FEED: 'http://test.com'
     }
     config = importer_mocks.get_basic_config(**params)
     status, error_message = configuration.validate(config)
     self.assertTrue(status is True)
     self.assertEqual(error_message, None)
 def test_username_requires_password(self):
     parameters = {importer_constants.KEY_PROXY_USER: '******', importer_constants.KEY_FEED: 'http://fake.com',
                   importer_constants.KEY_PROXY_HOST: 'http://fake.com'}
     config = importer_mocks.get_basic_config(**parameters)
     status, error_message = configuration.validate(config)
     self.assertTrue(status is False)
     expected_message = ('The configuration parameter <%(proxy_user)s> requires the '
                         '<%(proxy_pass)s> parameter to also be set.')
     expected_message = expected_message % {'proxy_user': importer_constants.KEY_PROXY_USER,
                                            'proxy_pass': importer_constants.KEY_PROXY_PASS}
     self.assertEqual(error_message, expected_message)
 def test_username_is_non_string(self):
     parameters = {importer_constants.KEY_PROXY_PASS: '******', importer_constants.KEY_PROXY_USER: 185,
                   importer_constants.KEY_PROXY_HOST: 'http://test.com',
                   importer_constants.KEY_FEED: 'http://test2.com'}
     config = importer_mocks.get_basic_config(**parameters)
     status, error_message = configuration.validate(config)
     self.assertTrue(status is False)
     expected_message = ("The configuration parameter <%(proxy_user)s> should be a string, but it was "
                         "<type 'int'>.")
     expected_message = expected_message % {'proxy_user': importer_constants.KEY_PROXY_USER}
     self.assertEqual(error_message, expected_message)
예제 #43
0
    def test_upload_unit_validate_unset(self, remove, validate):
        """
        Assert correct behavior from upload_unit() when the validation setting is not set. This
        should default to validating the upload.
        """
        # Set up the test
        file_data = 'This is a file.\n'
        working_dir = os.path.join(self.temp_dir, "working")
        os.mkdir(working_dir)
        pkg_dir = os.path.join(self.temp_dir, 'content')
        os.mkdir(pkg_dir)
        repo = mock.MagicMock(spec=Repository)
        repo.working_dir = working_dir
        # Set the checksum incorrect. The upload should be unsuccessful since the default is to
        # validate
        unit_key = {'name': 'test.iso', 'size': 16, 'checksum': 'Wrong'}
        metadata = {}
        temp_file_location = os.path.join(self.temp_dir, 'test.iso')
        with open(temp_file_location, 'w') as temp_file:
            temp_file.write(file_data)
        sync_conduit = importer_mocks.get_sync_conduit(type_id=ids.TYPE_ID_ISO, pkg_dir=pkg_dir)
        # validate isn't set, so default should happen
        config = importer_mocks.get_basic_config()

        # Run the upload. This should report a failure
        report = self.iso_importer.upload_unit(repo, ids.TYPE_ID_ISO, unit_key, metadata,
                                               temp_file_location, sync_conduit, config)

        self.assertEqual(report['success_flag'], False)
        self.assertEqual(
            report['summary'],
            ('Downloading <test.iso> failed checksum validation. The manifest specified the '
             'checksum to be Wrong, but it was '
             'f02d5a72cd2d57fa802840a76b44c6c6920a8b8e6b90b20e26c03876275069e0.'))

        # The conduit's init_unit method should have been called
        expected_rel_path = os.path.join(unit_key['name'], unit_key['checksum'],
                                         str(unit_key['size']), unit_key['name'])
        sync_conduit.init_unit.assert_called_once_with(ids.TYPE_ID_ISO, unit_key, metadata,
                                                       expected_rel_path)

        # The file should have been moved to its final destination
        self.assertFalse(os.path.exists(temp_file_location))
        would_be_destination = os.path.join(pkg_dir, expected_rel_path)
        self.assertFalse(os.path.exists(would_be_destination))
        # The file should have been removed
        remove.assert_called_once_with(would_be_destination)

        # validate() should have been called with the full_validation=True flag
        iso = validate.mock_calls[0][1][0]
        validate.assert_called_once_with(iso, full_validation=True)

        # The conduit's save_unit method should have been called
        self.assertEqual(sync_conduit.save_unit.call_count, 0)
예제 #44
0
 def test_validate(self):
     params = {
         importer_constants.KEY_PROXY_PASS: '******',
         importer_constants.KEY_PROXY_USER: '******',
         importer_constants.KEY_PROXY_HOST: 'http://fake.com/',
         importer_constants.KEY_FEED: 'http://test.com'
     }
     config = importer_mocks.get_basic_config(**params)
     status, error_message = configuration.validate(config)
     self.assertTrue(status is True)
     self.assertEqual(error_message, None)
예제 #45
0
    def test_sync_calls_sync(self, mock_sync_run):
        repo = Repository('repo1')
        sync_conduit = importer_mocks.get_sync_conduit(pkg_dir='/a/b/c')
        config = importer_mocks.get_basic_config(
            **{importer_constants.KEY_FEED: 'http://fake.com/iso_feed/'})

        self.iso_importer.sync_repo(repo, sync_conduit, config)

        # make sure the sync workflow is called with the right stuff
        mock_sync_run.assert_called_once_with(sync_conduit, config)
        mock_sync_run.return_value.perform_sync.assert_called_once_with()
예제 #46
0
    def test_upload_unit_named_PULP_MANIFEST(self, remove):
        """
        We had a bug[0] due to the ISOImporter allowing units to be uploaded named PULP_MANIFEST.
        This test asserts that that is no longer allowed.

        [0] https://bugzilla.redhat.com/show_bug.cgi?id=973678
        """
        # Set up the test
        file_data = "This is a PULP_MANIFEST file. The upload should be rejected.\n"
        working_dir = os.path.join(self.temp_dir, "working")
        os.mkdir(working_dir)
        pkg_dir = os.path.join(self.temp_dir, "content")
        os.mkdir(pkg_dir)
        repo = mock.MagicMock(spec=Repository)
        repo.working_dir = working_dir
        # We'll set validation off so the checksum doesn't matter
        unit_key = {"name": "PULP_MANIFEST", "size": len(file_data), "checksum": "Doesn't matter"}
        metadata = {}
        temp_file_location = os.path.join(self.temp_dir, unit_key["name"])
        with open(temp_file_location, "w") as temp_file:
            temp_file.write(file_data)
        sync_conduit = importer_mocks.get_sync_conduit(pkg_dir=pkg_dir)
        # Just so we don't have to care about the checksum
        config = importer_mocks.get_basic_config(**{importer_constants.KEY_VALIDATE: "false"})

        report = self.iso_importer.upload_unit(
            repo, ids.TYPE_ID_ISO, unit_key, metadata, temp_file_location, sync_conduit, config
        )

        self.assertEqual(report["success_flag"], False)
        self.assertEqual(
            report["summary"],
            "An ISO may not be named PULP_MANIFEST, as it "
            "conflicts with the name of the manifest during "
            "publishing.",
        )

        # init_unit() should have been called
        expected_rel_path = os.path.join(
            unit_key["name"], unit_key["checksum"], str(unit_key["size"]), unit_key["name"]
        )
        modified_metadata = metadata.copy()
        modified_metadata[server_constants.PULP_USER_METADATA_FIELDNAME] = {}
        sync_conduit.init_unit.assert_called_once_with(ids.TYPE_ID_ISO, unit_key, modified_metadata, expected_rel_path)

        # The file should have been deleted
        self.assertFalse(os.path.exists(temp_file_location))
        would_be_destination = os.path.join(pkg_dir, expected_rel_path)
        self.assertFalse(os.path.exists(would_be_destination))
        # The file should have been removed from there
        remove.assert_called_once_with(would_be_destination)

        # The conduit's save_unit method should not have been called
        self.assertEqual(sync_conduit.save_unit.call_count, 0)
예제 #47
0
 def test_client_cert_is_non_string(self):
     config = importer_mocks.get_basic_config(
         **{
             importer_constants.KEY_SSL_CLIENT_CERT: 8,
             importer_constants.KEY_FEED: 'http://test.com'
         })
     status, error_message = configuration.validate(config)
     self.assertTrue(status is False)
     self.assertEqual(
         error_message,
         "The configuration parameter <ssl_client_cert> should be a string, "
         "but it was <type 'int'>.")
예제 #48
0
 def test_client_key_requires_client_cert(self):
     config = importer_mocks.get_basic_config(
         **{
             importer_constants.KEY_SSL_CLIENT_KEY: 'Client Key!',
             importer_constants.KEY_FEED: 'http://test.com'
         })
     status, error_message = configuration.validate(config)
     self.assertTrue(status is False)
     self.assertEqual(
         error_message,
         'The configuration parameter <ssl_client_key> requires the '
         '<ssl_client_cert> parameter to also be set.')
예제 #49
0
 def test_invalid_str(self):
     config = importer_mocks.get_basic_config(
         **{
             importer_constants.KEY_MAX_SPEED: '-42.0',
             importer_constants.KEY_FEED: 'http://test.com'
         })
     status, error_message = configuration.validate(config)
     self.assertTrue(status is False)
     self.assertEqual(
         error_message,
         'The configuration parameter <max_speed> must be set to a positive '
         'numerical value, but is currently set to <-42.0>.')
예제 #50
0
 def test_float_str(self):
     config = importer_mocks.get_basic_config(
         **{importer_constants.KEY_MAX_DOWNLOADS: "%s" % math.e, importer_constants.KEY_FEED: "http://test.com"}
     )
     status, error_message = configuration.validate(config)
     self.assertTrue(status is False)
     expected_message = (
         "The configuration parameter <%(num_threads)s> must be set to a positive "
         "integer, but is currently set to <%(e)s>."
     )
     expected_message = expected_message % {"num_threads": importer_constants.KEY_MAX_DOWNLOADS, "e": math.e}
     self.assertEqual(error_message, expected_message)
예제 #51
0
 def test_password_is_non_string(self):
     parameters = {
         importer_constants.KEY_PROXY_PASS: 7,
         importer_constants.KEY_PROXY_USER: "******",
         importer_constants.KEY_FEED: 'http://test.com'
     }
     config = importer_mocks.get_basic_config(**parameters)
     status, error_message = configuration.validate(config)
     self.assertTrue(status is False)
     self.assertEqual(
         error_message,
         "The configuration parameter <proxy_password> should be a string, "
         "but it was <type 'int'>.")
예제 #52
0
 def test_zero(self):
     parameters = {
         importer_constants.KEY_PROXY_PORT: 0,
         importer_constants.KEY_PROXY_HOST: 'http://test.com',
         importer_constants.KEY_FEED: 'http://test.com'
     }
     config = importer_mocks.get_basic_config(**parameters)
     status, error_message = configuration.validate(config)
     self.assertTrue(status is False)
     self.assertEqual(
         error_message,
         'The configuration parameter <proxy_port> must be set to a positive '
         'integer, but is currently set to <0>.')
예제 #53
0
    def test_perform_sync_remove_missing_units_set_false(self, mock_download):
        mock_download.side_effect = self.fake_download

        # Make sure the missing ISOs don't get removed if they aren't supposed to
        config = importer_mocks.get_basic_config(
            **{
                importer_constants.KEY_FEED: 'http://fake.com/iso_feed/',
                importer_constants.KEY_MAX_SPEED: 500.0,
                importer_constants.KEY_MAX_DOWNLOADS: 5,
                importer_constants.KEY_PROXY_HOST: 'proxy.com',
                importer_constants.KEY_PROXY_PORT: 1234,
                importer_constants.KEY_PROXY_USER: "******",
                importer_constants.KEY_PROXY_PASS: '******',
                importer_constants.KEY_UNITS_REMOVE_MISSING: False,
                importer_constants.KEY_SSL_CLIENT_CERT:
                "Trust me, I'm who I say I am.",
                importer_constants.KEY_SSL_CLIENT_KEY: "Secret Key",
                importer_constants.KEY_SSL_CA_CERT:
                "Uh, I guess that's the right server.",
                importer_constants.KEY_VALIDATE: False,
            })

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

        self.iso_sync_run.perform_sync()

        # There should now be three Units in the DB
        units = [
            tuple(call)[1][0]
            for call in self.sync_conduit.save_unit.mock_calls
        ]
        self.assertEqual(len(units), 1)
        expected_unit = {
            'checksum':
            '94f7fe923212286855dea858edac1b4a292301045af0ddb275544e5251a50b3c',
            'size': 34,
            'contents': 'Are you starting to get the idea?\n',
            'name': 'test3.iso'
        }
        unit = units[0]
        self.assertEqual(unit.unit_key['checksum'], expected_unit['checksum'])
        self.assertEqual(unit.unit_key['size'], expected_unit['size'])
        expected_storage_path = os.path.join(self.pkg_dir,
                                             unit.unit_key['name'],
                                             unit.unit_key['checksum'],
                                             str(unit.unit_key['size']),
                                             unit.unit_key['name'])
        self.assertEqual(unit.storage_path, expected_storage_path)
        # There should be 0 calls to sync_conduit.remove_unit, since remove_missing_units is
        # False by default
        self.assertEqual(self.sync_conduit.remove_unit.call_count, 0)
예제 #54
0
    def test_upload_unit_named_PULP_MANIFEST(self, remove):
        """
        We had a bug[0] due to the ISOImporter allowing units to be uploaded named PULP_MANIFEST.
        This test asserts that that is no longer allowed.

        [0] https://bugzilla.redhat.com/show_bug.cgi?id=973678
        """
        # Set up the test
        file_data = 'This is a PULP_MANIFEST file. The upload should be rejected.\n'
        working_dir = os.path.join(self.temp_dir, "working")
        os.mkdir(working_dir)
        pkg_dir = os.path.join(self.temp_dir, 'content')
        os.mkdir(pkg_dir)
        repo = mock.MagicMock(spec=Repository)
        repo.working_dir = working_dir
        # We'll set validation off so the checksum doesn't matter
        unit_key = {'name': 'PULP_MANIFEST', 'size': len(file_data), 'checksum': "Doesn't matter"}
        metadata = {}
        temp_file_location = os.path.join(self.temp_dir, unit_key['name'])
        with open(temp_file_location, 'w') as temp_file:
            temp_file.write(file_data)
        sync_conduit = importer_mocks.get_sync_conduit(pkg_dir=pkg_dir)
        # Just so we don't have to care about the checksum
        config = importer_mocks.get_basic_config(**{importer_constants.KEY_VALIDATE: 'false'})

        report = self.iso_importer.upload_unit(repo, ids.TYPE_ID_ISO, unit_key, metadata,
                                               temp_file_location, sync_conduit, config)

        self.assertEqual(report['success_flag'], False)
        self.assertEqual(report['summary'], 'An ISO may not be named PULP_MANIFEST, as it '
                                            'conflicts with the name of the manifest during '
                                            'publishing.')

        # init_unit() should have been called
        expected_rel_path = os.path.join(unit_key['name'], unit_key['checksum'],
                                         str(unit_key['size']), unit_key['name'])
        modified_metadata = metadata.copy()
        modified_metadata[server_constants.PULP_USER_METADATA_FIELDNAME] = {}
        sync_conduit.init_unit.assert_called_once_with(ids.TYPE_ID_ISO, unit_key, modified_metadata,
                                                       expected_rel_path)

        # The file should have been deleted
        self.assertFalse(os.path.exists(temp_file_location))
        would_be_destination = os.path.join(pkg_dir, expected_rel_path)
        self.assertFalse(os.path.exists(would_be_destination))
        # The file should have been removed from there
        remove.assert_called_once_with(would_be_destination)

        # The conduit's save_unit method should not have been called
        self.assertEqual(sync_conduit.save_unit.call_count, 0)
예제 #55
0
 def test_float_str(self):
     parameters = {
         importer_constants.KEY_PROXY_PORT: "%s" % math.e,
         importer_constants.KEY_PROXY_HOST: "http://proxy.com",
         importer_constants.KEY_FEED: "http://test.com",
     }
     config = importer_mocks.get_basic_config(**parameters)
     status, error_message = configuration.validate(config)
     self.assertTrue(status is False)
     self.assertEqual(
         error_message,
         "The configuration parameter <proxy_port> must be set to a positive "
         "integer, but is currently set to <%s>." % math.e,
     )
예제 #56
0
 def test_invalid_config(self):
     config = importer_mocks.get_basic_config(
         **{
             importer_constants.KEY_VALIDATE: 1,
             importer_constants.KEY_FEED: 'http://feed.com'
         })
     status, error_message = configuration.validate(config)
     self.assertTrue(status is False)
     expected_message = (
         'The configuration parameter <%(validate)s> may only be set to a '
         'boolean value, but is currently set to <1>.')
     expected_message = expected_message % {
         'validate': importer_constants.KEY_VALIDATE
     }
     self.assertEqual(error_message, expected_message)
예제 #57
0
 def test_zero(self):
     config = importer_mocks.get_basic_config(
         **{
             importer_constants.KEY_MAX_DOWNLOADS: 0,
             importer_constants.KEY_FEED: 'http://test.com'
         })
     status, error_message = configuration.validate(config)
     self.assertTrue(status is False)
     expected_message = (
         'The configuration parameter <%(num_threads)s> must be set to a positive '
         'integer, but is currently set to <0>.')
     expected_message = expected_message % {
         'num_threads': importer_constants.KEY_MAX_DOWNLOADS
     }
     self.assertEqual(error_message, expected_message)
예제 #58
0
 def test_url_is_non_string(self):
     config = importer_mocks.get_basic_config(
         **{
             importer_constants.KEY_PROXY_HOST: 7,
             importer_constants.KEY_FEED: 'http://test.com'
         })
     status, error_message = configuration.validate(config)
     self.assertTrue(status is False)
     expected_message = (
         "The configuration parameter <%(proxy_host)s> should be a string, but it was "
         "<type 'int'>.")
     expected_message = expected_message % {
         'proxy_host': importer_constants.KEY_PROXY_HOST
     }
     self.assertEqual(error_message, expected_message)
예제 #59
0
 def test_invalid_config(self):
     config = importer_mocks.get_basic_config(
         **{
             importer_constants.KEY_UNITS_REMOVE_MISSING: 'trizue',
             importer_constants.KEY_FEED: 'http://feed.com'
         })
     status, error_message = configuration.validate(config)
     self.assertTrue(status is False)
     expected_message = (
         'The configuration parameter <%(remove_missing)s> may only be set to a '
         'boolean value, but is currently set to <trizue>.')
     expected_message = expected_message % {
         'remove_missing': importer_constants.KEY_UNITS_REMOVE_MISSING
     }
     self.assertEqual(error_message, expected_message)