Source code for autotest.client.shared.test_utils.config_change_validation

"""
Module for testing config file changes.

:author: Kristof Katus and Plamen Dimitrov
:copyright: Intra2net AG 2012
@license: GPL v2
"""

import commands
import os
import shutil


[docs]def get_temp_file_path(file_path): """ Generates a temporary filename """ return file_path + '.tmp'
[docs]def make_temp_file_copies(file_paths): """ Creates temporary copies of the provided files """ for file_path in file_paths: temp_file_path = get_temp_file_path(file_path) shutil.copyfile(file_path, temp_file_path)
[docs]def del_temp_file_copies(file_paths): """ Deletes all the provided files """ for file_path in file_paths: temp_file_path = get_temp_file_path(file_path) os.remove(temp_file_path)
[docs]def parse_unified_diff_output(lines): """ Parses the unified diff output of two files Returns a pair of adds and removes, where each is a list of trimmed lines """ adds = [] removes = [] for line in lines: # ignore filepaths in the output if (len(line) > 2 and (line[:3] == "+++" or line[:3] == "---")): continue # ignore line range information in the output elif len(line) > 1 and line[:2] == "@@": continue # gather adds elif len(line) > 0 and line[0] == "+": added_line = line[1:].lstrip().rstrip() if len(added_line) == 0: continue adds = adds + [added_line] # gather removes elif len(line) > 0 and line[0] == "-": removed_line = line[1:].lstrip().rstrip() if len(removed_line) == 0: continue removes = removes + [removed_line] return (adds, removes)
[docs]def extract_config_changes(file_paths, compared_file_paths=[]): """ Extracts diff information based on the new and temporarily saved old config files Returns a dictionary of file path and corresponding diff information key-value pairs. """ changes = {} for i in range(len(file_paths)): temp_file_path = get_temp_file_path(file_paths[i]) if len(compared_file_paths) > i: command = ("diff -U 0 -b " + compared_file_paths[i] + " " + file_paths[i]) else: command = "diff -U 0 -b " + temp_file_path + " " + file_paths[i] (_, output) = commands.getstatusoutput(command) lines = output.split('\n') changes[file_paths[i]] = parse_unified_diff_output(lines) return changes
[docs]def assert_config_change_dict(actual_result, expected_result): """ Calculates unexpected line changes. The arguments actual_result and expected_results are of the same data structure type: Dict[file_path] --> (adds, removes), where adds = [added_line, ...] and removes = [removed_line, ...]. The return value has the following structure: Dict[file_path] --> (unexpected_adds, not_present_adds, unexpected_removes, not_present_removes) """ change_diffs = {} for file_path, actual_changes in actual_result.items(): expected_changes = expected_result[file_path] actual_adds = actual_changes[0] actual_removes = actual_changes[1] expected_adds = expected_changes[0] expected_removes = expected_changes[1] # Additional unexpected adds -- they should have been not added unexpected_adds = sorted(set(actual_adds) - set(expected_adds)) # Not present expected adds -- they should have been added not_present_adds = sorted(set(expected_adds) - set(actual_adds)) # Additional unexpected removes - they should have been not removed unexpected_removes = sorted(set(actual_removes) - set(expected_removes)) # Not present expected removes - they should have been removed not_present_removes = sorted(set(expected_removes) - set(actual_removes)) change_diffs[file_path] = (unexpected_adds, not_present_adds, unexpected_removes, not_present_removes) return change_diffs
[docs]def assert_config_change(actual_result, expected_result): """ Wrapper of the upper method returning boolean true if no config changes were detected. """ change_diffs = assert_config_change_dict(actual_result, expected_result) for file_change in change_diffs.values(): for line_change in file_change: if len(line_change) != 0: return False return True