| George Keishing | e7e9171 | 2021-09-03 11:28:44 -0500 | [diff] [blame] | 1 | #!/usr/bin/env python3 | 
| George Keishing | 04d9345 | 2017-05-03 09:14:15 -0500 | [diff] [blame] | 2 |  | 
|  | 3 | r""" | 
|  | 4 | This module contains keyword functions to supplement robot's built in | 
|  | 5 | functions and use in test where generic robot keywords don't support. | 
| George Keishing | 04d9345 | 2017-05-03 09:14:15 -0500 | [diff] [blame] | 6 | """ | 
| Steven Sombar | 130a04f | 2017-07-16 10:02:37 -0500 | [diff] [blame] | 7 |  | 
|  | 8 | try: | 
| George Keishing | e635ddc | 2022-12-08 07:38:02 -0600 | [diff] [blame] | 9 | from robot.libraries import DateTime | 
| Patrick Williams | 20f3871 | 2022-12-08 06:18:26 -0600 | [diff] [blame] | 10 | from robot.libraries.BuiltIn import BuiltIn | 
| Steven Sombar | 130a04f | 2017-07-16 10:02:37 -0500 | [diff] [blame] | 11 | except ImportError: | 
|  | 12 | pass | 
| George Keishing | e16f158 | 2022-12-15 07:32:21 -0600 | [diff] [blame] | 13 | import re | 
| Patrick Williams | 20f3871 | 2022-12-08 06:18:26 -0600 | [diff] [blame] | 14 | import time | 
| Steven Sombar | 130a04f | 2017-07-16 10:02:37 -0500 | [diff] [blame] | 15 |  | 
|  | 16 |  | 
| Patrick Williams | 20f3871 | 2022-12-08 06:18:26 -0600 | [diff] [blame] | 17 | def run_until_keyword_fails(retry, retry_interval, name, *args): | 
| George Keishing | 04d9345 | 2017-05-03 09:14:15 -0500 | [diff] [blame] | 18 | r""" | 
|  | 19 | Execute a robot keyword repeatedly until it either fails or the timeout | 
|  | 20 | value is exceeded. | 
|  | 21 | Note: Opposite of robot keyword "Wait Until Keyword Succeeds". | 
|  | 22 |  | 
|  | 23 | Description of argument(s): | 
|  | 24 | retry              Max timeout time in hour(s). | 
|  | 25 | retry_interval     Time interval in minute(s) for looping. | 
|  | 26 | name               Robot keyword to execute. | 
|  | 27 | args               Robot keyword arguments. | 
|  | 28 | """ | 
|  | 29 |  | 
|  | 30 | # Convert the retry time in seconds | 
| George Keishing | 4bbf520 | 2017-05-18 06:55:53 -0500 | [diff] [blame] | 31 | retry_seconds = DateTime.convert_time(retry) | 
| George Keishing | 04d9345 | 2017-05-03 09:14:15 -0500 | [diff] [blame] | 32 | timeout = time.time() + int(retry_seconds) | 
|  | 33 |  | 
|  | 34 | # Convert the interval time in seconds | 
| George Keishing | 4bbf520 | 2017-05-18 06:55:53 -0500 | [diff] [blame] | 35 | interval_seconds = DateTime.convert_time(retry_interval) | 
| George Keishing | 04d9345 | 2017-05-03 09:14:15 -0500 | [diff] [blame] | 36 | interval = int(interval_seconds) | 
|  | 37 |  | 
|  | 38 | BuiltIn().log(timeout) | 
|  | 39 | BuiltIn().log(interval) | 
|  | 40 |  | 
|  | 41 | while True: | 
| George Keishing | 4bbf520 | 2017-05-18 06:55:53 -0500 | [diff] [blame] | 42 | status = BuiltIn().run_keyword_and_return_status(name, *args) | 
| George Keishing | 04d9345 | 2017-05-03 09:14:15 -0500 | [diff] [blame] | 43 |  | 
|  | 44 | # Return if keywords returns as failure. | 
| George Keishing | 4bbf520 | 2017-05-18 06:55:53 -0500 | [diff] [blame] | 45 | if status is False: | 
| George Keishing | 04d9345 | 2017-05-03 09:14:15 -0500 | [diff] [blame] | 46 | BuiltIn().log("Failed as expected") | 
| George Keishing | 4bbf520 | 2017-05-18 06:55:53 -0500 | [diff] [blame] | 47 | return False | 
| George Keishing | 04d9345 | 2017-05-03 09:14:15 -0500 | [diff] [blame] | 48 | # Return if retry timeout as success. | 
|  | 49 | elif time.time() > timeout > 0: | 
|  | 50 | BuiltIn().log("Max retry timeout") | 
| George Keishing | 4bbf520 | 2017-05-18 06:55:53 -0500 | [diff] [blame] | 51 | return True | 
| George Keishing | 04d9345 | 2017-05-03 09:14:15 -0500 | [diff] [blame] | 52 | time.sleep(interval) | 
|  | 53 | BuiltIn().log(time.time()) | 
|  | 54 |  | 
| George Keishing | 4bbf520 | 2017-05-18 06:55:53 -0500 | [diff] [blame] | 55 | return True | 
| George Keishing | 4bbf520 | 2017-05-18 06:55:53 -0500 | [diff] [blame] | 56 |  | 
|  | 57 |  | 
| George Keishing | 4bbf520 | 2017-05-18 06:55:53 -0500 | [diff] [blame] | 58 | def htx_error_log_to_list(htx_error_log_output): | 
| George Keishing | 4bbf520 | 2017-05-18 06:55:53 -0500 | [diff] [blame] | 59 | r""" | 
|  | 60 | Parse htx error log output string and return list of strings in the form | 
|  | 61 | "<field name>:<field value>". | 
|  | 62 | The output of this function may be passed to the build_error_dict function. | 
|  | 63 |  | 
|  | 64 | Description of argument(s): | 
|  | 65 | htx_error_log_output        Error entry string containing the stdout | 
|  | 66 | generated by "htxcmdline -geterrlog". | 
|  | 67 |  | 
|  | 68 | Example of htx_error_log_output contents: | 
|  | 69 |  | 
|  | 70 | ######################## Result Starts Here ############################### | 
|  | 71 | Currently running ECG/MDT : /usr/lpp/htx/mdt/mdt.whit | 
|  | 72 | =========================== | 
|  | 73 | --------------------------------------------------------------------- | 
|  | 74 | Device id:/dev/nvidia0 | 
|  | 75 | Timestamp:Mar 29 19:41:54 2017 | 
|  | 76 | err=00000027 | 
|  | 77 | sev=1 | 
|  | 78 | Exerciser Name:hxenvidia | 
|  | 79 | Serial No:Not Available | 
|  | 80 | Part No:Not Available | 
|  | 81 | Location:Not Available | 
|  | 82 | FRU Number:Not Available | 
|  | 83 | Device:Not Available | 
|  | 84 | Error Text:cudaEventSynchronize for stopEvent returned err = 0039 from file | 
|  | 85 | , line 430. | 
|  | 86 | --------------------------------------------------------------------- | 
|  | 87 | --------------------------------------------------------------------- | 
|  | 88 | Device id:/dev/nvidia0 | 
|  | 89 | Timestamp:Mar 29 19:41:54 2017 | 
|  | 90 | err=00000027 | 
|  | 91 | sev=1 | 
|  | 92 | Exerciser Name:hxenvidia | 
|  | 93 | Serial No:Not Available | 
|  | 94 | Part No:Not Available | 
|  | 95 | Location:Not Available | 
|  | 96 | FRU Number:Not Available | 
|  | 97 | Device:Not Available | 
|  | 98 | Error Text:Hardware Exerciser stopped on error | 
|  | 99 | --------------------------------------------------------------------- | 
|  | 100 | ######################### Result Ends Here ################################ | 
|  | 101 |  | 
|  | 102 | Example output: | 
|  | 103 | Returns the lists of error string per entry | 
|  | 104 | ['Device id:/dev/nvidia0', | 
|  | 105 | 'Timestamp:Mar 29 19:41:54 2017', | 
|  | 106 | 'err=00000027', | 
|  | 107 | 'sev=1', | 
|  | 108 | 'Exerciser Name:hxenvidia', | 
|  | 109 | 'Serial No:Not Available', | 
|  | 110 | 'Part No:Not Available', | 
|  | 111 | 'Location:Not Available', | 
|  | 112 | 'FRU Number:Not Available', | 
|  | 113 | 'Device:Not Available', | 
|  | 114 | 'Error Text:cudaEventSynchronize for stopEvent returned err = 0039 | 
|  | 115 | from file , line 430.'] | 
|  | 116 | """ | 
|  | 117 |  | 
|  | 118 | # List which will hold all the list of entries. | 
|  | 119 | error_list = [] | 
|  | 120 |  | 
|  | 121 | temp_error_list = [] | 
|  | 122 | parse_walk = False | 
|  | 123 |  | 
|  | 124 | for line in htx_error_log_output.splitlines(): | 
|  | 125 | # Skip lines starting with "#" | 
|  | 126 | if line.startswith("#"): | 
|  | 127 | continue | 
|  | 128 |  | 
|  | 129 | # Mark line starting with "-" and set parse flag. | 
|  | 130 | if line.startswith("-") and parse_walk is False: | 
|  | 131 | parse_walk = True | 
|  | 132 | continue | 
|  | 133 | # Mark line starting with "-" and reset parse flag. | 
|  | 134 | # Set temp error list to EMPTY. | 
|  | 135 | elif line.startswith("-"): | 
|  | 136 | error_list.append(temp_error_list) | 
|  | 137 | parse_walk = False | 
|  | 138 | temp_error_list = [] | 
| Gunnar Mills | 917ba1a | 2018-04-08 16:42:12 -0500 | [diff] [blame] | 139 | # Add entry to list if line is not empty | 
| George Keishing | 4bbf520 | 2017-05-18 06:55:53 -0500 | [diff] [blame] | 140 | elif parse_walk: | 
|  | 141 | temp_error_list.append(str(line)) | 
|  | 142 |  | 
|  | 143 | return error_list | 
| George Keishing | 4bbf520 | 2017-05-18 06:55:53 -0500 | [diff] [blame] | 144 |  | 
|  | 145 |  | 
| George Keishing | 4bbf520 | 2017-05-18 06:55:53 -0500 | [diff] [blame] | 146 | def build_error_dict(htx_error_log_output): | 
| George Keishing | 4bbf520 | 2017-05-18 06:55:53 -0500 | [diff] [blame] | 147 | r""" | 
|  | 148 | Builds error list into a list of dictionary entries. | 
|  | 149 |  | 
|  | 150 | Description of argument(s): | 
|  | 151 | error_list        Error list entries. | 
|  | 152 |  | 
|  | 153 | Example output dictionary: | 
|  | 154 | { | 
|  | 155 | 0: | 
|  | 156 | { | 
|  | 157 | 'sev': '1', | 
|  | 158 | 'err': '00000027', | 
|  | 159 | 'Timestamp': 'Mar 29 19:41:54 2017', | 
|  | 160 | 'Part No': 'Not Available', | 
|  | 161 | 'Serial No': 'Not Available', | 
|  | 162 | 'Device': 'Not Available', | 
|  | 163 | 'FRU Number': 'Not Available', | 
|  | 164 | 'Location': 'Not Available', | 
|  | 165 | 'Device id': '/dev/nvidia0', | 
|  | 166 | 'Error Text': 'cudaEventSynchronize for stopEvent returned err = 0039 | 
|  | 167 | from file , line 430.', | 
|  | 168 | 'Exerciser Name': 'hxenvidia' | 
|  | 169 | }, | 
|  | 170 | 1: | 
|  | 171 | { | 
|  | 172 | 'sev': '1', | 
|  | 173 | 'err': '00000027', | 
|  | 174 | 'Timestamp': 'Mar 29 19:41:54 2017', | 
|  | 175 | 'Part No': 'Not Available', | 
|  | 176 | 'Serial No': 'Not Available', | 
|  | 177 | 'Device': 'Not Available', | 
|  | 178 | 'FRU Number': 'Not Available', | 
|  | 179 | 'Location': 'Not Available', | 
|  | 180 | 'Device id': '/dev/nvidia0', | 
|  | 181 | 'Error Text': 'Hardware Exerciser stopped on error', | 
|  | 182 | 'Exerciser Name': 'hxenvidia' | 
|  | 183 | } | 
|  | 184 | }, | 
|  | 185 |  | 
|  | 186 | """ | 
|  | 187 |  | 
|  | 188 | # List which will hold all the list of entries. | 
|  | 189 | error_list = [] | 
|  | 190 | error_list = htx_error_log_to_list(htx_error_log_output) | 
|  | 191 |  | 
| George Keishing | e16f158 | 2022-12-15 07:32:21 -0600 | [diff] [blame] | 192 | # dictionary which holds the error dictionary entry. | 
| George Keishing | 4bbf520 | 2017-05-18 06:55:53 -0500 | [diff] [blame] | 193 | error_dict = {} | 
|  | 194 |  | 
|  | 195 | temp_error_dict = {} | 
|  | 196 | error_index = 0 | 
|  | 197 |  | 
|  | 198 | # Loop through the error list. | 
|  | 199 | for entry_list in error_list: | 
|  | 200 | # Loop through the first error list entry. | 
|  | 201 | for entry in entry_list: | 
|  | 202 | # Split string into list for key value update. | 
|  | 203 | # Example: 'Device id:/dev/nvidia0' | 
|  | 204 | # Example: 'err=00000027' | 
|  | 205 | parm_split = re.split("[:=]", entry) | 
|  | 206 | # Populate temp dictionary with key value pair data. | 
|  | 207 | temp_error_dict[str(parm_split[0])] = parm_split[1] | 
|  | 208 |  | 
|  | 209 | # Update the master dictionary per entry index. | 
|  | 210 | error_dict[error_index] = temp_error_dict | 
|  | 211 | # Reset temp dict to EMPTY and increment index count. | 
|  | 212 | temp_error_dict = {} | 
|  | 213 | error_index += 1 | 
|  | 214 |  | 
|  | 215 | return error_dict |