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