def step_impl(context, spec=None): IN = ['Command Line',] ACTIONS = ['Install', 'Removed', 'Upgrade', 'Upgraded', 'Reinstall', 'Downgrade'] check_context_table(context, ["Key", "Value"]) if spec is None: spec = "" h_info = parsed_history_info(context, spec) for key, value in context.table: if key in h_info: if key in IN and value in h_info[key]: continue elif value == h_info[key]: continue else: raise AssertionError( '[history] {0} "{1}" not matched by "{2}".'.format( key, h_info[key], value)) elif key in ACTIONS: for pkg in value.split(','): for line in h_info[None]: if key in line and pkg in line: break else: raise AssertionError( '[history] "{0}" not matched as "{1}".'.format(pkg, key)) else: raise AssertionError('[history] key "{0}" not found.'.format(key))
def step_impl(context): check_context_table(context, ["Package", "Reason"]) cmd = context.dnf.get_cmd(context) + [ "repoquery --qf '%{name}-%{evr}.%{arch},%{reason}' --installed" ] run_in_context(context, " ".join(cmd)) expected = [[p, r] for p, r in context.table] found = sorted( [r.split(",") for r in context.cmd_stdout.strip().split('\n')]) if found != expected: print_lines_diff(expected, found) raise AssertionError("Package reasons mismatch")
def step_impl(context): check_context_table(context, ["Action", "Package"]) cmd = " ".join(context.dnf.get_cmd(context) + ["history", "userinstalled"]) run_in_context(context, cmd) for action, package in context.table: if action == 'match': if package not in context.cmd_stdout: raise AssertionError( '[history] package "{0}" not matched as userinstalled.'.format(package)) elif action == 'not match': if package in context.cmd_stdout: raise AssertionError( '[history] package "{0}" matched as userinstalled.'.format(package)) else: raise ValueError('Invalid action "{0}".'.format(action))
def check_microdnf_transaction(context, mode): check_context_table(context, ["Action", "Package"]) transaction = parse_microdnf_transaction_table( context.cmd_stdout.splitlines()) table = sorted([(a, p) for a, p in context.table]) updated_table = [] for action, nevra in table: if action in ["upgraded", "downgraded", "reinstalled", "obsoleted"]: action = "replaced" updated_table.append((action, nevra)) updated_table.sort() if transaction != updated_table: print_lines_diff(updated_table, transaction) raise AssertionError("Transaction table mismatch")
def assert_history_list(context, cmd_stdout): def history_equal(history, table): if table['Id'] and table['Id'] != history['id']: return False if table['Action'] and table['Action'] != history['action']: return False if table['Altered'] and table['Altered'] != history['altered']: return False if table['Command']: # command column in `history list` output is trimmed to limited space # to get full command, we need to ask `history info` h_info = parsed_history_info(context, history['id']) if not table['Command'] in h_info.get('Command Line', ''): return False return True check_context_table(context, ["Id", "Command", "Action", "Altered"]) stdout_lines = cmd_stdout.splitlines()[2:] history = parse_history_list(stdout_lines) table_idx = 0 for t_line in context.table: try: h_line = history[table_idx] except IndexError: print(cmd_stdout) raise AssertionError( "[history] table line (%s, %s, %s, %s) missing in history" % (t_line['Id'], t_line['Command'], t_line['Action'], t_line['Altered'])) if not history_equal(h_line, t_line): print(cmd_stdout) raise AssertionError( "[history] table line (%s, %s, %s, %s) does not match \"%s\"" % (t_line['Id'], t_line['Command'], t_line['Action'], t_line['Altered'], h_line['_line'])) table_idx += 1 if len(history) > table_idx: print(cmd_stdout) raise AssertionError( "[history] Following history lines not captured in the table:\n%s" % ('\n'.join(stdout_lines[table_idx:])))
def step_impl(context, spec=None): IN = [ 'Command Line', ] ACTIONS = [ 'Install', 'Removed', 'Upgrade', 'Upgraded', 'Reinstall', 'Reinstalled', 'Downgrade', 'Downgraded', 'Obsoleted', 'Reason Change' ] check_context_table(context, ["Key", "Value"]) if spec is None: spec = "" h_info = parsed_history_info(context, spec) expected_actions = [] for key, value in context.table: if key in h_info: if key in IN and value in h_info[key]: continue elif value == h_info[key]: continue else: raise AssertionError( '[history] {0} "{1}" not matched by "{2}".'.format( key, h_info[key], value)) elif key in ACTIONS: expected_actions.append([key, value]) else: raise AssertionError('[history] key "{0}" not found.'.format(key)) found_actions = [] for a in h_info[None]: action = a.split() if action[0:2] == ["Reason", "Change"]: found_actions.append(["Reason Change", action[2]]) else: found_actions.append(action[0:2]) if expected_actions != found_actions: print_lines_diff(expected_actions, found_actions) raise AssertionError("History actions mismatch")
def repodata_in_path_is(context, path): check_context_table(context, ["Type", "File", "Checksum Type", "Compression Type"]) # repomd.xml is mandatory in this form repomd_filepath = os.path.join(context.tempdir_manager.tempdir, path.lstrip("/"), "repomd.xml") if not os.path.exists(repomd_filepath): raise AssertionError("Error: repomd.xml is missing (%s)" % repomd_filepath) files = os.listdir(os.path.dirname(repomd_filepath)) files.remove("repomd.xml") for repodata_type, repodata_file, checksum_type, compression_type in context.table: checksum_regex = get_checksum_regex(checksum_type) filename_parts = repodata_file.split("-") if (len(filename_parts) == 1): pass # Simple-md-filenames elif (filename_parts[0] == "${checksum}"): filename_parts[0] = Template(filename_parts[0]).substitute(checksum=checksum_regex) else: if checksum_regex: if not (re.compile(checksum_regex + "$")).match(filename_parts[0]): raise ValueError("Checksum type: " + checksum_type + " does not" " match to File: " + repodata_file) filepath = os.path.join(context.tempdir_manager.tempdir, path.lstrip("/"), '-'.join(filename_parts)) # Final path to file, even when specified as regex # At the same time verifies that file exists filepath = regex_find_file_from_list(filepath, files) files.remove(os.path.basename(filepath)) # Verify checksum checksum = checksum_of_file(filepath, checksum_type) if (checksum_regex): filename_parts_final = os.path.basename(filepath).split("-") if (len(filename_parts_final) == 1): pass # Simple-md-filenames elif not checksum == filename_parts_final[0]: raise ValueError("Checksum of File: " + repodata_file + " doesn't match checksum" " in the name of the File: " + os.path.basename(filepath)) # Verify compression compression_suffix = get_compression_suffix(compression_type) if compression_suffix: if not filepath.endswith(compression_suffix): raise ValueError("Compression type: " + compression_type + " does" " not match suffix of File: " + repodata_file) try: tmp = next(decompression_iter(filepath, compression_type, blocksize=100)) if tmp: if filepath.endswith(".zck"): assert("ZCK" in str(tmp)) elif filepath.endswith(".sqlite"): assert("SQLITE" in str(tmp)) elif filepath.endswith(".xml"): assert("xml" in str(tmp)) else: pass # We don't know the filetype, assume it's correct except (AssertionError, IOError): raise AssertionError("Cannot decompress File: " + repodata_file + " using" " copression type: " + compression_type) if len(files) > 0: raise AssertionError("repodata directory contains additional metadata files:\n{0}".format('\n'.join(files)))