def start_tests(request): ts = get_object_or_404(TestSuite, slug=request.POST.get('name', None)) url = request.POST.get('url') or ts.default_url token_is_valid = False if request.POST.get('token', None): if Token.is_valid(request.POST['token'], ts): token_is_valid = True if not token_is_valid: raise InvalidToken('Invalid or expired token sent to start_tests. ' 'Contact an administrator.') work.views.collect_garbage() # TODO(kumar) don't start a test suite if it's already running. test = TestRun(test_suite=ts, url=url) test.save() workers = [] qs = Worker.objects.filter(is_alive=True) browsers = request.POST.get('browsers', None) if not browsers: raise ValueError("No browsers were specified in GET request") for worker in get_workers(qs, browsers): # TODO(kumar) add options to ignore workers for # unwanted browsers perhaps? worker.run_test(test) workers.append(worker) return {'test_run_id': test.id, 'workers': [{'worker_id': w.id, 'user_agent': w.user_agent} for w in workers]}
def test_start_tests_with_no_workers(self): ts = create_ts() token = Token.create(ts) r = self.client.post(reverse('system.start_tests'), data={'browsers': 'firefox', 'token': token, 'name': ts.slug}) eq_(r.status_code, 500) data = json.loads(r.content) eq_(data['error'], True) eq_(data['message'], "No workers for u'firefox' are connected")
def test_start_tests_with_correct_token(self): ts = create_ts() worker = create_worker() token = Token.create(ts) r = self.client.post(reverse('system.start_tests'), data={'browsers': 'firefox', 'token': token, 'name': ts.slug}) eq_(r.status_code, 200) data = json.loads(r.content) assert 'test_run_id' in data, ('Unexpected: %s' % data)
def test_user_string_truncation(self): user_agent = ('Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) ' 'AppleWebKit/535.1 (KHTML, like Gecko) ' 'Chrome/13.0.782.215 Safari/535.1') worker = Worker() worker.save() ts = self.suite() token = Token.create(ts) # This was raising a MySQL error r = self.client.post(reverse('work.query'), dict(worker_id=worker.id, user_agent=user_agent)) eq_(r.status_code, 200)
def test_start_tests_with_no_workers(self): ts = create_ts() token = Token.create(ts) r = self.client.post(reverse('system.start_tests'), data={ 'browsers': 'firefox', 'token': token, 'name': ts.slug }) eq_(r.status_code, 500) data = json.loads(r.content) eq_(data['error'], True) eq_(data['message'], "No workers for u'firefox' are connected")
def test_start_tests_with_wrong_token(self): ts = create_ts('one') other_ts = create_ts('two') token = Token.create(other_ts) r = self.client.post(reverse('system.start_tests'), data={'browsers': 'firefox', 'token': token, 'name': ts.slug}) eq_(r.status_code, 500) data = json.loads(r.content) eq_(data['error'], True) eq_(data['message'], 'Invalid or expired token sent to start_tests. ' 'Contact an administrator.')
def test_start_tests_with_correct_token(self): ts = create_ts() worker = create_worker() token = Token.create(ts) r = self.client.post(reverse('system.start_tests'), data={ 'browsers': 'firefox', 'token': token, 'name': ts.slug }) eq_(r.status_code, 200) data = json.loads(r.content) assert 'test_run_id' in data, ('Unexpected: %s' % data)
def test_start_tests_with_custom_url(self): ts = create_ts() token = Token.create(ts) fx_worker = create_worker( user_agent='Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; ' 'rv:2.0b10) Gecko/20100101 Firefox/4.0b10') custom_url = 'http://custom.com/qunit' r = self.client.post(reverse('system.start_tests'), data={'browsers': 'firefox=~*', 'token': token, 'name': ts.slug, 'url': custom_url}) eq_(r.status_code, 200) data = json.loads(r.content) test_run_id = data['test_run_id'] test_run = TestRun.objects.get(id=test_run_id) eq_(custom_url, test_run.url)
def test_start_tests_with_partial_worker(self): ts = create_ts() token = Token.create(ts) # Be sure a worker that has not fully started up doesn't get # chosen for work: w = Worker() w.last_heartbeat = None w.is_alive = True w.save() r = self.client.post(reverse('system.start_tests'), data={'browsers': '*', 'token': token, 'name': ts.slug}) eq_(r.status_code, 500) data = json.loads(r.content) eq_(data['error'], True) eq_(data['message'], "No workers for u'*' are connected")
def test_start_tests_with_wrong_token(self): ts = create_ts('one') other_ts = create_ts('two') token = Token.create(other_ts) r = self.client.post(reverse('system.start_tests'), data={ 'browsers': 'firefox', 'token': token, 'name': ts.slug }) eq_(r.status_code, 500) data = json.loads(r.content) eq_(data['error'], True) eq_( data['message'], 'Invalid or expired token sent to start_tests. ' 'Contact an administrator.')
def setUp(self): user_agent = ('Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; ' 'en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12') worker = Worker.objects.create() worker.parse_user_agent(user_agent) worker.save() ts = TestSuite(name='Zamboni', slug='zamboni', url='http://server/qunit1.html') ts.save() token = Token.create(ts) r = self.client.post(reverse('system.start_tests'), data={'browsers': 'firefox', 'token': token, 'name': ts.slug}) eq_(r.status_code, 200) r = self.client.post(reverse('work.query'), dict(worker_id=worker.id, user_agent=user_agent)) eq_(r.status_code, 200) data = json.loads(r.content) self.work_queue_id = data['work_queue_id']
def test_start_tests_with_custom_url(self): ts = create_ts() token = Token.create(ts) fx_worker = create_worker( user_agent='Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; ' 'rv:2.0b10) Gecko/20100101 Firefox/4.0b10') custom_url = 'http://custom.com/qunit' r = self.client.post(reverse('system.start_tests'), data={ 'browsers': 'firefox=~*', 'token': token, 'name': ts.slug, 'url': custom_url }) eq_(r.status_code, 200) data = json.loads(r.content) test_run_id = data['test_run_id'] test_run = TestRun.objects.get(id=test_run_id) eq_(custom_url, test_run.url)
def setUp(self): user_agent = ('Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; ' 'en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12') worker = Worker.objects.create() worker.parse_user_agent(user_agent) worker.save() ts = TestSuite(name='Zamboni', slug='zamboni', default_url='http://server/qunit1.html') ts.save() token = Token.create(ts) r = self.client.post(reverse('system.start_tests'), data={'browsers': 'firefox', 'token': token, 'name': ts.slug}) eq_(r.status_code, 200) r = self.client.post(reverse('work.query'), dict(worker_id=worker.id, user_agent=user_agent)) eq_(r.status_code, 200) data = json.loads(r.content) self.work_queue_id = data['work_queue_id']
def test_start_tests_with_partial_worker(self): ts = create_ts() token = Token.create(ts) # Be sure a worker that has not fully started up doesn't get # chosen for work: w = Worker() w.last_heartbeat = None w.is_alive = True w.save() r = self.client.post(reverse('system.start_tests'), data={ 'browsers': '*', 'token': token, 'name': ts.slug }) eq_(r.status_code, 500) data = json.loads(r.content) eq_(data['error'], True) eq_(data['message'], "No workers for u'*' are connected")
def test_start_specific_worker(self): ts = create_ts() token = Token.create(ts) fx_worker = create_worker( user_agent='Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; ' 'rv:2.0b10) Gecko/20100101 Firefox/4.0b10') ch_worker = create_worker( user_agent='Mozilla/5.0 (Windows; U; Windows NT 5.2; ' 'en-US) AppleWebKit/534.17 (KHTML, like Gecko)' ' Chrome/11.0.652.0 Safari/534.17') r = self.client.post(reverse('system.start_tests'), data={'browsers': 'firefox=~*', 'token': token, 'name': ts.slug}) eq_(r.status_code, 200) data = json.loads(r.content) data = self.query(ch_worker) eq_(data, {u'desc': u'No commands from server.'}) data = self.query(fx_worker) eq_(data['cmd'], 'run_test')
def test_start_specific_worker(self): ts = create_ts() token = Token.create(ts) fx_worker = create_worker( user_agent='Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; ' 'rv:2.0b10) Gecko/20100101 Firefox/4.0b10') ch_worker = create_worker( user_agent='Mozilla/5.0 (Windows; U; Windows NT 5.2; ' 'en-US) AppleWebKit/534.17 (KHTML, like Gecko)' ' Chrome/11.0.652.0 Safari/534.17') r = self.client.post(reverse('system.start_tests'), data={ 'browsers': 'firefox=~*', 'token': token, 'name': ts.slug }) eq_(r.status_code, 200) data = json.loads(r.content) data = self.query(ch_worker) eq_(data, {u'desc': u'No commands from server.'}) data = self.query(fx_worker) eq_(data['cmd'], 'run_test')
def test_work(self): user_agent = ('Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; ' 'en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12') worker = Worker() worker.save() ts = TestSuite(name='Zamboni', slug='zamboni', url='http://server/qunit1.html') ts.save() token = Token.create(ts) # No work to fetch. r = self.client.post(reverse('work.query'), dict(worker_id=worker.id, user_agent=user_agent)) eq_(r.status_code, 200) data = json.loads(r.content) eq_(data['desc'], 'No commands from server.') # Simulate Hudson requesting a job: r = self.client.post(reverse('system.start_tests'), data={'browsers': 'firefox', 'token': token, 'name': ts.slug}) eq_(r.status_code, 200) # Do work r = self.client.post(reverse('work.query'), dict(worker_id=worker.id, user_agent=user_agent)) eq_(r.status_code, 200) data = json.loads(r.content) eq_(data['cmd'], 'run_test') eq_(data['args'][0]['url'], ts.url) eq_(data['args'][0]['name'], ts.name) work_queue_id = data['args'][0]['work_queue_id'] queue = WorkQueue.objects.get(pk=work_queue_id) eq_(queue.worker.id, worker.id) eq_(queue.finished, False) eq_(queue.results, None) eq_(queue.results_received, False) eq_(queue.worker.last_heartbeat.timetuple()[0:3], datetime.now().timetuple()[0:3]) eq_(queue.worker.user_agent, user_agent) eq_(sorted([(e.engine, e.version) for e in queue.worker.engines.all()]), sorted(parse_useragent(user_agent))) results = { 'failures': 0, 'total': 1, 'tests': [{'test': 'foo', 'message': '1 equals 2', 'module': 'some module', 'result': True}] } r = self.client.post(reverse('work.submit_results'), dict(work_queue_id=queue.id, results=json.dumps(results))) eq_(r.status_code, 200) data = json.loads(r.content) eq_(data['desc'], 'Test result received') # Refresh from db... queue = WorkQueue.objects.get(pk=queue.id) eq_(queue.finished, True) eq_(queue.results, json.dumps(results)) eq_(queue.results_received, False) # Cannot fetch more work. r = self.client.post(reverse('work.query'), dict(worker_id=worker.id, user_agent=user_agent)) eq_(r.status_code, 200) data = json.loads(r.content) eq_(data['desc'], 'No commands from server.')
def generate_token(request): ts = get_object_or_404(TestSuite, pk=request.POST['test_suite_id']) Token.create(ts) return http.HttpResponseRedirect(reverse('system.test_suites'))
def test_work(self): user_agent = ('Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; ' 'en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12') worker = Worker() worker.save() ts = self.suite() token = Token.create(ts) # No work to fetch. r = self.client.post(reverse('work.query'), dict(worker_id=worker.id, user_agent=user_agent)) eq_(r.status_code, 200) data = json.loads(r.content) eq_(data['desc'], 'No commands from server.') # Simulate Hudson requesting a job: r = self.client.post(reverse('system.start_tests'), data={'browsers': 'firefox', 'token': token, 'name': ts.slug}) eq_(r.status_code, 200) # Do work r = self.client.post(reverse('work.query'), dict(worker_id=worker.id, user_agent=user_agent)) eq_(r.status_code, 200) data = json.loads(r.content) eq_(data['cmd'], 'run_test') eq_(data['args'][0]['url'], ts.default_url) eq_(data['args'][0]['name'], ts.name) work_queue_id = data['args'][0]['work_queue_id'] queue = WorkQueue.objects.get(pk=work_queue_id) eq_(queue.worker.id, worker.id) eq_(queue.finished, False) eq_(queue.results, None) eq_(queue.results_received, False) eq_(queue.worker.last_heartbeat.timetuple()[0:3], datetime.now().timetuple()[0:3]) eq_(queue.worker.user_agent, user_agent) eq_(sorted([(e.engine, e.version) for e in queue.worker.engines.all()]), sorted(parse_useragent(user_agent))) results = { 'failures': 0, 'total': 1, 'tests': [{'test': 'foo', 'message': '1 equals 2', 'module': 'some module', 'result': True}] } r = self.client.post(reverse('work.submit_results'), dict(work_queue_id=queue.id, results=json.dumps(results))) eq_(r.status_code, 200) data = json.loads(r.content) eq_(data['desc'], 'Test result received') # Refresh from db... queue = WorkQueue.objects.get(pk=queue.id) eq_(queue.finished, True) eq_(queue.results, json.dumps(results)) eq_(queue.results_received, False) # Cannot fetch more work. r = self.client.post(reverse('work.query'), dict(worker_id=worker.id, user_agent=user_agent)) eq_(r.status_code, 200) data = json.loads(r.content) eq_(data['desc'], 'No commands from server.')
def test_get_job_result(self): ts = create_ts() token = Token.create(ts) worker = create_worker() r = self.client.post(reverse('system.start_tests'), data={ 'browsers': 'firefox', 'token': token, 'name': ts.slug }) eq_(r.status_code, 200) data = json.loads(r.content) test_run_id = data['test_run_id'] r = self.client.get(reverse('system.test_result', args=[test_run_id])) eq_(r.status_code, 200) data = json.loads(r.content) eq_(data['finished'], False) eq_(data['results'], []) data = self.query(worker) queue_id = data['work_queue_id'] results = { 'failures': 0, 'total': 1, 'tests': [ { 'module': 'Bar', 'test': 'foo', 'message': '1 equals 2', 'result': False }, { 'module': 'Bar', 'test': 'foo', 'message': 'ok', 'result': True }, { 'module': 'Zebo', 'test': 'zee', 'message': 'ok', 'result': True }, ] } r = self.client.post( reverse('work.submit_results'), dict(work_queue_id=queue_id, results=json.dumps(results))) eq_(r.status_code, 200) r = self.client.get(reverse('system.test_result', args=[test_run_id])) eq_(r.status_code, 200) data = json.loads(r.content) eq_(data['finished'], True) tests = sorted(data['results']) eq_(tests[0]['module'], 'Bar') eq_(tests[0]['test'], 'foo') eq_(tests[0]['assertions'], [ { 'module': 'Bar', 'test': 'foo', 'worker_id': worker.id, 'worker_user_agent': worker.user_agent, 'browser': 'firefox/3.6.12, gecko/1.9.2.12', 'message': '1 equals 2', 'result': False }, { 'module': 'Bar', 'test': 'foo', 'worker_id': worker.id, 'worker_user_agent': worker.user_agent, 'browser': 'firefox/3.6.12, gecko/1.9.2.12', 'message': 'ok', 'result': True }, ]) eq_(tests[1]['module'], 'Zebo') eq_(tests[1]['test'], 'zee') eq_(tests[1]['assertions'], [ { 'module': 'Zebo', 'test': 'zee', 'worker_id': worker.id, 'worker_user_agent': worker.user_agent, 'browser': 'firefox/3.6.12, gecko/1.9.2.12', 'message': 'ok', 'result': True }, ])
def save(self, *args, **kw): ts = super(TestSuiteForm, self).save(*args, **kw) if self.creating_test_suite: Token.create(ts) return ts
def test_get_job_result(self): ts = create_ts() token = Token.create(ts) worker = create_worker() r = self.client.post(reverse('system.start_tests'), data={'browsers': 'firefox', 'token': token, 'name': ts.slug}) eq_(r.status_code, 200) data = json.loads(r.content) test_run_id = data['test_run_id'] r = self.client.get(reverse('system.test_result', args=[test_run_id])) eq_(r.status_code, 200) data = json.loads(r.content) eq_(data['finished'], False) eq_(data['results'], []) data = self.query(worker) queue_id = data['work_queue_id'] results = { 'failures': 0, 'total': 1, 'tests': [ {'module':'Bar', 'test':'foo', 'message':'1 equals 2', 'result':False}, {'module':'Bar', 'test':'foo', 'message':'ok', 'result':True}, {'module':'Zebo', 'test':'zee', 'message':'ok', 'result':True}, ] } r = self.client.post(reverse('work.submit_results'), dict(work_queue_id=queue_id, results=json.dumps(results))) eq_(r.status_code, 200) r = self.client.get(reverse('system.test_result', args=[test_run_id])) eq_(r.status_code, 200) data = json.loads(r.content) eq_(data['finished'], True) tests = sorted(data['results']) eq_(tests[0]['module'], 'Bar') eq_(tests[0]['test'], 'foo') eq_(tests[0]['assertions'], [ {'module':'Bar', 'test':'foo', 'worker_id': worker.id, 'worker_user_agent': worker.user_agent, 'browser': 'firefox/3.6.12, gecko/1.9.2.12', 'message':'1 equals 2', 'result':False}, {'module':'Bar', 'test':'foo', 'worker_id': worker.id, 'worker_user_agent': worker.user_agent, 'browser': 'firefox/3.6.12, gecko/1.9.2.12', 'message':'ok', 'result':True}, ]) eq_(tests[1]['module'], 'Zebo') eq_(tests[1]['test'], 'zee') eq_(tests[1]['assertions'], [ {'module':'Zebo', 'test':'zee', 'worker_id': worker.id, 'worker_user_agent': worker.user_agent, 'browser': 'firefox/3.6.12, gecko/1.9.2.12', 'message':'ok', 'result':True}, ])