Steven Sombar | b6749a6 | 2017-10-06 08:34:23 -0500 | [diff] [blame] | 1 | #!/usr/bin/env python |
| 2 | |
| 3 | r""" |
| 4 | This module contains file functions such as file_diff. |
| 5 | """ |
| 6 | |
| 7 | import time |
| 8 | import os |
| 9 | import re |
| 10 | from gen_cmd import cmd_fnc_u |
| 11 | robot_env = 1 |
| 12 | try: |
| 13 | from robot.libraries.BuiltIn import BuiltIn |
| 14 | from robot.libraries import DateTime |
| 15 | except ImportError: |
| 16 | robot_env = 0 |
| 17 | |
| 18 | |
| 19 | ########################################################################## |
| 20 | def file_diff(file1_path, |
| 21 | file2_path, |
| 22 | diff_file_path, |
| 23 | skip_string): |
| 24 | r""" |
| 25 | Compare the contents of two text files. The comparison uses the Unix |
| 26 | 'diff' command. Differences can be selectively ignored by use of |
| 27 | the skip_string parameter. The output of diff command is written |
| 28 | to a user-specified file and is also written (logged) to the console. |
| 29 | |
| 30 | Description of arguments: |
| 31 | file1_path File containing text data. |
| 32 | file2_path Text file to compare to file1. |
| 33 | diff_file_path Text file which will contain the diff output. |
| 34 | skip_string To allow for differences which may expected or immaterial, |
| 35 | skip_string parameter is a word or a string of comma |
| 36 | separated words which specify what should be ignored. |
| 37 | For example, "size,speed". Any line containing the word |
| 38 | size or the word speed will be ignored when the diff is |
| 39 | performed. This parameter is optional. |
| 40 | |
| 41 | Returns: |
| 42 | 0 if both files contain the same information or they differ only in |
| 43 | items specified by the skip_string. |
| 44 | 2 if FILES_DO_NOT_MATCH. |
| 45 | 3 if INPUT_FILE_DOES_NOT_EXIST. |
| 46 | 4 if IO_EXCEPTION_READING_FILE. |
| 47 | 5 if IO_EXCEPTION_WRITING_FILE. |
| 48 | 6 if INPUT_FILE_MALFORMED |
| 49 | """ |
| 50 | |
| 51 | FILES_MATCH = 0 |
| 52 | FILES_DO_NOT_MATCH = 2 |
| 53 | INPUT_FILE_DOES_NOT_EXIST = 3 |
| 54 | IO_EXCEPTION_READING_FILE = 4 |
| 55 | IO_EXCEPTION_WRITING_FILE = 5 |
| 56 | INPUT_FILE_MALFORMED = 6 |
| 57 | |
| 58 | # The minimum size in bytes a file must be. |
| 59 | min_file_byte_size = 1 |
| 60 | |
| 61 | now = time.strftime("%Y-%m-%d %H:%M:%S") |
| 62 | |
| 63 | if (not os.path.exists(file1_path) or (not os.path.exists(file2_path))): |
| 64 | return INPUT_FILE_DOES_NOT_EXIST |
| 65 | try: |
| 66 | with open(file1_path, 'r') as file: |
| 67 | initial = file.readlines() |
| 68 | with open(file2_path, 'r') as file: |
| 69 | final = file.readlines() |
| 70 | except IOError: |
| 71 | file.close() |
| 72 | return IO_EXCEPTION_READING_FILE |
| 73 | except ValueError: |
| 74 | file.close() |
| 75 | return INPUT_FILE_MALFORMED |
| 76 | else: |
| 77 | file.close() |
| 78 | |
| 79 | # Must have more than a trivial number of bytes. |
| 80 | if len(initial) < min_file_byte_size: |
| 81 | return INPUT_FILE_MALFORMED |
| 82 | |
| 83 | if (initial == final): |
| 84 | try: |
| 85 | file = open(diff_file_path, 'w') |
| 86 | except IOError: |
| 87 | file.close() |
| 88 | line_to_print = "Specified skip (ignore) string = " + \ |
| 89 | skip_string + "\n\n" |
| 90 | file.write(line_to_print) |
| 91 | line_to_print = now + " found no difference between file " + \ |
| 92 | file1_path + " and " + \ |
| 93 | file2_path + "\n" |
| 94 | file.write(line_to_print) |
| 95 | file.close() |
| 96 | return FILES_MATCH |
| 97 | |
| 98 | # Find the differences and write difference report to diff_file_path file |
| 99 | try: |
| 100 | file = open(diff_file_path, 'w') |
| 101 | except IOError: |
| 102 | file.close() |
| 103 | return IO_EXCEPTION_WRITING_FILE |
| 104 | |
| 105 | # Form a UNIX diff command and its parameters as a string. For example, |
| 106 | # if skip_string="size,capacity", command = 'diff -I "size" |
| 107 | # -I "capacity" file1_path file2_path'. |
| 108 | skip_list = filter(None, re.split(r"[ ]*,[ ]*", skip_string)) |
| 109 | ignore_string = ' '.join([("-I " + '"' + x + '"') for x in skip_list]) |
| 110 | command = ' '.join(filter(None, ["diff", ignore_string, file1_path, |
| 111 | file2_path])) |
| 112 | |
| 113 | line_to_print = now + " " + command + "\n" |
| 114 | file.write(line_to_print) |
| 115 | |
| 116 | # Run the command and get the differences |
| 117 | rc, out_buf = cmd_fnc_u(command, quiet=0, print_output=0, show_err=0) |
| 118 | |
| 119 | # Write the differences to the specified diff_file and console. |
| 120 | if robot_env == 1: |
| 121 | BuiltIn().log_to_console("DIFF:\n" + out_buf) |
| 122 | else: |
| 123 | print "DIFF:\n", out_buf |
| 124 | |
| 125 | file.write(out_buf) |
| 126 | file.close() |
| 127 | |
| 128 | if rc == 0: |
| 129 | # Any differences found were on the skip_string. |
| 130 | return FILES_MATCH |
| 131 | else: |
| 132 | # We have at least one difference not in the skip_string. |
| 133 | return FILES_DO_NOT_MATCH |
| 134 | ############################################################################### |