예제 #1
0
    def test_log_stderr(self):
        Utils.prepare_test(connect_logger=True)

        with Utils.nostderr() as err:
            Logger.error("FOO_CAT", "Log message")
        self.assertIn("FOO_CAT", err.buffer)
        self.assertIn("Log message", err.buffer)
예제 #2
0
    def download_results(self):
        """
        POST /admin/download_pack
        """
        Logger.info("ADMIN", "Creating zip file")
        zip_directory = os.path.join(Config.storedir, "zips",
                                     Database.gen_id())
        os.makedirs(zip_directory, exist_ok=True)
        zipf_name = ("results-" +
                     Database.get_meta("admin_token").split("-", 1)[0] + "-" +
                     time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime()) +
                     ".zip")
        zipf_name = os.path.join(zip_directory, zipf_name)
        command = ("zip -r '" + zipf_name + "' db.sqlite3* log.sqlite3* "
                   "files/input files/output "
                   "files/source /version* "
                   "/proc/cpuinfo* "
                   "/var/log/nginx")

        try:
            gevent.subprocess.check_output(command,
                                           shell=True,
                                           stderr=subprocess.STDOUT)
        except subprocess.CalledProcessError as e:
            Logger.error("ADMIN", "Zip error: %s" % e.output)
            raise e
        return {
            "path": os.path.relpath(zipf_name, Config.storedir)
        }  # pragma: nocover
 def evaluate_output(task_name, input_path, output_path):
     """
     Given an input of a task, evaluate the correctness of the output
     :param task_name: Name of the task
     :param input_path: Path to the user's input file
     :param output_path: Path to the user's output file
     :return: The stdout of the checker
     """
     try:
         # call the checker and store the output
         start_time = time.monotonic()
         output = gevent.subprocess.check_output([
             ContestManager.tasks[task_name]["checker"],
             StorageManager.get_absolute_path(input_path),
             StorageManager.get_absolute_path(output_path)
         ])
         if time.monotonic() > start_time + 1:
             Logger.warning(
                 "TASK", "Evaluation of output %s "
                 "for task %s, with input %s, took %f "
                 "seconds" % (output_path, task_name, input_path,
                              time.monotonic() - start_time))
     except:
         # TODO log the stdout and stderr of the checker
         Logger.error(
             "TASK", "Error while evaluating output %s "
             "for task %s, with input %s: %s" %
             (output_path, task_name, input_path, traceback.format_exc()))
         raise
     Logger.info(
         "TASK", "Evaluated output %s for task %s, with input %s" %
         (output_path, task_name, input_path))
     return output
예제 #4
0
 def run(self):
     """
     Start a greenlet with the main HTTP server loop
     """
     server = gevent.pywsgi.WSGIServer(
         (Config.address, Config.port), self, log=None)
     try:
         server.init_socket()
     except OSError:
         Logger.error("PORT_ALREADY_IN_USE", "Address: '%s' Port: %d" %
                      (Config.address, Config.port))
         sys.exit(1)
     greenlet = gevent.spawn(server.serve_forever)
     port = "" if Config.port == 80 else ":" + str(Config.port)
     Logger.info("SERVER_STATUS", "Server started at http://%s%s/" %
                 (str(Config.address), port))
     greenlet.join()
예제 #5
0
 def __call__(self, environ, start_response):
     try:
         return self.wsgi_app(environ, start_response)
     except:
         Logger.error("UNCAUGHT_EXCEPTION", traceback.format_exc())
         return InternalServerError()
예제 #6
0
    def worker(task_name):
        """ Method that stays in the background and generates inputs """
        task = ContestManager.tasks[task_name]
        queue = ContestManager.input_queue[task_name]

        while True:
            try:
                id = Database.gen_id()
                path = StorageManager.new_input_file(id, task_name, "invalid")
                seed = int(sha256(id.encode()).hexdigest(), 16) % (2**31)

                stdout = os.open(
                    StorageManager.get_absolute_path(path),
                    os.O_WRONLY | os.O_CREAT,
                    0o644,
                )

                try:
                    start_time = time.monotonic()
                    # generate the input and store the stdout into a file
                    retcode = gevent.subprocess.call(
                        [task["generator"], str(seed), "0"], stdout=stdout)
                    if time.monotonic() > start_time + 1:
                        Logger.warning(
                            "TASK",
                            "Generation of input %s for task %s took %f seconds"
                            % (seed, task_name, time.monotonic() - start_time),
                        )
                finally:
                    os.close(stdout)

                if retcode != 0:
                    Logger.error(
                        "TASK",
                        "Error %d generating input %s (%d) for task %s" %
                        (retcode, id, seed, task_name),
                    )
                    # skip the input
                    continue

                # if there is a validator in the task use it to check if the
                # generated input is valid
                if "validator" in task:
                    stdin = os.open(StorageManager.get_absolute_path(path),
                                    os.O_RDONLY)
                    try:
                        start_time = time.monotonic()
                        # execute the validator piping the input file to stdin
                        retcode = gevent.subprocess.call(
                            [task["validator"], "0"], stdin=stdin)
                        if time.monotonic() > start_time + 1:
                            Logger.warning(
                                "TASK",
                                "Validation of input %s for task %s took %f "
                                "seconds" % (seed, task_name,
                                             time.monotonic() - start_time),
                            )
                    finally:
                        os.close(stdin)

                    if retcode != 0:
                        Logger.error(
                            "TASK",
                            "Error %d validating input %s (%d) for task %s" %
                            (retcode, id, seed, task_name),
                        )
                        # skip the input
                        continue

                Logger.debug(
                    "TASK",
                    "Generated input %s (%d) for task %s" %
                    (id, seed, task_name),
                )
                # this method is blocking if the queue is full
                queue.put({"id": id, "path": path})
            except:
                Logger.error(
                    "TASK",
                    "Exception while creating an input file: " +
                    traceback.format_exc(),
                )