def extract_metadata(filename, temp_dir, module=None): """ Pulls the module's metadata file out of the module's tarball and updates the module instance with its contents. The module instance itself is updated as part of this call. It is up to the caller to delete the temp_dir after this executes. :param filename: full path to the module file :type filename: str :param temp_dir: location the module's files should be extracted to; must exist prior to this call :type temp_dir: str :param module: module instance with name, author, version to help find the directory which contains metadata.json (optional) :type module: Module :raise InvalidTarball: if the module file cannot be opened :raise MissingModuleFile: if the module's metadata file cannot be found """ if module is None: metadata = _extract_non_standard_json(filename, temp_dir) return json.loads(metadata) # Attempt to load from the standard metadata file location. If it's not # found, try the brute force approach. If it's still not found, that call # will raise the appropriate MissingModuleFile exception. try: metadata = _extract_json(module, filename, temp_dir) return json.loads(metadata) except MissingModuleFile: metadata = _extract_non_standard_json(filename, temp_dir) return json.loads(metadata)
def test_run_no_group(self): # Setup data = {OPTION_GROUP_ID.keyword: "test-group"} self.server_mock.request.return_value = 200, [] # Test self.command.run(**data) # Verify self.assertEqual(1, self.server_mock.request.call_count) # Group lookup call call_args = self.server_mock.request.call_args_list[0] self.assertEqual("POST", call_args[0][0]) url = call_args[0][1] self.assertTrue(url.endswith("/repo_groups/search/")) body = json.loads(call_args[0][2]) self.assertEqual(body["criteria"]["filters"]["id"], "test-group") # Output self.assertEqual(2, len(self.prompt.get_write_tags())) self.assertEqual(TAG_TITLE, self.prompt.get_write_tags()[0]) self.assertEqual("not-found", self.prompt.get_write_tags()[1])
def test_run(self): # Setup data = { OPTION_GROUP_ID.keyword: "test-group", OPTION_NAME.keyword: "Group", OPTION_DESCRIPTION.keyword: "Description", OPTION_NOTES.keyword: {"a": "a", "b": "b"}, } self.server_mock.request.return_value = 201, {} # Test self.command.run(**data) # Verify self.assertEqual(1, self.server_mock.request.call_count) self.assertEqual("POST", self.server_mock.request.call_args[0][0]) body = self.server_mock.request.call_args[0][2] body = json.loads(body) self.assertEqual(body["id"], "test-group") self.assertEqual(body["display_name"], "Group") self.assertEqual(body["description"], "Description") self.assertEqual(body["notes"], {"a": "a", "b": "b"}) self.assertEqual(1, len(self.prompt.get_write_tags())) self.assertEqual(TAG_SUCCESS, self.prompt.get_write_tags()[0])
def test_run(self): # Setup data = { 'from-repo-id': 'from', 'to-repo-id': 'to' } self.server_mock.request.return_value = 202, self.task() mock_poll = mock.MagicMock().poll self.command.poll = mock_poll # Test self.command.run(**data) # Verify call_args = self.server_mock.request.call_args[0] self.assertEqual('POST', call_args[0]) self.assertTrue(call_args[1].endswith('/to/actions/associate/')) body = json.loads(call_args[2]) self.assertEqual(body['source_repo_id'], 'from') self.assertEqual(body['criteria']['type_ids'], [constants.TYPE_PUPPET_MODULE]) self.assertEqual(1, mock_poll.call_count)
def test_run_through_cli(self): """ This test isn't complete, but is at minimum being included to verify 903262 (--only-newest being parsed correctly). Ideally this should be flushed out to test all of the options. The test above kicks in after okaara has parsed the user input, simulating what okaara would pass to the command itself. That's fine, but doesn't pick up on issues in the parsing itself. This test will simulate the string entered by the user from the command line and force okaara to do the parsing and hand those results to the command. """ # Setup self.server_mock.request.return_value = 201, {} # Test command = repo.RpmRepoCreateCommand(self.context) self.cli.add_command(command) self.cli.run("create --repo-id r --only-newest true".split()) # Verify self.assertEqual(1, self.server_mock.request.call_count) body = self.server_mock.request.call_args[0][2] body = json.loads(body) self.assertEqual(body['id'], 'r') self.assertEqual(body['importer_config']['newest'], True) # not the string "true"
def test_migrate(self, start_logging_mock, listdir_mock, mock_plugin_definitions, mock_drop_indices): """ Ensure that migrate() imports types on a clean types database. """ migration.migrate() self.assertTrue(mock_drop_indices.called) all_collection_names = types_db.all_type_collection_names() self.assertEqual(len(all_collection_names), 1) self.assertEqual(['units_test_type_id'], all_collection_names) # Let's make sure we loaded the type definitions correctly db_type_definitions = types_db.all_type_definitions() self.assertEquals(len(db_type_definitions), 1) test_json = json.loads(_test_type_json) for attribute in ['id', 'display_name', 'description', 'unit_key', 'search_indexes']: self.assertEquals(test_json['types'][0][attribute], db_type_definitions[0][attribute]) # Now let's ensure that we have the correct indexes collection = types_db.type_units_collection('test_type_id') indexes = collection.index_information() self.assertEqual(indexes['_id_']['key'], [(u'_id', 1)]) # Make sure we have the unique constraint on all three attributes self.assertEqual(indexes['attribute_1_1_attribute_2_1_attribute_3_1']['unique'], True) self.assertEqual(indexes['attribute_1_1_attribute_2_1_attribute_3_1']['key'], [(u'attribute_1', 1), (u'attribute_2', 1), (u'attribute_3', 1)]) # Make sure we indexed attributes 1 and 3 self.assertEqual(indexes['attribute_1_1']['key'], [(u'attribute_1', 1)]) self.assertEqual(indexes['attribute_3_1']['key'], [(u'attribute_3', 1)]) # Make sure we only have the indexes that we've hand inspected here self.assertEqual(indexes.keys(), [u'_id_', u'attribute_1_1_attribute_2_1_attribute_3_1', u'attribute_1_1', u'attribute_3_1'])
def test_to_json(self): # Setup metadata = RepositoryMetadata() metadata.update_from_json(VALID_REPO_METADATA_JSON) # Test serialized = metadata.to_json() # Verify parsed = json.loads(serialized) self.assertEqual(2, len(parsed)) sorted_modules = sorted(parsed, key=lambda x : x['name']) self.assertEqual(4, len(sorted_modules[0])) self.assertEqual(sorted_modules[0]['name'], 'common') self.assertEqual(sorted_modules[0]['author'], 'lab42') self.assertEqual(sorted_modules[0]['version'], '0.0.1') self.assertEqual(sorted_modules[0]['tag_list'], []) self.assertEqual(4, len(sorted_modules[1])) self.assertEqual(sorted_modules[1]['name'], 'postfix') self.assertEqual(sorted_modules[1]['author'], 'lab42') self.assertEqual(sorted_modules[1]['version'], '0.0.2') self.assertEqual(sorted_modules[1]['tag_list'], ['postfix', 'applications'])
def test_to_json(self): # Setup metadata = RepositoryMetadata() metadata.update_from_json(VALID_REPO_METADATA_JSON) # Test serialized = metadata.to_json() # Verify parsed = json.loads(serialized) self.assertEqual(2, len(parsed)) sorted_modules = sorted(parsed, key=lambda x: x["name"]) self.assertEqual(4, len(sorted_modules[0])) self.assertEqual(sorted_modules[0]["name"], "common") self.assertEqual(sorted_modules[0]["author"], "lab42") self.assertEqual(sorted_modules[0]["version"], "0.0.1") self.assertEqual(sorted_modules[0]["tag_list"], []) self.assertEqual(4, len(sorted_modules[1])) self.assertEqual(sorted_modules[1]["name"], "postfix") self.assertEqual(sorted_modules[1]["author"], "lab42") self.assertEqual(sorted_modules[1]["version"], "0.0.2") self.assertEqual(sorted_modules[1]["tag_list"], ["postfix", "applications"])
def _interpret_operation_report(output, operation, full_name): """ Makes a best effort to locate and deserialize the JSON output from the "puppet module" tool. The tool does not document exactly how this will be included in the output, so this method returns an empty dictionary if a JSON-serialized report is not found. It also logs a warning in that case. :param output: text output from the "puppet module" tool, which presumably includes some JSON :type output: str :param operation: one of "install", "upgrade", "uninstall", used only for logging. :type operation: str :param full_name: full name in form "author/title", used only for logging :return: deserialized JSON output from the "puppet module" tool :rtype: dict """ try: potential_json = output.split('\n')[-2] operation_report = json.loads(potential_json) # if there was any error trying to parse puppet's JSON output, make # an empty report except (IndexError, ValueError): logger.warning('failed to parse JSON output from %s of %s' % (operation, full_name)) operation_report = {} return operation_report
def test_run(self): # Setup repo_id = 'test-repo' data = { OPTION_REPO_ID.keyword : repo_id, OPTION_NAME.keyword : 'Test Repository', OPTION_DESCRIPTION.keyword : 'Repository Description', OPTION_NOTES.keyword : {'a' : 'a', 'b' : 'b'}, } self.server_mock.request.return_value = 200, {} # Test self.command.run(**data) # Verify self.assertEqual(1, self.server_mock.request.call_count) self.assertEqual('PUT', self.server_mock.request.call_args[0][0]) url = self.server_mock.request.call_args[0][1] self.assertTrue(url.endswith('/repositories/%s/' % repo_id)) body = self.server_mock.request.call_args[0][2] body = json.loads(body) self.assertEqual(body['delta']['display_name'], 'Test Repository') self.assertEqual(body['delta']['description'], 'Repository Description') self.assertEqual(body['delta']['notes'], {'a' : 'a', 'b' : 'b'}) self.assertEqual(1, len(self.prompt.get_write_tags())) self.assertEqual(TAG_SUCCESS, self.prompt.get_write_tags()[0])
def test_pulp_manage_db_loads_types(self, listdir_mock): """ Test calling pulp-manage-db imports types on a clean types database. """ manage.main() all_collection_names = types_db.all_type_collection_names() self.assertEqual(len(all_collection_names), 1) self.assertEqual(['units_test_type_id'], all_collection_names) # Let's make sure we loaded the type definitions correctly db_type_definitions = types_db.all_type_definitions() self.assertEquals(len(db_type_definitions), 1) test_json = json.loads(_test_type_json) for attribute in ['id', 'display_name', 'description', 'unit_key', 'search_indexes']: self.assertEquals(test_json['types'][0][attribute], db_type_definitions[0][attribute]) # Now let's ensure that we have the correct indexes collection = types_db.type_units_collection('test_type_id') indexes = collection.index_information() self.assertEqual(indexes['_id_']['key'], [(u'_id', 1)]) # Make sure we have the unique constraint on all three attributes self.assertEqual(indexes['attribute_1_1_attribute_2_1_attribute_3_1']['unique'], True) self.assertEqual(indexes['attribute_1_1_attribute_2_1_attribute_3_1']['dropDups'], False) self.assertEqual(indexes['attribute_1_1_attribute_2_1_attribute_3_1']['key'], [(u'attribute_1', 1), (u'attribute_2', 1), (u'attribute_3', 1)]) # Make sure we indexes attributes 1 and 3 self.assertEqual(indexes['attribute_1_1']['dropDups'], False) self.assertEqual(indexes['attribute_1_1']['key'], [(u'attribute_1', 1)]) self.assertEqual(indexes['attribute_3_1']['dropDups'], False) self.assertEqual(indexes['attribute_3_1']['key'], [(u'attribute_3', 1)]) # Make sure we only have the indexes that we've hand inspected here self.assertEqual(indexes.keys(), [u'_id_', u'attribute_1_1_attribute_2_1_attribute_3_1', u'attribute_1_1', u'attribute_3_1'])
def test_run_no_group(self): # Setup data = { OPTION_GROUP_ID.keyword : 'test-group', } self.server_mock.request.return_value = 200, [] # Test self.command.run(**data) # Verify self.assertEqual(1, self.server_mock.request.call_count) # Group lookup call call_args = self.server_mock.request.call_args_list[0] self.assertEqual('POST', call_args[0][0]) url = call_args[0][1] self.assertTrue(url.endswith('/repo_groups/search/')) body = json.loads(call_args[0][2]) self.assertEqual(body['criteria']['filters']['id'], 'test-group') # Output self.assertEqual(2, len(self.prompt.get_write_tags())) self.assertEqual(TAG_TITLE, self.prompt.get_write_tags()[0]) self.assertEqual('not-found', self.prompt.get_write_tags()[1])
def test_run(self): # Setup data = { OPTION_REPO_ID.keyword : 'test-repo', OPTION_NAME.keyword : 'Test Repository', OPTION_DESCRIPTION.keyword : 'Repository Description', OPTION_NOTES.keyword : ['a=a', 'b=b'], } self.server_mock.request.return_value = 201, {} # Test self.command.run(**data) # Verify self.assertEqual(1, self.server_mock.request.call_count) self.assertEqual('POST', self.server_mock.request.call_args[0][0]) body = self.server_mock.request.call_args[0][2] body = json.loads(body) self.assertEqual(body['id'], 'test-repo') self.assertEqual(body['display_name'], 'Test Repository') self.assertEqual(body['description'], 'Repository Description') self.assertEqual(body['notes'], {'a' : 'a', 'b' : 'b'}) self.assertEqual(1, len(self.prompt.get_write_tags())) self.assertEqual(TAG_SUCCESS, self.prompt.get_write_tags()[0])
def test_run(self): # Setup data = { OPTION_GROUP_ID.keyword : 'test-group', OPTION_NAME.keyword : 'Group', OPTION_DESCRIPTION.keyword : 'Description', OPTION_NOTES.keyword : {'a' : 'a', 'b' : 'b'}, } self.server_mock.request.return_value = 200, {} # Test self.command.run(**data) # Verify self.assertEqual(1, self.server_mock.request.call_count) self.assertEqual('PUT', self.server_mock.request.call_args[0][0]) url = self.server_mock.request.call_args[0][1] self.assertTrue(url.endswith('/repo_groups/test-group/')) body = self.server_mock.request.call_args[0][2] delta = json.loads(body) self.assertTrue('display-name' not in delta) self.assertEqual(delta['display_name'], 'Group') self.assertEqual(delta['description'], 'Description') self.assertEqual(delta['notes'], {'a' : 'a', 'b' : 'b'})
def _do_request(self, request_type, uri, params, additional_headers, serialize_json=True): """ Override the base class controller to allow for less deterministic responses due to integration with the dispatch package. """ # Use the default headers established at setup and override/add any headers = dict(PulpWebserviceTests.HEADERS) if additional_headers is not None: headers.update(additional_headers) # Serialize the parameters if any are specified if params is None: params = {} if serialize_json: params = json.dumps(params) # Invoke the API f = getattr(PulpWebserviceTests.TEST_APP, request_type) response = f('http://localhost' + uri, params=params, headers=headers, expect_errors=True) # Collect return information and deserialize it status = response.status try: body = json.loads(response.body) except ValueError: body = None return status, body
def test_run(self): # Setup data = { OPTION_REPO_ID.keyword: "test-repo", OPTION_NAME.keyword: "Test Repository", OPTION_DESCRIPTION.keyword: "Repository Description", OPTION_NOTES.keyword: ["a=a", "b=b"], } self.command.default_notes = {"foo": "bar"} self.server_mock.request.return_value = 201, {} # Test self.command.run(**data) # Verify self.assertEqual(1, self.server_mock.request.call_count) self.assertEqual("POST", self.server_mock.request.call_args[0][0]) body = self.server_mock.request.call_args[0][2] body = json.loads(body) self.assertEqual(body["id"], "test-repo") self.assertEqual(body["display_name"], "Test Repository") self.assertEqual(body["description"], "Repository Description") self.assertEqual(body["notes"], {"a": "a", "b": "b", "foo": "bar"}) self.assertEqual(body["distributors"], []) self.assertEqual(body["importer_type_id"], None) self.assertEqual(1, len(self.prompt.get_write_tags())) self.assertEqual(TAG_SUCCESS, self.prompt.get_write_tags()[0])
def test_unset_queries(self): # make sure an empty list gets sent as the new value for "queries", # and definitely not None data = { options.OPTION_REPO_ID.keyword : 'test-repo', options.OPTION_NAME.keyword : 'Test Name', options.OPTION_DESCRIPTION.keyword : 'Test Description', options.OPTION_NOTES.keyword : {'a' : 'a'}, cudl.OPTION_FEED.keyword : 'http://localhost', cudl.OPTION_HTTP.keyword : 'true', cudl.OPTION_HTTPS.keyword : 'true', cudl.OPTION_QUERY.keyword : None, cudl.OPTION_QUERIES_UPDATE.keyword : [] } self.server_mock.request.return_value = 200, {} # Test self.command.run(**data) body = self.server_mock.request.call_args[0][2] body = json.loads(body) expected_config = { u'feed' : u'http://localhost', u'queries' : [], # this is the key part of this test } self.assertEqual(expected_config, body['importer_config'])
def test_queries_overrides_query(self): # make sure --queries overrides --query, which is deprecated data = { options.OPTION_REPO_ID.keyword : 'test-repo', options.OPTION_NAME.keyword : 'Test Name', options.OPTION_DESCRIPTION.keyword : 'Test Description', options.OPTION_NOTES.keyword : {'a' : 'a'}, cudl.OPTION_FEED.keyword : 'http://localhost', cudl.OPTION_HTTP.keyword : 'true', cudl.OPTION_HTTPS.keyword : 'true', cudl.OPTION_QUERY.keyword : ['q1', 'q2'], cudl.OPTION_QUERIES.keyword : ['x', 'y'] } self.server_mock.request.return_value = 200, {} # Test self.command.run(**data) body = self.server_mock.request.call_args[0][2] body = json.loads(body) expected_config = { u'feed' : u'http://localhost', u'queries' : [u'x', u'y'], } self.assertEqual(expected_config, body['importer_config'])
def test_run(self): # Setup data = { OPTION_GROUP_ID.keyword: "test-group", OPTION_NAME.keyword: "Group", OPTION_DESCRIPTION.keyword: "Description", OPTION_NOTES.keyword: {"a": "a", "b": "b"}, } self.server_mock.request.return_value = 200, {} # Test self.command.run(**data) # Verify self.assertEqual(1, self.server_mock.request.call_count) self.assertEqual("PUT", self.server_mock.request.call_args[0][0]) url = self.server_mock.request.call_args[0][1] self.assertTrue(url.endswith("/repo_groups/test-group/")) body = self.server_mock.request.call_args[0][2] delta = json.loads(body) self.assertTrue("display-name" not in delta) self.assertEqual(delta["display_name"], "Group") self.assertEqual(delta["description"], "Description") self.assertEqual(delta["notes"], {"a": "a", "b": "b"})
def load_plugin_config(config_file_name): """ @type config_file_name: str @rtype: dict """ _LOG.debug('Loading config file: %s' % config_file_name) contents = read_content(config_file_name) cfg = json.loads(contents) return cfg
def test_adds_repo_to_search(self): data = {OPTION_GROUP_ID.keyword: "test-group", FLAG_ALL.keyword: False, OPTION_REPO_ID.keyword: ["repo1"]} self.server_mock.request.return_value = 200, {} self.command.run(**data) criteria = json.loads(self.server_mock.request.call_args[0][2])["criteria"] self.assertEqual(criteria["filters"]["id"]["$in"], ["repo1"])
def test_from_dict(self): # Setup data = json.loads(VALID_MODULE_METADATA_JSON) # Test module = Module.from_dict(data) # Verify self.assert_valid_module(module)
def test_repo_id_and_all(self): # --all should not prevent other filters from being added. data = {OPTION_GROUP_ID.keyword: "test-group", FLAG_ALL.keyword: False, OPTION_REPO_ID.keyword: ["repo1"]} self.server_mock.request.return_value = 200, {} self.command.run(**data) criteria = json.loads(self.server_mock.request.call_args[0][2])["criteria"] self.assertEqual(criteria["filters"]["id"]["$in"], ["repo1"])
def update_from_json(self, metadata_json): """ Takes the module's metadata in JSON format and merges it into this instance. :param metadata_json: module metadata in JSON :type metadata_json: str """ parsed = json.loads(metadata_json) self.update_from_dict(parsed)
def test_run(self): # Setup data = { OPTION_GROUP_ID.keyword : 'test-group', } return_values = [ (200, [{'repo_ids' : ['repo-1']}]), # return from search groups call (200, [{'id' : 'a'}]), # return from the repo search call ] self.server_mock.request.side_effect = return_values # Test self.command.run(**data) # Verify self.assertEqual(2, self.server_mock.request.call_count) # Group lookup call call_args = self.server_mock.request.call_args_list[0] self.assertEqual('POST', call_args[0][0]) url = call_args[0][1] self.assertTrue(url.endswith('/repo_groups/search/')) body = json.loads(call_args[0][2]) self.assertEqual(body['criteria']['filters']['id'], 'test-group') # Repo lookup call call_args = self.server_mock.request.call_args_list[1] self.assertEqual('POST', call_args[0][0]) url = call_args[0][1] self.assertTrue(url.endswith('/repositories/search/')) body = json.loads(call_args[0][2]) self.assertEqual(body['criteria']['filters']['id'], {'$in' : ['repo-1']}) # Output self.assertEqual(2, len(self.prompt.get_write_tags())) self.assertEqual(TAG_TITLE, self.prompt.get_write_tags()[0]) self.assertEqual(TAG_DOCUMENT, self.prompt.get_write_tags()[1])
def update_from_json(self, json_string): """ Updates this metadata instance with packages found in the given JSON document. This can be called multiple times to merge multiple repository metadata JSON documents into this instance. :param json_string: A JSON string :type json_string: basestr """ parsed = json.loads(json_string) self.add_packages(parsed.pop('packages', [])) self.data(parsed)
def test_run(self): # Setup data = {OPTION_GROUP_ID.keyword: "test-group"} return_values = [ (200, [{"repo_ids": ["repo-1"]}]), # return from search groups call (200, [{"id": "a"}]), # return from the repo search call ] self.server_mock.request.side_effect = return_values # Test self.command.run(**data) # Verify self.assertEqual(2, self.server_mock.request.call_count) # Group lookup call call_args = self.server_mock.request.call_args_list[0] self.assertEqual("POST", call_args[0][0]) url = call_args[0][1] self.assertTrue(url.endswith("/repo_groups/search/")) body = json.loads(call_args[0][2]) self.assertEqual(body["criteria"]["filters"]["id"], "test-group") # Repo lookup call call_args = self.server_mock.request.call_args_list[1] self.assertEqual("POST", call_args[0][0]) url = call_args[0][1] self.assertTrue(url.endswith("/repositories/search/")) body = json.loads(call_args[0][2]) self.assertEqual(body["criteria"]["filters"]["id"], {"$in": ["repo-1"]}) # Output self.assertEqual(2, len(self.prompt.get_write_tags())) self.assertEqual(TAG_TITLE, self.prompt.get_write_tags()[0]) self.assertEqual(TAG_DOCUMENT, self.prompt.get_write_tags()[1])
def test_run(self): # Setup data = { options.OPTION_REPO_ID.keyword: 'test-repo', options.OPTION_NAME.keyword: 'Test Name', options.OPTION_DESCRIPTION.keyword: 'Test Description', options.OPTION_NOTES.keyword: {'b': 'b'}, self.options_bundle.opt_feed.keyword: 'http://localhost', repo_options.OPT_SERVE_HTTP.keyword: True, repo_options.OPT_SERVE_HTTPS.keyword: True, repo_options.OPT_SKIP.keyword: [ids.TYPE_ID_RPM], repo_options.OPT_CHECKSUM_TYPE.keyword: 'sha1', repo_options.OPT_UPDATEINFO_CHECKSUM_TYPE.keyword: 'md5', repo_options.OPT_REPOVIEW.keyword: True, } self.server_mock.request.return_value = 200, {} # Test command = repo_create_update.RpmRepoUpdateCommand(self.context) command.run(**data) # Verify self.assertEqual(1, self.server_mock.request.call_count) body = self.server_mock.request.call_args[0][2] body = json.loads(body) delta = body['delta'] self.assertEqual(delta['display_name'], 'Test Name') self.assertEqual(delta['description'], 'Test Description') self.assertEqual(delta['notes'], {'b': 'b'}) yum_imp_config = body['importer_config'] self.assertEqual(yum_imp_config[constants.KEY_FEED], 'http://localhost') self.assertEqual(yum_imp_config[rpm_constants.CONFIG_SKIP], [ids.TYPE_ID_RPM]) yum_dist_config = body['distributor_configs'][ids.YUM_DISTRIBUTOR_ID] self.assertEqual(yum_dist_config['http'], True) self.assertEqual(yum_dist_config['https'], True) self.assertEqual(yum_dist_config['skip'], [ids.TYPE_ID_RPM]) self.assertEqual(yum_dist_config['checksum_type'], 'sha1') self.assertEqual(yum_dist_config['updateinfo_checksum_type'], 'md5') self.assertEqual(yum_dist_config['repoview'], True) self.assertEqual(yum_dist_config['generate_sqlite'], True) iso_dist_config = body['distributor_configs'][ids.EXPORT_DISTRIBUTOR_ID] self.assertEqual(iso_dist_config['http'], True) self.assertEqual(iso_dist_config['https'], True) self.assertEqual(iso_dist_config['skip'], [ids.TYPE_ID_RPM]) self.assertEqual(iso_dist_config['checksum_type'], 'sha1') self.assertEqual(iso_dist_config['updateinfo_checksum_type'], 'md5')
def test_run(self): # Setup data = { options.OPTION_REPO_ID.keyword : 'test-repo', options.OPTION_NAME.keyword : 'Test Name', options.OPTION_DESCRIPTION.keyword : 'Test Description', options.OPTION_NOTES.keyword : {'a' : 'a'}, cudl.OPTION_FEED.keyword : 'http://localhost', cudl.OPTION_HTTP.keyword : 'true', cudl.OPTION_HTTPS.keyword : 'true', cudl.OPTION_QUERY.keyword : ['q1', 'q2'], cudl.OPTION_QUERIES.keyword : None } self.server_mock.request.return_value = 200, {} # Test self.command.run(**data) # Verify self.assertEqual(1, self.server_mock.request.call_count) self.assertEqual('POST', self.server_mock.request.call_args[0][0]) self.assertTrue(self.server_mock.request.call_args[0][1].endswith('/v2/repositories/')) body = self.server_mock.request.call_args[0][2] body = json.loads(body) self.assertEqual('test-repo', body['id']) self.assertEqual('Test Name', body['display_name']) self.assertEqual('Test Description', body['description']) expected_notes = {'a' : 'a', constants.REPO_NOTE_KEY : constants.REPO_NOTE_PUPPET} self.assertEqual(expected_notes, body['notes']) self.assertEqual(constants.IMPORTER_TYPE_ID, body['importer_type_id']) expected_config = { u'feed' : u'http://localhost', u'queries' : [u'q1', u'q2'], } self.assertEqual(expected_config, body['importer_config']) dist = body['distributors'][0] self.assertEqual(constants.DISTRIBUTOR_TYPE_ID, dist['distributor_type']) self.assertEqual(True, dist['auto_publish']) self.assertEqual(constants.DISTRIBUTOR_ID, dist['distributor_id']) expected_config = { u'serve_http' : True, u'serve_https' : True, } self.assertEqual(expected_config, dist['distributor_config']) self.assertEqual([TAG_SUCCESS], self.prompt.get_write_tags())
def test_adds_repo_to_search(self): data = { OPTION_GROUP_ID.keyword : 'test-group', FLAG_ALL.keyword : False, OPTION_REPO_ID.keyword : ['repo1'] } self.server_mock.request.return_value = 200, {} self.command.run(**data) criteria = json.loads(self.server_mock.request.call_args[0][2])['criteria'] self.assertEqual(criteria['filters']['id']['$in'], ['repo1'])
def test_run(self): # Setup repo_id = 'test-repo' data = { OPTION_REPO_ID.keyword: repo_id, OPTION_NAME.keyword: 'Test Repository', OPTION_DESCRIPTION.keyword: 'Repository Description', OPTION_NOTES.keyword: {'a': 'a', 'b': 'b'}, 'distributor_configs': {'alpha': {'beta': 'gamma'}}, 'importer_config': {'delta': 'epsilon'} } self.server_mock.request.return_value = 200, {} # Test self.command.run(**data) # Verify self.assertEqual(1, self.server_mock.request.call_count) self.assertEqual('PUT', self.server_mock.request.call_args[0][0]) url = self.server_mock.request.call_args[0][1] self.assertTrue(url.endswith('/repositories/%s/' % repo_id)) body = self.server_mock.request.call_args[0][2] body = json.loads(body) body_target = { 'delta': { 'display_name': 'Test Repository', 'description': 'Repository Description', 'notes': {'a': 'a', 'b': 'b'} }, 'distributor_configs': {'alpha': {'beta': 'gamma'}}, 'importer_config': {'delta': 'epsilon'} } compare_dict(body, body_target) self.assertEqual(1, len(self.prompt.get_write_tags())) self.assertEqual(TAG_SUCCESS, self.prompt.get_write_tags()[0])
def test_run_through_cli(self): """ See the note in test_run_through_cli under the create tests for more info. """ # Setup self.server_mock.request.return_value = 201, {} # Test command = repo_create_update.RpmRepoUpdateCommand(self.context) self.cli.add_command(command) self.cli.run("update --repo-id r --validate true".split()) # Verify self.assertEqual(1, self.server_mock.request.call_count) body = self.server_mock.request.call_args[0][2] body = json.loads(body) self.assertEqual(body['importer_config'][constants.KEY_VALIDATE], True) # not the string "true"
def test_pulp_manage_db_loads_types(self, initialize, start_logging_mock, listdir_mock, mock_drop_indices): """ Test calling pulp-manage-db imports types on a clean types database. """ manage.main() all_collection_names = types_db.all_type_collection_names() self.assertFalse(mock_drop_indices.called) self.assertEqual(len(all_collection_names), 1) self.assertEqual(['units_test_type_id'], all_collection_names) # Let's make sure we loaded the type definitions correctly db_type_definitions = types_db.all_type_definitions() self.assertEquals(len(db_type_definitions), 1) test_json = json.loads(_test_type_json) for attribute in ['id', 'display_name', 'description', 'unit_key', 'search_indexes']: self.assertEquals(test_json['types'][0][attribute], db_type_definitions[0][attribute]) # Now let's ensure that we have the correct indexes collection = types_db.type_units_collection('test_type_id') indexes = collection.index_information() self.assertEqual(indexes['_id_']['key'], [(u'_id', 1)]) # Make sure we have the unique constraint on all three attributes self.assertEqual(indexes['attribute_1_1_attribute_2_1_attribute_3_1']['unique'], True) self.assertEqual(indexes['attribute_1_1_attribute_2_1_attribute_3_1']['dropDups'], False) self.assertEqual(indexes['attribute_1_1_attribute_2_1_attribute_3_1']['key'], [(u'attribute_1', 1), (u'attribute_2', 1), (u'attribute_3', 1)]) # Make sure we indexes attributes 1 and 3 self.assertEqual(indexes['attribute_1_1']['dropDups'], False) self.assertEqual(indexes['attribute_1_1']['key'], [(u'attribute_1', 1)]) self.assertEqual(indexes['attribute_3_1']['dropDups'], False) self.assertEqual(indexes['attribute_3_1']['key'], [(u'attribute_3', 1)]) # Make sure we only have the indexes that we've hand inspected here self.assertEqual(indexes.keys(), [u'_id_', u'attribute_1_1_attribute_2_1_attribute_3_1', u'attribute_1_1', u'attribute_3_1']) initialize.assert_called_once_with(max_timeout=1)
def test_run_through_cli(self): # Setup self.server_mock.request.return_value = 201, {} # Test command = repo_create_update.PkgRepoCreateCommand(self.context) self.cli.add_command(command) cmd = ["create", "--repo-id", "r", "--validate", "true"] self.cli.run(cmd) # Verify self.assertEqual(1, self.server_mock.request.call_count) body = self.server_mock.request.call_args[0][2] body = json.loads(body) self.assertEqual(body['id'], 'r') self.assertEqual(body['importer_config'][constants.KEY_VALIDATE], True) # not the string "true" dconfig = body['distributors'][0]['distributor_config'] self.assertEquals(dict(http=False, https=True, relative_url='r'), dconfig)
def test_run(self): # Setup data = {'from-repo-id': 'from', 'to-repo-id': 'to'} self.server_mock.request.return_value = 202, self.task() mock_poll = mock.MagicMock().poll self.command.poll = mock_poll # Test self.command.run(**data) # Verify call_args = self.server_mock.request.call_args[0] self.assertEqual('POST', call_args[0]) self.assertTrue(call_args[1].endswith('/to/actions/associate/')) body = json.loads(call_args[2]) self.assertEqual(body['source_repo_id'], 'from') self.assertEqual(body['criteria']['type_ids'], [constants.TYPE_PUPPET_MODULE]) self.assertEqual(1, mock_poll.call_count)
def test_repo_id_and_match(self): data = { OPTION_GROUP_ID.keyword: 'test-group', FLAG_ALL.keyword: False, OPTION_REPO_ID.keyword: ['repo1'], 'match': [('id', 'repo.+')] } self.server_mock.request.return_value = 200, {} self.command.run(**data) criteria = json.loads( self.server_mock.request.call_args[0][2])['criteria'] self.assertEqual(len(criteria['filters']['$and']), 2) # make sure each of these filter types shows up in the criteria self.assertEqual( len( set(['$in', '$regex']) & set(criteria['filters']['$and'][0]['id'])), 1) self.assertEqual( len( set(['$in', '$regex']) & set(criteria['filters']['$and'][1]['id'])), 1)
class HTTPSServerWrapper(object): """ Used by the PulpConnection class to make an invocation against the server. This abstraction is used to simplify mocking. In this implementation, the intricacies (read: ugliness) of invoking and getting the response from the HTTPConnection class are hidden in favor of a simpler API to mock. """ def __init__(self, pulp_connection): """ :param pulp_connection: A pulp connection object. :type pulp_connection: PulpConnection """ self.pulp_connection = pulp_connection def request(self, method, url, body): """ Make the request against the Pulp server, returning a tuple of (status_code, respose_body). This method creates a new connection each time since HTTPSConnection has problems reusing a connection for multiple calls (as claimed by a prior comment in this module). :param method: The HTTP method to be used for the request (GET, POST, etc.) :type method: str :param url: The Pulp URL to make the request against :type url: str :param body: The body to pass with the request :type body: str :return: A 2-tuple of the status_code and response_body. status_code is the HTTP status code (200, 404, etc.). If the server's response is valid json, it will be parsed and response_body will be a dictionary. If not, it will be returned as a string. :rtype: tuple """ headers = dict(self.pulp_connection.headers ) # copy so we don't affect the calling method # Despite the confusing name, 'sslv23' configures m2crypto to use any available protocol in # the underlying openssl implementation. ssl_context = SSL.Context('sslv23') # This restricts the protocols we are willing to do by configuring m2 not to do SSLv2.0 or # SSLv3.0. EL 5 does not have support for TLS > v1.0, so we have to leave support for # TLSv1.0 enabled. ssl_context.set_options(m2.SSL_OP_NO_SSLv2 | m2.SSL_OP_NO_SSLv3) if self.pulp_connection.verify_ssl: ssl_context.set_verify(SSL.verify_peer, depth=100) # We need to stat the ca_path to see if it exists (error if it doesn't), and if so # whether it is a file or a directory. m2crypto has different directives depending on # which type it is. if os.path.isfile(self.pulp_connection.ca_path): ssl_context.load_verify_locations( cafile=self.pulp_connection.ca_path) elif os.path.isdir(self.pulp_connection.ca_path): ssl_context.load_verify_locations( capath=self.pulp_connection.ca_path) else: # If it's not a file and it's not a directory, it's not a valid setting raise exceptions.MissingCAPathException( self.pulp_connection.ca_path) ssl_context.set_session_timeout(self.pulp_connection.timeout) if self.pulp_connection.username and self.pulp_connection.password: raw = ':'.join( (self.pulp_connection.username, self.pulp_connection.password)) encoded = base64.encodestring(raw)[:-1] headers['Authorization'] = 'Basic ' + encoded elif self.pulp_connection.cert_filename: ssl_context.load_cert(self.pulp_connection.cert_filename) # oauth configuration. This block is only True if oauth is not None, so it won't run on RHEL # 5. if self.pulp_connection.oauth_key and self.pulp_connection.oauth_secret and oauth: oauth_consumer = oauth.Consumer(self.pulp_connection.oauth_key, self.pulp_connection.oauth_secret) oauth_request = oauth.Request.from_consumer_and_token( oauth_consumer, http_method=method, http_url='https://%s:%d%s' % (self.pulp_connection.host, self.pulp_connection.port, url)) oauth_request.sign_request(oauth.SignatureMethod_HMAC_SHA1(), oauth_consumer, None) oauth_header = oauth_request.to_header() # unicode header values causes m2crypto to do odd things. for k, v in oauth_header.items(): oauth_header[k] = encode_unicode(v) headers.update(oauth_header) headers['pulp-user'] = self.pulp_connection.oauth_user connection = httpslib.HTTPSConnection(self.pulp_connection.host, self.pulp_connection.port, ssl_context=ssl_context) try: # Request against the server connection.request(method, url, body=body, headers=headers) response = connection.getresponse() except SSL.SSLError, err: # Translate stale login certificate to an auth exception if 'sslv3 alert certificate expired' == str(err): raise exceptions.ClientCertificateExpiredException( self.pulp_connection.cert_filename) elif 'certificate verify failed' in str(err): raise exceptions.CertificateVerificationException() else: raise exceptions.ConnectionException(None, str(err), None) # Attempt to deserialize the body (should pass unless the server is busted) response_body = response.read() try: response_body = json.loads(response_body) except: pass return response.status, response_body
def test_run(self): # Setup cert_file = os.path.join(DATA_DIR, 'cert.crt') cert_key = os.path.join(DATA_DIR, 'cert.key') ca_cert = os.path.join(DATA_DIR, 'valid_ca.crt') gpg_key = os.path.join(DATA_DIR, 'cert.key') # contents shouldn't matter data = { options.OPTION_REPO_ID.keyword: 'test-repo', options.OPTION_NAME.keyword: 'Test Name', options.OPTION_DESCRIPTION.keyword: 'Test Description', options.OPTION_NOTES.keyword: { 'a': 'a' }, self.options_bundle.opt_feed.keyword: 'http://localhost', self.options_bundle.opt_validate.keyword: True, self.options_bundle.opt_remove_missing.keyword: True, self.options_bundle.opt_retain_old_count.keyword: 2, self.options_bundle.opt_proxy_host.keyword: 'http://localhost', self.options_bundle.opt_proxy_port.keyword: 80, self.options_bundle.opt_proxy_user.keyword: 'user', self.options_bundle.opt_proxy_pass.keyword: 'pass', self.options_bundle.opt_basic_auth_user.keyword: 'basicuser', self.options_bundle.opt_basic_auth_pass.keyword: 'basicpass', self.options_bundle.opt_max_speed.keyword: 1024, self.options_bundle.opt_max_downloads.keyword: 8, self.options_bundle.opt_feed_ca_cert.keyword: ca_cert, self.options_bundle.opt_verify_feed_ssl.keyword: True, self.options_bundle.opt_feed_cert.keyword: cert_file, self.options_bundle.opt_feed_key.keyword: cert_key, repo_options.OPT_SKIP.keyword: [ids.TYPE_ID_RPM], repo_options.OPT_RELATIVE_URL.keyword: '/repo', repo_options.OPT_SERVE_HTTP.keyword: True, repo_options.OPT_SERVE_HTTPS.keyword: True, repo_options.OPT_CHECKSUM_TYPE.keyword: 'sha256', repo_options.OPT_UPDATEINFO_CHECKSUM_TYPE.keyword: 'md5', repo_options.OPT_GPG_KEY.keyword: gpg_key, repo_options.OPT_HOST_CA.keyword: ca_cert, repo_options.OPT_AUTH_CA.keyword: ca_cert, repo_options.OPT_AUTH_CERT.keyword: cert_file, repo_options.OPT_REPOVIEW.keyword: True, } self.server_mock.request.return_value = 201, {} # Test command = repo_create_update.RpmRepoCreateCommand(self.context) command.run(**data) # Verify self.assertEqual(1, self.server_mock.request.call_count) body = self.server_mock.request.call_args[0][2] body = json.loads(body) self.assertEqual(body['display_name'], 'Test Name') self.assertEqual(body['description'], 'Test Description') self.assertEqual(body['notes'], {'_repo-type': 'rpm-repo', 'a': 'a'}) self.assertEqual(ids.TYPE_ID_IMPORTER_YUM, body['importer_type_id']) importer_config = body['importer_config'] self.assertEqual(importer_config[constants.KEY_FEED], 'http://localhost') self.assertTrue(importer_config[constants.KEY_SSL_CA_CERT] is not None) self.assertTrue( importer_config[constants.KEY_SSL_CLIENT_CERT] is not None) self.assertTrue( importer_config[constants.KEY_SSL_CLIENT_KEY] is not None) self.assertEqual(importer_config[constants.KEY_SSL_VALIDATION], True) self.assertEqual(importer_config[constants.KEY_VALIDATE], True) self.assertEqual(importer_config[constants.KEY_PROXY_HOST], 'http://localhost') self.assertEqual(importer_config[constants.KEY_PROXY_PORT], 80) self.assertEqual(importer_config[constants.KEY_PROXY_USER], 'user') self.assertEqual(importer_config[constants.KEY_PROXY_PASS], 'pass') self.assertEqual(importer_config[constants.KEY_BASIC_AUTH_USER], 'basicuser') self.assertEqual(importer_config[constants.KEY_BASIC_AUTH_PASS], 'basicpass') self.assertEqual(importer_config[constants.KEY_MAX_SPEED], 1024) self.assertEqual(importer_config[constants.KEY_MAX_DOWNLOADS], 8) self.assertEqual(importer_config[rpm_constants.CONFIG_SKIP], [ids.TYPE_ID_RPM]) self.assertEqual(importer_config[constants.KEY_UNITS_REMOVE_MISSING], True) self.assertEqual(importer_config[constants.KEY_UNITS_RETAIN_OLD_COUNT], 2) # The API will be changing to be a dict for each distributor, not a # list. This code will have to change to look up the parts by key # instead of index. yum_distributor = body['distributors'][0] self.assertEqual(ids.TYPE_ID_DISTRIBUTOR_YUM, yum_distributor['distributor_type_id']) self.assertEqual(True, yum_distributor['auto_publish']) self.assertEqual(ids.YUM_DISTRIBUTOR_ID, yum_distributor['distributor_id']) yum_config = yum_distributor['distributor_config'] self.assertEqual(yum_config['relative_url'], '/repo') self.assertEqual(yum_config['http'], True) self.assertEqual(yum_config['https'], True) self.assertTrue(yum_config['gpgkey'] is not None) self.assertEqual(yum_config['checksum_type'], 'sha256') self.assertEqual(yum_config['updateinfo_checksum_type'], 'md5') self.assertTrue(yum_config['auth_ca'] is not None) self.assertTrue(yum_config['auth_cert'] is not None) self.assertTrue(yum_config['https_ca'] is not None) self.assertEqual(yum_config['skip'], [ids.TYPE_ID_RPM]) self.assertEqual(yum_config['repoview'], True) self.assertEqual(yum_config['generate_sqlite'], True) iso_distributor = body['distributors'][1] self.assertEqual(ids.TYPE_ID_DISTRIBUTOR_EXPORT, iso_distributor['distributor_id']) self.assertEqual(False, iso_distributor['auto_publish']) self.assertEqual(ids.EXPORT_DISTRIBUTOR_ID, iso_distributor['distributor_id']) iso_config = iso_distributor['distributor_config'] self.assertEqual(iso_config['http'], True) self.assertEqual(iso_config['https'], True) self.assertEqual(iso_config['relative_url'], '/repo') self.assertEqual(iso_config['skip'], [ids.TYPE_ID_RPM]) self.assertEqual(iso_config['checksum_type'], 'sha256') self.assertEqual(iso_config['updateinfo_checksum_type'], 'md5') self.assertEqual([TAG_SUCCESS], self.prompt.get_write_tags())
class HTTPSServerWrapper(object): """ Used by the PulpConnection class to make an invocation against the server. This abstraction is used to simplify mocking. In this implementation, the intricacies (read: ugliness) of invoking and getting the response from the HTTPConnection class are hidden in favor of a simpler API to mock. """ def __init__(self, pulp_connection): """ :param pulp_connection: A pulp connection object. :type pulp_connection: PulpConnection """ self.pulp_connection = pulp_connection def request(self, method, url, body): headers = dict(self.pulp_connection.headers ) # copy so we don't affect the calling method # Create a new connection each time since HTTPSConnection has problems # reusing a connection for multiple calls (lame). ssl_context = None if self.pulp_connection.username and self.pulp_connection.password: raw = ':'.join( (self.pulp_connection.username, self.pulp_connection.password)) encoded = base64.encodestring(raw)[:-1] headers['Authorization'] = 'Basic ' + encoded elif self.pulp_connection.cert_filename: ssl_context = SSL.Context('sslv3') ssl_context.set_session_timeout(self.pulp_connection.timeout) ssl_context.load_cert(self.pulp_connection.cert_filename) # oauth configuration if self.pulp_connection.oauth_key and self.pulp_connection.oauth_secret: oauth_consumer = oauth.Consumer(self.pulp_connection.oauth_key, self.pulp_connection.oauth_secret) oauth_request = oauth.Request.from_consumer_and_token( oauth_consumer, http_method=method, http_url='https://%s:%d%s' % (self.pulp_connection.host, self.pulp_connection.port, url)) oauth_request.sign_request(oauth.SignatureMethod_HMAC_SHA1(), oauth_consumer, None) oauth_header = oauth_request.to_header() # unicode header values causes m2crypto to do odd things. for k, v in oauth_header.items(): oauth_header[k] = encode_unicode(v) headers.update(oauth_header) headers['pulp-user'] = self.pulp_connection.oauth_user # Can't pass in None, so need to decide between two signatures (also lame) if ssl_context is not None: connection = httpslib.HTTPSConnection(self.pulp_connection.host, self.pulp_connection.port, ssl_context=ssl_context) else: connection = httpslib.HTTPSConnection(self.pulp_connection.host, self.pulp_connection.port) # Request against the server connection.request(method, url, body=body, headers=headers) try: response = connection.getresponse() except SSL.SSLError, err: # Translate stale login certificate to an auth exception if 'sslv3 alert certificate expired' == str(err): raise exceptions.ClientSSLException( self.pulp_connection.cert_filename) else: raise exceptions.ConnectionException(None, str(err), None) # Attempt to deserialize the body (should pass unless the server is busted) response_body = response.read() try: response_body = json.loads(response_body) except: pass return response.status, response_body
def test_run(self): # Setup data = { options.OPTION_REPO_ID.keyword: 'test-repo', options.OPTION_NAME.keyword: 'Test Name', options.OPTION_DESCRIPTION.keyword: 'Test Description', options.OPTION_NOTES.keyword: { 'a': 'a' }, self.options_bundle.opt_feed.keyword: 'http://localhost', self.options_bundle.opt_validate.keyword: True, self.options_bundle.opt_remove_missing.keyword: True, repo_options.OPT_SKIP.keyword: [ids.TYPE_ID_DEB], repo_options.OPT_RELATIVE_URL.keyword: '/repo', repo_options.OPT_SERVE_HTTP.keyword: True, repo_options.OPT_SERVE_HTTPS.keyword: True, } self.server_mock.request.return_value = 201, {} # Test command = repo_create_update.PkgRepoCreateCommand(self.context) command.run(**data) # Verify self.assertEqual(1, self.server_mock.request.call_count) body = self.server_mock.request.call_args[0][2] body = json.loads(body) self.assertEqual(body['display_name'], 'Test Name') self.assertEqual(body['description'], 'Test Description') self.assertEqual(body['notes'], {'_repo-type': 'deb-repo', 'a': 'a'}) self.assertEqual(ids.TYPE_ID_IMPORTER, body['importer_type_id']) importer_config = body['importer_config'] self.assertEqual(importer_config[constants.KEY_FEED], 'http://localhost') self.assertEqual(importer_config[repo_create_update.CONFIG_KEY_SKIP], [ids.TYPE_ID_DEB]) self.assertEqual(importer_config[constants.KEY_UNITS_REMOVE_MISSING], True) # The API will be changing to be a dict for each distributor, not a # list. This code will have to change to look up the parts by key # instead of index. yum_distributor = body['distributors'][0] self.assertEqual(ids.TYPE_ID_DISTRIBUTOR, yum_distributor['distributor_type_id']) self.assertEqual(True, yum_distributor['auto_publish']) self.assertEqual(ids.TYPE_ID_DISTRIBUTOR, yum_distributor['distributor_id']) yum_config = yum_distributor['distributor_config'] self.assertEqual(yum_config['relative_url'], '/repo') self.assertEqual(yum_config['http'], True) self.assertEqual(yum_config['https'], True) self.assertEqual(yum_config['skip'], [ids.TYPE_ID_DEB]) self.assertEqual([TAG_SUCCESS], self.prompt.get_write_tags())
def test_run(self): # Setup data = { options.OPTION_REPO_ID.keyword: 'test-repo', options.OPTION_NAME.keyword: 'Test Name', options.OPTION_DESCRIPTION.keyword: 'Test Description', options.OPTION_NOTES.keyword: { 'a': 'a' }, cudl.OPTION_FEED.keyword: 'http://localhost', cudl.OPTION_HTTP.keyword: 'true', cudl.OPTION_HTTPS.keyword: 'true', cudl.OPTION_QUERY.keyword: ['q1', 'q2'], cudl.OPTION_QUERIES.keyword: None, cudl.OPTION_REMOVE_MISSING.keyword: True } self.server_mock.request.return_value = 200, {} # Test self.command.run(**data) # Verify self.assertEqual(1, self.server_mock.request.call_count) self.assertEqual('POST', self.server_mock.request.call_args[0][0]) self.assertTrue(self.server_mock.request.call_args[0][1].endswith( '/v2/repositories/')) body = self.server_mock.request.call_args[0][2] body = json.loads(body) self.assertEqual('test-repo', body['id']) self.assertEqual('Test Name', body['display_name']) self.assertEqual('Test Description', body['description']) expected_notes = { 'a': 'a', constants.REPO_NOTE_KEY: constants.REPO_NOTE_PUPPET } self.assertEqual(expected_notes, body['notes']) self.assertEqual(constants.IMPORTER_TYPE_ID, body['importer_type_id']) expected_config = { u'feed': u'http://localhost', u'queries': [u'q1', u'q2'], u'remove_missing': True } self.assertEqual(expected_config, body['importer_config']) dist = body['distributors'][0] self.assertEqual(constants.DISTRIBUTOR_TYPE_ID, dist['distributor_type_id']) self.assertEqual(True, dist['auto_publish']) self.assertEqual(constants.DISTRIBUTOR_ID, dist['distributor_id']) expected_config = { u'serve_http': True, u'serve_https': True, } self.assertEqual(expected_config, dist['distributor_config']) self.assertEqual([TAG_SUCCESS], self.prompt.get_write_tags())