def handle_scpi_file(self, filepath=SCPI_FILEPATH):
        """Checks file location for scpi script

        Description:
            Checks for a scpi file at the filepath parameter.
            This method is a wrapper for the read_scpi_file
            method, which gets called as long as a file exists
            at the filepath. This will build the G1Script that
            can be run later by calling the run_script method.
            Exceptions raised by the read_scpi_file method are
            logged here.

        Parameters:
            filepath: the location to check with os.path.exists
                to see if a scpi file exists.

        Returns:
            None. This command does not return a value
        """
        if not os.path.exists(filepath):
            logger.error("No SCPI file at {}".format(filepath))
            return

        self.script = None
        try:
            self.script = self.read_scpi_file(filepath)
        except IOError as e:
            logger.warning(e)
        except OSError as e:
            logger.warning(e)
        except Exception as e:
            logger.error("Unexpected error: {}".format(e), exc_info=True)
Exemple #2
0
    def get_default_headers(self, refresh=False):
        """Gets the headers for a request

        Summary:
            Assigns the auth token to the Auth-Token header.
            If a refresh is needed, a request is made with the
            refresh token and the auth token is updated.

        Paramters:
            refresh: a boolean to trigger refreshes

        Returns:
            a dictionary with the Auth-Token header

        """
        if refresh and 'REFRESH_TOKEN' in COMMON_SETTINGS:
            url = BASE_URL + '/profile/auth_token/refresh'
            headers = {'Refresh-Token': COMMON_SETTINGS['REFRESH_TOKEN']}
            try:
                response = requests.get(url, headers=headers)
                assert response.status_code == 200
            except Exception:
                logger.warning("Unable to get refresh token", exc_info=True)
            data = json.loads(response.text)
            try:
                self.auth_token = data['new auth token']
            except KeyError:
                logger.warning("No new auth token in response")
        headers = {
            'Auth-Token': self.auth_token,
            'Content-Type': 'application/json',
            'Accept': 'text/plain',
        }
        return headers
Exemple #3
0
    def _set_divisions(self, h_divs=0, v_divs=0):
        """Checks the instrument for divisions

        If the instrument does not have them then default values
        are used. If vertical and horizontal divisions are passed
        in as parameters then those will take priority in setting
        the class attributes.
        """
        DEFAULT_HORIZONTAL_DIVS = 10
        DEFAULT_VERTICAL_DIVS = 8
        if self.instr and self.instr._horizontal_divisions:
            self._horizontal_divisions = self.instr._horizontal_divisions
        else:
            self._horizontal_divisions = DEFAULT_HORIZONTAL_DIVS
        if self.instr and self.instr._vertical_divisions:
            self._vertical_divisions = self.instr._vertical_divisions
        else:
            self._vertical_divisions = DEFAULT_VERTICAL_DIVS
        if h_divs:
            self._horizontal_divisions = h_divs
        if v_divs:
            self._vertical_divisions = v_divs
        if not isinstance(self.trace_dict, dict):
            print(self.trace_dict)
            logger.warning("trace data not properly initialized")
            self.trace_dict = {}
        self.trace_dict['h_divs'] = self._horizontal_divisions
        self.trace_dict['v_divs'] = self._vertical_divisions
 def write(self, file='', mode='r', content=''):
     try:
         with open(file, mode) as f:
             f.write(content)
     except IOError as e:
         # not able to read the file
         logger.warning("IOError write(): {}".format(e))
     except TypeError as e:
         # bad data in the file
         logger.warning("TypeError write(): {}".format(e))
     except Exception as e:
         logger.error("Unexpected error in write(): {}".format(e))
 def run(self):
     for command in self.commands:
         try:
             response = command.run()
         except TimeoutError:
             logger.warning("Command '{}' timed out!".format(command))
         except Exception as e:
             logger.warning("Command '{}' encountered an unexpected "
                            "exception: {};".format(command, e))
         else:
             if isinstance(response, list):
                 self.responses.extend(response)
             else:
                 self.responses.append(response)
Exemple #6
0
    def run(self):
        """Runs the Fetch Screenshot Command

        Summary:
            Fetches the screenshot and writes it to file
        """
        scn = None
        try:
            scn = self.instrument.fetch_screenshot()
        except NotInitializedException as e:
            logger.warning("instrument not initialized for screenshot")
        except IOError as e:
            logger.warning(e)
        except OSError as e:
            logger.warning(e)
        except Exception as e:
            logger.error("Unexpected error: {}".format(e), exc_info=True)
        if scn:
            response = self.save_to_file(scn)
        else:
            response = "Unable to fetch screenshot!"
            logger.warning(response)
        self.response = response
        logger.info("FetchScreenshotCommand response: {}".format(response))
        return self.response
Exemple #7
0
    def _read_trace_data(self, filepath=''):
        if not filepath:
            filepath = settings.WAVEFORM_FILE
        data = None
        with open(filepath, 'rb') as f:
            try:
                data = json.loads(f.read())
            except IOError as e:
                logger.warning(e)
            except OSError as e:
                logger.warning(e)
            except Exception as e:
                logger.error("Unexpected error: {}".format(e), exc_info=True)
        if not data:
            data = {}

        return data
Exemple #8
0
 def save_to_file(self, data, filepath=''):
     """saves data to filepath designated in settings.py"""
     if not filepath:
         filepath = settings.WAVEFORM_FILE
     response = 'No waveform saved'  # default msg until success
     try:
         with open(filepath, 'wb') as f:
             f.write(json.dumps(data))
     except IOError as e:
         logger.warning(e)
     except OSError as e:
         logger.warning(e)
     except Exception as e:
         logger.error("Unexpected error: {}".format(e), exc_info=True)
     else:
         # success!
         response = "Waveform saved to: {}".format(filepath)
     return response
Exemple #9
0
 def save_to_file(self, data, filepath=''):
     """saves data to filepath designated in settings.py"""
     if not filepath:
         filepath = SCREENSHOT_FILE
     response = 'No screenshot saved'  # default msg until success
     try:
         with open(SCREENSHOT_FILE, 'wb') as f:
             f.write((data))
     except IOError as e:
         logger.warning(e)
     except OSError as e:
         logger.warning(e)
     except Exception as e:
         logger.error("Unexpected error: {}".format(e), exc_info=True)
     else:
         # success!
         response = "Screenshot saved to: {}".format(filepath)
     return response
Exemple #10
0
 def run(self):
     for i in range(self.maxcount):
         for command in self.commands:
             try:
                 response = command.run()
             except TimeoutError:
                 response = "G1Loop: '{}' timed out!".format(command)
                 logger.warning(response)
             except Exception as e:
                 response = ("G1Loop: '{}' encountered an unexpected "
                             "exception: {};".format(command, e))
                 logger.warning(response)
             self.responses.append(response)
             if self.break_on is not None and response == self.break_on:
                 # Note: will break from the outer range() loop also
                 logger.info(
                     "Received response {}; Breaking from loop".format(
                         response))
                 return
Exemple #11
0
 def _retry_request(self, url, kind, data={}, params={}, headers={}):
     """Retries the https request with a fresh session"""
     self.session = requests.session()
     self.session.headers.update(self.get_default_headers())
     response = None
     if headers:
         # include any headers from method arg
         self.session.headers.update(headers)
     try:
         if data:
             response = self.request_dict[kind](url, data=data)
         else:
             response = self.request_dict[kind](url, params=params)
     except ssl.SSLError:
         logger.warning("SSLError on retry. Aborting request.")
     except Exception as e:
         logger.warning("The retry request encountered an unexpected "
                        "exception: {}".format(e))
         logger.debug("The retry request exception info:", exc_info=True)
     return response
Exemple #12
0
    def transmit(self, filepath, file_key='', mode='rb'):
        """transmits file to server"""
        with open(filepath, mode) as f:
            filename = os.path.basename(f.name)
        if not file_key:
            file_key = filename
        fields = {
            'file': (filename, open(filepath, mode)),
            'file_key': file_key,
            'category': self.category,
        }
        multipartblob = MultipartEncoder(fields=fields)

        # get the temporary upload url to post the file to
        resp = self.requester.https_get(BASE_URL + "/upload/geturl")
        if not resp:
            logger.warning("No response from {}. Aborting upload.".format(
                BASE_URL + "/upload/geturl"))
            return

        headers = {'Content-Type': multipartblob.content_type}
        response = None
        try:
            response = requests.post(resp.text,
                                     data=multipartblob,
                                     headers=headers)
        except TypeError:
            logger.warning("TypeError during transmit_file call",
                           exc_info=True)
        except ssl.SSLError:
            logger.warning("SSLError! during transmit_file", exc_info=True)
        self._log_upload_response(response)
        return response
Exemple #13
0
    def run(self):
        """Posts the screenshot file to the server

        Summary:
            Transmits the screenshot file with a file_key to
            look up the file at a later date. The file_key
            is set with date and time to the second, e.g.
                "screenshot-2019-08-14T15:50:43"
            If this was successful a result_id is generated
            and will be logged.
        """
        transmitter = FileTransmitter(category='fetch_screenshot')
        dt_str = datetime.datetime.now().isoformat()
        file_key = 'screenshot-' + dt_str.split(',')[0]
        logger.info("Using file_key: " + file_key)
        response = transmitter.transmit(SCREENSHOT_FILE, file_key=file_key)
        result_id = self._handle_response(response)
        if result_id:
            logger.info("Result ID for screenshot: {}".format(result_id))
            rid_url = BASE_URL + '/results/{}'.format(result_id)
            logger.info("You can view the result at: {}".format(rid_url))
        else:
            logger.warning("No Result ID from waveform upload")
    def _parse_command_string(self, cmdstr):
        """Parses the commands string and adds it to the G1Script

        Summary:
            Either initializes the instrument or handles a scpi
            command. Handling a scpi command will instantiate a
            SCPICommand object to use for controlling the instrument.

        Returns:
            None
        """
        cmdcaps = cmdstr.upper()
        if cmdcaps.startswith('G1:OPEN') or cmdcaps.startswith('TCPIP'):
            try:
                self.instrument = self._open_instrument(cmdstr)
            except InstrumentConnectionError:
                logger.warning("Encountered InstrumentConnectionError when "
                               "attempting to open with '{}'".format(cmdstr))
                logger.warning("Exiting...")
                sys.exit()
        elif cmdcaps.startswith('G1:STARTLOOP') or cmdcaps == 'G1:ENDLOOP':
            self._parse_loop_cmd(cmdstr)
        else:
            self._parse_basic_cmd(cmdstr)
Exemple #15
0
 def _log_http_err_response(self, response, data={}, params={}):
     logger.warning("response.text %s" % response.text)
     logger.warning("request headers %s" % self.session.headers)
     logger.warning("more request details in debug level")
     if data:
         msg = "request data %s" % data
     elif params:
         msg = "request params %s" % params
     if len(msg) > 500:
         msg = msg[0:500] + "..."
     logger.debug(msg)
Exemple #16
0
 def _log_upload_response(self, response):
     if response and response.status_code == 200:
         logger.info("File upload succeeded!")
     else:
         logger.warning("File upload failed")
         response_text = None
         if hasattr(response, 'text'):
             response_text = response.text
         if not response_text:
             logger.warning("No response text to log")
         else:
             logger.warning("Non 200 response {}".format(response_text))
Exemple #17
0
    def https_request(self, url, data={}, params={}, headers={},
                      kind='get'):
        """Makes https requests

        Summary:
            Tries to make a https request and logs exceptions.
            Will retry the

        Parameters:
            url: the target url
            data: a dictionary payload for POST or PUT requests
            params: a dictionary of params for GET or DEL requests
            headers: request headers, these will update the base
                headers that are already assigned by get_default_headers
            kind: the flavor of the request (GET, POST, etc.)

        Returs:
            a requests module response object
        """
        hdrs = self.get_default_headers()
        hdrs.update(headers)

        response = None
        try:
            if data:
                response = self.request_dict[kind](url, data=data, headers=hdrs)
            else:
                response = self.request_dict[kind](url, params=params, headers=hdrs)
        except ssl.SSLError:
            logger.warning("SSLError!", exc_info=True)
            logger.info("Retrying request to {}".format(url))
            response = self._retry_request(url, kind, data, params, headers)
        except Exception as e:
            logger.warning("Unexpected request exc: {}".format(e))
            logger.debug("The request exception info:", exc_info=True)

        if not response:
            logger.warning("No response from {}".format(url))
        elif response.status_code in [401, 403]:
            # refresh headers and try again
            hdrs = self.get_default_headers(refresh=True)
            self.session.headers.update(hdrs)
            response = self._retry_request(url, kind, data, params,
                                           headers)
        elif response.status_code != 200:
            self._log_http_err_response(response, data, params)

        # reset the headers to default
        self.session.headers = self.get_default_headers()
        return response
Exemple #18
0
    def _create_waveform_result(self):
        """Creates a waveform result on the server"""
        dt_str = datetime.datetime.now().isoformat()
        waveform_id = 'waveform-' + dt_str.split(',')[0]
        if 'instrument_type' in self.trace_dict:
            instrument_type = self.trace_dict.pop('instrument_type')
        else:
            instrument_type = 'sample_instrument_type'
        data = {
            'command_id': waveform_id,
            'config_name': waveform_id,
            'instrument_type': instrument_type,
            'kind': 'Result_Summary',
            'upload_kind': 'Waveform',
            'info': {},
            'waveform': self.trace_dict,
        }

        # assuming these are set in settings them
        # data['instrument_type'] = settings.INSTRUMENT_TYPE,
        # data['device_under_test'] = settings.DUT

        r_url = BASE_URL + '/results'
        json_data = json.dumps(data, ensure_ascii=True)
        response = self.requester.https_post(r_url, data=json_data)
        result_id = ''
        if not response:
            return

        logger.info("Request to {} response.status_code: {}".format(
            r_url, response.status_code))
        try:
            result_id = json.loads(response.text)['result']['id']
        except ValueError:
            logger.warning("ValueError in _create_waveform_results")
            logger.info("response text: {}".format(response.text))
        except KeyError:
            logger.warning("KeyError in _create_waveform_results")
        except Exception as e:
            logger.warning("Unexpected error: {}".format(e), exc_info=True)
        else:
            logger.info(
                "Result created successfully with result_id: {}".format(
                    result_id))
            rid_url = r_url + '/{}'.format(result_id)
            logger.info("You can view the result at: {}".format(rid_url))
        self.trace_dict['result_id'] = result_id
        return result_id
 def _handle_socket_err(self, err):
     logger.warning("Socket Error: {}".format(err))