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