def register_environment() -> Response: _, body = _validate_request() with transaction() as s: _ = _validate_token(s, admin_required=True) e = Environment(name=body.name, active=getattr(body, 'active', True), published=getattr(body, 'published', False), compile_image_name=getattr(body, 'compile_image_name', ''), test_image_name=body.test_image_name) s.add(e) s.flush() return jsonify(e.to_dict())
def test_submissions_pagination(self): test_data = [] start_time = datetime.now(tz=timezone.utc) end_time = start_time + timedelta(hours=1) app.post_json('/contests', { 'id': 'id0', 'title': 'Test Contest', 'description': '**Pagination** Test', 'start_time': start_time.isoformat(), 'end_time': end_time.isoformat(), 'published': True, }, headers=self.admin_headers) app.post_json('/contests/id0/problems', { 'id': 'A', 'title': 'Problem', 'description': '# A', 'time_limit': 2, 'score': 100 }, headers=self.admin_headers) test_data = [] with transaction() as s: env = Environment(name='Python 3.7', test_image_name='image') s.add(env) s.flush() for i in range(100): submission = Submission(contest_id='id0', problem_id='A', user_id='admin', code=b'dummy', code_bytes=1, environment_id=env.id) s.add(submission) s.flush() test_data.append(submission.to_dict()) resp = app.get('/contests/id0/submissions', headers=self.admin_headers) self.assertEqual(len(resp.json), 20) self.assertEqual(int(resp.headers['X-Page']), 1) self.assertEqual(int(resp.headers['X-Per-Page']), 20) self.assertEqual(int(resp.headers['X-Total']), 100) self.assertEqual(int(resp.headers['X-Total-Pages']), 5) resp = app.get('/contests/id0/submissions?page=2&per_page=31', headers=self.admin_headers) self.assertEqual(len(resp.json), 31) self.assertEqual([x['id'] for x in resp.json], [x['id'] for x in test_data[31:62]]) self.assertEqual(int(resp.headers['X-Page']), 2) self.assertEqual(int(resp.headers['X-Per-Page']), 31) self.assertEqual(int(resp.headers['X-Total']), 100) self.assertEqual(int(resp.headers['X-Total-Pages']), 4)
def test_list_environments(self): envs = app.get('/environments').json self.assertEqual(envs, []) env = dict(name='Python 3.7', test_image_name='docker-image', published=True) with transaction() as s: s.add(Environment(**env)) envs = app.get('/environments').json self.assertEqual(len(envs), 1) self.assertIsInstance(envs[0]['id'], int) self.assertEqual(envs[0]['name'], env['name'])
def test_ranking(self): salt = b'penguin' passwd = _kdf('penguinpenguin', salt) app.get('/contests/abc000/rankings', status=404) with transaction() as s: env = Environment( name='Python3 (3.8.0)', test_image_name='penguin_judge_python:3.8') s.add(env) s.add(Contest( id='abc000', title='ABC000', description='# Title\nMarkdown Test\n\n* Item0\n* Item1\n', published=True, start_time=datetime.now(tz=timezone.utc), end_time=datetime.now( tz=timezone.utc) + timedelta(days=365))) s.flush() env_id = env.id problem_ids = ['A', 'B', 'C', 'D', 'E'] for i, id in enumerate(problem_ids): s.add(Problem( contest_id='abc000', id=id, title='Problem {}'.format(id), description='', time_limit=1, memory_limit=1024, score=(i + 1) * 100)) user_mapping = {} for i in range(10): u = User( login_id='user{}'.format(i), name='User{}'.format(i), salt=salt, password=passwd) s.add(u) s.flush() user_mapping['user{}'.format(i)] = u.id # 未提出者もランキングに載せるようにした # self.assertEquals([], app.get('/contests/abc000/rankings').json) with transaction() as s: problem_kwargs = [dict( contest_id='abc000', problem_id=id, code=b'', code_bytes=0, environment_id=env_id) for id in problem_ids] start = datetime.now(tz=timezone.utc) d = timedelta(seconds=1) users = { 'user0': [ (1, 0, 1), (1, 0, 2), (1, 0, 4), (1, 0, 8), (1, 0, 16)], 'user1': [ (1, 1, 4), (1, 2, 8), (1, 1, 16), (1, 2, 32), (1, 1, 64)], 'user2': [ (1, 1, 2), (0, 2, 0), (0, 1, 0), (0, 0, 0), (0, 0, 0)], 'user3': [ (0, 1, 0), (0, 2, 0), (0, 1, 0), (0, 1, 0), (0, 1, 0)], } for u, v in users.items(): for i, (n_ac, n_wa, t) in enumerate(v): for j in range(n_wa): if t > 0: tmp = t - 1 else: tmp = i + j + 1 s.add(Submission( user_id=user_mapping[u], status=JudgeStatus.WrongAnswer, created=start + d * tmp, **problem_kwargs[i])) if n_ac > 0: s.add(Submission( user_id=user_mapping[u], status=JudgeStatus.Accepted, created=start + d * t, **problem_kwargs[i])) ret = app.get('/contests/abc000/rankings').json # 未提出者もランキングに載せるようにした # self.assertEquals(4, len(ret)) for i in range(4): self.assertEquals(ret[i]['user_id'], user_mapping['user{}'.format(i)]) self.assertEquals(ret[i]['user_name'], 'User{}'.format(i)) self.assertEquals(ret[0]['ranking'], 1) self.assertEquals(ret[0]['score'], 1500) self.assertEquals(ret[0]['penalties'], 0) self.assertEquals(ret[0]['time'], ret[0]['adjusted_time']) self.assertEquals(ret[1]['ranking'], 2) self.assertEquals(ret[1]['score'], 1500) self.assertEquals(ret[1]['penalties'], 7) self.assertEquals(ret[1]['time'] + 7 * 300, ret[1]['adjusted_time']) self.assertEquals(ret[2]['ranking'], 3) self.assertEquals(ret[2]['score'], 100) self.assertEquals(ret[2]['penalties'], 1) self.assertEquals(ret[2]['time'] + 300, ret[2]['adjusted_time']) self.assertEquals(ret[3]['ranking'], 4) self.assertEquals(ret[3]['score'], 0) self.assertEquals(ret[3]['penalties'], 0) self.assertEquals(ret[3]['time'], 0) self.assertEquals(ret[3]['problems'], { 'A': {'penalties': 1, 'pending': False}, 'B': {'penalties': 2, 'pending': False}, 'C': {'penalties': 1, 'pending': False}, 'D': {'penalties': 1, 'pending': False}, 'E': {'penalties': 1, 'pending': False}, })
def test_submission(self, mock_conn, mock_get_params): # TODO(kazuki): API経由に書き換える env = dict(name='Python 3.7', test_image_name='docker-image') with transaction() as s: env = Environment(**env) s.add(env) s.flush() env = env.to_dict() start_time = datetime.now(tz=timezone.utc) contest_id = app.post_json('/contests', { 'id': 'abc000', 'title': 'ABC000', 'description': '# ABC000\n\nほげほげ\n', 'start_time': start_time.isoformat(), 'end_time': (start_time + timedelta(hours=1)).isoformat(), 'published': True, }, headers=self.admin_headers).json['id'] prefix = '/contests/{}'.format(contest_id) app.post_json( '{}/problems'.format(prefix), dict( id='A', title='A Problem', description='# A', time_limit=2, score=100 ), headers=self.admin_headers) # TODO(kazuki): API経由に書き換える ctx = ZstdCompressor() with transaction() as s: s.add(TestCase( contest_id=contest_id, problem_id='A', id='1', input=ctx.compress(b'1'), output=ctx.compress(b'2'))) app.get('{}/submissions'.format(prefix), status=403) self.assertEqual([], app.get( '{}/submissions'.format(prefix), headers=self.admin_headers).json) app.get('/contests/invalid/submissions', status=404) code = 'print("Hello World")' resp = app.post_json('{}/submissions'.format(prefix), { 'problem_id': 'A', 'environment_id': env['id'], 'code': code, }, headers=self.admin_headers).json self.assertEqual([resp], app.get( '{}/submissions'.format(prefix), headers=self.admin_headers).json) app.get('{}/submissions/{}'.format(prefix, resp['id']), status=404) resp2 = app.get('{}/submissions/{}'.format(prefix, resp['id']), headers=self.admin_headers).json self.assertEqual(resp2.pop('code'), code) resp['tests'] = [] self.assertEqual(resp, resp2) app.post_json('{}/submissions'.format(prefix), { 'problem_id': 'invalid', 'environment_id': env['id'], 'code': code, }, headers=self.admin_headers, status=400) app.post_json('{}/submissions'.format(prefix), { 'problem_id': 'A', 'environment_id': 99999, 'code': code, }, headers=self.admin_headers, status=400) app.get('{}/submissions/99999'.format(prefix), status=404) contest_id2 = app.post_json('/contests', { 'id': 'abc001', 'title': 'ABC001', 'description': '# ABC001', 'start_time': start_time.isoformat(), 'end_time': (start_time + timedelta(hours=1)).isoformat(), }, headers=self.admin_headers).json['id'] app.get( '/contests/{}/submissions/{}'.format(contest_id2, resp['id']), status=404) with transaction() as s: s.query(Contest).update({'end_time': start_time}) app.get('{}/submissions'.format(prefix))