예제 #1
0
 def post(self, fullname):
   conf = config.get_config()
   obj = logic.get_requested_object(fullname, conf)
   if isinstance(obj, logic.BadTest):
     if obj.exists:
       self.render_error('Error loading test object %s: \n%s' %
                         (fullname, obj.load_errors[0][1]), 500)
     else:
       self.render_error('Test object %s does not exist.' % fullname, 404)
     return
   conf = config.get_config()
   try:
     batch = runner.start_batch(fullname, conf)
   except DeadlineExceededError:
     self.render_error('Tests took too long to run.  Consider setting the '
                       '"storage" option in aeta.yaml to something other '
                       'than "immediate", such as "memcache".', 500)
     return
   if conf.storage == 'immediate':
     tasks = batch.get_tasks(conf)
     data = {'batch_info': batch.get_json(),
             'results': [task.get_json() for task in tasks]
            }
   else:
     data = {'batch_id': str(batch.key.id())}
   self.response.out.write(json.dumps(data))
예제 #2
0
def _run_test_unit(fullname, task_key, conf):
  """Runs a single test unit based on a RunTestUnitTask.

  The test identified by the task is run and the result is stored in the
  RunTestUnitTask.

  Args:
    fullname: The full name of the test unit to run.
    task_key: The key of the RunTestUnitTask to run.
    conf: The configuration to use.
  """
  ctx_options = models.get_ctx_options(conf)
  task = models.RunTestUnitTask(key=task_key, fullname=fullname)
  load_errors = []
  if _this_task_has_failed_before():
    # This will appear to the user as a "load error" in the test.
    msg = 'Unknown error running test %s.  See log for details.' % fullname
    load_errors.append((fullname, msg))
    try:
      task.set_test_result(load_errors, unittest.TestResult(), '', conf)
      task.put(**ctx_options)
    # pylint: disable-msg=W0703
    except:
      msg = 'Error writing message about the test %s that failed!' % fullname
      logging.exception(msg)
    return
  test = logic.get_requested_object(fullname, conf)
  suite = test.get_suite(conf, load_errors)
  # Since the test is a TestSuite, its run method will handle all the
  # administrative work involved in setUpModule, setUpClass, skipping, etc.
  result, output = _run_test_and_capture_output(suite)
  task.set_test_result(load_errors, result, output, conf)
  task.put(**ctx_options)
예제 #3
0
 def get(self, fullname):
   conf = config.get_config()
   load_errors = []
   test = logic.get_requested_object(fullname, conf)
   methods = test.get_methods(conf, load_errors)
   data = {'method_names': [method.fullname for method in methods],
           'load_errors': load_errors}
   self.response.out.write(json.dumps(data))
예제 #4
0
def _initialize_batch(fullname, batch_key, conf):
  """Initializes a TestBatch to start the tests running.

  This function creates a RunTestUnitTask for every test unit in the batch and
  starts running them in the background.

  Args:
    batch_key: The ndb.Key of the batch to initialize.
    conf: The configuration to use.
    run_immediately: If set to True, tests will be run immediately rather than
        in the task queue.  They will be finished before this function returns.
  """
  ctx_options = models.get_ctx_options(conf)
  errors_out = []
  batch = models.TestBatch(key=batch_key, fullname=fullname)
  if _this_task_has_failed_before():
    # This will appear to the user as a "load error" in the batch.
    msg = ('Unknown error initializing batch %s.  See log for details.' %
           fullname)
    errors_out.append((fullname, msg))
    try:
      batch.set_info(errors_out, {}, conf)
      batch.put(**ctx_options)
    # pylint: disable-msg=W0703
    except:
      msg = 'Error writing message about the batch %s that failed!' % fullname
      logging.exception(msg)
    return
  test = logic.get_requested_object(fullname, conf)
  test_units = test.get_units(conf, errors_out)
  test_unit_methods = {}
  tasks = []
  defer_calls = []
  for (i, unit) in enumerate(test_units):
    # Ignore loading errors for now.  _run_test_unit will detect loading errors
    # when its task is executed.
    method_names = [method.fullname for method in unit.get_methods(conf)]
    test_unit_methods[unit.fullname] = method_names
    task_key = models.RunTestUnitTask.get_key(batch_key, i)
    tasks.append(models.RunTestUnitTask(key=task_key, fullname=unit.fullname))
  batch.set_info(errors_out, test_unit_methods, conf)
  # Put batch after tasks, so that we don't see that the batch has tasks before
  # they exist.
  ndb.put_multi(tasks + [batch], **ctx_options)
  for task in tasks:
    call = deferred.DeferredCall(_run_test_unit, str(task.fullname), task.key,
                                 conf)
    if conf.storage == 'immediate':
      call.run()
    else:
      defer_calls.append(call)
  if ctx_options.get('use_datastore', True):
    defer_calls.append(deferred.DeferredCall(_delete_batch, batch.key, 0, conf,
                                             _countdown=_DELETE_TIME_SECS))
  deferred.defer_multi(defer_calls, queue=conf.test_queue)
예제 #5
0
 def get(self, fullname):
   """Default view."""
   conf = config.get_config()
   obj = logic.get_requested_object(fullname, conf)
   if isinstance(obj, logic.BadTest):
     if obj.exists:
       self.render_error('Error loading test object %s: \n%s' %
                         (fullname, obj.load_errors[0][1]), 500)
     else:
       self.render_error('Test object %s does not exist.' % fullname, 404)
     return
   # urllib.quote is necessary for things embedded in <script> tags to avoid
   # things like quotes and </script> in the string literals.
   values = {'root_name': urllib.quote(fullname),
             'rest_path': urllib.quote(conf.url_path_rest),
             'static_path': conf.url_path_static,
            }
   self.render_page(_get_template_path('index.html'), values)