コード例 #1
0
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())
コード例 #2
0
ファイル: test_api.py プロジェクト: kazuki/PenguinJudge
    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)
コード例 #3
0
ファイル: test_api.py プロジェクト: shiodat/PenguinJudge
    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'])
コード例 #4
0
ファイル: test_api.py プロジェクト: shiodat/PenguinJudge
    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},
        })
コード例 #5
0
ファイル: test_api.py プロジェクト: shiodat/PenguinJudge
    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))