示例#1
0
    def test_submit(self, g_f_s_mock, g_i_mock):
        Utils.start_contest()
        self._insert_data()
        self.handler.generate_input(token='token', task='poldo', _ip='1.1.1.1')

        Database.c.execute(
            "INSERT INTO outputs (id, input, path, size, result) "
            "VALUES ('outputid', 'inputid', '/output', 42,"
            ":result)", {
                "result":
                b'{\"score\":0.5,\"feedback\":{\"a\":1},'
                b'\"validation\":{\"b\":2}}'
            })
        Database.c.execute("INSERT INTO sources (id, input, path, size) "
                           "VALUES ('sourceid', 'inputid', '/source', 42)")

        response = self.handler.submit(output_id='outputid',
                                       source_id='sourceid',
                                       _ip='1.1.1.1')
        self.assertEqual("token", response["token"])
        self.assertEqual("poldo", response["task"])
        self.assertEqual(21, response["score"])
        self.assertEqual("inputid", response["input"]["id"])
        self.assertEqual("sourceid", response["source"]["id"])
        self.assertEqual("outputid", response["output"]["id"])
        self.assertEqual(1, response["feedback"]["a"])
        self.assertEqual(2, response["output"]["validation"]["b"])

        user_task = Database.get_user_task("token", "poldo")
        self.assertEqual(21, user_task["score"])
        self.assertEqual(response["id"],
                         Database.get_submission(response["id"])["id"])
    def test_submit_broken_transaction(self, gen_i_mock, a_s_mock, g_f_s_mock,
                                       g_i_mock):
        Utils.start_contest()
        self._insert_data()
        self.handler.generate_input(token="token", task="poldo", _ip="1.1.1.1")

        Database.c.execute(
            "INSERT INTO outputs (id, input, path, size, result) "
            "VALUES ('outputid', 'inputid', '/output', 42,"
            ":result)",
            {
                "result":
                b'{"score":0.5,"feedback":{"a":1},'
                b'"validation":{"b":2}}'
            },
        )
        Database.c.execute("INSERT INTO sources (id, input, path, size) "
                           "VALUES ('sourceid', 'inputid', '/source', 42)")

        with self.assertRaises(BadRequest) as ex:
            self.handler.submit(output_id="outputid",
                                source_id="sourceid",
                                _ip="1.1.1.1")
        self.assertIn("Error inserting the submission",
                      ex.exception.response.data.decode())
        self.assertIsNone(Database.get_submission("subid"))
示例#3
0
    def submit(self, output, source):
        """
        POST /submit
        """
        input = Database.get_input(output["input"])
        if input is None:
            Logger.warning("DB_CONSISTENCY_ERROR",
                           "Input %s not found in the db" % output["input"])
            self.raise_exc(BadRequest, "WRONG_INPUT",
                           "The provided input in invalid")
        if output["input"] != source["input"]:
            Logger.warning("POSSIBLE_CHEAT",
                           "Trying to submit wrong pair source-output")
            self.raise_exc(Forbidden, "WRONG_OUTPUT_SOURCE",
                           "The provided pair of source-output is invalid")

        score = ContestHandler.compute_score(input["task"], output["result"])
        Database.begin()
        try:
            submission_id = Database.gen_id()
            if not Database.add_submission(submission_id,
                                           input["id"],
                                           output["id"],
                                           source["id"],
                                           score,
                                           autocommit=False):
                self.raise_exc(BadRequest, "INTERNAL_ERROR",
                               "Error inserting the submission")
            ContestHandler.update_user_score(input["token"], input["task"],
                                             score)
            Database.set_user_attempt(input["token"],
                                      input["task"],
                                      None,
                                      autocommit=False)
            Database.commit()
        except sqlite3.IntegrityError as ex:
            Database.rollback()
            # provide a better error message if the input has already been
            # submitted
            if "UNIQUE constraint failed: submissions.input" in str(ex):
                self.raise_exc(Forbidden, "ALREADY_SUBMITTED",
                               "This input has already been submitted")
            raise
        except:
            Database.rollback()
            raise
        Logger.info(
            "CONTEST", "User %s has submitted %s on %s" %
            (input["token"], submission_id, input["task"]))
        return InfoHandler.patch_submission(
            Database.get_submission(submission_id))
示例#4
0
 def _guess_token(**kwargs):
     if "token" in kwargs:
         return kwargs["token"]
     elif "input_id" in kwargs:
         input = Database.get_input(kwargs["input_id"])
         if input: return input["token"]
     elif "output_id" in kwargs:
         output = Database.get_output(kwargs["output_id"])
         if output:
             input = Database.get_input(output["input"])
             if input: return input["token"]
     elif "source_id" in kwargs:
         source = Database.get_source(kwargs["source_id"])
         if source:
             input = Database.get_input(source["input"])
             if input: return input["token"]
     elif "submission_id" in kwargs:
         submission = Database.get_submission(kwargs["submission_id"])
         if submission: return submission["token"]
     return None