blob: 70e0887e7b5c123a6ed95ee8f3ff05573f5fe1a7 [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
Steven Sombarb6749a62017-10-06 08:34:23 -05007import os
8import re
Patrick Williams20f38712022-12-08 06:18:26 -06009import time
10
Steven Sombarb6749a62017-10-06 08:34:23 -050011from gen_cmd import cmd_fnc_u
Patrick Williams20f38712022-12-08 06:18:26 -060012
Steven Sombarb6749a62017-10-06 08:34:23 -050013robot_env = 1
14try:
George Keishinge635ddc2022-12-08 07:38:02 -060015 from robot.libraries import DateTime
Patrick Williams20f38712022-12-08 06:18:26 -060016 from robot.libraries.BuiltIn import BuiltIn
Steven Sombarb6749a62017-10-06 08:34:23 -050017except ImportError:
18 robot_env = 0
19
20
Patrick Williams20f38712022-12-08 06:18:26 -060021def file_diff(file1_path, file2_path, diff_file_path, skip_string):
Steven Sombarb6749a62017-10-06 08:34:23 -050022 r"""
23 Compare the contents of two text files. The comparison uses the Unix
24 'diff' command. Differences can be selectively ignored by use of
25 the skip_string parameter. The output of diff command is written
26 to a user-specified file and is also written (logged) to the console.
27
28 Description of arguments:
29 file1_path File containing text data.
30 file2_path Text file to compare to file1.
31 diff_file_path Text file which will contain the diff output.
32 skip_string To allow for differences which may expected or immaterial,
33 skip_string parameter is a word or a string of comma
34 separated words which specify what should be ignored.
35 For example, "size,speed". Any line containing the word
36 size or the word speed will be ignored when the diff is
37 performed. This parameter is optional.
38
39 Returns:
40 0 if both files contain the same information or they differ only in
41 items specified by the skip_string.
42 2 if FILES_DO_NOT_MATCH.
43 3 if INPUT_FILE_DOES_NOT_EXIST.
44 4 if IO_EXCEPTION_READING_FILE.
45 5 if IO_EXCEPTION_WRITING_FILE.
46 6 if INPUT_FILE_MALFORMED
47 """
48
49 FILES_MATCH = 0
50 FILES_DO_NOT_MATCH = 2
51 INPUT_FILE_DOES_NOT_EXIST = 3
52 IO_EXCEPTION_READING_FILE = 4
53 IO_EXCEPTION_WRITING_FILE = 5
54 INPUT_FILE_MALFORMED = 6
55
56 # The minimum size in bytes a file must be.
57 min_file_byte_size = 1
58
59 now = time.strftime("%Y-%m-%d %H:%M:%S")
60
Patrick Williams20f38712022-12-08 06:18:26 -060061 if not os.path.exists(file1_path) or (not os.path.exists(file2_path)):
Steven Sombarb6749a62017-10-06 08:34:23 -050062 return INPUT_FILE_DOES_NOT_EXIST
63 try:
Patrick Williams20f38712022-12-08 06:18:26 -060064 with open(file1_path, "r") as file:
Steven Sombarb6749a62017-10-06 08:34:23 -050065 initial = file.readlines()
Patrick Williams20f38712022-12-08 06:18:26 -060066 with open(file2_path, "r") as file:
Steven Sombarb6749a62017-10-06 08:34:23 -050067 final = file.readlines()
68 except IOError:
69 file.close()
70 return IO_EXCEPTION_READING_FILE
71 except ValueError:
72 file.close()
73 return INPUT_FILE_MALFORMED
74 else:
75 file.close()
76
77 # Must have more than a trivial number of bytes.
78 if len(initial) < min_file_byte_size:
79 return INPUT_FILE_MALFORMED
80
Patrick Williams20f38712022-12-08 06:18:26 -060081 if initial == final:
Steven Sombarb6749a62017-10-06 08:34:23 -050082 try:
Patrick Williams20f38712022-12-08 06:18:26 -060083 file = open(diff_file_path, "w")
Steven Sombarb6749a62017-10-06 08:34:23 -050084 except IOError:
85 file.close()
Patrick Williams20f38712022-12-08 06:18:26 -060086 line_to_print = (
87 "Specified skip (ignore) string = " + skip_string + "\n\n"
88 )
Steven Sombarb6749a62017-10-06 08:34:23 -050089 file.write(line_to_print)
Patrick Williams20f38712022-12-08 06:18:26 -060090 line_to_print = (
91 now
92 + " found no difference between file "
93 + file1_path
94 + " and "
95 + file2_path
96 + "\n"
97 )
Steven Sombarb6749a62017-10-06 08:34:23 -050098 file.write(line_to_print)
99 file.close()
100 return FILES_MATCH
101
102 # Find the differences and write difference report to diff_file_path file
103 try:
Patrick Williams20f38712022-12-08 06:18:26 -0600104 file = open(diff_file_path, "w")
Steven Sombarb6749a62017-10-06 08:34:23 -0500105 except IOError:
106 file.close()
107 return IO_EXCEPTION_WRITING_FILE
108
109 # Form a UNIX diff command and its parameters as a string. For example,
110 # if skip_string="size,capacity", command = 'diff -I "size"
111 # -I "capacity" file1_path file2_path'.
112 skip_list = filter(None, re.split(r"[ ]*,[ ]*", skip_string))
Patrick Williams20f38712022-12-08 06:18:26 -0600113 ignore_string = " ".join([("-I " + '"' + x + '"') for x in skip_list])
114 command = " ".join(
115 filter(None, ["diff", ignore_string, file1_path, file2_path])
116 )
Steven Sombarb6749a62017-10-06 08:34:23 -0500117
118 line_to_print = now + " " + command + "\n"
119 file.write(line_to_print)
120
121 # Run the command and get the differences
122 rc, out_buf = cmd_fnc_u(command, quiet=0, print_output=0, show_err=0)
123
124 # Write the differences to the specified diff_file and console.
125 if robot_env == 1:
126 BuiltIn().log_to_console("DIFF:\n" + out_buf)
127 else:
Joy Onyerikwud806cc02019-10-01 07:46:18 -0500128 print("DIFF:\n", out_buf)
Steven Sombarb6749a62017-10-06 08:34:23 -0500129
130 file.write(out_buf)
131 file.close()
132
133 if rc == 0:
134 # Any differences found were on the skip_string.
135 return FILES_MATCH
136 else:
137 # We have at least one difference not in the skip_string.
Gunnar Mills096cd562018-03-26 10:19:12 -0500138 return FILES_DO_NOT_MATCH