Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
bbef0ac
fix: pin MarkupSafe to 2.0.1 (#33) (#1211)
SvizelPritula Dec 15, 2022
392a441
Updated Romanian translations (#1203)
CodeRadu Dec 15, 2022
db27018
Use docker-compose to run tests (#1221)
wil93 Dec 17, 2022
f541efc
Handle IntegrityError on file commit gracefully (#1223)
magula Jan 30, 2023
7d96215
Added Ukrainian translation (#1225)
arsijo Feb 6, 2023
07b4017
Add support for importing score_precision in italian_yaml (#1229)
edomora97 Mar 6, 2023
4baeee8
Update Simplified Chinese translations (#1231)
psz2007 Mar 23, 2023
4aa39c1
Adding C++17 to the default list of allowed programming language (#1232)
nstefan13 May 10, 2023
dac1cdf
Use pytest for unit tests
wil93 May 13, 2023
37e4fa0
Fix test failures
wil93 May 13, 2023
152501c
Fix deprecation warnings surfaced by pytest output
wil93 May 13, 2023
a775792
Optimize docker build time
wil93 May 13, 2023
3896952
Improve documentation on how to run tests
wil93 May 13, 2023
8fad02d
Enhance Korean translation (#1237)
leejseo Jul 29, 2023
2af71ca
Add Notice task type
ranaldmiao Sep 4, 2020
5ceac7b
Save the first time each submission is scored
aguss787 Feb 13, 2021
3325f39
Change scoreboard gradient to white to green
aguss787 Feb 21, 2021
2555b4c
Use SCORE_MODE_MAX_SUBTASK as default score_mode for tps loader
jonathanirvings Mar 16, 2021
e884a30
Allow contestant to see submission after the contest ends
aguss787 Sep 24, 2021
c4bbefc
Add -d/--default flag in cmsAddStatement to indicate is the statement…
aguss787 Sep 27, 2021
bba8607
Add unofficial submission setting
aguss787 Oct 31, 2021
c557ec9
Show confirmation dialog before reevaluation
fushar Dec 27, 2021
f918b0f
Start subtask numbering from 0 instead of 1
fushar Dec 27, 2021
6bfb9ee
feat: add config for removing submission rate limit
aguss787 Mar 29, 2021
6643d5d
Update clarification answer template options
fushar May 22, 2022
4df05ae
Reduce scoreboard font size and widen layout
fushar May 20, 2022
a2a05d0
Better scoreboard score color gradient
fushar May 20, 2022
34f6079
Increase file cache chunk size from 16 KB to 1 MB
nathanchrs Jul 18, 2022
050e3a6
tps loader: Compile manager and checker using gnu++17
jonathanirvings Jul 21, 2022
35cc95c
Add C++20 programming language
pobrn Feb 28, 2023
68d27ff
Add Hungarian translation
pobrn Feb 28, 2023
c8be91f
Set width of language chooser to `auto`
pobrn Aug 5, 2023
7b50ff7
scoretypes: improve restricted feedback behaviour
birka0 Aug 7, 2023
f52f91d
Add new restricted feedback mode
birka0 Aug 18, 2023
7f9403e
Ranking style changes for flags
niklaci Aug 19, 2023
b70f11b
loaders/tps: add support for setting the `feedback_level` of a task
pobrn Aug 19, 2023
d1e2b52
Ranking: Retain selected teams/contestants upon page refresh
ranaldmiao Aug 11, 2022
7ac3edc
Ranking: scroll to the correct position when clicking on a selected c…
fushar Aug 31, 2022
29cc4df
Ranking: add user id column
niklaci Aug 23, 2023
1f95f14
AWS: show connected / total number of workers
pobrn Aug 25, 2023
b694723
Do not mark Ukrainian translation `fuzzy`
pobrn Aug 29, 2023
6afea34
AWS: do not depend on ordering of `UNION ALL`
pobrn Aug 30, 2023
e2c5ac3
RWS: disable caching for ajax calls
pobrn Aug 31, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.dockerignore
Dockerfile
docker-compose*.yml
.vagrant/
codecov/
5 changes: 5 additions & 0 deletions .github/codecov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
coverage:
status:
project:
default:
threshold: 1%
77 changes: 14 additions & 63 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,78 +8,29 @@ jobs:
test:
runs-on: ubuntu-20.04

services:
postgres:
image: postgres:12
env:
POSTGRES_PASSWORD: postgres
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432

steps:
- uses: actions/checkout@v2
with:
submodules: true

- uses: actions/setup-python@v2
with:
python-version: 3.8

- name: Install dependencies
- name: Check available cgroups
run: |
sudo apt-get update -y
sudo apt-get install -y \
build-essential \
php7.4-cli \
haskell-platform \
fp-compiler \
python2.7 \
cppreference-doc-en-html \
cgroup-lite \
libcap-dev \
python-dev \
libpq-dev \
libcups2-dev \
libyaml-dev \
rustc \
mono-mcs
mount | grep cgroup

- name: Install requirements
- name: Build docker image
run: |
# Use distutils from the standard library for 2to3 translation
export SETUPTOOLS_USE_DISTUTILS="stdlib"

pip install -U pip setuptools wheel
pip install -r requirements.txt
pip install -r dev-requirements.txt
docker-compose -f docker-compose.test.yml build cms_test

sudo $(which python) prerequisites.py -y --cmsuser=$USER install
python setup.py install

- name: Set up database
env:
PGPASSWORD: postgres
- name: Run tests
run: |
psql --host=localhost --username=postgres --command="CREATE USER cmsuser WITH PASSWORD 'your_password_here';"

createdb --host=localhost --username=postgres --owner=cmsuser cmsdb
psql --host=localhost --username=postgres --dbname=cmsdb --command='ALTER SCHEMA public OWNER TO cmsuser'
psql --host=localhost --username=postgres --dbname=cmsdb --command='GRANT SELECT ON pg_largeobject TO cmsuser'
docker-compose -f docker-compose.test.yml run --rm cms_test

createdb --host=localhost --username=postgres --owner=cmsuser cmsdbfortesting
psql --host=localhost --username=postgres --dbname=cmsdbfortesting --command='ALTER SCHEMA public OWNER TO cmsuser'
psql --host=localhost --username=postgres --dbname=cmsdbfortesting --command='GRANT SELECT ON pg_largeobject TO cmsuser'

cp ./config/cms.conf.sample ./config/cms.conf
sed -e "s/\"cmsuser\": \"cmsuser\"/\"cmsuser\": \"$USER\"/" -i ./config/cms.conf

cmsInitDB
- uses: codecov/codecov-action@v3
with:
files: ./codecov/unittests.xml
flags: unittests

- name: Run tests
run: |
cmsRunTests -v --coverage --codecov
- uses: codecov/codecov-action@v3
with:
files: ./codecov/functionaltests.xml
flags: functionaltests
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
*~
.DS_Store
*.mo
.*.sw?
*.pyc
Expand All @@ -11,3 +12,5 @@ cms.egg-info
cache/
lib/
log/
.vagrant/
codecov/
57 changes: 57 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# syntax=docker/dockerfile:1
FROM ubuntu:20.04

RUN apt-get update
RUN apt-get install -y \
build-essential \
cgroup-lite \
cppreference-doc-en-html \
fp-compiler \
git \
haskell-platform \
libcap-dev \
libcups2-dev \
libffi-dev \
libpq-dev \
libyaml-dev \
mono-mcs \
openjdk-8-jdk-headless \
php7.4-cli \
postgresql-client \
python2 \
python3-pip \
python3.8 \
python3.8-dev \
rustc \
sudo \
wait-for-it \
zip

# Create cmsuser user with sudo privileges
RUN useradd -ms /bin/bash cmsuser && \
usermod -aG sudo cmsuser
# Disable sudo password
RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
# Set cmsuser as default user
USER cmsuser

RUN mkdir /home/cmsuser/cms
COPY --chown=cmsuser:cmsuser requirements.txt dev-requirements.txt /home/cmsuser/cms/

WORKDIR /home/cmsuser/cms

RUN sudo pip3 install -r requirements.txt
RUN sudo pip3 install -r dev-requirements.txt

COPY --chown=cmsuser:cmsuser . /home/cmsuser/cms

RUN sudo python3 setup.py install

RUN sudo python3 prerequisites.py --yes --cmsuser=cmsuser install

RUN sudo sed 's|/cmsuser:your_password_here@localhost:5432/cmsdb"|/postgres@cms_test_db:5432/cmsdbfortesting"|' ./config/cms.conf.sample \
| sudo tee /usr/local/etc/cms-testdb.conf

ENV LANG C.UTF-8

CMD [""]
4 changes: 4 additions & 0 deletions cms/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"TOKEN_MODE_DISABLED", "TOKEN_MODE_FINITE", "TOKEN_MODE_INFINITE",
"TOKEN_MODE_MIXED",
"FEEDBACK_LEVEL_FULL", "FEEDBACK_LEVEL_RESTRICTED",
"FEEDBACK_LEVEL_OI_RESTRICTED",
# log
# Nothing intended for external use, no need to advertise anything.
# conf
Expand Down Expand Up @@ -68,6 +69,9 @@
# Restricted set of information (no killing signal, time or memory, testcases
# can be omitted).
FEEDBACK_LEVEL_RESTRICTED = "restricted"
# Restricted set of information in accordance with the Contest Rules of
# the International Olympiad of Informatics
FEEDBACK_LEVEL_OI_RESTRICTED = "oi_restricted"


from .conf import Address, ServiceCoord, ConfigError, async_config, config
Expand Down
12 changes: 11 additions & 1 deletion cms/db/contest.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ class Contest(Base):
languages = Column(
ARRAY(String),
nullable=False,
default=["C11 / gcc", "C++11 / g++", "Pascal / fpc"])
default=["C11 / gcc", "C++17 / g++", "Pascal / fpc"])

# Whether contestants allowed to download their submissions.
submissions_download_allowed = Column(
Expand All @@ -99,6 +99,12 @@ class Contest(Base):
nullable=False,
default=True)

# Allow unofficial submission before analysis mode
allow_unofficial_submission_before_analysis_mode = Column(
Boolean,
nullable=False,
default=False)

# Whether to prevent hidden participations to log in.
block_hidden_participations = Column(
Boolean,
Expand Down Expand Up @@ -245,6 +251,10 @@ class Contest(Base):
Interval,
CheckConstraint("min_submission_interval > '0 seconds'"),
nullable=True)
min_submission_interval_grace_period = Column(
Interval,
CheckConstraint("min_submission_interval_grace_period > '0 seconds'"),
nullable=True)
min_user_test_interval = Column(
Interval,
CheckConstraint("min_user_test_interval > '0 seconds'"),
Expand Down
11 changes: 8 additions & 3 deletions cms/db/filecacher.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
# Copyright © 2013 Luca Wehrstedt <luca.wehrstedt@gmail.com>
# Copyright © 2016 Luca Versari <veluca93@gmail.com>
# Copyright © 2021 Fabian Gundlach <320pointsguy@gmail.com>
# Copyright © 2023 Manuel Gundlach <manuel.gundlach@gmail.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
Expand Down Expand Up @@ -362,8 +363,12 @@ def commit_file(self, fobj, digest, desc=""):
# If someone beat us to adding the same object to the database, we
# should at least drop the large object.
LargeObject.unlink(fobj.loid)
logger.warning("File %s (%s) caused an IntegrityError, ignoring.",
digest, desc)
logger.info("File %s (%s) caused an IntegrityError, ignoring. "
"Note: If the file is a compiled submission "
"executable, this can occur when a contestant has "
"submitted identical source code multiple times, "
"and is harmless in that case.",
digest, desc)
return False
return True

Expand Down Expand Up @@ -481,7 +486,7 @@ class FileCacher:
# - The `io' module defines a DEFAULT_BUFFER_SIZE constant, whose
# value is 8192.
# CHUNK_SIZE should be a multiple of these values.
CHUNK_SIZE = 16 * 1024 # 16 KiB
CHUNK_SIZE = 1024 * 1024 # 1 MiB

def __init__(self, service=None, path=None, null=False):
"""Initialize.
Expand Down
5 changes: 5 additions & 0 deletions cms/db/submission.py
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,11 @@ class SubmissionResult(Base):
JSONB,
nullable=True)

# Time when the submission is scored for the first time
scored_at = Column(
DateTime,
nullable=True)

# The same as the last two fields, but only showing information
# visible to the user (assuming they did not use a token on this
# submission).
Expand Down
3 changes: 2 additions & 1 deletion cms/db/task.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
Interval, Enum, BigInteger

from cms import TOKEN_MODE_DISABLED, TOKEN_MODE_FINITE, TOKEN_MODE_INFINITE, \
FEEDBACK_LEVEL_FULL, FEEDBACK_LEVEL_RESTRICTED
FEEDBACK_LEVEL_FULL, FEEDBACK_LEVEL_RESTRICTED, FEEDBACK_LEVEL_OI_RESTRICTED
from cmscommon.constants import \
SCORE_MODE_MAX, SCORE_MODE_MAX_SUBTASK, SCORE_MODE_MAX_TOKENED_LAST
from . import Codename, Filename, FilenameSchemaArray, Digest, Base, Contest
Expand Down Expand Up @@ -193,6 +193,7 @@ class Task(Base):
# reverse engineer task data.
feedback_level = Column(
Enum(FEEDBACK_LEVEL_FULL, FEEDBACK_LEVEL_RESTRICTED,
FEEDBACK_LEVEL_OI_RESTRICTED,
name="feedback_level"),
nullable=False,
default=FEEDBACK_LEVEL_RESTRICTED)
Expand Down
4 changes: 2 additions & 2 deletions cms/db/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ class FilenameSchema(TypeDecorator):
@classmethod
def get_create_command(cls):
return DDL("CREATE DOMAIN %(domain)s VARCHAR "
"CHECK (VALUE ~ '^[A-Za-z0-9_.-]+(\.%%l)?$') "
"CHECK (VALUE ~ '^[A-Za-z0-9_.-]+(.%%l)?$') "
"CHECK (VALUE != '.') "
"CHECK (VALUE != '..')",
context={"domain": cls.domain_name})
Expand Down Expand Up @@ -187,7 +187,7 @@ def get_create_command(cls):
return DDL("CREATE DOMAIN %(domain)s VARCHAR[] "
"CHECK (array_to_string(VALUE, '') ~ '^[A-Za-z0-9_.%%-]*$') "
"CHECK (array_to_string(VALUE, ',') "
" ~ '^([A-Za-z0-9_.-]+(\.%%l)?(,|$))*$') "
" ~ '^([A-Za-z0-9_.-]+(.%%l)?(,|$))*$') "
"CHECK ('.' != ALL(VALUE)) "
"CHECK ('..' != ALL(VALUE))",
context={"domain": cls.domain_name})
Expand Down
64 changes: 64 additions & 0 deletions cms/grading/languages/cpp20_gpp.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#!/usr/bin/env python3

# Contest Management System - http://cms-dev.github.io/
# Copyright © 2016 Stefano Maggiolo <s.maggiolo@gmail.com>
# Copyright © 2020 Andrey Vihrov <andrey.vihrov@gmail.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

"""C++20 programming language definition."""

from cms.grading import CompiledLanguage


__all__ = ["Cpp20Gpp"]


class Cpp20Gpp(CompiledLanguage):
"""This defines the C++ programming language, compiled with g++ (the
version available on the system) using the C++20 standard.

"""

@property
def name(self):
"""See Language.name."""
return "C++20 / g++"

@property
def source_extensions(self):
"""See Language.source_extensions."""
return [".cpp", ".cc", ".cxx", ".c++", ".C"]

@property
def header_extensions(self):
"""See Language.header_extensions."""
return [".h"]

@property
def object_extensions(self):
"""See Language.object_extensions."""
return [".o"]

def get_compilation_commands(self,
source_filenames, executable_filename,
for_evaluation=True):
"""See Language.get_compilation_commands."""
command = ["/usr/bin/g++"]
if for_evaluation:
command += ["-DEVAL"]
command += ["-std=gnu++20", "-O2", "-pipe", "-static",
"-s", "-o", executable_filename]
command += source_filenames
return [command]
Loading