blob: 0b194325430617ab5cb1adcd99354c592ca983d4 [file] [log] [blame]
George Keishinge7e91712021-09-03 11:28:44 -05001#!/usr/bin/env python3
Steven Sombarb6749a62017-10-06 08:34:23 -05002
3r"""
4This module contains file functions such as file_diff.
5"""
6
George Keishinge635ddc2022-12-08 07:38:02 -06007import time
Steven Sombarb6749a62017-10-06 08:34:23 -05008import os
9import re
10from gen_cmd import cmd_fnc_u
11robot_env = 1
12try:
Patrick Williams57318182022-12-08 06:18:26 -060013 from robot.libraries.BuiltIn import BuiltIn
George Keishinge635ddc2022-12-08 07:38:02 -060014 from robot.libraries import DateTime
Steven Sombarb6749a62017-10-06 08:34:23 -050015except ImportError:
16 robot_env = 0
17
18
George Keishinge635ddc2022-12-08 07:38:02 -060019def file_diff(file1_path,
20 file2_path,
21 diff_file_path,
22 skip_string):
Steven Sombarb6749a62017-10-06 08:34:23 -050023 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 Keishinge635ddc2022-12-08 07:38:02 -060062 if (not os.path.exists(file1_path) or (not os.path.exists(file2_path))):
Steven Sombarb6749a62017-10-06 08:34:23 -050063 return INPUT_FILE_DOES_NOT_EXIST
64 try:
George Keishinge635ddc2022-12-08 07:38:02 -060065 with open(file1_path, 'r') as file:
Steven Sombarb6749a62017-10-06 08:34:23 -050066 initial = file.readlines()
George Keishinge635ddc2022-12-08 07:38:02 -060067 with open(file2_path, 'r') as file:
Steven Sombarb6749a62017-10-06 08:34:23 -050068 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 Keishinge635ddc2022-12-08 07:38:02 -060082 if (initial == final):
Steven Sombarb6749a62017-10-06 08:34:23 -050083 try:
George Keishinge635ddc2022-12-08 07:38:02 -060084 file = open(diff_file_path, 'w')
Steven Sombarb6749a62017-10-06 08:34:23 -050085 except IOError:
86 file.close()
George Keishinge635ddc2022-12-08 07:38:02 -060087 line_to_print = "Specified skip (ignore) string = " + \
88 skip_string + "\n\n"
Steven Sombarb6749a62017-10-06 08:34:23 -050089 file.write(line_to_print)
George Keishinge635ddc2022-12-08 07:38:02 -060090 line_to_print = now + " found no difference between file " + \
91 file1_path + " and " + \
92 file2_path + "\n"
Steven Sombarb6749a62017-10-06 08:34:23 -050093 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 Keishinge635ddc2022-12-08 07:38:02 -060099 file = open(diff_file_path, 'w')
Steven Sombarb6749a62017-10-06 08:34:23 -0500100 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 Keishinge635ddc2022-12-08 07:38:02 -0600108 ignore_string = ' '.join([("-I " + '"' + x + '"') for x in skip_list])
109 command = ' '.join(filter(None, ["diff", ignore_string, file1_path,
110 file2_path]))
Steven Sombarb6749a62017-10-06 08:34:23 -0500111
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 Onyerikwud806cc02019-10-01 07:46:18 -0500122 print("DIFF:\n", out_buf)
Steven Sombarb6749a62017-10-06 08:34:23 -0500123
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 Mills096cd562018-03-26 10:19:12 -0500132 return FILES_DO_NOT_MATCH