def got_response(self, stream, request, response): if response.code != "200": LOG.complete("bad response") self._schedule() else: LOG.complete() s = response.body.read() try: m1 = marshal.unmarshal_object(s, "application/json", compat.RendezvousResponse) except ValueError: LOG.exception() self._schedule() else: if "version" in m1.update and "uri" in m1.update: ver, uri = m1.update["version"], m1.update["uri"] LOG.info("Version %s available at %s" % (ver, uri)) STATE.update("update", {"version": ver, "uri": uri}) _open_browser_on_windows("update.html") # Update tests known by the runner runner_lst.update(m1.available) # # Choose the test we would like to run even if # we're not going to run it because we're running # in debug mode or tests are disabled. # This allows us to print to the logger the test # we /would/ have choosen if we were allowed to run # it. # test = runner_lst.get_next_test() if not test: LOG.warning("No test available") self._schedule() return LOG.info("* Chosen test: %s" % test) # Are we allowed to run a test? if not CONFIG["enabled"] or CONFIG["rendezvous.client.debug"]: LOG.info("Tests are disabled... not running") self._schedule() else: # Do we have negotiate URI for test? negotiate_uri = runner_lst.test_to_negotiate_uri(test) if not negotiate_uri: LOG.warning("No negotiate URI for test") self._schedule() else: # Actually run the test runner_core.run(test, negotiate_uri, self._schedule)
def runner_api(stream, request, query): ''' Implements /api/runner ''' response = Message() # # DO NOT allow to start a test when another test is in # progress because I have noticed that is confusing both # from # command line and WUI. # if runner_core.test_is_running(): raise ConfigError('A test is already in progress, try again later') # # If there is not a query string this API is just # a no-operation and returns an empty JSON body to # keep happy the AJAX code. # if not query: response.compose(code='200', reason='Ok', body='{}', mimetype='application/json') stream.send_response(request, response) return options = cgi.parse_qs(query) # # If the query does not contain the name of the # test, this is an error and we must notify that # to the caller. Raise ConfigError, which will # be automatically transformed into a 500 message # with the proper body and reason. # if not 'test' in options: raise ConfigError('Missing "test" option in query string') # # Extract the test name and then attempt to map it # to the related negotiate URI. If that fails, tell # the caller, using ConfigError, which will be auto- # matically transformed into a 500 message with the # proper body and reason. # test = options['test'][0] negotiate_uri = runner_lst.test_to_negotiate_uri(test) if not negotiate_uri: raise ConfigError('Cannot map test name to negotiate URI') # # Simple case: the caller does not want to follow the # test via log streaming. We can immediately start # the test using the runner and, if everything is OK, # we can send a succesful response, with an empty JSON # body to keep happy the AJAX code. # if not 'streaming' in options or not utils.intify(options['streaming'][0]): runner_core.run(test, negotiate_uri, runner_api_done) response.compose(code='200', reason='Ok', body='{}', mimetype='application/json') stream.send_response(request, response) return # # More interesting case: the caller wants to see the log # messages during the test via the log streaming API. # We prepare a succesful response terminated by EOF and # then arrange things so that every new log message will # be copied to the HTTP response. # Then we kick off the runner, and note that we do that # AFTER we setup the response for eventual runner errors # to be copied to the HTTP response. # The runner core will automatically close all attached # streams at the end of the test. # response.compose(code='200', reason='Ok', up_to_eof=True, mimetype='text/plain') stream.send_response(request, response) LOG.start_streaming(stream) runner_core.run(test, negotiate_uri, runner_api_done)