def test_dict_semantic_default_value(self): config = DownloaderConfig(basic_auth_username='******') self.assertEqual(config.get('basic_auth_username'), 'username') # Make sure passing a default password works. self.assertEqual(config.get('basic_auth_password', 'default'), 'default')
def test_ssl_data_config_value(self): ca_cert_value = 'test cert' config = DownloaderConfig(ssl_ca_cert=ca_cert_value) # temporary file created self.assertTrue(os.path.exists(config.ssl_ca_cert_path)) # same contents as data value self.assertEqual(ca_cert_value, open(config.ssl_ca_cert_path).read()) config.finalize() # temporary file removed self.assertFalse(os.path.exists(config.ssl_ca_cert_path))
def setUp(self): super(TestGetAncestry, self).setUp() self.working_dir = tempfile.mkdtemp() self.config = DownloaderConfig() self.repo = registry.V1Repository('pulp/crane', self.config, 'http://pulpproject.org/', self.working_dir)
def test_progress_interval(self): # check the default default_progress_interval = datetime.timedelta(seconds=local.DEFAULT_PROGRESS_INTERVAL) config = DownloaderConfig() downloader = local.LocalFileDownloader(config) self.assertFalse(hasattr(downloader, '_progress_interval')) self.assertEqual(downloader.progress_interval, default_progress_interval) self.assertTrue(hasattr(downloader, '_progress_interval')) # check configured value ten_second_interval = datetime.timedelta(seconds=10) config = DownloaderConfig(progress_interval=10) downloader = local.LocalFileDownloader(config) self.assertEqual(downloader.progress_interval, ten_second_interval)
def importer_config_to_nectar_config(importer_config): """ Translates the Pulp standard importer configuration into a DownloaderConfig instance. :param importer_config: use the PluginCallConfiguration.flatten method to retrieve a single dict view on the configuration :type importer_config: dict :rtype: nectar.config.DownloaderConfig """ # Mapping of importer config key to downloader config key translations = ( (constants.KEY_SSL_CA_CERT, 'ssl_ca_cert'), (constants.KEY_SSL_VALIDATION, 'ssl_validation'), (constants.KEY_SSL_CLIENT_CERT, 'ssl_client_cert'), (constants.KEY_SSL_CLIENT_KEY, 'ssl_client_key'), (constants.KEY_PROXY_HOST, 'proxy_url'), (constants.KEY_PROXY_PORT, 'proxy_port'), (constants.KEY_PROXY_USER, 'proxy_username'), (constants.KEY_PROXY_PASS, 'proxy_password'), (constants.KEY_MAX_DOWNLOADS, 'max_concurrent'), (constants.KEY_MAX_SPEED, 'max_speed'), ) download_config_kwargs = {} adder = partial(_safe_add_arg, importer_config, download_config_kwargs) map(adder, translations) download_config = DownloaderConfig(**download_config_kwargs) return download_config
def test_download_cancelled_in_failed(self, mock_started, mock_cancel): request_list = [] for n in range(0, 5): unit_key = { 'name': 'unit_%d' % n, 'version': '1.0.%d' % n, 'release': '1', 'checksum': str(uuid4()) } request = Request(TYPE_ID, unit_key, 'http://unit-city/unit_%d' % n, os.path.join(self.downloaded, 'unit_%d' % n)) request_list.append(request) downloader = HTTPThreadedDownloader(DownloaderConfig()) container = ContentContainer(path=self.tmp_dir) container.refresh = Mock() event = CancelEvent(2) report = container.download(event, downloader, request_list) self.assertTrue(mock_started.called) self.assertTrue(mock_cancel.called) self.assertEqual(report.total_passes, 1) self.assertEqual(report.total_sources, 2) self.assertEqual(len(report.downloads), 1) self.assertEqual(report.downloads[PRIMARY_ID].total_succeeded, 0) self.assertEqual(report.downloads[PRIMARY_ID].total_failed, 5)
def __init__(self, sync_conduit, config): """ Initialize an ISOSyncRun. :param sync_conduit: the sync conduit to use for this sync run. :type sync_conduit: pulp.plugins.conduits.repo_sync.RepoSyncConduit :param config: plugin configuration :type config: pulp.plugins.config.PluginCallConfiguration """ self.sync_conduit = sync_conduit self._remove_missing_units = config.get( importer_constants.KEY_UNITS_REMOVE_MISSING, default=constants.CONFIG_UNITS_REMOVE_MISSING_DEFAULT) self._validate_downloads = config.get( importer_constants.KEY_VALIDATE, default=constants.CONFIG_VALIDATE_DEFAULT) self._repo_url = encode_unicode(config.get( importer_constants.KEY_FEED)) # The _repo_url must end in a trailing slash, because we will use urljoin to determine # the path to # PULP_MANIFEST later if self._repo_url[-1] != '/': self._repo_url = self._repo_url + '/' # Cast our config parameters to the correct types and use them to build a Downloader max_speed = config.get(importer_constants.KEY_MAX_SPEED) if max_speed is not None: max_speed = float(max_speed) max_downloads = config.get(importer_constants.KEY_MAX_DOWNLOADS) if max_downloads is not None: max_downloads = int(max_downloads) else: max_downloads = constants.CONFIG_MAX_DOWNLOADS_DEFAULT ssl_validation = config.get_boolean( importer_constants.KEY_SSL_VALIDATION) ssl_validation = ssl_validation if ssl_validation is not None else \ constants.CONFIG_VALIDATE_DEFAULT downloader_config = { 'max_speed': max_speed, 'max_concurrent': max_downloads, 'ssl_client_cert': config.get(importer_constants.KEY_SSL_CLIENT_CERT), 'ssl_client_key': config.get(importer_constants.KEY_SSL_CLIENT_KEY), 'ssl_ca_cert': config.get(importer_constants.KEY_SSL_CA_CERT), 'ssl_validation': ssl_validation, 'proxy_url': config.get(importer_constants.KEY_PROXY_HOST), 'proxy_port': config.get(importer_constants.KEY_PROXY_PORT), 'proxy_username': config.get(importer_constants.KEY_PROXY_USER), 'proxy_password': config.get(importer_constants.KEY_PROXY_PASS) } downloader_config = DownloaderConfig(**downloader_config) # We will pass self as the event_listener, so that we can receive the callbacks in this # class if self._repo_url.lower().startswith('file'): self.downloader = LocalFileDownloader(downloader_config, self) else: self.downloader = HTTPThreadedDownloader(downloader_config, self) self.progress_report = SyncProgressReport(sync_conduit)
def test__get_path_success(self): """ Test _get_path() for the case when the download is successful. """ def download_one(request): """ Mock the download_one() method. """ self.assertEqual(request.url, 'https://registry.example.com/some/path') self.assertEqual(type(request.destination), type(StringIO())) report = DownloadReport(request.url, request.destination) report.download_succeeded() report.headers = {'some': 'cool stuff'} report.destination.write("This is the stuff you've been waiting for.") return report name = 'pulp' download_config = DownloaderConfig(max_concurrent=25) registry_url = 'https://registry.example.com' working_dir = '/a/working/dir' r = registry.V2Repository(name, download_config, registry_url, working_dir) r.downloader.download_one = mock.MagicMock(side_effect=download_one) headers, body = r._get_path('/some/path') self.assertEqual(headers, {'some': 'cool stuff'}) self.assertEqual(body, "This is the stuff you've been waiting for.")
def test_round_trip(self): # Setup units = [] manifest_path = os.path.join(self.tmp_dir, MANIFEST_FILE_NAME) for i in range(0, self.NUM_UNITS): unit = dict(unit_id=i, type_id='T', unit_key={}) units.append(unit) # Test units_path = os.path.join(self.tmp_dir, UNITS_FILE_NAME) writer = UnitWriter(units_path) for u in units: writer.add(u) writer.close() manifest = Manifest(self.MANIFEST_ID) manifest.set_units(writer) manifest.write(manifest_path) # Test cfg = DownloaderConfig() downloader = HTTPSCurlDownloader(cfg) working_dir = os.path.join(self.tmp_dir, 'working_dir') os.makedirs(working_dir) path = os.path.join(self.tmp_dir, MANIFEST_FILE_NAME) url = 'file://%s' % path manifest = Manifest() manifest.fetch(url, working_dir, downloader) manifest.fetch_units(url, downloader) # Verify units_in = [] for unit, ref in manifest.get_units(): units_in.append(unit) _unit = ref.fetch() self.assertEqual(unit, _unit) self.verify(units, units_in)
def setUp(self): self.metadata_files = metadata.MetadataFiles('http://pulpproject.org', '/a/b/c', DownloaderConfig()) self.repo = Repository('repo1') self.config = PluginCallConfiguration({}, {}) self.conduit = RepoSyncConduit(self.repo.id, 'yum_importer', 'abc123')
def test_api_version_check_incorrect_header(self): """ The the api_version_check() method when the response has the Docker-Distribution-API-Version header, but it is not the correct value for a Docker v2 registry. """ def download_one(request): """ Mock the download_one() method to manipulate the path. """ self.assertEqual(request.url, 'https://registry.example.com/v2/') self.assertEqual(type(request.destination), type(StringIO())) report = DownloadReport(request.url, request.destination) report.download_succeeded() report.headers = {'Docker-Distribution-API-Version': 'WRONG_VALUE!'} report.destination.write("") return report name = 'pulp' download_config = DownloaderConfig(max_concurrent=25) registry_url = 'https://registry.example.com' working_dir = '/a/working/dir' r = registry.V2Repository(name, download_config, registry_url, working_dir) r.downloader.download_one = mock.MagicMock(side_effect=download_one) self.assertFalse(r.api_version_check())
def setUp(self): self.qstring = '?foo' self.url_modify = RepoURLModifier(query_auth_token=self.qstring[1:]) self.metadata_files = metadata.MetadataFiles('http://pulpproject.org', '/a/b/c', DownloaderConfig(), self.url_modify)
def test_api_version_check_successful(self): """ The the api_version_check() method when the registry_url is indeed a Docker v2 registry. """ def download_one(request): """ Mock the download_one() method to manipulate the path. """ self.assertEqual(request.url, 'https://registry.example.com/v2/') self.assertEqual(type(request.destination), type(StringIO())) report = DownloadReport(request.url, request.destination) report.download_succeeded() report.headers = {'Docker-Distribution-API-Version': 'registry/2.0'} report.destination.write("") return report name = 'pulp' download_config = DownloaderConfig(max_concurrent=25) registry_url = 'https://registry.example.com' working_dir = '/a/working/dir' r = registry.V2Repository(name, download_config, registry_url, working_dir) r.downloader.download_one = mock.MagicMock(side_effect=download_one) # This should not raise an Exception r.api_version_check()
def test_api_version_check_missing_header(self): """ The the api_version_check() method when the response is missing the Docker-Distribution-API-Version header. Since we want to support servers that are just serving simple directories of files, it should be OK if the header is not present. """ def download_one(request): """ Mock the download_one() method to manipulate the path. """ self.assertEqual(request.url, 'https://registry.example.com/v2/') self.assertEqual(type(request.destination), type(StringIO())) report = DownloadReport(request.url, request.destination) report.download_succeeded() # The Version header is not present report.headers = {} report.destination.write("") return report name = 'pulp' download_config = DownloaderConfig(max_concurrent=25) registry_url = 'https://registry.example.com' working_dir = '/a/working/dir' r = registry.V2Repository(name, download_config, registry_url, working_dir) r.downloader.download_one = mock.MagicMock(side_effect=download_one) # This should not raise an Exception r.api_version_check()
def test_get_manifest(self): """ Assert correct behavior from get_manifest(). """ def download_one(request): """ Mock the download_one() method to manipulate the path. """ self.assertEqual(request.url, 'https://registry.example.com/v2/pulp/manifests/best_version_ever') self.assertEqual(type(request.destination), type(StringIO())) report = DownloadReport(request.url, request.destination) report.download_succeeded() schema2 = 'application/vnd.docker.distribution.manifest.v2+json' report.headers = {'Docker-Distribution-API-Version': 'registry/2.0', 'docker-content-digest': digest, 'content-type': schema2} report.destination.write(manifest) return report name = 'pulp' download_config = DownloaderConfig(max_concurrent=25) registry_url = 'https://registry.example.com' working_dir = '/a/working/dir' r = registry.V2Repository(name, download_config, registry_url, working_dir) r.downloader.download_one = mock.MagicMock(side_effect=download_one) digest = 'sha256:46356a7d9575b4cee21e7867b1b83a51788610b7719a616096d943b44737ad9a' with open(os.path.join(TEST_DATA_PATH, 'manifest_repeated_layers.json')) as manifest_file: manifest = manifest_file.read() schema2 = 'application/vnd.docker.distribution.manifest.v2+json' m = r.get_manifest('best_version_ever', None, None) self.assertEqual([(manifest, digest, schema2)], m)
def test_get_tags(self): """ Assert correct behavior from get_tags(). """ def download_one(request): """ Mock the download_one() method to manipulate the path. """ self.assertEqual(request.url, 'https://registry.example.com/v2/pulp/tags/list') self.assertEqual(type(request.destination), type(StringIO())) report = DownloadReport(request.url, request.destination) report.download_succeeded() report.headers = {} report.destination.write('{"name": "pulp", "tags": ["best_ever", "latest", "decent"]}') return report name = 'pulp' download_config = DownloaderConfig(max_concurrent=25) registry_url = 'https://registry.example.com' working_dir = '/a/working/dir' r = registry.V2Repository(name, download_config, registry_url, working_dir) r.downloader.download_one = mock.MagicMock(side_effect=download_one) tags = r.get_tags() self.assertEqual(tags, ["best_ever", "latest", "decent"])
def test_default_configuration_values(self): config = DownloaderConfig() self.assertEqual(config.max_concurrent, None) self.assertEqual(config.basic_auth_username, None) self.assertEqual(config.basic_auth_password, None) self.assertEqual(config.ssl_ca_cert, None) self.assertEqual(config.ssl_ca_cert_path, None) self.assertEqual(config.ssl_client_cert, None) self.assertEqual(config.ssl_client_cert_path, None) self.assertEqual(config.ssl_client_key, None) self.assertEqual(config.ssl_client_key_path, None) self.assertEqual(config.ssl_validation, True) self.assertEqual(config.proxy_url, None) self.assertEqual(config.proxy_port, None) self.assertEqual(config.proxy_username, None) self.assertEqual(config.proxy_password, None) self.assertEqual(config.max_speed, None) self.assertEqual(config.headers, None) self.assertEqual(config.buffer_size, None) self.assertEqual(config.progress_interval, None) self.assertEqual(config.use_hard_links, False) self.assertEqual(config.use_sym_links, False) self.assertEqual(config.connect_timeout, 6.05) self.assertEqual(config.read_timeout, 27)
def importer_config_to_nectar_config(importer_config, working_dir=None, download_config_kwargs=None): """ DEPRECATED. Use importer_to_nectar_config instead. Translates the Pulp standard importer configuration into a DownloaderConfig instance. :param importer_config: use the PluginCallConfiguration.flatten method to retrieve a single dict view on the configuration :type importer_config: dict :param working_dir: Allow the caller to override the working directory used :type working_dir: str :param download_config_kwargs: Any additional keyword arguments you would like to include in the download config. :type download_config_kwargs: dict :rtype: nectar.config.DownloaderConfig """ if download_config_kwargs is None: download_config_kwargs = {} if working_dir is None: working_dir = common_utils.get_working_directory() download_config_kwargs['working_dir'] = working_dir adder = partial(_safe_add_arg, importer_config, download_config_kwargs) map(adder, IMPORTER_DOWNLOADER_CONFIG_MAP) download_config = DownloaderConfig(**download_config_kwargs) return download_config
def __init__(self, step_type, step_description, lazy_status_conduit, download_requests): """ Initializes a Step that downloads all the download requests provided. :param lazy_status_conduit: Conduit used to update the task status. :type lazy_status_conduit: LazyStatusConduit :param download_requests: List of download requests to process. :type download_requests: list of nectar.request.DownloadRequest """ super(LazyUnitDownloadStep, self).__init__( step_type=step_type, status_conduit=lazy_status_conduit, ) self.description = step_description self.download_requests = download_requests self.download_config = { MAX_CONCURRENT: int(pulp_conf.get('lazy', 'download_concurrency')), HEADERS: { PULP_STREAM_REQUEST_HEADER: 'true' }, SSL_VALIDATION: True } self.downloader = HTTPThreadedDownloader( DownloaderConfig(**self.download_config), self)
def test_publish(self, mock_repo_ctrl): # Setup self.populate() with mock_config.patch({'server': {'storage_dir': self.parentfs}}): # Test dist = NodesHttpDistributor() repo = Repository(self.REPO_ID) conduit = RepoPublishConduit(self.REPO_ID, constants.HTTP_DISTRIBUTOR) dist.publish_repo(repo, conduit, self.dist_conf()) # Verify conf = DownloaderConfig() downloader = LocalFileDownloader(conf) pub = dist.publisher(repo, self.dist_conf()) url = pathlib.url_join(pub.base_url, pub.manifest_path()) working_dir = self.childfs manifest = RemoteManifest(url, downloader, working_dir) manifest.fetch() manifest.fetch_units() units = [u for u, r in manifest.get_units()] self.assertEqual(len(units), self.NUM_UNITS) for n in range(0, self.NUM_UNITS): unit = units[n] created = self.units[n] for p, v in unit['unit_key'].items(): self.assertEqual(created[p], v) for p, v in unit['metadata'].items(): if p in ('_ns', '_content_type_id'): continue self.assertEqual(created[p], v) self.assertEqual(created.get('_storage_path'), unit['storage_path']) self.assertEqual(unit['type_id'], self.UNIT_TYPE_ID)
def test_download_to_stream(self): request_list = [] _dir, cataloged = self.populate_catalog(ORPHANED, 0, 10) _dir, cataloged = self.populate_catalog(UNIT_WORLD, 0, 10) _dir = self.populate_content(PRIMARY, 0, 20) # unit-world for n in range(0, 10): request = Request( cataloged[n].type_id, cataloged[n].unit_key, 'file://%s/unit_%d' % (_dir, n), StringIO()) request_list.append(request) # primary for n in range(11, 20): unit_key = { 'name': 'unit_%d' % n, 'version': '1.0.%d' % n, 'release': '1', 'checksum': str(uuid4()) } request = Request( TYPE_ID, unit_key, 'file://%s/unit_%d' % (_dir, n), StringIO()) request_list.append(request) downloader = LocalFileDownloader(DownloaderConfig()) listener = Mock() container = ContentContainer(path=self.tmp_dir) container.threaded = False container.refresh = Mock() # test report = container.download(downloader, request_list, listener) # validation # unit-world for i in range(0, 10): request = request_list[i] self.assertTrue(request.downloaded) self.assertEqual(len(request.errors), 0) fp = request.destination s = fp.getvalue() self.assertTrue(UNIT_WORLD in s) # primary for i in range(11, len(request_list)): request = request_list[i] self.assertTrue(request.downloaded) self.assertEqual(len(request.errors), 0) fp = request.destination s = fp.getvalue() self.assertTrue(PRIMARY in s) self.assertEqual(report.total_sources, 2) self.assertEqual(len(report.downloads), 2) self.assertEqual(report.downloads[PRIMARY_ID].total_succeeded, 9) self.assertEqual(report.downloads[PRIMARY_ID].total_failed, 0) self.assertEqual(report.downloads[UNIT_WORLD].total_succeeded, 10) self.assertEqual(report.downloads[UNIT_WORLD].total_failed, 0)
def test_download_with_errors(self): request_list = [] _dir, cataloged = self.populate_catalog(ORPHANED, 0, 10) _dir, cataloged = self.populate_catalog(UNDERGROUND, 0, 10) _dir, cataloged = self.populate_catalog(UNIT_WORLD, 0, 10) shutil.rmtree(_dir) _dir = self.populate_content(PRIMARY, 0, 20) # unit-world for n in range(0, 10): request = Request(cataloged[n].type_id, cataloged[n].unit_key, 'file://%s/unit_%d' % (_dir, n), os.path.join(self.downloaded, 'unit_%d' % n)) request_list.append(request) # primary for n in range(11, 20): unit_key = { 'name': 'unit_%d' % n, 'version': '1.0.%d' % n, 'release': '1', 'checksum': str(uuid4()) } request = Request(TYPE_ID, unit_key, 'file://%s/unit_%d' % (_dir, n), os.path.join(self.downloaded, 'unit_%d' % n)) request_list.append(request) downloader = LocalFileDownloader(DownloaderConfig()) listener = Mock() container = ContentContainer(path=self.tmp_dir) container.refresh = Mock() event = Event() # test report = container.download(event, downloader, request_list, listener) # validation # unit-world for i in range(0, 10): request = request_list[i] self.assertTrue(request.downloaded, msg='URL: %s' % request.url) self.assertEqual(len(request.errors), 1) with open(request.destination) as fp: s = fp.read() self.assertTrue(UNDERGROUND in s) # primary for i in range(11, len(request_list)): request = request_list[i] self.assertTrue(request.downloaded, msg='URL: %s' % request.url) self.assertEqual(len(request.errors), 0) with open(request.destination) as fp: s = fp.read() self.assertTrue(PRIMARY in s) self.assertEqual(report.total_sources, 2) self.assertEqual(len(report.downloads), 3) self.assertEqual(report.downloads[PRIMARY_ID].total_succeeded, 9) self.assertEqual(report.downloads[PRIMARY_ID].total_failed, 0) self.assertEqual(report.downloads[UNDERGROUND].total_succeeded, 10) self.assertEqual(report.downloads[UNDERGROUND].total_failed, 0) self.assertEqual(report.downloads[UNIT_WORLD].total_succeeded, 0) self.assertEqual(report.downloads[UNIT_WORLD].total_failed, 10)
def test_symbolic_link(self): config = DownloaderConfig() downloader = local.LocalFileDownloader(config) request_list = self._make_requests(DATA_FILES[:1]) downloader._symbolic_link(request_list[0]) self.assertTrue(os.path.islink(request_list[0].destination))
def test_instantiation(self): config = DownloaderConfig() try: local.LocalFileDownloader(config) except Exception, e: self.fail(str(e))
def test_init(self): config = DownloaderConfig() repo = registry.V1Repository('pulp/crane', config, 'http://pulpproject.org/', '/a/b/c') self.assertEqual(repo.name, 'pulp/crane') self.assertEqual(repo.registry_url, 'http://pulpproject.org/') self.assertEqual(repo.working_dir, '/a/b/c') self.assertTrue(isinstance(repo.downloader, HTTPThreadedDownloader))
def test_does_fires_events(self): # collect the success event in this listener if one is fired listener = AggregatingEventListener() downloader = LyingDownloader(DownloaderConfig(), listener) downloader.download_one(self.request, events=True) self.assertEqual(len(listener.succeeded_reports), 1)
def test_common_link_canceled(self, mock_canceled): downloader = local.LocalFileDownloader(DownloaderConfig()) downloader.cancel() request = DownloadRequest('file://' + __file__, '/bar') downloader._common_link(mock.MagicMock(), request) # make sure the cancel method was called on the report mock_canceled.assert_called_once_with()
def test_copy(self): config = DownloaderConfig() listener = AggregatingEventListener() downloader = local.LocalFileDownloader(config, listener) request_list = self._make_requests(DATA_FILES) downloader.download(request_list) self.assertEqual(len(listener.succeeded_reports), len(request_list)) self.assertEqual(len(listener.failed_reports), 0)
def test_download_method(self): # check the default config = DownloaderConfig() downloader = local.LocalFileDownloader(config) self.assertEqual(downloader.download_method, downloader._copy) # check configured hard links config = DownloaderConfig(use_hard_links=True) downloader = local.LocalFileDownloader(config) self.assertEqual(downloader.download_method, downloader._hard_link) # check configured symbolic links config = DownloaderConfig(use_sym_links=True) downloader = local.LocalFileDownloader(config) self.assertEqual(downloader.download_method, downloader._symbolic_link)
def test_download_cancelled_during_refreshing(self): downloader = LocalFileDownloader(DownloaderConfig()) container = ContentContainer(path=self.tmp_dir) container.collated = Mock() event = CancelEvent(1) report = container.download(event, downloader, []) self.assertFalse(container.collated.called) self.assertEqual(report.total_passes, 0) self.assertEqual(report.total_sources, 2) self.assertEqual(len(report.downloads), 0)
def test_dict_semantic_default_value(self): config = DownloaderConfig(key_1='value_1') self.assertEqual(config.get('key_1'), 'value_1') self.assertEqual(config.get('key_2', 'value_2'), 'value_2')