From de001cec8685bf57a366febac6d774012f581f2f Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Sun, 28 Jan 2018 16:02:37 +0100 Subject: [PATCH 001/107] Add script to validate the JSON schema of a Contest API. --- check-api.sh | 151 +++++++++++++++++++++++++++++++ json-schema/awards.json | 20 ++++ json-schema/clarifications.json | 24 +++++ json-schema/common.json | 115 +++++++++++++++++++++++ json-schema/contest.json | 22 +++++ json-schema/event-feed.json | 14 +++ json-schema/groups.json | 19 ++++ json-schema/judgement-types.json | 18 ++++ json-schema/judgements.json | 35 +++++++ json-schema/languages.json | 16 ++++ json-schema/organizations.json | 52 +++++++++++ json-schema/problems.json | 31 +++++++ json-schema/runs.json | 24 +++++ json-schema/scoreboard.json | 65 +++++++++++++ json-schema/state.json | 15 +++ json-schema/submissions.json | 23 +++++ json-schema/team-members.json | 27 ++++++ json-schema/teams.json | 38 ++++++++ 18 files changed, 709 insertions(+) create mode 100755 check-api.sh create mode 100644 json-schema/awards.json create mode 100644 json-schema/clarifications.json create mode 100644 json-schema/common.json create mode 100644 json-schema/contest.json create mode 100644 json-schema/event-feed.json create mode 100644 json-schema/groups.json create mode 100644 json-schema/judgement-types.json create mode 100644 json-schema/judgements.json create mode 100644 json-schema/languages.json create mode 100644 json-schema/organizations.json create mode 100644 json-schema/problems.json create mode 100644 json-schema/runs.json create mode 100644 json-schema/scoreboard.json create mode 100644 json-schema/state.json create mode 100644 json-schema/submissions.json create mode 100644 json-schema/team-members.json create mode 100644 json-schema/teams.json diff --git a/check-api.sh b/check-api.sh new file mode 100755 index 00000000..db124e58 --- /dev/null +++ b/check-api.sh @@ -0,0 +1,151 @@ +#!/bin/bash +# Checks whether a Contest API conforms to the specification +# https://clics.ecs.baylor.edu/index.php/Contest_API +# +# Currently only checks a single contest under api/contests/{id}/ +# +# Rquires https://github.com/justinrainbow/json-schema +# which can be installed with: composer require justinrainbow/json-schema + +# Set path to json-validate binary if it's not in PATH: +#VALIDATE_JSON=/path/to/json-validate + +# Optional extra arguments to append to the API URLs: +#URL_EXTRA='?strict=1' + +ENDPOINTS=' +contest +judgement-types +languages +problems +groups +organizations +team-members +teams +state +submissions +judgements +runs +clarifications +awards +scoreboard +' + +# Note: event-feed is an NDJSON endpoint which is treated specially. + +ENDPOINTS_OPTIONAL=' +team-members +awards +' + +API_URL="$1" + +if [ -z "$API_URL" ]; then + echo "Error: API URL argument expected." + exit 1 +fi + +TMP=$(mktemp -d) + +MYDIR=$(dirname $0) + +query_endpoint() +{ + local OUTPUT="$1" + local URL="$2" + local OPTIONAL="$3" + + # Special case timeout for event-feed NDJSON endpoint. + if [ "${URL/event-feed/}" != "$URL" ]; then + TIMEOUT='--max-time 10' + fi + + local HTTPCODE=$(curl -kns $TIMEOUT -w "%{http_code}\n" -o "$OUTPUT" "${URL}${URL_EXTRA}") + local EXITCODE="$?" + if [ $EXITCODE -eq 28 ]; then # timeout + if [ -z "$TIMEOUT" ]; then + echo "Warning curl request timed out for '$URL'." + return $EXITCODE + fi + elif [ $EXITCODE -ne 0 ]; then + echo "Warning: curl returned exitcode $EXITCODE for '$URL'." + return $EXITCODE + elif [ $HTTPCODE -ne 200 ]; then + [ -n "$OPTIONAL" ] || echo "Warning: curl returned HTTP status $HTTPCODE for '$URL'." + return 1 + elif [ ! -e "$OUTPUT" -o ! -s "$OUTPUT" ]; then + [ -n "$OPTIONAL" ] || echo "Warning: no or empty file downloaded by curl." + return 1 + fi + return 0 +} + +validate_schema() +{ + local DATA="$1" SCHEMA="$2" + + ${VALIDATE_JSON:-validate-json} "$DATA" "$SCHEMA" + local EXITCODE=$? + [ $EXITCODE -eq 0 ] && echo "OK" + return $EXITCODE +} + +for ENDPOINT in $ENDPOINTS ; do + if [ "${ENDPOINTS_OPTIONAL/${ENDPOINT}/}" != "$ENDPOINTS_OPTIONAL" ]; then + OPTIONAL=1 + else + unset OPTIONAL + fi + + if [ "$ENDPOINT" = 'contest' ]; then + URL="$API_URL" + else + URL="${API_URL%/}/$ENDPOINT" + fi + + SCHEMA="$MYDIR/json-schema/$ENDPOINT.json" + OUTPUT="$TMP/$ENDPOINT.json" + + if query_endpoint "$OUTPUT" "$URL" $OPTIONAL ; then + printf '%20s: ' "$ENDPOINT" + validate_schema "$OUTPUT" "$SCHEMA" + else + if [ -n "$OPTIONAL" ]; then + printf '%20s: Optional, not present\n' "$ENDPOINT" + else + printf '%20s: Failed to download\n' "$ENDPOINT" + fi + fi +done + +# Now do special case event-feed endpoint +ENDPOINT='event-feed' +SCHEMA="$MYDIR/json-schema/$ENDPOINT.json" +OUTPUT="$TMP/$ENDPOINT.json" +URL="${API_URL%/}/$ENDPOINT" + +if query_endpoint "$OUTPUT" "$URL" ; then + printf '%20s: ' "$ENDPOINT" + # Do line by line validation of NDJSON, quit at first failure. + TMPOUTPUT="$TMP/event-feed-line.json" + TMPRESULT="$TMP/event-feed-tmp.txt" + VALID=1 + while read LINE ; do + # Skip empty lines that may be inserted as heartbeat. + [ -z "$LINE" ] && continue + echo "$LINE" > "$TMPOUTPUT" + if ! validate_schema "$TMPOUTPUT" "$SCHEMA" > "$TMPRESULT"; then + printf "Failed to validate:\n%s\n" "$LINE" + cat "$TMPRESULT" + VALID=0 + break + fi + done < "$OUTPUT" + [ "$VALID" -eq 1 ] && echo "OK" +else + printf '%20s: Failed to download\n' "$ENDPOINT" +fi + +rm -rf $TMP + +exit 0 diff --git a/json-schema/awards.json b/json-schema/awards.json new file mode 100644 index 00000000..2f2f15b4 --- /dev/null +++ b/json-schema/awards.json @@ -0,0 +1,20 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "CLICS CCS REST API: awards", + "description": "JSON response of this API call", + "type": "array", + "uniqueItems": true, + "items": { + "type": "object", + "properties": { + "id": { "$ref": "common.json#/identifier" }, + "citation": { "type": "string" }, + "team_ids": { + "type": "array", + "uniqueItems": true, + "items": { "$ref": "common.json#/identifier" } + } + }, + "required": ["id", "citation", "team_ids"] + } +} diff --git a/json-schema/clarifications.json b/json-schema/clarifications.json new file mode 100644 index 00000000..d648c6de --- /dev/null +++ b/json-schema/clarifications.json @@ -0,0 +1,24 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "CLICS CCS REST API: clarifications", + "description": "JSON response of this API call", + "type": "array", + "uniqueItems": true, + "items": { + "type": "object", + "properties": { + "id": { "$ref": "common.json#/identifier" }, + "from_team_id": { "$ref": "common.json#/identifierornull" }, + "to_team_id": { "$ref": "common.json#/identifierornull" }, + "reply_to_id": { "$ref": "common.json#/identifierornull" }, + "problem_id": { "$ref": "common.json#/identifierornull" }, + "text": { "type": "string" }, + "from_jury": { "type": "boolean" }, + "to_all_teams": { "type": "boolean" }, + "time": { "$ref": "common.json#/abstime" }, + "contest_time": { "$ref": "common.json#/reltime" } + }, + "required": ["id", "text", "time", "contest_time"], + "additionalProperties": false + } +} diff --git a/json-schema/common.json b/json-schema/common.json new file mode 100644 index 00000000..f4f31964 --- /dev/null +++ b/json-schema/common.json @@ -0,0 +1,115 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "CLICS CCS REST API - common definitions", + "description": "Common definitions of objects used in the API calls", + + "endpoints": { + "enum": [ + "contests", + "judgement-types", + "languages", + "problems", + "groups", + "organizations", + "team-members", + "teams", + "state", + "submissions", + "judgements", + "runs", + "clarifications", + "awards", + "scoreboard", + "event-feed" + ] + }, + + "abstime": { + "type": "string", + "pattern": "^[12][0-9]{3}-[01][0-9]-[0-3][0-9]T[0-2][0-9]:[0-6][0-9]:[0-6][0-9](\\.[0-9]{3})?([+-][0-1][0-9](:[0-5][0-9])?|Z)$" + }, + + "abstimeornull": { + "oneOf": [ + { "$ref": "#/abstime" }, + { "type": "null" } + ] + }, + + "reltime": { + "type": "string", + "pattern": "^-?([1-9][0-9]*)?[0-9]:[0-5][0-9]:[0-5][0-9](\\.[0-9]{3})?$" + }, + + "identifier": { + "type": "string", + "pattern": "^[A-Za-z0-9_][A-Za-z0-9_-]{0,35}" + }, + + "identifierornull": { + "oneOf": [ + { "$ref": "#/identifier" }, + { "type": "null" } + ] + }, + + "judgementtypeid": { + "enum": [ + "AC", "RE", "WA", "TLE", "RTE", "CE", "APE", "OLE", "PE", "EO", "IO", "NO", + "WTL", "ILE", "TCO", "TWA", "TPE", "TEO", "TIO", "TNO", "MLE", "SV", + "RCO", "RWA", "RPE", "REO", "RIO", "RNO", "CTL", "JE", "SE", "CS" + ] + }, + + "judgementtypeidornull": { + "oneOf": [ + { "$ref": "#/judgementtypeid" }, + { "type": "null" } + ] + }, + + "label": { + "type": "string", + "pattern": "^[A-Za-z0-9_][A-Za-z0-9_-]{0,9}" + }, + + "file": { + "type": "string" + }, + + "ordinal": { + "type": "integer", + "minimum": 0 + }, + + "decimal": { + "type": "number", + "multipleOf": 0.001 + }, + + "fileref": { + "type": "object", + "properties": { + "href": { "type": "string" }, + "mime": { + "oneOf": [ + { "type": "string" }, + { "type": "null" } + ] + }, + "width": { "type": "integer", "minimum": 1 }, + "height": { "type": "integer", "minimum": 1 } + }, + "required": ["href"], + "additionalProperties": false + }, + + "filerefs": { + "type": "array", + "uniqueItems": true, + "items": { + "$ref": "#/fileref" + } + + } +} diff --git a/json-schema/contest.json b/json-schema/contest.json new file mode 100644 index 00000000..02fd7457 --- /dev/null +++ b/json-schema/contest.json @@ -0,0 +1,22 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "CLICS CCS REST API: contest", + "description": "JSON response of this API call", + "type": "object", + "properties": { + "id": { "$ref": "common.json#/identifier" }, + "name": { "type": "string" }, + "formal_name": { "type": "string" }, + "start_time": { "$ref": "common.json#/abstimeornull" }, + "duration": { "$ref": "common.json#/reltime" }, + "scoreboard_freeze_duration": { "$ref": "common.json#/reltime" }, + "penalty_time": { + "type": "integer", + "minimum": 0 + }, + "banner": { "$ref": "common.json#/filerefs" }, + "logo": { "$ref": "common.json#/filerefs" } + }, + "required": ["id", "name", "duration"], + "additionalProperties": false +} diff --git a/json-schema/event-feed.json b/json-schema/event-feed.json new file mode 100644 index 00000000..3b9ee221 --- /dev/null +++ b/json-schema/event-feed.json @@ -0,0 +1,14 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "CLICS CCS REST API: event-feed", + "description": "Single line response of this NDJSON API call", + "type": "object", + "properties": { + "id": { "$ref": "common.json#/identifier" }, + "type": { "$ref": "common.json#/endpoints" }, + "op": { "enum": [ "create", "update", "delete" ] }, + "data": { "type": "object" } + }, + "required": ["id", "type", "op", "data"], + "additionalProperties": false +} diff --git a/json-schema/groups.json b/json-schema/groups.json new file mode 100644 index 00000000..e79874c8 --- /dev/null +++ b/json-schema/groups.json @@ -0,0 +1,19 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "CLICS CCS REST API: groups", + "description": "JSON response of this API call", + "type": "array", + "uniqueItems": true, + "items": { + "type": "object", + "properties": { + "id": { "$ref": "common.json#/identifier" }, + "icpc_id": { "type": [ "string", "null" ] }, + "name": { "type": "string" }, + "type": { "type": "string" }, + "hidden": { "type": "boolean" } + }, + "required": ["id", "name"], + "additionalProperties": false + } +} diff --git a/json-schema/judgement-types.json b/json-schema/judgement-types.json new file mode 100644 index 00000000..c7211bab --- /dev/null +++ b/json-schema/judgement-types.json @@ -0,0 +1,18 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "CLICS CCS REST API: judgement_types", + "description": "JSON response of this API call", + "type": "array", + "uniqueItems": true, + "items": { + "type": "object", + "properties": { + "id": { "$ref": "common.json#/judgementtypeid" }, + "name": { "type": "string" }, + "penalty": { "type": "boolean" }, + "solved": { "type": "boolean" } + }, + "required": ["id", "name", "solved"], + "additionalProperties": false + } +} diff --git a/json-schema/judgements.json b/json-schema/judgements.json new file mode 100644 index 00000000..a00c2387 --- /dev/null +++ b/json-schema/judgements.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "CLICS CCS REST API: judgements", + "description": "JSON response of this API call", + "type": "array", + "uniqueItems": true, + "items": { + "type": "object", + "properties": { + "id": { "$ref": "common.json#/identifier" }, + "submission_id": { "$ref": "common.json#/identifier" }, + "judgement_type_id": { "$ref": "common.json#/judgementtypeidornull" }, + "start_time": { "$ref": "common.json#/abstime" }, + "start_contest_time": { "$ref": "common.json#/reltime" }, + "end_time": { "$ref": "common.json#/abstimeornull" }, + "end_contest_time": { + "oneOf": [ + { "$ref": "common.json#/reltime" }, + { "type": "null" } + ] + }, + "max_run_time": { + "oneOf": [ + { + "$ref": "common.json#/decimal", + "minimum": 0 + }, + { "type": "null" } + ] + } + }, + "required": ["id", "submission_id", "start_time", "start_contest_time", "end_time", "end_contest_time"], + "additionalProperties": false + } +} diff --git a/json-schema/languages.json b/json-schema/languages.json new file mode 100644 index 00000000..680cba27 --- /dev/null +++ b/json-schema/languages.json @@ -0,0 +1,16 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "CLICS CCS REST API: languages", + "description": "JSON response of this API call", + "type": "array", + "uniqueItems": true, + "items": { + "type": "object", + "properties": { + "id": { "$ref": "common.json#/identifier" }, + "name": { "type": "string" } + }, + "required": ["id", "name"], + "additionalProperties": false + } +} diff --git a/json-schema/organizations.json b/json-schema/organizations.json new file mode 100644 index 00000000..4f10835c --- /dev/null +++ b/json-schema/organizations.json @@ -0,0 +1,52 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "CLICS CCS REST API: organizations", + "description": "JSON response of this API call", + "type": "array", + "uniqueItems": true, + "items": { + "type": "object", + "properties": { + "id": { "$ref": "common.json#/identifier" }, + "icpc_id": { "type": [ "string", "null" ] }, + "name": { "type": "string" }, + "formal_name": { "type": [ "string", "null" ] }, + "country": { + "oneOf": [ + { + "type": "string", + "pattern": "^[A-Z]{3}$" + }, + { "type": "null" } + ] + }, + "url": { "type": [ "string", "null" ] }, + "twitter_hashtag": { "type": [ "string", "null" ] }, + "location": { + "oneOf": [ + { + "type": "object", + "properties": { + "latitude": { + "type": "number", + "minimum": -90, + "maximum": 90 + }, + "longitude": { + "type": "number", + "minimum": -180, + "maximum": 180 + } + }, + "required": ["latitude", "longitude"], + "additionalProperties": false + }, + { "type": "null" } + ] + }, + "logo": { "$ref": "common.json#/filerefs" } + }, + "required": ["id", "name"], + "additionalProperties": false + } +} diff --git a/json-schema/problems.json b/json-schema/problems.json new file mode 100644 index 00000000..4ea308bb --- /dev/null +++ b/json-schema/problems.json @@ -0,0 +1,31 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "CLICS CCS REST API: problems", + "description": "JSON response of this API call", + "type": "array", + "uniqueItems": true, + "items": { + "type": "object", + "properties": { + "id": { "$ref": "common.json#/identifier" }, + "label": { "$ref": "common.json#/label" }, + "name": { "type": "string" }, + "ordinal": { "$ref": "common.json#/ordinal" }, + "rgb": { + "type": "string", + "pattern": "^#[A-Fa-f0-9]{3}([A-Fa-f0-9]{3})?$" + }, + "color": { "type": "string" }, + "time_limit": { + "$ref": "common.json#/decimal", + "minimum": 0 + }, + "test_data_count": { + "type": "integer", + "minimum": 0 + } + }, + "required": ["id", "label", "name", "ordinal", "test_data_count"], + "additionalProperties": false + } +} diff --git a/json-schema/runs.json b/json-schema/runs.json new file mode 100644 index 00000000..eca9605d --- /dev/null +++ b/json-schema/runs.json @@ -0,0 +1,24 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "CLICS CCS REST API: runs", + "description": "JSON response of this API call", + "type": "array", + "uniqueItems": true, + "items": { + "type": "object", + "properties": { + "id": { "$ref": "common.json#/identifier" }, + "judgement_id": { "$ref": "common.json#/identifier" }, + "ordinal": { "$ref": "common.json#/ordinal" }, + "judgement_type_id": { "$ref": "common.json#/judgementtypeid" }, + "time": { "$ref": "common.json#/abstime" }, + "contest_time": { "$ref": "common.json#/reltime" }, + "run_time": { + "$ref": "common.json#/decimal", + "minimum": 0 + } + }, + "required": ["id", "judgement_id", "ordinal", "judgement_type_id", "time", "contest_time"], + "additionalProperties": false + } +} diff --git a/json-schema/scoreboard.json b/json-schema/scoreboard.json new file mode 100644 index 00000000..6face4d4 --- /dev/null +++ b/json-schema/scoreboard.json @@ -0,0 +1,65 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "CLICS CCS REST API: scoreboard", + "description": "JSON response of this API call", + "type": "array", + "uniqueItems": true, + "items": { + "type": "object", + "properties": { + "rank": { + "type": "integer", + "minimum": 1 + }, + "team_id": { "$ref": "common.json#/identifier" }, + "score": { + "type": "object", + "properties": { + "num_solved": { + "type": "integer", + "minimum": 0 + }, + "total_time": { + "type": "integer", + "minimum": 0 + } + }, + "required": ["num_solved", "total_time"], + "additionalProperties": false + }, + "problems": { + "type": "array", + "items": { + "type": "object", + "properties": { + "problem_id": { "$ref": "common.json#/identifier" }, + "num_judged": { + "type": "integer", + "minimum": 0 + }, + "num_pending": { + "type": "integer", + "minimum": 0 + }, + "solved": { "type": "boolean" }, + "time": { "type": "integer", "minimum": 0 } + }, + "oneOf": [ + { + "properties": { "solved": { "enum": [false] } }, + "not": { "required": ["time"] } + }, + { + "properties": { "solved": { "enum": [true] } }, + "required": ["time"] + } + ], + "required": ["problem_id", "num_judged", "num_pending", "solved"], + "additionalProperties": false + } + } + }, + "required": ["rank", "team_id", "score", "problems"], + "additionalProperties": false + } +} diff --git a/json-schema/state.json b/json-schema/state.json new file mode 100644 index 00000000..107c691c --- /dev/null +++ b/json-schema/state.json @@ -0,0 +1,15 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "CLICS CCS REST API: state", + "description": "JSON response of this API call", + "type": "object", + "properties": { + "started": { "$ref": "common.json#/abstimeornull" }, + "ended": { "$ref": "common.json#/abstimeornull" }, + "frozen": { "$ref": "common.json#/abstimeornull" }, + "thawed": { "$ref": "common.json#/abstimeornull" }, + "finalized": { "$ref": "common.json#/abstimeornull" } + }, + "required": ["started", "ended", "finalized"], + "additionalProperties": false +} diff --git a/json-schema/submissions.json b/json-schema/submissions.json new file mode 100644 index 00000000..7c02bfee --- /dev/null +++ b/json-schema/submissions.json @@ -0,0 +1,23 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "CLICS CCS REST API: submissions", + "description": "JSON response of this API call", + "type": "array", + "uniqueItems": true, + "items": { + "type": "object", + "properties": { + "id": { "$ref": "common.json#/identifier" }, + "language_id": { "$ref": "common.json#/identifier" }, + "problem_id": { "$ref": "common.json#/identifier" }, + "team_id": { "$ref": "common.json#/identifier" }, + "time": { "$ref": "common.json#/abstime" }, + "contest_time": { "$ref": "common.json#/reltime" }, + "entry_point": { "type": [ "string", "null" ] }, + "files": { "$ref": "common.json#/filerefs" }, + "reaction": { "$ref": "common.json#/filerefs" } + }, + "required": ["id", "language_id", "problem_id", "team_id", "time", "contest_time", "files"], + "additionalProperties": false + } +} diff --git a/json-schema/team-members.json b/json-schema/team-members.json new file mode 100644 index 00000000..3ec0f6d3 --- /dev/null +++ b/json-schema/team-members.json @@ -0,0 +1,27 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "CLICS CCS REST API: team-members", + "description": "JSON response of this API call", + "type": "array", + "uniqueItems": true, + "items": { + "type": "object", + "properties": { + "id": { "$ref": "common.json#/identifier" }, + "team_id": { "$ref": "common.json#/identifier" }, + "icpc_id": { "type": [ "string", "null" ] }, + "first_name": { "type": "string" }, + "last_name": { "type": "string" }, + "sex": { + "oneOf": [ + { "enum": [ "male", "female" ] }, + { "type": "null" } + ] + }, + "role": { "enum": [ "contestant", "coach" ] }, + "photo": { "$ref": "common.json#/filerefs" } + }, + "required": ["id", "team_id", "first_name", "last_name"], + "additionalProperties": false + } +} diff --git a/json-schema/teams.json b/json-schema/teams.json new file mode 100644 index 00000000..c7c35b60 --- /dev/null +++ b/json-schema/teams.json @@ -0,0 +1,38 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "CLICS CCS REST API: teams", + "description": "JSON response of this API call", + "type": "array", + "uniqueItems": true, + "items": { + "type": "object", + "properties": { + "id": { "$ref": "common.json#/identifier" }, + "icpc_id": { "type": [ "string", "null" ] }, + "name": { "type": "string" }, + "organization_id": { "$ref": "common.json#/identifierornull" }, + "group_ids": { + "type": "array", + "uniqueItems": true, + "items": { "$ref": "common.json#/identifierornull" } + }, + "location": { + "type": "object", + "properties": { + "x": { "type": "number" }, + "y": { "type": "number" }, + "rotation": { "type": "number" } + }, + "required": ["x", "y", "rotation"], + "additionalProperties": false + }, + "photo": { "$ref": "common.json#/filerefs" }, + "video": { "$ref": "common.json#/filerefs" }, + "backup": { "$ref": "common.json#/filerefs" }, + "desktop": { "$ref": "common.json#/filerefs" }, + "webcam": { "$ref": "common.json#/filerefs" } + }, + "required": ["id", "name"], + "additionalProperties": false + } +} From 7171d7b1792ec7f9f42c6d4394024049e93d3fe2 Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Sun, 28 Jan 2018 22:16:32 +0100 Subject: [PATCH 002/107] Simplify validating event-feed by transforming into JSON array. --- check-api.sh | 22 +++++----------------- json-schema/event-feed-array.json | 10 ++++++++++ json-schema/event-feed.json | 17 ++++++++++++++++- 3 files changed, 31 insertions(+), 18 deletions(-) create mode 100644 json-schema/event-feed-array.json diff --git a/check-api.sh b/check-api.sh index db124e58..62f651aa 100755 --- a/check-api.sh +++ b/check-api.sh @@ -120,28 +120,16 @@ done # Now do special case event-feed endpoint ENDPOINT='event-feed' -SCHEMA="$MYDIR/json-schema/$ENDPOINT.json" +SCHEMA="$MYDIR/json-schema/$ENDPOINT-array.json" OUTPUT="$TMP/$ENDPOINT.json" URL="${API_URL%/}/$ENDPOINT" if query_endpoint "$OUTPUT" "$URL" ; then + # Delete empty lines and transform NDJSON into a JSON array. + sed -i '/^$/d;1 s/^/[/;s/$/,/;$ s/,$/]/' "$OUTPUT" + printf '%20s: ' "$ENDPOINT" - # Do line by line validation of NDJSON, quit at first failure. - TMPOUTPUT="$TMP/event-feed-line.json" - TMPRESULT="$TMP/event-feed-tmp.txt" - VALID=1 - while read LINE ; do - # Skip empty lines that may be inserted as heartbeat. - [ -z "$LINE" ] && continue - echo "$LINE" > "$TMPOUTPUT" - if ! validate_schema "$TMPOUTPUT" "$SCHEMA" > "$TMPRESULT"; then - printf "Failed to validate:\n%s\n" "$LINE" - cat "$TMPRESULT" - VALID=0 - break - fi - done < "$OUTPUT" - [ "$VALID" -eq 1 ] && echo "OK" + validate_schema "$OUTPUT" "$SCHEMA" else printf '%20s: Failed to download\n' "$ENDPOINT" fi diff --git a/json-schema/event-feed-array.json b/json-schema/event-feed-array.json new file mode 100644 index 00000000..5d28559c --- /dev/null +++ b/json-schema/event-feed-array.json @@ -0,0 +1,10 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "CLICS CCS REST API: event-feed array", + "description": "JSON array of responses of this NDJSON API call", + "type": "array", + "uniqueItems": true, + "items": { + "$ref": "event-feed.json#/" + } +} diff --git a/json-schema/event-feed.json b/json-schema/event-feed.json index 3b9ee221..b325fc0c 100644 --- a/json-schema/event-feed.json +++ b/json-schema/event-feed.json @@ -7,7 +7,22 @@ "id": { "$ref": "common.json#/identifier" }, "type": { "$ref": "common.json#/endpoints" }, "op": { "enum": [ "create", "update", "delete" ] }, - "data": { "type": "object" } + "data": { + "type": "object", + "properties": { + "id": { "$ref": "common.json#/identifier" } + }, + "required": ["id"] + }, + "oneOf": [ + { + "op": { "enum": [ "create", "update" ] } + }, + { + "op": { "enum": [ "delete" ] }, + "data": { "additionalProperties": false } + } + ] }, "required": ["id", "type", "op", "data"], "additionalProperties": false From ff87d5f2ac0f2213c74b1fd945c4541262780055 Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Sun, 28 Jan 2018 22:35:15 +0100 Subject: [PATCH 003/107] Add contest-api script to README, rename to Contest API in schema file. --- json-schema/awards.json | 2 +- json-schema/clarifications.json | 2 +- json-schema/common.json | 2 +- json-schema/contest.json | 2 +- json-schema/event-feed-array.json | 2 +- json-schema/event-feed.json | 3 ++- json-schema/groups.json | 2 +- json-schema/judgement-types.json | 2 +- json-schema/judgements.json | 2 +- json-schema/languages.json | 2 +- json-schema/organizations.json | 2 +- json-schema/problems.json | 2 +- json-schema/runs.json | 2 +- json-schema/scoreboard.json | 2 +- json-schema/state.json | 2 +- json-schema/submissions.json | 2 +- json-schema/team-members.json | 2 +- json-schema/teams.json | 2 +- 18 files changed, 19 insertions(+), 18 deletions(-) diff --git a/json-schema/awards.json b/json-schema/awards.json index 2f2f15b4..2baf3227 100644 --- a/json-schema/awards.json +++ b/json-schema/awards.json @@ -1,6 +1,6 @@ { "$schema": "http://json-schema.org/draft-04/schema#", - "title": "CLICS CCS REST API: awards", + "title": "CLICS Contest API: awards", "description": "JSON response of this API call", "type": "array", "uniqueItems": true, diff --git a/json-schema/clarifications.json b/json-schema/clarifications.json index d648c6de..42d56506 100644 --- a/json-schema/clarifications.json +++ b/json-schema/clarifications.json @@ -1,6 +1,6 @@ { "$schema": "http://json-schema.org/draft-04/schema#", - "title": "CLICS CCS REST API: clarifications", + "title": "CLICS Contest API: clarifications", "description": "JSON response of this API call", "type": "array", "uniqueItems": true, diff --git a/json-schema/common.json b/json-schema/common.json index f4f31964..16e50806 100644 --- a/json-schema/common.json +++ b/json-schema/common.json @@ -1,6 +1,6 @@ { "$schema": "http://json-schema.org/draft-04/schema#", - "title": "CLICS CCS REST API - common definitions", + "title": "CLICS Contest API - common definitions", "description": "Common definitions of objects used in the API calls", "endpoints": { diff --git a/json-schema/contest.json b/json-schema/contest.json index 02fd7457..18d82d5c 100644 --- a/json-schema/contest.json +++ b/json-schema/contest.json @@ -1,6 +1,6 @@ { "$schema": "http://json-schema.org/draft-04/schema#", - "title": "CLICS CCS REST API: contest", + "title": "CLICS Contest API: contest", "description": "JSON response of this API call", "type": "object", "properties": { diff --git a/json-schema/event-feed-array.json b/json-schema/event-feed-array.json index 5d28559c..26726313 100644 --- a/json-schema/event-feed-array.json +++ b/json-schema/event-feed-array.json @@ -1,6 +1,6 @@ { "$schema": "http://json-schema.org/draft-04/schema#", - "title": "CLICS CCS REST API: event-feed array", + "title": "CLICS Contest API: event-feed array", "description": "JSON array of responses of this NDJSON API call", "type": "array", "uniqueItems": true, diff --git a/json-schema/event-feed.json b/json-schema/event-feed.json index b325fc0c..23d1850a 100644 --- a/json-schema/event-feed.json +++ b/json-schema/event-feed.json @@ -1,11 +1,12 @@ { "$schema": "http://json-schema.org/draft-04/schema#", - "title": "CLICS CCS REST API: event-feed", + "title": "CLICS Contest API: event-feed", "description": "Single line response of this NDJSON API call", "type": "object", "properties": { "id": { "$ref": "common.json#/identifier" }, "type": { "$ref": "common.json#/endpoints" }, + "time": { "$ref": "common.json#/abstime" }, "op": { "enum": [ "create", "update", "delete" ] }, "data": { "type": "object", diff --git a/json-schema/groups.json b/json-schema/groups.json index e79874c8..f585a680 100644 --- a/json-schema/groups.json +++ b/json-schema/groups.json @@ -1,6 +1,6 @@ { "$schema": "http://json-schema.org/draft-04/schema#", - "title": "CLICS CCS REST API: groups", + "title": "CLICS Contest API: groups", "description": "JSON response of this API call", "type": "array", "uniqueItems": true, diff --git a/json-schema/judgement-types.json b/json-schema/judgement-types.json index c7211bab..a6fe807c 100644 --- a/json-schema/judgement-types.json +++ b/json-schema/judgement-types.json @@ -1,6 +1,6 @@ { "$schema": "http://json-schema.org/draft-04/schema#", - "title": "CLICS CCS REST API: judgement_types", + "title": "CLICS Contest API: judgement_types", "description": "JSON response of this API call", "type": "array", "uniqueItems": true, diff --git a/json-schema/judgements.json b/json-schema/judgements.json index a00c2387..46964576 100644 --- a/json-schema/judgements.json +++ b/json-schema/judgements.json @@ -1,6 +1,6 @@ { "$schema": "http://json-schema.org/draft-04/schema#", - "title": "CLICS CCS REST API: judgements", + "title": "CLICS Contest API: judgements", "description": "JSON response of this API call", "type": "array", "uniqueItems": true, diff --git a/json-schema/languages.json b/json-schema/languages.json index 680cba27..10d0f758 100644 --- a/json-schema/languages.json +++ b/json-schema/languages.json @@ -1,6 +1,6 @@ { "$schema": "http://json-schema.org/draft-04/schema#", - "title": "CLICS CCS REST API: languages", + "title": "CLICS Contest API: languages", "description": "JSON response of this API call", "type": "array", "uniqueItems": true, diff --git a/json-schema/organizations.json b/json-schema/organizations.json index 4f10835c..04a77bac 100644 --- a/json-schema/organizations.json +++ b/json-schema/organizations.json @@ -1,6 +1,6 @@ { "$schema": "http://json-schema.org/draft-04/schema#", - "title": "CLICS CCS REST API: organizations", + "title": "CLICS Contest API: organizations", "description": "JSON response of this API call", "type": "array", "uniqueItems": true, diff --git a/json-schema/problems.json b/json-schema/problems.json index 4ea308bb..449c6669 100644 --- a/json-schema/problems.json +++ b/json-schema/problems.json @@ -1,6 +1,6 @@ { "$schema": "http://json-schema.org/draft-04/schema#", - "title": "CLICS CCS REST API: problems", + "title": "CLICS Contest API: problems", "description": "JSON response of this API call", "type": "array", "uniqueItems": true, diff --git a/json-schema/runs.json b/json-schema/runs.json index eca9605d..382b322f 100644 --- a/json-schema/runs.json +++ b/json-schema/runs.json @@ -1,6 +1,6 @@ { "$schema": "http://json-schema.org/draft-04/schema#", - "title": "CLICS CCS REST API: runs", + "title": "CLICS Contest API: runs", "description": "JSON response of this API call", "type": "array", "uniqueItems": true, diff --git a/json-schema/scoreboard.json b/json-schema/scoreboard.json index 6face4d4..f0b18ba7 100644 --- a/json-schema/scoreboard.json +++ b/json-schema/scoreboard.json @@ -1,6 +1,6 @@ { "$schema": "http://json-schema.org/draft-04/schema#", - "title": "CLICS CCS REST API: scoreboard", + "title": "CLICS Contest API: scoreboard", "description": "JSON response of this API call", "type": "array", "uniqueItems": true, diff --git a/json-schema/state.json b/json-schema/state.json index 107c691c..cff83ca1 100644 --- a/json-schema/state.json +++ b/json-schema/state.json @@ -1,6 +1,6 @@ { "$schema": "http://json-schema.org/draft-04/schema#", - "title": "CLICS CCS REST API: state", + "title": "CLICS Contest API: state", "description": "JSON response of this API call", "type": "object", "properties": { diff --git a/json-schema/submissions.json b/json-schema/submissions.json index 7c02bfee..4e351e95 100644 --- a/json-schema/submissions.json +++ b/json-schema/submissions.json @@ -1,6 +1,6 @@ { "$schema": "http://json-schema.org/draft-04/schema#", - "title": "CLICS CCS REST API: submissions", + "title": "CLICS Contest API: submissions", "description": "JSON response of this API call", "type": "array", "uniqueItems": true, diff --git a/json-schema/team-members.json b/json-schema/team-members.json index 3ec0f6d3..e4406886 100644 --- a/json-schema/team-members.json +++ b/json-schema/team-members.json @@ -1,6 +1,6 @@ { "$schema": "http://json-schema.org/draft-04/schema#", - "title": "CLICS CCS REST API: team-members", + "title": "CLICS Contest API: team-members", "description": "JSON response of this API call", "type": "array", "uniqueItems": true, diff --git a/json-schema/teams.json b/json-schema/teams.json index c7c35b60..39d50eda 100644 --- a/json-schema/teams.json +++ b/json-schema/teams.json @@ -1,6 +1,6 @@ { "$schema": "http://json-schema.org/draft-04/schema#", - "title": "CLICS CCS REST API: teams", + "title": "CLICS Contest API: teams", "description": "JSON response of this API call", "type": "array", "uniqueItems": true, From 8ab1ec6f432fefe45b86c56229dfa1307d5e1f16 Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Mon, 29 Jan 2018 00:33:10 +0100 Subject: [PATCH 004/107] Remove accidentally committed line used for testing. --- json-schema/event-feed.json | 1 - 1 file changed, 1 deletion(-) diff --git a/json-schema/event-feed.json b/json-schema/event-feed.json index 23d1850a..0a80a26b 100644 --- a/json-schema/event-feed.json +++ b/json-schema/event-feed.json @@ -6,7 +6,6 @@ "properties": { "id": { "$ref": "common.json#/identifier" }, "type": { "$ref": "common.json#/endpoints" }, - "time": { "$ref": "common.json#/abstime" }, "op": { "enum": [ "create", "update", "delete" ] }, "data": { "type": "object", From cc3a7b6f24247b601ff8282153e996b34da5e024 Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Sat, 10 Feb 2018 16:52:01 +0100 Subject: [PATCH 005/107] Record and return exit code. --- check-api.sh | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/check-api.sh b/check-api.sh index 62f651aa..8ce5057b 100755 --- a/check-api.sh +++ b/check-api.sh @@ -90,6 +90,8 @@ validate_schema() return $EXITCODE } +EXITCODE=0 + for ENDPOINT in $ENDPOINTS ; do if [ "${ENDPOINTS_OPTIONAL/${ENDPOINT}/}" != "$ENDPOINTS_OPTIONAL" ]; then OPTIONAL=1 @@ -109,11 +111,14 @@ for ENDPOINT in $ENDPOINTS ; do if query_endpoint "$OUTPUT" "$URL" $OPTIONAL ; then printf '%20s: ' "$ENDPOINT" validate_schema "$OUTPUT" "$SCHEMA" + EXIT=$? + [ $EXIT -gt $EXITCODE ] && EXITCODE=$EXIT else if [ -n "$OPTIONAL" ]; then printf '%20s: Optional, not present\n' "$ENDPOINT" else printf '%20s: Failed to download\n' "$ENDPOINT" + [ $EXITCODE -eq 0 ] && EXITCODE=1 fi fi done @@ -130,10 +135,12 @@ if query_endpoint "$OUTPUT" "$URL" ; then printf '%20s: ' "$ENDPOINT" validate_schema "$OUTPUT" "$SCHEMA" + EXIT=$? + [ $EXIT -gt $EXITCODE ] && EXITCODE=$EXIT else printf '%20s: Failed to download\n' "$ENDPOINT" fi rm -rf $TMP -exit 0 +exit $EXITCODE From 56db13200c524922db9b3e3faa0eeb29abf51548 Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Sat, 10 Feb 2018 20:46:28 +0100 Subject: [PATCH 006/107] Add options for debugging and quiet mode. --- check-api.sh | 74 +++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 59 insertions(+), 15 deletions(-) diff --git a/check-api.sh b/check-api.sh index 8ce5057b..b80de972 100755 --- a/check-api.sh +++ b/check-api.sh @@ -38,10 +38,50 @@ team-members awards ' +error() +{ + echo "Error: $*" + exit 1 +} + +verbose() +{ + if [ -z "$QUIET" ]; then + if [ $# -eq 1 ]; then + echo "$1" + else + printf "$@" + fi + fi +} + +# Parse command-line options: +while getopts 'dq' OPT ; do + case "$OPT" in + d) DEBUG=1 ;; + q) QUIET=1 ;; + :) + error "option '$OPTARG' requires an argument." + exit 1 + ;; + ?) + error "unknown option '$OPTARG'." + exit 1 + ;; + *) + error "unknown error reading option '$OPT', value '$OPTARG'." + exit 1 + ;; + esac +done +shift $((OPTIND-1)) + +[ -n "$DEBUG" ] && set -x + API_URL="$1" if [ -z "$API_URL" ]; then - echo "Error: API URL argument expected." + error "API URL argument expected." exit 1 fi @@ -55,26 +95,29 @@ query_endpoint() local URL="$2" local OPTIONAL="$3" + local CURLOPTS='-k -n -s' + [ -n "$DEBUG" ] && CURLOPTS="$CURLOPTS -S" + # Special case timeout for event-feed NDJSON endpoint. if [ "${URL/event-feed/}" != "$URL" ]; then - TIMEOUT='--max-time 10' + CURLOPTS="$CURLOPTS --max-time 10" fi - local HTTPCODE=$(curl -kns $TIMEOUT -w "%{http_code}\n" -o "$OUTPUT" "${URL}${URL_EXTRA}") + local HTTPCODE=$(curl $CURLOPTS -w "%{http_code}\n" -o "$OUTPUT" "${URL}${URL_EXTRA}") local EXITCODE="$?" if [ $EXITCODE -eq 28 ]; then # timeout if [ -z "$TIMEOUT" ]; then - echo "Warning curl request timed out for '$URL'." + verbose "Warning: curl request timed out for '$URL'." return $EXITCODE fi elif [ $EXITCODE -ne 0 ]; then - echo "Warning: curl returned exitcode $EXITCODE for '$URL'." + verbose "Warning: curl returned exitcode $EXITCODE for '$URL'." return $EXITCODE elif [ $HTTPCODE -ne 200 ]; then - [ -n "$OPTIONAL" ] || echo "Warning: curl returned HTTP status $HTTPCODE for '$URL'." + [ -n "$OPTIONAL" ] || verbose "Warning: curl returned HTTP status $HTTPCODE for '$URL'." return 1 elif [ ! -e "$OUTPUT" -o ! -s "$OUTPUT" ]; then - [ -n "$OPTIONAL" ] || echo "Warning: no or empty file downloaded by curl." + [ -n "$OPTIONAL" ] || verbose "Warning: no or empty file downloaded by curl." return 1 fi return 0 @@ -84,9 +127,10 @@ validate_schema() { local DATA="$1" SCHEMA="$2" - ${VALIDATE_JSON:-validate-json} "$DATA" "$SCHEMA" + local RESULT=$(${VALIDATE_JSON:-validate-json} "$DATA" "$SCHEMA") local EXITCODE=$? - [ $EXITCODE -eq 0 ] && echo "OK" + verbose '%s' "$RESULT" + [ $EXITCODE -eq 0 ] && verbose "OK" return $EXITCODE } @@ -109,15 +153,15 @@ for ENDPOINT in $ENDPOINTS ; do OUTPUT="$TMP/$ENDPOINT.json" if query_endpoint "$OUTPUT" "$URL" $OPTIONAL ; then - printf '%20s: ' "$ENDPOINT" + verbose '%20s: ' "$ENDPOINT" validate_schema "$OUTPUT" "$SCHEMA" EXIT=$? [ $EXIT -gt $EXITCODE ] && EXITCODE=$EXIT else if [ -n "$OPTIONAL" ]; then - printf '%20s: Optional, not present\n' "$ENDPOINT" + verbose '%20s: Optional, not present\n' "$ENDPOINT" else - printf '%20s: Failed to download\n' "$ENDPOINT" + verbose '%20s: Failed to download\n' "$ENDPOINT" [ $EXITCODE -eq 0 ] && EXITCODE=1 fi fi @@ -133,14 +177,14 @@ if query_endpoint "$OUTPUT" "$URL" ; then # Delete empty lines and transform NDJSON into a JSON array. sed -i '/^$/d;1 s/^/[/;s/$/,/;$ s/,$/]/' "$OUTPUT" - printf '%20s: ' "$ENDPOINT" + verbose '%20s: ' "$ENDPOINT" validate_schema "$OUTPUT" "$SCHEMA" EXIT=$? [ $EXIT -gt $EXITCODE ] && EXITCODE=$EXIT else - printf '%20s: Failed to download\n' "$ENDPOINT" + verbose '%20s: Failed to download\n' "$ENDPOINT" fi -rm -rf $TMP +[ -n "$DEBUG" ] || rm -rf $TMP exit $EXITCODE From 8bc3f9b09b6d78a2a65417165701e4141de72cb9 Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Sun, 11 Feb 2018 01:34:10 +0100 Subject: [PATCH 007/107] Separate local var declaration and assigning from command. We want to get the exit code of the command, but if we do the variable assignment inside the local declaration, then the exit code will be that of local not the command executed. --- check-api.sh | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/check-api.sh b/check-api.sh index b80de972..65b9dc2e 100755 --- a/check-api.sh +++ b/check-api.sh @@ -94,6 +94,7 @@ query_endpoint() local OUTPUT="$1" local URL="$2" local OPTIONAL="$3" + local HTTPCODE EXITCODE local CURLOPTS='-k -n -s' [ -n "$DEBUG" ] && CURLOPTS="$CURLOPTS -S" @@ -103,8 +104,8 @@ query_endpoint() CURLOPTS="$CURLOPTS --max-time 10" fi - local HTTPCODE=$(curl $CURLOPTS -w "%{http_code}\n" -o "$OUTPUT" "${URL}${URL_EXTRA}") - local EXITCODE="$?" + HTTPCODE=$(curl $CURLOPTS -w "%{http_code}\n" -o "$OUTPUT" "${URL}${URL_EXTRA}") + EXITCODE="$?" if [ $EXITCODE -eq 28 ]; then # timeout if [ -z "$TIMEOUT" ]; then verbose "Warning: curl request timed out for '$URL'." @@ -125,10 +126,10 @@ query_endpoint() validate_schema() { - local DATA="$1" SCHEMA="$2" + local DATA="$1" SCHEMA="$2" RESULT EXITCODE - local RESULT=$(${VALIDATE_JSON:-validate-json} "$DATA" "$SCHEMA") - local EXITCODE=$? + RESULT=$(${VALIDATE_JSON:-validate-json} "$DATA" "$SCHEMA") + EXITCODE=$? verbose '%s' "$RESULT" [ $EXITCODE -eq 0 ] && verbose "OK" return $EXITCODE From 37249ef3308010a361712b2cb86d7d7ee512bf07 Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Sun, 11 Feb 2018 16:51:36 +0100 Subject: [PATCH 008/107] Tiny tweak to insert newline after any validation results. --- check-api.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/check-api.sh b/check-api.sh index 65b9dc2e..51e8b64a 100755 --- a/check-api.sh +++ b/check-api.sh @@ -131,7 +131,11 @@ validate_schema() RESULT=$(${VALIDATE_JSON:-validate-json} "$DATA" "$SCHEMA") EXITCODE=$? verbose '%s' "$RESULT" - [ $EXITCODE -eq 0 ] && verbose "OK" + if [ $EXITCODE -eq 0 ]; then + verbose 'OK' + else + verbose '' + fi return $EXITCODE } From e056a58ed00d275d5bcff8abe0aeb8cf4d188323 Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Sun, 11 Feb 2018 18:15:19 +0100 Subject: [PATCH 009/107] Readd TIMEOUT variable to check for when getting the event-feed. --- check-api.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/check-api.sh b/check-api.sh index 51e8b64a..6c4f2a09 100755 --- a/check-api.sh +++ b/check-api.sh @@ -101,6 +101,7 @@ query_endpoint() # Special case timeout for event-feed NDJSON endpoint. if [ "${URL/event-feed/}" != "$URL" ]; then + TIMEOUT=1 CURLOPTS="$CURLOPTS --max-time 10" fi From 64578da6488f4cd81a16aad43e0cb60e880152be Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Sun, 11 Feb 2018 23:12:37 +0100 Subject: [PATCH 010/107] Add usage information. --- check-api.sh | 41 +++++++++++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/check-api.sh b/check-api.sh index 6c4f2a09..4abb3c7a 100755 --- a/check-api.sh +++ b/check-api.sh @@ -1,11 +1,6 @@ #!/bin/bash # Checks whether a Contest API conforms to the specification # https://clics.ecs.baylor.edu/index.php/Contest_API -# -# Currently only checks a single contest under api/contests/{id}/ -# -# Rquires https://github.com/justinrainbow/json-schema -# which can be installed with: composer require justinrainbow/json-schema # Set path to json-validate binary if it's not in PATH: #VALIDATE_JSON=/path/to/json-validate @@ -55,10 +50,44 @@ verbose() fi } +usage() +{ + cat < Date: Sun, 11 Feb 2018 23:39:24 +0100 Subject: [PATCH 011/107] Add option to check that collection endpoints are non-empty. --- check-api.sh | 12 +++++++++++- json-schema/awards.json | 1 + json-schema/clarifications.json | 1 + json-schema/common.json | 4 ++++ json-schema/event-feed-array.json | 1 + json-schema/groups.json | 1 + json-schema/judgement-types.json | 1 + json-schema/judgements.json | 1 + json-schema/languages.json | 1 + json-schema/organizations.json | 1 + json-schema/problems.json | 1 + json-schema/submissions.json | 1 + json-schema/team-members.json | 1 + json-schema/teams.json | 1 + 14 files changed, 27 insertions(+), 1 deletion(-) diff --git a/check-api.sh b/check-api.sh index 4abb3c7a..3c3ef746 100755 --- a/check-api.sh +++ b/check-api.sh @@ -73,6 +73,7 @@ Options: -d Turn on shell script debugging. -h Snow this help output. -j PROG Specify the path to the 'validate-json' binary. + -n Require that all collection endpoints are non-empty. -q Quiet mode: suppress all output except script errors. The script reports endpoints checked and validations errors. @@ -88,6 +89,7 @@ while getopts 'dhj:nq' OPT ; do d) DEBUG=1 ;; h) usage ; exit 0 ;; j) VALIDATE_JSON="$OPTARG" ;; + n) NONEMPTY=1 ;; q) QUIET=1 ;; :) error "option '$OPTARG' requires an argument." @@ -169,6 +171,14 @@ validate_schema() return $EXITCODE } +# Copy schema files so we can modify common.json for the non-empty option +cp -a "$MYDIR/json-schema" "$TMP" + +if [ -n "$NONEMPTY" ]; then + # Don't understand why the first '\t' needs a double escape... + sed -i '/"nonemptyarray":/a \\t\t"minItems": 1' "$TMP/json-schema/common.json" +fi + EXITCODE=0 for ENDPOINT in $ENDPOINTS ; do @@ -184,7 +194,7 @@ for ENDPOINT in $ENDPOINTS ; do URL="${API_URL%/}/$ENDPOINT" fi - SCHEMA="$MYDIR/json-schema/$ENDPOINT.json" + SCHEMA="$TMP/json-schema/$ENDPOINT.json" OUTPUT="$TMP/$ENDPOINT.json" if query_endpoint "$OUTPUT" "$URL" $OPTIONAL ; then diff --git a/json-schema/awards.json b/json-schema/awards.json index 2baf3227..79885f27 100644 --- a/json-schema/awards.json +++ b/json-schema/awards.json @@ -4,6 +4,7 @@ "description": "JSON response of this API call", "type": "array", "uniqueItems": true, + "$ref": "common.json#/nonemptyarray", "items": { "type": "object", "properties": { diff --git a/json-schema/clarifications.json b/json-schema/clarifications.json index 42d56506..cea8f5ea 100644 --- a/json-schema/clarifications.json +++ b/json-schema/clarifications.json @@ -4,6 +4,7 @@ "description": "JSON response of this API call", "type": "array", "uniqueItems": true, + "$ref": "common.json#/nonemptyarray", "items": { "type": "object", "properties": { diff --git a/json-schema/common.json b/json-schema/common.json index 16e50806..580e59fc 100644 --- a/json-schema/common.json +++ b/json-schema/common.json @@ -111,5 +111,9 @@ "$ref": "#/fileref" } + }, + + "$comment": "Inside here add '\"minItems\": 1' to require all collection endpoints to contain at least one element.", + "nonemptyarray": { } } diff --git a/json-schema/event-feed-array.json b/json-schema/event-feed-array.json index 26726313..339a72c8 100644 --- a/json-schema/event-feed-array.json +++ b/json-schema/event-feed-array.json @@ -4,6 +4,7 @@ "description": "JSON array of responses of this NDJSON API call", "type": "array", "uniqueItems": true, + "$ref": "common.json#/nonemptyarray", "items": { "$ref": "event-feed.json#/" } diff --git a/json-schema/groups.json b/json-schema/groups.json index f585a680..e3da3cd4 100644 --- a/json-schema/groups.json +++ b/json-schema/groups.json @@ -4,6 +4,7 @@ "description": "JSON response of this API call", "type": "array", "uniqueItems": true, + "$ref": "common.json#/nonemptyarray", "items": { "type": "object", "properties": { diff --git a/json-schema/judgement-types.json b/json-schema/judgement-types.json index a6fe807c..e05f2449 100644 --- a/json-schema/judgement-types.json +++ b/json-schema/judgement-types.json @@ -4,6 +4,7 @@ "description": "JSON response of this API call", "type": "array", "uniqueItems": true, + "$ref": "common.json#/nonemptyarray", "items": { "type": "object", "properties": { diff --git a/json-schema/judgements.json b/json-schema/judgements.json index 46964576..26aa1884 100644 --- a/json-schema/judgements.json +++ b/json-schema/judgements.json @@ -4,6 +4,7 @@ "description": "JSON response of this API call", "type": "array", "uniqueItems": true, + "$ref": "common.json#/nonemptyarray", "items": { "type": "object", "properties": { diff --git a/json-schema/languages.json b/json-schema/languages.json index 10d0f758..f5e24a91 100644 --- a/json-schema/languages.json +++ b/json-schema/languages.json @@ -4,6 +4,7 @@ "description": "JSON response of this API call", "type": "array", "uniqueItems": true, + "$ref": "common.json#/nonemptyarray", "items": { "type": "object", "properties": { diff --git a/json-schema/organizations.json b/json-schema/organizations.json index 04a77bac..39bbdab1 100644 --- a/json-schema/organizations.json +++ b/json-schema/organizations.json @@ -4,6 +4,7 @@ "description": "JSON response of this API call", "type": "array", "uniqueItems": true, + "$ref": "common.json#/nonemptyarray", "items": { "type": "object", "properties": { diff --git a/json-schema/problems.json b/json-schema/problems.json index 449c6669..ca0f4ccd 100644 --- a/json-schema/problems.json +++ b/json-schema/problems.json @@ -4,6 +4,7 @@ "description": "JSON response of this API call", "type": "array", "uniqueItems": true, + "$ref": "common.json#/nonemptyarray", "items": { "type": "object", "properties": { diff --git a/json-schema/submissions.json b/json-schema/submissions.json index 4e351e95..669368b2 100644 --- a/json-schema/submissions.json +++ b/json-schema/submissions.json @@ -4,6 +4,7 @@ "description": "JSON response of this API call", "type": "array", "uniqueItems": true, + "$ref": "common.json#/nonemptyarray", "items": { "type": "object", "properties": { diff --git a/json-schema/team-members.json b/json-schema/team-members.json index e4406886..6f93457c 100644 --- a/json-schema/team-members.json +++ b/json-schema/team-members.json @@ -4,6 +4,7 @@ "description": "JSON response of this API call", "type": "array", "uniqueItems": true, + "$ref": "common.json#/nonemptyarray", "items": { "type": "object", "properties": { diff --git a/json-schema/teams.json b/json-schema/teams.json index 39d50eda..11794dd4 100644 --- a/json-schema/teams.json +++ b/json-schema/teams.json @@ -4,6 +4,7 @@ "description": "JSON response of this API call", "type": "array", "uniqueItems": true, + "$ref": "common.json#/nonemptyarray", "items": { "type": "object", "properties": { From df8ea2d176f6143588b8b2e349449aef8553094f Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Thu, 22 Feb 2018 00:27:23 +0100 Subject: [PATCH 012/107] Add option to specify timeout for downloading event-feed. --- check-api.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/check-api.sh b/check-api.sh index 3c3ef746..25db4b9b 100755 --- a/check-api.sh +++ b/check-api.sh @@ -74,6 +74,7 @@ Options: -h Snow this help output. -j PROG Specify the path to the 'validate-json' binary. -n Require that all collection endpoints are non-empty. + -t TIME Timeout in seconds for downloading event feed (default: 10s) -q Quiet mode: suppress all output except script errors. The script reports endpoints checked and validations errors. @@ -82,14 +83,16 @@ In quiet mode only the exit code indicates successful validation. EOF } +FEED_TIMEOUT=10 # Parse command-line options: -while getopts 'dhj:nq' OPT ; do +while getopts 'dhj:nt:q' OPT ; do case "$OPT" in d) DEBUG=1 ;; h) usage ; exit 0 ;; j) VALIDATE_JSON="$OPTARG" ;; n) NONEMPTY=1 ;; + t) FEED_TIMEOUT="$OPTARG" ;; q) QUIET=1 ;; :) error "option '$OPTARG' requires an argument." @@ -133,7 +136,7 @@ query_endpoint() # Special case timeout for event-feed NDJSON endpoint. if [ "${URL/event-feed/}" != "$URL" ]; then TIMEOUT=1 - CURLOPTS="$CURLOPTS --max-time 10" + CURLOPTS="$CURLOPTS --max-time ${FEED_TIMEOUT}" fi HTTPCODE=$(curl $CURLOPTS -w "%{http_code}\n" -o "$OUTPUT" "${URL}${URL_EXTRA}") From f7c344be4e284ed2f2640a45966c65af41f484dc Mon Sep 17 00:00:00 2001 From: Tobias Werth Date: Thu, 22 Feb 2018 17:39:57 +0100 Subject: [PATCH 013/107] Add -N to disable buffering when checking the API. --- check-api.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/check-api.sh b/check-api.sh index 25db4b9b..f69361a5 100755 --- a/check-api.sh +++ b/check-api.sh @@ -136,7 +136,7 @@ query_endpoint() # Special case timeout for event-feed NDJSON endpoint. if [ "${URL/event-feed/}" != "$URL" ]; then TIMEOUT=1 - CURLOPTS="$CURLOPTS --max-time ${FEED_TIMEOUT}" + CURLOPTS="$CURLOPTS -N --max-time ${FEED_TIMEOUT}" fi HTTPCODE=$(curl $CURLOPTS -w "%{http_code}\n" -o "$OUTPUT" "${URL}${URL_EXTRA}") From 36645fb3f93a2b57c57c31a05df3827910c85206 Mon Sep 17 00:00:00 2001 From: Tobias Werth Date: Thu, 22 Feb 2018 18:40:43 +0100 Subject: [PATCH 014/107] Add more debug output for travis. --- check-api.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/check-api.sh b/check-api.sh index f69361a5..77338939 100755 --- a/check-api.sh +++ b/check-api.sh @@ -229,6 +229,7 @@ if query_endpoint "$OUTPUT" "$URL" ; then validate_schema "$OUTPUT" "$SCHEMA" EXIT=$? [ $EXIT -gt $EXITCODE ] && EXITCODE=$EXIT + [ $EXIT -ne 0 ] && cat "$OUTPUT" else verbose '%20s: Failed to download\n' "$ENDPOINT" fi From 8fed4ce251d7cbd2eef95cfb86558fdbb1dee99d Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Sat, 24 Feb 2018 13:26:24 +0100 Subject: [PATCH 015/107] Add option to pass options to curl. --- check-api.sh | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/check-api.sh b/check-api.sh index 77338939..7c067a7d 100755 --- a/check-api.sh +++ b/check-api.sh @@ -70,11 +70,12 @@ to validate the API endpoints under contest 'wf17'. Options: + -c OPTS Options to pass to curl to request API data (default: $CURL_OPTIONS) -d Turn on shell script debugging. -h Snow this help output. -j PROG Specify the path to the 'validate-json' binary. -n Require that all collection endpoints are non-empty. - -t TIME Timeout in seconds for downloading event feed (default: 10s) + -t TIME Timeout in seconds for downloading event feed (default: $FEED_TIMEOUT) -q Quiet mode: suppress all output except script errors. The script reports endpoints checked and validations errors. @@ -84,10 +85,12 @@ EOF } FEED_TIMEOUT=10 +CURL_OPTIONS='-n -s' # Parse command-line options: -while getopts 'dhj:nt:q' OPT ; do +while getopts 'c:dhj:nt:q' OPT ; do case "$OPT" in + c) CURL_OPTIONS="$OPTARG" ;; d) DEBUG=1 ;; h) usage ; exit 0 ;; j) VALIDATE_JSON="$OPTARG" ;; @@ -130,7 +133,7 @@ query_endpoint() local OPTIONAL="$3" local HTTPCODE EXITCODE - local CURLOPTS='-k -n -s' + local CURLOPTS="$CURL_OPTIONS" [ -n "$DEBUG" ] && CURLOPTS="$CURLOPTS -S" # Special case timeout for event-feed NDJSON endpoint. From bff4f0ecf0d8b4cff8515e0e2662e3ea1854e219 Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Sat, 24 Feb 2018 13:26:54 +0100 Subject: [PATCH 016/107] Only output downloaded JSON data when debugging. --- check-api.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/check-api.sh b/check-api.sh index 7c067a7d..896d2c03 100755 --- a/check-api.sh +++ b/check-api.sh @@ -232,7 +232,7 @@ if query_endpoint "$OUTPUT" "$URL" ; then validate_schema "$OUTPUT" "$SCHEMA" EXIT=$? [ $EXIT -gt $EXITCODE ] && EXITCODE=$EXIT - [ $EXIT -ne 0 ] && cat "$OUTPUT" + [ $EXIT -ne 0 -a -n "$DEBUG" ] && cat "$OUTPUT" else verbose '%20s: Failed to download\n' "$ENDPOINT" fi From 1e17a896f87ff37b210cac9b546d27234c6de372 Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Sat, 24 Feb 2018 14:57:48 +0100 Subject: [PATCH 017/107] Improve handling of URL arguments and pass new 'stream=0' argument when getting the event-feed. --- check-api.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/check-api.sh b/check-api.sh index 896d2c03..409225c9 100755 --- a/check-api.sh +++ b/check-api.sh @@ -6,7 +6,8 @@ #VALIDATE_JSON=/path/to/json-validate # Optional extra arguments to append to the API URLs: -#URL_EXTRA='?strict=1' +# Separate with '&', do not add initial '?'. +#URL_ARGS='strict=1' ENDPOINTS=' contest @@ -136,13 +137,16 @@ query_endpoint() local CURLOPTS="$CURL_OPTIONS" [ -n "$DEBUG" ] && CURLOPTS="$CURLOPTS -S" + local ARGS="$URL_ARGS" + # Special case timeout for event-feed NDJSON endpoint. if [ "${URL/event-feed/}" != "$URL" ]; then TIMEOUT=1 CURLOPTS="$CURLOPTS -N --max-time ${FEED_TIMEOUT}" + ARGS="${ARGS:+$ARGS&}stream=0" fi - HTTPCODE=$(curl $CURLOPTS -w "%{http_code}\n" -o "$OUTPUT" "${URL}${URL_EXTRA}") + HTTPCODE=$(curl $CURLOPTS -w "%{http_code}\n" -o "$OUTPUT" "${URL}${ARGS:+?$ARGS}") EXITCODE="$?" if [ $EXITCODE -eq 28 ]; then # timeout if [ -z "$TIMEOUT" ]; then From 1ef92901ed461e8d4b484912143947abc2fed6d5 Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Sat, 24 Feb 2018 14:58:17 +0100 Subject: [PATCH 018/107] Remove curl silence option when debugging. --- check-api.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/check-api.sh b/check-api.sh index 409225c9..ce636fac 100755 --- a/check-api.sh +++ b/check-api.sh @@ -135,7 +135,7 @@ query_endpoint() local HTTPCODE EXITCODE local CURLOPTS="$CURL_OPTIONS" - [ -n "$DEBUG" ] && CURLOPTS="$CURLOPTS -S" + [ -n "$DEBUG" ] && CURLOPTS="${CURLOPTS/ -s/} -S" local ARGS="$URL_ARGS" From 3d7ee22d48925c14f69f2dc0d6378deb4df9e81a Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Sat, 24 Feb 2018 15:42:52 +0100 Subject: [PATCH 019/107] Make specifying URL_ARGS a script option. --- check-api.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/check-api.sh b/check-api.sh index ce636fac..87e548ff 100755 --- a/check-api.sh +++ b/check-api.sh @@ -5,10 +5,6 @@ # Set path to json-validate binary if it's not in PATH: #VALIDATE_JSON=/path/to/json-validate -# Optional extra arguments to append to the API URLs: -# Separate with '&', do not add initial '?'. -#URL_ARGS='strict=1' - ENDPOINTS=' contest judgement-types @@ -71,6 +67,8 @@ to validate the API endpoints under contest 'wf17'. Options: + -a ARGS Arguments to pass to the API request URLs. Separate arguments + with '&', do not add initial '?'. (default: $URL_ARGS) -c OPTS Options to pass to curl to request API data (default: $CURL_OPTIONS) -d Turn on shell script debugging. -h Snow this help output. @@ -87,10 +85,12 @@ EOF FEED_TIMEOUT=10 CURL_OPTIONS='-n -s' +URL_ARGS='' # Parse command-line options: -while getopts 'c:dhj:nt:q' OPT ; do +while getopts 'a:c:dhj:nt:q' OPT ; do case "$OPT" in + a) URL_ARGS="$OPTARG" ;; c) CURL_OPTIONS="$OPTARG" ;; d) DEBUG=1 ;; h) usage ; exit 0 ;; From 4c95e80b528855c54ab5f88a7e0c385c2af5c7be Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Sat, 24 Feb 2018 16:07:12 +0100 Subject: [PATCH 020/107] Document curl required and stream=0 hack for DOMjudge on Travis. --- check-api.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/check-api.sh b/check-api.sh index 87e548ff..6f225d6d 100755 --- a/check-api.sh +++ b/check-api.sh @@ -57,7 +57,7 @@ Usage: $(basename $0) [option]... URL This program validates a Contest API implementation against the specification: https://clics.ecs.baylor.edu/index.php/Contest_API -It requires the validate-json binary from +It requires curl and the validate-json binary from https://github.com/justinrainbow/json-schema which can be installed with \`composer require justinrainbow/json-schema\`. @@ -143,7 +143,11 @@ query_endpoint() if [ "${URL/event-feed/}" != "$URL" ]; then TIMEOUT=1 CURLOPTS="$CURLOPTS -N --max-time ${FEED_TIMEOUT}" - ARGS="${ARGS:+$ARGS&}stream=0" + # This is a hack around the --max-time option not working well + # on Travis CI for the DOMjudge event-feed endpoint. + if [ "${URL/domjudge/}" != "$URL" ]; then + ARGS="${ARGS:+$ARGS&}stream=0" + fi fi HTTPCODE=$(curl $CURLOPTS -w "%{http_code}\n" -o "$OUTPUT" "${URL}${ARGS:+?$ARGS}") From ac121918563a9621be0d1f6ebe93933f49b2f85b Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Sat, 3 Mar 2018 10:53:57 +0100 Subject: [PATCH 021/107] Add missing reference to check for a non-empty array. --- json-schema/runs.json | 1 + 1 file changed, 1 insertion(+) diff --git a/json-schema/runs.json b/json-schema/runs.json index 382b322f..e48e572a 100644 --- a/json-schema/runs.json +++ b/json-schema/runs.json @@ -4,6 +4,7 @@ "description": "JSON response of this API call", "type": "array", "uniqueItems": true, + "$ref": "common.json#/nonemptyarray", "items": { "type": "object", "properties": { From 86ae26d3b0723e26167251392336b4a9f8191b20 Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Sat, 3 Mar 2018 11:24:57 +0100 Subject: [PATCH 022/107] Split single API element definitions for easier reuse. --- json-schema/award.json | 17 +++++++++++ json-schema/awards.json | 13 ++------- json-schema/clarification.json | 21 ++++++++++++++ json-schema/clarifications.json | 17 ++--------- json-schema/group.json | 16 +++++++++++ json-schema/groups.json | 12 ++------ json-schema/judgement-type.json | 15 ++++++++++ json-schema/judgement-types.json | 11 ++----- json-schema/judgement.json | 32 +++++++++++++++++++++ json-schema/judgements.json | 28 ++---------------- json-schema/language.json | 13 +++++++++ json-schema/languages.json | 9 ++---- json-schema/organization.json | 49 ++++++++++++++++++++++++++++++++ json-schema/organizations.json | 45 ++--------------------------- json-schema/problem.json | 28 ++++++++++++++++++ json-schema/problems.json | 24 ++-------------- json-schema/run.json | 21 ++++++++++++++ json-schema/runs.json | 17 ++--------- json-schema/submission.json | 20 +++++++++++++ json-schema/submissions.json | 16 ++--------- json-schema/team-member.json | 24 ++++++++++++++++ json-schema/team-members.json | 20 ++----------- json-schema/team.json | 35 +++++++++++++++++++++++ json-schema/teams.json | 31 ++------------------ 24 files changed, 315 insertions(+), 219 deletions(-) create mode 100644 json-schema/award.json create mode 100644 json-schema/clarification.json create mode 100644 json-schema/group.json create mode 100644 json-schema/judgement-type.json create mode 100644 json-schema/judgement.json create mode 100644 json-schema/language.json create mode 100644 json-schema/organization.json create mode 100644 json-schema/problem.json create mode 100644 json-schema/run.json create mode 100644 json-schema/submission.json create mode 100644 json-schema/team-member.json create mode 100644 json-schema/team.json diff --git a/json-schema/award.json b/json-schema/award.json new file mode 100644 index 00000000..57c0d355 --- /dev/null +++ b/json-schema/award.json @@ -0,0 +1,17 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "CLICS Contest API - award", + "description": "Definition of a single award object", + + "type": "object", + "properties": { + "id": { "$ref": "common.json#/identifier" }, + "citation": { "type": "string" }, + "team_ids": { + "type": "array", + "uniqueItems": true, + "items": { "$ref": "common.json#/identifier" } + } + }, + "required": ["id", "citation", "team_ids"] +} diff --git a/json-schema/awards.json b/json-schema/awards.json index 79885f27..326a9536 100644 --- a/json-schema/awards.json +++ b/json-schema/awards.json @@ -2,20 +2,11 @@ "$schema": "http://json-schema.org/draft-04/schema#", "title": "CLICS Contest API: awards", "description": "JSON response of this API call", + "type": "array", "uniqueItems": true, "$ref": "common.json#/nonemptyarray", "items": { - "type": "object", - "properties": { - "id": { "$ref": "common.json#/identifier" }, - "citation": { "type": "string" }, - "team_ids": { - "type": "array", - "uniqueItems": true, - "items": { "$ref": "common.json#/identifier" } - } - }, - "required": ["id", "citation", "team_ids"] + "$ref": "award.json#" } } diff --git a/json-schema/clarification.json b/json-schema/clarification.json new file mode 100644 index 00000000..303cc93c --- /dev/null +++ b/json-schema/clarification.json @@ -0,0 +1,21 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "CLICS Contest API - clarification", + "description": "Definition of a single clarification object", + + "type": "object", + "properties": { + "id": { "$ref": "common.json#/identifier" }, + "from_team_id": { "$ref": "common.json#/identifierornull" }, + "to_team_id": { "$ref": "common.json#/identifierornull" }, + "reply_to_id": { "$ref": "common.json#/identifierornull" }, + "problem_id": { "$ref": "common.json#/identifierornull" }, + "text": { "type": "string" }, + "from_jury": { "type": "boolean" }, + "to_all_teams": { "type": "boolean" }, + "time": { "$ref": "common.json#/abstime" }, + "contest_time": { "$ref": "common.json#/reltime" } + }, + "required": ["id", "text", "time", "contest_time"], + "additionalProperties": false +} diff --git a/json-schema/clarifications.json b/json-schema/clarifications.json index cea8f5ea..7cedc634 100644 --- a/json-schema/clarifications.json +++ b/json-schema/clarifications.json @@ -2,24 +2,11 @@ "$schema": "http://json-schema.org/draft-04/schema#", "title": "CLICS Contest API: clarifications", "description": "JSON response of this API call", + "type": "array", "uniqueItems": true, "$ref": "common.json#/nonemptyarray", "items": { - "type": "object", - "properties": { - "id": { "$ref": "common.json#/identifier" }, - "from_team_id": { "$ref": "common.json#/identifierornull" }, - "to_team_id": { "$ref": "common.json#/identifierornull" }, - "reply_to_id": { "$ref": "common.json#/identifierornull" }, - "problem_id": { "$ref": "common.json#/identifierornull" }, - "text": { "type": "string" }, - "from_jury": { "type": "boolean" }, - "to_all_teams": { "type": "boolean" }, - "time": { "$ref": "common.json#/abstime" }, - "contest_time": { "$ref": "common.json#/reltime" } - }, - "required": ["id", "text", "time", "contest_time"], - "additionalProperties": false + "$ref": "clarification.json#" } } diff --git a/json-schema/group.json b/json-schema/group.json new file mode 100644 index 00000000..b80a5bf6 --- /dev/null +++ b/json-schema/group.json @@ -0,0 +1,16 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "CLICS Contest API - group", + "description": "Definition of a single group object", + + "type": "object", + "properties": { + "id": { "$ref": "common.json#/identifier" }, + "icpc_id": { "type": [ "string", "null" ] }, + "name": { "type": "string" }, + "type": { "type": "string" }, + "hidden": { "type": "boolean" } + }, + "required": ["id", "name"], + "additionalProperties": false +} diff --git a/json-schema/groups.json b/json-schema/groups.json index e3da3cd4..776c2ec6 100644 --- a/json-schema/groups.json +++ b/json-schema/groups.json @@ -2,19 +2,11 @@ "$schema": "http://json-schema.org/draft-04/schema#", "title": "CLICS Contest API: groups", "description": "JSON response of this API call", + "type": "array", "uniqueItems": true, "$ref": "common.json#/nonemptyarray", "items": { - "type": "object", - "properties": { - "id": { "$ref": "common.json#/identifier" }, - "icpc_id": { "type": [ "string", "null" ] }, - "name": { "type": "string" }, - "type": { "type": "string" }, - "hidden": { "type": "boolean" } - }, - "required": ["id", "name"], - "additionalProperties": false + "$ref": "group.json#" } } diff --git a/json-schema/judgement-type.json b/json-schema/judgement-type.json new file mode 100644 index 00000000..e4b0f748 --- /dev/null +++ b/json-schema/judgement-type.json @@ -0,0 +1,15 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "CLICS Contest API - judgement_type", + "description": "Definition of a single judgement-type object", + + "type": "object", + "properties": { + "id": { "$ref": "common.json#/judgementtypeid" }, + "name": { "type": "string" }, + "penalty": { "type": "boolean" }, + "solved": { "type": "boolean" } + }, + "required": ["id", "name", "solved"], + "additionalProperties": false +} diff --git a/json-schema/judgement-types.json b/json-schema/judgement-types.json index e05f2449..c4193b29 100644 --- a/json-schema/judgement-types.json +++ b/json-schema/judgement-types.json @@ -2,18 +2,11 @@ "$schema": "http://json-schema.org/draft-04/schema#", "title": "CLICS Contest API: judgement_types", "description": "JSON response of this API call", + "type": "array", "uniqueItems": true, "$ref": "common.json#/nonemptyarray", "items": { - "type": "object", - "properties": { - "id": { "$ref": "common.json#/judgementtypeid" }, - "name": { "type": "string" }, - "penalty": { "type": "boolean" }, - "solved": { "type": "boolean" } - }, - "required": ["id", "name", "solved"], - "additionalProperties": false + "$ref": "judgement-type.json#" } } diff --git a/json-schema/judgement.json b/json-schema/judgement.json new file mode 100644 index 00000000..5455eb50 --- /dev/null +++ b/json-schema/judgement.json @@ -0,0 +1,32 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "CLICS Contest API - judgement", + "description": "Definition of a single judgement object", + + "type": "object", + "properties": { + "id": { "$ref": "common.json#/identifier" }, + "submission_id": { "$ref": "common.json#/identifier" }, + "judgement_type_id": { "$ref": "common.json#/judgementtypeidornull" }, + "start_time": { "$ref": "common.json#/abstime" }, + "start_contest_time": { "$ref": "common.json#/reltime" }, + "end_time": { "$ref": "common.json#/abstimeornull" }, + "end_contest_time": { + "oneOf": [ + { "$ref": "common.json#/reltime" }, + { "type": "null" } + ] + }, + "max_run_time": { + "oneOf": [ + { + "$ref": "common.json#/decimal", + "minimum": 0 + }, + { "type": "null" } + ] + } + }, + "required": ["id", "submission_id", "start_time", "start_contest_time", "end_time", "end_contest_time"], + "additionalProperties": false +} diff --git a/json-schema/judgements.json b/json-schema/judgements.json index 26aa1884..5434c071 100644 --- a/json-schema/judgements.json +++ b/json-schema/judgements.json @@ -2,35 +2,11 @@ "$schema": "http://json-schema.org/draft-04/schema#", "title": "CLICS Contest API: judgements", "description": "JSON response of this API call", + "type": "array", "uniqueItems": true, "$ref": "common.json#/nonemptyarray", "items": { - "type": "object", - "properties": { - "id": { "$ref": "common.json#/identifier" }, - "submission_id": { "$ref": "common.json#/identifier" }, - "judgement_type_id": { "$ref": "common.json#/judgementtypeidornull" }, - "start_time": { "$ref": "common.json#/abstime" }, - "start_contest_time": { "$ref": "common.json#/reltime" }, - "end_time": { "$ref": "common.json#/abstimeornull" }, - "end_contest_time": { - "oneOf": [ - { "$ref": "common.json#/reltime" }, - { "type": "null" } - ] - }, - "max_run_time": { - "oneOf": [ - { - "$ref": "common.json#/decimal", - "minimum": 0 - }, - { "type": "null" } - ] - } - }, - "required": ["id", "submission_id", "start_time", "start_contest_time", "end_time", "end_contest_time"], - "additionalProperties": false + "$ref": "judgement.json#" } } diff --git a/json-schema/language.json b/json-schema/language.json new file mode 100644 index 00000000..0ca85fdf --- /dev/null +++ b/json-schema/language.json @@ -0,0 +1,13 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "CLICS Contest API - language", + "description": "Definition of a single language object", + + "type": "object", + "properties": { + "id": { "$ref": "common.json#/identifier" }, + "name": { "type": "string" } + }, + "required": ["id", "name"], + "additionalProperties": false +} diff --git a/json-schema/languages.json b/json-schema/languages.json index f5e24a91..6ee62543 100644 --- a/json-schema/languages.json +++ b/json-schema/languages.json @@ -2,16 +2,11 @@ "$schema": "http://json-schema.org/draft-04/schema#", "title": "CLICS Contest API: languages", "description": "JSON response of this API call", + "type": "array", "uniqueItems": true, "$ref": "common.json#/nonemptyarray", "items": { - "type": "object", - "properties": { - "id": { "$ref": "common.json#/identifier" }, - "name": { "type": "string" } - }, - "required": ["id", "name"], - "additionalProperties": false + "$ref": "language.json#" } } diff --git a/json-schema/organization.json b/json-schema/organization.json new file mode 100644 index 00000000..1c590e88 --- /dev/null +++ b/json-schema/organization.json @@ -0,0 +1,49 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "CLICS Contest API - organization", + "description": "Definition of a single organization object", + + "type": "object", + "properties": { + "id": { "$ref": "common.json#/identifier" }, + "icpc_id": { "type": [ "string", "null" ] }, + "name": { "type": "string" }, + "formal_name": { "type": [ "string", "null" ] }, + "country": { + "oneOf": [ + { + "type": "string", + "pattern": "^[A-Z]{3}$" + }, + { "type": "null" } + ] + }, + "url": { "type": [ "string", "null" ] }, + "twitter_hashtag": { "type": [ "string", "null" ] }, + "location": { + "oneOf": [ + { + "type": "object", + "properties": { + "latitude": { + "type": "number", + "minimum": -90, + "maximum": 90 + }, + "longitude": { + "type": "number", + "minimum": -180, + "maximum": 180 + } + }, + "required": ["latitude", "longitude"], + "additionalProperties": false + }, + { "type": "null" } + ] + }, + "logo": { "$ref": "common.json#/filerefs" } + }, + "required": ["id", "name"], + "additionalProperties": false +} diff --git a/json-schema/organizations.json b/json-schema/organizations.json index 39bbdab1..e243d051 100644 --- a/json-schema/organizations.json +++ b/json-schema/organizations.json @@ -2,52 +2,11 @@ "$schema": "http://json-schema.org/draft-04/schema#", "title": "CLICS Contest API: organizations", "description": "JSON response of this API call", + "type": "array", "uniqueItems": true, "$ref": "common.json#/nonemptyarray", "items": { - "type": "object", - "properties": { - "id": { "$ref": "common.json#/identifier" }, - "icpc_id": { "type": [ "string", "null" ] }, - "name": { "type": "string" }, - "formal_name": { "type": [ "string", "null" ] }, - "country": { - "oneOf": [ - { - "type": "string", - "pattern": "^[A-Z]{3}$" - }, - { "type": "null" } - ] - }, - "url": { "type": [ "string", "null" ] }, - "twitter_hashtag": { "type": [ "string", "null" ] }, - "location": { - "oneOf": [ - { - "type": "object", - "properties": { - "latitude": { - "type": "number", - "minimum": -90, - "maximum": 90 - }, - "longitude": { - "type": "number", - "minimum": -180, - "maximum": 180 - } - }, - "required": ["latitude", "longitude"], - "additionalProperties": false - }, - { "type": "null" } - ] - }, - "logo": { "$ref": "common.json#/filerefs" } - }, - "required": ["id", "name"], - "additionalProperties": false + "$ref": "organization.json#" } } diff --git a/json-schema/problem.json b/json-schema/problem.json new file mode 100644 index 00000000..f73b38a3 --- /dev/null +++ b/json-schema/problem.json @@ -0,0 +1,28 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "CLICS Contest API - problem", + "description": "Definition of a single problem object", + + "type": "object", + "properties": { + "id": { "$ref": "common.json#/identifier" }, + "label": { "$ref": "common.json#/label" }, + "name": { "type": "string" }, + "ordinal": { "$ref": "common.json#/ordinal" }, + "rgb": { + "type": "string", + "pattern": "^#[A-Fa-f0-9]{3}([A-Fa-f0-9]{3})?$" + }, + "color": { "type": "string" }, + "time_limit": { + "$ref": "common.json#/decimal", + "minimum": 0 + }, + "test_data_count": { + "type": "integer", + "minimum": 0 + } + }, + "required": ["id", "label", "name", "ordinal", "test_data_count"], + "additionalProperties": false +} diff --git a/json-schema/problems.json b/json-schema/problems.json index ca0f4ccd..b8d79cd2 100644 --- a/json-schema/problems.json +++ b/json-schema/problems.json @@ -2,31 +2,11 @@ "$schema": "http://json-schema.org/draft-04/schema#", "title": "CLICS Contest API: problems", "description": "JSON response of this API call", + "type": "array", "uniqueItems": true, "$ref": "common.json#/nonemptyarray", "items": { - "type": "object", - "properties": { - "id": { "$ref": "common.json#/identifier" }, - "label": { "$ref": "common.json#/label" }, - "name": { "type": "string" }, - "ordinal": { "$ref": "common.json#/ordinal" }, - "rgb": { - "type": "string", - "pattern": "^#[A-Fa-f0-9]{3}([A-Fa-f0-9]{3})?$" - }, - "color": { "type": "string" }, - "time_limit": { - "$ref": "common.json#/decimal", - "minimum": 0 - }, - "test_data_count": { - "type": "integer", - "minimum": 0 - } - }, - "required": ["id", "label", "name", "ordinal", "test_data_count"], - "additionalProperties": false + "$ref": "problem.json#" } } diff --git a/json-schema/run.json b/json-schema/run.json new file mode 100644 index 00000000..1da21719 --- /dev/null +++ b/json-schema/run.json @@ -0,0 +1,21 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "CLICS Contest API - run", + "description": "Definition of a single run object", + + "type": "object", + "properties": { + "id": { "$ref": "common.json#/identifier" }, + "judgement_id": { "$ref": "common.json#/identifier" }, + "ordinal": { "$ref": "common.json#/ordinal" }, + "judgement_type_id": { "$ref": "common.json#/judgementtypeid" }, + "time": { "$ref": "common.json#/abstime" }, + "contest_time": { "$ref": "common.json#/reltime" }, + "run_time": { + "$ref": "common.json#/decimal", + "minimum": 0 + } + }, + "required": ["id", "judgement_id", "ordinal", "judgement_type_id", "time", "contest_time"], + "additionalProperties": false +} diff --git a/json-schema/runs.json b/json-schema/runs.json index e48e572a..fff126d0 100644 --- a/json-schema/runs.json +++ b/json-schema/runs.json @@ -2,24 +2,11 @@ "$schema": "http://json-schema.org/draft-04/schema#", "title": "CLICS Contest API: runs", "description": "JSON response of this API call", + "type": "array", "uniqueItems": true, "$ref": "common.json#/nonemptyarray", "items": { - "type": "object", - "properties": { - "id": { "$ref": "common.json#/identifier" }, - "judgement_id": { "$ref": "common.json#/identifier" }, - "ordinal": { "$ref": "common.json#/ordinal" }, - "judgement_type_id": { "$ref": "common.json#/judgementtypeid" }, - "time": { "$ref": "common.json#/abstime" }, - "contest_time": { "$ref": "common.json#/reltime" }, - "run_time": { - "$ref": "common.json#/decimal", - "minimum": 0 - } - }, - "required": ["id", "judgement_id", "ordinal", "judgement_type_id", "time", "contest_time"], - "additionalProperties": false + "$ref": "run.json#" } } diff --git a/json-schema/submission.json b/json-schema/submission.json new file mode 100644 index 00000000..d133d6e7 --- /dev/null +++ b/json-schema/submission.json @@ -0,0 +1,20 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "CLICS Contest API - submission", + "description": "Definition of a single submission object", + + "type": "object", + "properties": { + "id": { "$ref": "common.json#/identifier" }, + "language_id": { "$ref": "common.json#/identifier" }, + "problem_id": { "$ref": "common.json#/identifier" }, + "team_id": { "$ref": "common.json#/identifier" }, + "time": { "$ref": "common.json#/abstime" }, + "contest_time": { "$ref": "common.json#/reltime" }, + "entry_point": { "type": [ "string", "null" ] }, + "files": { "$ref": "common.json#/filerefs" }, + "reaction": { "$ref": "common.json#/filerefs" } + }, + "required": ["id", "language_id", "problem_id", "team_id", "time", "contest_time", "files"], + "additionalProperties": false +} diff --git a/json-schema/submissions.json b/json-schema/submissions.json index 669368b2..e091b4b2 100644 --- a/json-schema/submissions.json +++ b/json-schema/submissions.json @@ -2,23 +2,11 @@ "$schema": "http://json-schema.org/draft-04/schema#", "title": "CLICS Contest API: submissions", "description": "JSON response of this API call", + "type": "array", "uniqueItems": true, "$ref": "common.json#/nonemptyarray", "items": { - "type": "object", - "properties": { - "id": { "$ref": "common.json#/identifier" }, - "language_id": { "$ref": "common.json#/identifier" }, - "problem_id": { "$ref": "common.json#/identifier" }, - "team_id": { "$ref": "common.json#/identifier" }, - "time": { "$ref": "common.json#/abstime" }, - "contest_time": { "$ref": "common.json#/reltime" }, - "entry_point": { "type": [ "string", "null" ] }, - "files": { "$ref": "common.json#/filerefs" }, - "reaction": { "$ref": "common.json#/filerefs" } - }, - "required": ["id", "language_id", "problem_id", "team_id", "time", "contest_time", "files"], - "additionalProperties": false + "$ref": "submission.json#" } } diff --git a/json-schema/team-member.json b/json-schema/team-member.json new file mode 100644 index 00000000..a4435fce --- /dev/null +++ b/json-schema/team-member.json @@ -0,0 +1,24 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "CLICS Contest API - team-member", + "description": "Definition of a single team-member object", + + "type": "object", + "properties": { + "id": { "$ref": "common.json#/identifier" }, + "team_id": { "$ref": "common.json#/identifier" }, + "icpc_id": { "type": [ "string", "null" ] }, + "first_name": { "type": "string" }, + "last_name": { "type": "string" }, + "sex": { + "oneOf": [ + { "enum": [ "male", "female" ] }, + { "type": "null" } + ] + }, + "role": { "enum": [ "contestant", "coach" ] }, + "photo": { "$ref": "common.json#/filerefs" } + }, + "required": ["id", "team_id", "first_name", "last_name"], + "additionalProperties": false +} diff --git a/json-schema/team-members.json b/json-schema/team-members.json index 6f93457c..a86a0690 100644 --- a/json-schema/team-members.json +++ b/json-schema/team-members.json @@ -2,27 +2,11 @@ "$schema": "http://json-schema.org/draft-04/schema#", "title": "CLICS Contest API: team-members", "description": "JSON response of this API call", + "type": "array", "uniqueItems": true, "$ref": "common.json#/nonemptyarray", "items": { - "type": "object", - "properties": { - "id": { "$ref": "common.json#/identifier" }, - "team_id": { "$ref": "common.json#/identifier" }, - "icpc_id": { "type": [ "string", "null" ] }, - "first_name": { "type": "string" }, - "last_name": { "type": "string" }, - "sex": { - "oneOf": [ - { "enum": [ "male", "female" ] }, - { "type": "null" } - ] - }, - "role": { "enum": [ "contestant", "coach" ] }, - "photo": { "$ref": "common.json#/filerefs" } - }, - "required": ["id", "team_id", "first_name", "last_name"], - "additionalProperties": false + "$ref": "team-member.json#" } } diff --git a/json-schema/team.json b/json-schema/team.json new file mode 100644 index 00000000..9e42a6d0 --- /dev/null +++ b/json-schema/team.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "CLICS Contest API - team", + "description": "Definition of a single team object", + + "type": "object", + "properties": { + "id": { "$ref": "common.json#/identifier" }, + "icpc_id": { "type": [ "string", "null" ] }, + "name": { "type": "string" }, + "organization_id": { "$ref": "common.json#/identifierornull" }, + "group_ids": { + "type": "array", + "uniqueItems": true, + "items": { "$ref": "common.json#/identifierornull" } + }, + "location": { + "type": "object", + "properties": { + "x": { "type": "number" }, + "y": { "type": "number" }, + "rotation": { "type": "number" } + }, + "required": ["x", "y", "rotation"], + "additionalProperties": false + }, + "photo": { "$ref": "common.json#/filerefs" }, + "video": { "$ref": "common.json#/filerefs" }, + "backup": { "$ref": "common.json#/filerefs" }, + "desktop": { "$ref": "common.json#/filerefs" }, + "webcam": { "$ref": "common.json#/filerefs" } + }, + "required": ["id", "name"], + "additionalProperties": false +} diff --git a/json-schema/teams.json b/json-schema/teams.json index 11794dd4..93778ce1 100644 --- a/json-schema/teams.json +++ b/json-schema/teams.json @@ -2,38 +2,11 @@ "$schema": "http://json-schema.org/draft-04/schema#", "title": "CLICS Contest API: teams", "description": "JSON response of this API call", + "type": "array", "uniqueItems": true, "$ref": "common.json#/nonemptyarray", "items": { - "type": "object", - "properties": { - "id": { "$ref": "common.json#/identifier" }, - "icpc_id": { "type": [ "string", "null" ] }, - "name": { "type": "string" }, - "organization_id": { "$ref": "common.json#/identifierornull" }, - "group_ids": { - "type": "array", - "uniqueItems": true, - "items": { "$ref": "common.json#/identifierornull" } - }, - "location": { - "type": "object", - "properties": { - "x": { "type": "number" }, - "y": { "type": "number" }, - "rotation": { "type": "number" } - }, - "required": ["x", "y", "rotation"], - "additionalProperties": false - }, - "photo": { "$ref": "common.json#/filerefs" }, - "video": { "$ref": "common.json#/filerefs" }, - "backup": { "$ref": "common.json#/filerefs" }, - "desktop": { "$ref": "common.json#/filerefs" }, - "webcam": { "$ref": "common.json#/filerefs" } - }, - "required": ["id", "name"], - "additionalProperties": false + "$ref": "team.json#" } } From 842cc85a219c7fb7ea00cb284390c0c9a30c546b Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Sat, 3 Mar 2018 12:15:57 +0100 Subject: [PATCH 023/107] Specify contents of event-feed more precisely. --- json-schema/event-feed-array.json | 3 ++- json-schema/event-feed.json | 38 +++++++++++++++++++++++-------- 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/json-schema/event-feed-array.json b/json-schema/event-feed-array.json index 339a72c8..6d115448 100644 --- a/json-schema/event-feed-array.json +++ b/json-schema/event-feed-array.json @@ -2,10 +2,11 @@ "$schema": "http://json-schema.org/draft-04/schema#", "title": "CLICS Contest API: event-feed array", "description": "JSON array of responses of this NDJSON API call", + "type": "array", "uniqueItems": true, "$ref": "common.json#/nonemptyarray", "items": { - "$ref": "event-feed.json#/" + "$ref": "event-feed.json#" } } diff --git a/json-schema/event-feed.json b/json-schema/event-feed.json index 0a80a26b..8fa576c1 100644 --- a/json-schema/event-feed.json +++ b/json-schema/event-feed.json @@ -2,25 +2,45 @@ "$schema": "http://json-schema.org/draft-04/schema#", "title": "CLICS Contest API: event-feed", "description": "Single line response of this NDJSON API call", + "type": "object", "properties": { "id": { "$ref": "common.json#/identifier" }, "type": { "$ref": "common.json#/endpoints" }, "op": { "enum": [ "create", "update", "delete" ] }, - "data": { - "type": "object", - "properties": { - "id": { "$ref": "common.json#/identifier" } - }, - "required": ["id"] - }, + "data": {}, "oneOf": [ { - "op": { "enum": [ "create", "update" ] } + "op": { "enum": [ "create", "update" ] }, + "data": { + "oneOf": [ + { "$ref": "contest.json#" }, + { "$ref": "judgement-type.json#" }, + { "$ref": "language.json#" }, + { "$ref": "problem.json#" }, + { "$ref": "group.json#" }, + { "$ref": "organization.json#" }, + { "$ref": "team.json#" }, + { "$ref": "team-member.json#" }, + { "$ref": "state.json#" }, + { "$ref": "submission.json#" }, + { "$ref": "judgement.json#" }, + { "$ref": "run.json#" }, + { "$ref": "clarification.json#" }, + { "$ref": "award.json#" } + ] + } }, { "op": { "enum": [ "delete" ] }, - "data": { "additionalProperties": false } + "data": { + "type": "object", + "properties": { + "id": { "$ref": "common.json#/identifier" } + }, + "required": ["id"], + "additionalProperties": false + } } ] }, From f47d12df124e13afce06a1bf09059251c0add32a Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Sat, 3 Mar 2018 13:35:00 +0100 Subject: [PATCH 024/107] Validate the full multi-contest API from the base. --- check-api.sh | 122 ++++++++++++++++++++++++-------------- json-schema/contests.json | 12 ++++ 2 files changed, 88 insertions(+), 46 deletions(-) create mode 100644 json-schema/contests.json diff --git a/check-api.sh b/check-api.sh index 6f225d6d..ed4f9a14 100755 --- a/check-api.sh +++ b/check-api.sh @@ -57,13 +57,20 @@ Usage: $(basename $0) [option]... URL This program validates a Contest API implementation against the specification: https://clics.ecs.baylor.edu/index.php/Contest_API -It requires curl and the validate-json binary from -https://github.com/justinrainbow/json-schema which can be installed -with \`composer require justinrainbow/json-schema\`. +The URL must point to the base of the API, for example: -For now, the URL must point to a specific single contest inside the -API, for example \`$(basename $0) https://example.com/api/contests/wf17\` -to validate the API endpoints under contest 'wf17'. + $(basename $0) -n -c '-knS' -a 'strict=1' https://example.com/api + +where the options -knS passed to curl make it ignore SSL certificate +errors, use ~/.netrc for credentials, and be verbose. The option -a +makes that 'strict=1' is appended as argument to each API call. + +This script requires: +- the curl command line client +- the validate-json binary from https://github.com/justinrainbow/json-schema + which can be installed with \`composer require justinrainbow/json-schema\` +- the jq program from https://github.com/stedolan/jq + which is available as the \`jq\` package in Debian and Ubuntu. Options: @@ -85,7 +92,7 @@ EOF FEED_TIMEOUT=10 CURL_OPTIONS='-n -s' -URL_ARGS='' +URL_ARGS='strict=1' # Parse command-line options: while getopts 'a:c:dhj:nt:q' OPT ; do @@ -193,57 +200,80 @@ if [ -n "$NONEMPTY" ]; then sed -i '/"nonemptyarray":/a \\t\t"minItems": 1' "$TMP/json-schema/common.json" fi +# First validate and get all contests +ENDPOINT='contests' +URL="${API_URL%/}/$ENDPOINT" +SCHEMA="$TMP/json-schema/$ENDPOINT.json" +OUTPUT="$TMP/$ENDPOINT.json" +if query_endpoint "$OUTPUT" "$URL" ; then + verbose '%20s: ' "$ENDPOINT" + validate_schema "$OUTPUT" "$SCHEMA" + EXIT=$? + [ $EXIT -ne 0 -a $EXIT -ne 23 ] && exit $EXIT + CONTESTS=$(jq -r '.[].id' "$OUTPUT") + verbose "Contests: $CONTESTS" +else + verbose '%20s: Failed to download\n' "$ENDPOINT" + exit 1 +fi + EXITCODE=0 -for ENDPOINT in $ENDPOINTS ; do - if [ "${ENDPOINTS_OPTIONAL/${ENDPOINT}/}" != "$ENDPOINTS_OPTIONAL" ]; then - OPTIONAL=1 - else - unset OPTIONAL - fi +for CONTEST in $CONTESTS ; do + verbose "Validating contest '$CONTEST'..." + CONTEST_URL="${API_URL%/}/contests/$CONTEST" - if [ "$ENDPOINT" = 'contest' ]; then - URL="$API_URL" - else - URL="${API_URL%/}/$ENDPOINT" - fi + for ENDPOINT in $ENDPOINTS ; do + if [ "${ENDPOINTS_OPTIONAL/${ENDPOINT}/}" != "$ENDPOINTS_OPTIONAL" ]; then + OPTIONAL=1 + else + unset OPTIONAL + fi + + if [ "$ENDPOINT" = 'contest' ]; then + URL="$CONTEST_URL" + else + URL="$CONTEST_URL/$ENDPOINT" + fi + + SCHEMA="$TMP/json-schema/$ENDPOINT.json" + OUTPUT="$TMP/$CONTEST_$ENDPOINT.json" + + if query_endpoint "$OUTPUT" "$URL" $OPTIONAL ; then + verbose '%20s: ' "$ENDPOINT" + validate_schema "$OUTPUT" "$SCHEMA" + EXIT=$? + [ $EXIT -gt $EXITCODE ] && EXITCODE=$EXIT + else + if [ -n "$OPTIONAL" ]; then + verbose '%20s: Optional, not present\n' "$ENDPOINT" + else + verbose '%20s: Failed to download\n' "$ENDPOINT" + [ $EXITCODE -eq 0 ] && EXITCODE=1 + fi + fi + done + + # Now do special case event-feed endpoint + ENDPOINT='event-feed' + SCHEMA="$MYDIR/json-schema/$ENDPOINT-array.json" + OUTPUT="$TMP/$CONTEST_$ENDPOINT.json" + URL="$CONTEST_URL/$ENDPOINT" - SCHEMA="$TMP/json-schema/$ENDPOINT.json" - OUTPUT="$TMP/$ENDPOINT.json" + if query_endpoint "$OUTPUT" "$URL" ; then + # Delete empty lines and transform NDJSON into a JSON array. + sed -i '/^$/d;1 s/^/[/;s/$/,/;$ s/,$/]/' "$OUTPUT" - if query_endpoint "$OUTPUT" "$URL" $OPTIONAL ; then verbose '%20s: ' "$ENDPOINT" validate_schema "$OUTPUT" "$SCHEMA" EXIT=$? [ $EXIT -gt $EXITCODE ] && EXITCODE=$EXIT + [ $EXIT -ne 0 -a -n "$DEBUG" ] && cat "$OUTPUT" else - if [ -n "$OPTIONAL" ]; then - verbose '%20s: Optional, not present\n' "$ENDPOINT" - else - verbose '%20s: Failed to download\n' "$ENDPOINT" - [ $EXITCODE -eq 0 ] && EXITCODE=1 - fi + verbose '%20s: Failed to download\n' "$ENDPOINT" fi -done -# Now do special case event-feed endpoint -ENDPOINT='event-feed' -SCHEMA="$MYDIR/json-schema/$ENDPOINT-array.json" -OUTPUT="$TMP/$ENDPOINT.json" -URL="${API_URL%/}/$ENDPOINT" - -if query_endpoint "$OUTPUT" "$URL" ; then - # Delete empty lines and transform NDJSON into a JSON array. - sed -i '/^$/d;1 s/^/[/;s/$/,/;$ s/,$/]/' "$OUTPUT" - - verbose '%20s: ' "$ENDPOINT" - validate_schema "$OUTPUT" "$SCHEMA" - EXIT=$? - [ $EXIT -gt $EXITCODE ] && EXITCODE=$EXIT - [ $EXIT -ne 0 -a -n "$DEBUG" ] && cat "$OUTPUT" -else - verbose '%20s: Failed to download\n' "$ENDPOINT" -fi +done [ -n "$DEBUG" ] || rm -rf $TMP diff --git a/json-schema/contests.json b/json-schema/contests.json new file mode 100644 index 00000000..d386395b --- /dev/null +++ b/json-schema/contests.json @@ -0,0 +1,12 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "CLICS Contest API: contests", + "description": "JSON response of this API call", + + "type": "array", + "uniqueItems": true, + "$ref": "common.json#/nonemptyarray", + "items": { + "$ref": "contest.json#" + } +} From abbfe9a479c95b86a13e0c1c6e888139c404230a Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Sat, 3 Mar 2018 21:53:39 +0100 Subject: [PATCH 025/107] Various small fixes on top of 531cdb63498: - remove accidentally committed argument 'strict=1' - bugfix in variable use - remove debugging output --- check-api.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/check-api.sh b/check-api.sh index ed4f9a14..950ecd08 100755 --- a/check-api.sh +++ b/check-api.sh @@ -92,7 +92,7 @@ EOF FEED_TIMEOUT=10 CURL_OPTIONS='-n -s' -URL_ARGS='strict=1' +URL_ARGS='' # Parse command-line options: while getopts 'a:c:dhj:nt:q' OPT ; do @@ -211,7 +211,6 @@ if query_endpoint "$OUTPUT" "$URL" ; then EXIT=$? [ $EXIT -ne 0 -a $EXIT -ne 23 ] && exit $EXIT CONTESTS=$(jq -r '.[].id' "$OUTPUT") - verbose "Contests: $CONTESTS" else verbose '%20s: Failed to download\n' "$ENDPOINT" exit 1 @@ -237,7 +236,7 @@ for CONTEST in $CONTESTS ; do fi SCHEMA="$TMP/json-schema/$ENDPOINT.json" - OUTPUT="$TMP/$CONTEST_$ENDPOINT.json" + OUTPUT="$TMP/${CONTEST}_${ENDPOINT}.json" if query_endpoint "$OUTPUT" "$URL" $OPTIONAL ; then verbose '%20s: ' "$ENDPOINT" From eb063d1751ca35806503fa145a3da1561d3fa276 Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Sat, 3 Mar 2018 22:39:11 +0100 Subject: [PATCH 026/107] Move to version draft-07 of JSON schema. --- json-schema/award.json | 2 +- json-schema/awards.json | 2 +- json-schema/clarification.json | 2 +- json-schema/clarifications.json | 2 +- json-schema/common.json | 2 +- json-schema/contest.json | 3 ++- json-schema/contests.json | 2 +- json-schema/event-feed-array.json | 2 +- json-schema/event-feed.json | 2 +- json-schema/group.json | 2 +- json-schema/groups.json | 2 +- json-schema/judgement-type.json | 2 +- json-schema/judgement-types.json | 2 +- json-schema/judgement.json | 2 +- json-schema/judgements.json | 2 +- json-schema/language.json | 2 +- json-schema/languages.json | 2 +- json-schema/organization.json | 2 +- json-schema/organizations.json | 2 +- json-schema/problem.json | 2 +- json-schema/problems.json | 2 +- json-schema/run.json | 2 +- json-schema/runs.json | 2 +- json-schema/scoreboard.json | 3 ++- json-schema/state.json | 3 ++- json-schema/submission.json | 2 +- json-schema/submissions.json | 2 +- json-schema/team-member.json | 2 +- json-schema/team-members.json | 2 +- json-schema/team.json | 2 +- json-schema/teams.json | 2 +- 31 files changed, 34 insertions(+), 31 deletions(-) diff --git a/json-schema/award.json b/json-schema/award.json index 57c0d355..7286d538 100644 --- a/json-schema/award.json +++ b/json-schema/award.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", + "$schema": "http://json-schema.org/draft-07/schema#", "title": "CLICS Contest API - award", "description": "Definition of a single award object", diff --git a/json-schema/awards.json b/json-schema/awards.json index 326a9536..5d2d040f 100644 --- a/json-schema/awards.json +++ b/json-schema/awards.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", + "$schema": "http://json-schema.org/draft-07/schema#", "title": "CLICS Contest API: awards", "description": "JSON response of this API call", diff --git a/json-schema/clarification.json b/json-schema/clarification.json index 303cc93c..a6bc9e0b 100644 --- a/json-schema/clarification.json +++ b/json-schema/clarification.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", + "$schema": "http://json-schema.org/draft-07/schema#", "title": "CLICS Contest API - clarification", "description": "Definition of a single clarification object", diff --git a/json-schema/clarifications.json b/json-schema/clarifications.json index 7cedc634..a06137d4 100644 --- a/json-schema/clarifications.json +++ b/json-schema/clarifications.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", + "$schema": "http://json-schema.org/draft-07/schema#", "title": "CLICS Contest API: clarifications", "description": "JSON response of this API call", diff --git a/json-schema/common.json b/json-schema/common.json index 580e59fc..45e85860 100644 --- a/json-schema/common.json +++ b/json-schema/common.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", + "$schema": "http://json-schema.org/draft-07/schema#", "title": "CLICS Contest API - common definitions", "description": "Common definitions of objects used in the API calls", diff --git a/json-schema/contest.json b/json-schema/contest.json index 18d82d5c..a3e38dea 100644 --- a/json-schema/contest.json +++ b/json-schema/contest.json @@ -1,7 +1,8 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", + "$schema": "http://json-schema.org/draft-07/schema#", "title": "CLICS Contest API: contest", "description": "JSON response of this API call", + "type": "object", "properties": { "id": { "$ref": "common.json#/identifier" }, diff --git a/json-schema/contests.json b/json-schema/contests.json index d386395b..4c0f2b8a 100644 --- a/json-schema/contests.json +++ b/json-schema/contests.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", + "$schema": "http://json-schema.org/draft-07/schema#", "title": "CLICS Contest API: contests", "description": "JSON response of this API call", diff --git a/json-schema/event-feed-array.json b/json-schema/event-feed-array.json index 6d115448..69d102c8 100644 --- a/json-schema/event-feed-array.json +++ b/json-schema/event-feed-array.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", + "$schema": "http://json-schema.org/draft-07/schema#", "title": "CLICS Contest API: event-feed array", "description": "JSON array of responses of this NDJSON API call", diff --git a/json-schema/event-feed.json b/json-schema/event-feed.json index 8fa576c1..5e24fb1f 100644 --- a/json-schema/event-feed.json +++ b/json-schema/event-feed.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", + "$schema": "http://json-schema.org/draft-07/schema#", "title": "CLICS Contest API: event-feed", "description": "Single line response of this NDJSON API call", diff --git a/json-schema/group.json b/json-schema/group.json index b80a5bf6..78b280d3 100644 --- a/json-schema/group.json +++ b/json-schema/group.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", + "$schema": "http://json-schema.org/draft-07/schema#", "title": "CLICS Contest API - group", "description": "Definition of a single group object", diff --git a/json-schema/groups.json b/json-schema/groups.json index 776c2ec6..79d28043 100644 --- a/json-schema/groups.json +++ b/json-schema/groups.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", + "$schema": "http://json-schema.org/draft-07/schema#", "title": "CLICS Contest API: groups", "description": "JSON response of this API call", diff --git a/json-schema/judgement-type.json b/json-schema/judgement-type.json index e4b0f748..084fad36 100644 --- a/json-schema/judgement-type.json +++ b/json-schema/judgement-type.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", + "$schema": "http://json-schema.org/draft-07/schema#", "title": "CLICS Contest API - judgement_type", "description": "Definition of a single judgement-type object", diff --git a/json-schema/judgement-types.json b/json-schema/judgement-types.json index c4193b29..4ec484b6 100644 --- a/json-schema/judgement-types.json +++ b/json-schema/judgement-types.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", + "$schema": "http://json-schema.org/draft-07/schema#", "title": "CLICS Contest API: judgement_types", "description": "JSON response of this API call", diff --git a/json-schema/judgement.json b/json-schema/judgement.json index 5455eb50..cb092051 100644 --- a/json-schema/judgement.json +++ b/json-schema/judgement.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", + "$schema": "http://json-schema.org/draft-07/schema#", "title": "CLICS Contest API - judgement", "description": "Definition of a single judgement object", diff --git a/json-schema/judgements.json b/json-schema/judgements.json index 5434c071..9acbbfee 100644 --- a/json-schema/judgements.json +++ b/json-schema/judgements.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", + "$schema": "http://json-schema.org/draft-07/schema#", "title": "CLICS Contest API: judgements", "description": "JSON response of this API call", diff --git a/json-schema/language.json b/json-schema/language.json index 0ca85fdf..7b309e1a 100644 --- a/json-schema/language.json +++ b/json-schema/language.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", + "$schema": "http://json-schema.org/draft-07/schema#", "title": "CLICS Contest API - language", "description": "Definition of a single language object", diff --git a/json-schema/languages.json b/json-schema/languages.json index 6ee62543..413c4667 100644 --- a/json-schema/languages.json +++ b/json-schema/languages.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", + "$schema": "http://json-schema.org/draft-07/schema#", "title": "CLICS Contest API: languages", "description": "JSON response of this API call", diff --git a/json-schema/organization.json b/json-schema/organization.json index 1c590e88..1bd045a5 100644 --- a/json-schema/organization.json +++ b/json-schema/organization.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", + "$schema": "http://json-schema.org/draft-07/schema#", "title": "CLICS Contest API - organization", "description": "Definition of a single organization object", diff --git a/json-schema/organizations.json b/json-schema/organizations.json index e243d051..9b0bafa2 100644 --- a/json-schema/organizations.json +++ b/json-schema/organizations.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", + "$schema": "http://json-schema.org/draft-07/schema#", "title": "CLICS Contest API: organizations", "description": "JSON response of this API call", diff --git a/json-schema/problem.json b/json-schema/problem.json index f73b38a3..f642d5e4 100644 --- a/json-schema/problem.json +++ b/json-schema/problem.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", + "$schema": "http://json-schema.org/draft-07/schema#", "title": "CLICS Contest API - problem", "description": "Definition of a single problem object", diff --git a/json-schema/problems.json b/json-schema/problems.json index b8d79cd2..6056fa1f 100644 --- a/json-schema/problems.json +++ b/json-schema/problems.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", + "$schema": "http://json-schema.org/draft-07/schema#", "title": "CLICS Contest API: problems", "description": "JSON response of this API call", diff --git a/json-schema/run.json b/json-schema/run.json index 1da21719..71bfceff 100644 --- a/json-schema/run.json +++ b/json-schema/run.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", + "$schema": "http://json-schema.org/draft-07/schema#", "title": "CLICS Contest API - run", "description": "Definition of a single run object", diff --git a/json-schema/runs.json b/json-schema/runs.json index fff126d0..5d51622e 100644 --- a/json-schema/runs.json +++ b/json-schema/runs.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", + "$schema": "http://json-schema.org/draft-07/schema#", "title": "CLICS Contest API: runs", "description": "JSON response of this API call", diff --git a/json-schema/scoreboard.json b/json-schema/scoreboard.json index f0b18ba7..4801ef89 100644 --- a/json-schema/scoreboard.json +++ b/json-schema/scoreboard.json @@ -1,7 +1,8 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", + "$schema": "http://json-schema.org/draft-07/schema#", "title": "CLICS Contest API: scoreboard", "description": "JSON response of this API call", + "type": "array", "uniqueItems": true, "items": { diff --git a/json-schema/state.json b/json-schema/state.json index cff83ca1..95c026cd 100644 --- a/json-schema/state.json +++ b/json-schema/state.json @@ -1,7 +1,8 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", + "$schema": "http://json-schema.org/draft-07/schema#", "title": "CLICS Contest API: state", "description": "JSON response of this API call", + "type": "object", "properties": { "started": { "$ref": "common.json#/abstimeornull" }, diff --git a/json-schema/submission.json b/json-schema/submission.json index d133d6e7..dcb66eb1 100644 --- a/json-schema/submission.json +++ b/json-schema/submission.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", + "$schema": "http://json-schema.org/draft-07/schema#", "title": "CLICS Contest API - submission", "description": "Definition of a single submission object", diff --git a/json-schema/submissions.json b/json-schema/submissions.json index e091b4b2..bb1fa88d 100644 --- a/json-schema/submissions.json +++ b/json-schema/submissions.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", + "$schema": "http://json-schema.org/draft-07/schema#", "title": "CLICS Contest API: submissions", "description": "JSON response of this API call", diff --git a/json-schema/team-member.json b/json-schema/team-member.json index a4435fce..bba94fe9 100644 --- a/json-schema/team-member.json +++ b/json-schema/team-member.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", + "$schema": "http://json-schema.org/draft-07/schema#", "title": "CLICS Contest API - team-member", "description": "Definition of a single team-member object", diff --git a/json-schema/team-members.json b/json-schema/team-members.json index a86a0690..074a3b39 100644 --- a/json-schema/team-members.json +++ b/json-schema/team-members.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", + "$schema": "http://json-schema.org/draft-07/schema#", "title": "CLICS Contest API: team-members", "description": "JSON response of this API call", diff --git a/json-schema/team.json b/json-schema/team.json index 9e42a6d0..0e232fec 100644 --- a/json-schema/team.json +++ b/json-schema/team.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", + "$schema": "http://json-schema.org/draft-07/schema#", "title": "CLICS Contest API - team", "description": "Definition of a single team object", diff --git a/json-schema/teams.json b/json-schema/teams.json index 93778ce1..4c88c2a9 100644 --- a/json-schema/teams.json +++ b/json-schema/teams.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", + "$schema": "http://json-schema.org/draft-07/schema#", "title": "CLICS Contest API: teams", "description": "JSON response of this API call", From 2155dd0a4b2b23bdef28d6f06aaa6d6261d158ce Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Sat, 3 Mar 2018 23:01:55 +0100 Subject: [PATCH 027/107] Make enforcing no extra JSON properties configurable. --- check-api.sh | 7 ++++++- json-schema/award.json | 3 ++- json-schema/clarification.json | 2 +- json-schema/common.json | 6 +++++- json-schema/contest.json | 2 +- json-schema/event-feed.json | 4 ++-- json-schema/group.json | 2 +- json-schema/judgement-type.json | 2 +- json-schema/judgement.json | 2 +- json-schema/language.json | 2 +- json-schema/organization.json | 4 ++-- json-schema/problem.json | 2 +- json-schema/run.json | 2 +- json-schema/scoreboard.json | 6 +++--- json-schema/state.json | 2 +- json-schema/submission.json | 2 +- json-schema/team-member.json | 2 +- json-schema/team.json | 4 ++-- 18 files changed, 33 insertions(+), 23 deletions(-) diff --git a/check-api.sh b/check-api.sh index 950ecd08..e3331b22 100755 --- a/check-api.sh +++ b/check-api.sh @@ -81,6 +81,7 @@ Options: -h Snow this help output. -j PROG Specify the path to the 'validate-json' binary. -n Require that all collection endpoints are non-empty. + -p Allow extra properties beyond those defined in the Contest API. -t TIME Timeout in seconds for downloading event feed (default: $FEED_TIMEOUT) -q Quiet mode: suppress all output except script errors. @@ -95,7 +96,7 @@ CURL_OPTIONS='-n -s' URL_ARGS='' # Parse command-line options: -while getopts 'a:c:dhj:nt:q' OPT ; do +while getopts 'a:c:dhj:npt:q' OPT ; do case "$OPT" in a) URL_ARGS="$OPTARG" ;; c) CURL_OPTIONS="$OPTARG" ;; @@ -103,6 +104,7 @@ while getopts 'a:c:dhj:nt:q' OPT ; do h) usage ; exit 0 ;; j) VALIDATE_JSON="$OPTARG" ;; n) NONEMPTY=1 ;; + p) EXTRAPROP=1 ;; t) FEED_TIMEOUT="$OPTARG" ;; q) QUIET=1 ;; :) @@ -199,6 +201,9 @@ if [ -n "$NONEMPTY" ]; then # Don't understand why the first '\t' needs a double escape... sed -i '/"nonemptyarray":/a \\t\t"minItems": 1' "$TMP/json-schema/common.json" fi +if [ -z "$EXTRAPROP" ]; then + sed -i '/"strictproperties":/a \\t\t"additionalProperties": false' "$TMP/json-schema/common.json" +fi # First validate and get all contests ENDPOINT='contests' diff --git a/json-schema/award.json b/json-schema/award.json index 7286d538..a149133a 100644 --- a/json-schema/award.json +++ b/json-schema/award.json @@ -13,5 +13,6 @@ "items": { "$ref": "common.json#/identifier" } } }, - "required": ["id", "citation", "team_ids"] + "required": ["id", "citation", "team_ids"], + "$ref": "common.json#/strictproperties" } diff --git a/json-schema/clarification.json b/json-schema/clarification.json index a6bc9e0b..d690cfdc 100644 --- a/json-schema/clarification.json +++ b/json-schema/clarification.json @@ -17,5 +17,5 @@ "contest_time": { "$ref": "common.json#/reltime" } }, "required": ["id", "text", "time", "contest_time"], - "additionalProperties": false + "$ref": "common.json#/strictproperties" } diff --git a/json-schema/common.json b/json-schema/common.json index 45e85860..4042070a 100644 --- a/json-schema/common.json +++ b/json-schema/common.json @@ -101,7 +101,7 @@ "height": { "type": "integer", "minimum": 1 } }, "required": ["href"], - "additionalProperties": false + "$ref": "#/strictproperties" }, "filerefs": { @@ -115,5 +115,9 @@ "$comment": "Inside here add '\"minItems\": 1' to require all collection endpoints to contain at least one element.", "nonemptyarray": { + }, + + "$comment": "Inside here add '\"additionalProperties\": false' to force that no additional properties can be present beyond those defined in the API.", + "strictproperties": { } } diff --git a/json-schema/contest.json b/json-schema/contest.json index a3e38dea..b83048d3 100644 --- a/json-schema/contest.json +++ b/json-schema/contest.json @@ -19,5 +19,5 @@ "logo": { "$ref": "common.json#/filerefs" } }, "required": ["id", "name", "duration"], - "additionalProperties": false + "$ref": "common.json#/strictproperties" } diff --git a/json-schema/event-feed.json b/json-schema/event-feed.json index 5e24fb1f..cccc2079 100644 --- a/json-schema/event-feed.json +++ b/json-schema/event-feed.json @@ -39,11 +39,11 @@ "id": { "$ref": "common.json#/identifier" } }, "required": ["id"], - "additionalProperties": false + "$ref": "common.json#/strictproperties" } } ] }, "required": ["id", "type", "op", "data"], - "additionalProperties": false + "$ref": "common.json#/strictproperties" } diff --git a/json-schema/group.json b/json-schema/group.json index 78b280d3..1c70d0a4 100644 --- a/json-schema/group.json +++ b/json-schema/group.json @@ -12,5 +12,5 @@ "hidden": { "type": "boolean" } }, "required": ["id", "name"], - "additionalProperties": false + "$ref": "common.json#/strictproperties" } diff --git a/json-schema/judgement-type.json b/json-schema/judgement-type.json index 084fad36..ab121cc4 100644 --- a/json-schema/judgement-type.json +++ b/json-schema/judgement-type.json @@ -11,5 +11,5 @@ "solved": { "type": "boolean" } }, "required": ["id", "name", "solved"], - "additionalProperties": false + "$ref": "common.json#/strictproperties" } diff --git a/json-schema/judgement.json b/json-schema/judgement.json index cb092051..c927f809 100644 --- a/json-schema/judgement.json +++ b/json-schema/judgement.json @@ -28,5 +28,5 @@ } }, "required": ["id", "submission_id", "start_time", "start_contest_time", "end_time", "end_contest_time"], - "additionalProperties": false + "$ref": "common.json#/strictproperties" } diff --git a/json-schema/language.json b/json-schema/language.json index 7b309e1a..d66ce78b 100644 --- a/json-schema/language.json +++ b/json-schema/language.json @@ -9,5 +9,5 @@ "name": { "type": "string" } }, "required": ["id", "name"], - "additionalProperties": false + "$ref": "common.json#/strictproperties" } diff --git a/json-schema/organization.json b/json-schema/organization.json index 1bd045a5..d08b0fb4 100644 --- a/json-schema/organization.json +++ b/json-schema/organization.json @@ -37,7 +37,7 @@ } }, "required": ["latitude", "longitude"], - "additionalProperties": false + "$ref": "common.json#/strictproperties" }, { "type": "null" } ] @@ -45,5 +45,5 @@ "logo": { "$ref": "common.json#/filerefs" } }, "required": ["id", "name"], - "additionalProperties": false + "$ref": "common.json#/strictproperties" } diff --git a/json-schema/problem.json b/json-schema/problem.json index f642d5e4..8943e194 100644 --- a/json-schema/problem.json +++ b/json-schema/problem.json @@ -24,5 +24,5 @@ } }, "required": ["id", "label", "name", "ordinal", "test_data_count"], - "additionalProperties": false + "$ref": "common.json#/strictproperties" } diff --git a/json-schema/run.json b/json-schema/run.json index 71bfceff..eb703e82 100644 --- a/json-schema/run.json +++ b/json-schema/run.json @@ -17,5 +17,5 @@ } }, "required": ["id", "judgement_id", "ordinal", "judgement_type_id", "time", "contest_time"], - "additionalProperties": false + "$ref": "common.json#/strictproperties" } diff --git a/json-schema/scoreboard.json b/json-schema/scoreboard.json index 4801ef89..76379a47 100644 --- a/json-schema/scoreboard.json +++ b/json-schema/scoreboard.json @@ -26,7 +26,7 @@ } }, "required": ["num_solved", "total_time"], - "additionalProperties": false + "$ref": "common.json#/strictproperties" }, "problems": { "type": "array", @@ -56,11 +56,11 @@ } ], "required": ["problem_id", "num_judged", "num_pending", "solved"], - "additionalProperties": false + "$ref": "common.json#/strictproperties" } } }, "required": ["rank", "team_id", "score", "problems"], - "additionalProperties": false + "$ref": "common.json#/strictproperties" } } diff --git a/json-schema/state.json b/json-schema/state.json index 95c026cd..47f9754f 100644 --- a/json-schema/state.json +++ b/json-schema/state.json @@ -12,5 +12,5 @@ "finalized": { "$ref": "common.json#/abstimeornull" } }, "required": ["started", "ended", "finalized"], - "additionalProperties": false + "$ref": "common.json#/strictproperties" } diff --git a/json-schema/submission.json b/json-schema/submission.json index dcb66eb1..e77765ef 100644 --- a/json-schema/submission.json +++ b/json-schema/submission.json @@ -16,5 +16,5 @@ "reaction": { "$ref": "common.json#/filerefs" } }, "required": ["id", "language_id", "problem_id", "team_id", "time", "contest_time", "files"], - "additionalProperties": false + "$ref": "common.json#/strictproperties" } diff --git a/json-schema/team-member.json b/json-schema/team-member.json index bba94fe9..5ad22504 100644 --- a/json-schema/team-member.json +++ b/json-schema/team-member.json @@ -20,5 +20,5 @@ "photo": { "$ref": "common.json#/filerefs" } }, "required": ["id", "team_id", "first_name", "last_name"], - "additionalProperties": false + "$ref": "common.json#/strictproperties" } diff --git a/json-schema/team.json b/json-schema/team.json index 0e232fec..08e2870d 100644 --- a/json-schema/team.json +++ b/json-schema/team.json @@ -22,7 +22,7 @@ "rotation": { "type": "number" } }, "required": ["x", "y", "rotation"], - "additionalProperties": false + "$ref": "common.json#/strictproperties" }, "photo": { "$ref": "common.json#/filerefs" }, "video": { "$ref": "common.json#/filerefs" }, @@ -31,5 +31,5 @@ "webcam": { "$ref": "common.json#/filerefs" } }, "required": ["id", "name"], - "additionalProperties": false + "$ref": "common.json#/strictproperties" } From 0fb418d46d05d77ee9021abe7d6a7a00aec6193a Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Sat, 3 Mar 2018 23:32:42 +0100 Subject: [PATCH 028/107] Fix 07ef02740542e10c9d33: can't use "oneOf" within "properties". --- json-schema/event-feed.json | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/json-schema/event-feed.json b/json-schema/event-feed.json index cccc2079..096f72a7 100644 --- a/json-schema/event-feed.json +++ b/json-schema/event-feed.json @@ -6,14 +6,15 @@ "type": "object", "properties": { "id": { "$ref": "common.json#/identifier" }, - "type": { "$ref": "common.json#/endpoints" }, - "op": { "enum": [ "create", "update", "delete" ] }, - "data": {}, - "oneOf": [ - { + "type": { "$ref": "common.json#/endpoints" } + }, + "oneOf": [ + { + "properties": { "op": { "enum": [ "create", "update" ] }, "data": { - "oneOf": [ + "$comment": "Use anyOf since some types match others without strict attribute checking.", + "anyOf": [ { "$ref": "contest.json#" }, { "$ref": "judgement-type.json#" }, { "$ref": "language.json#" }, @@ -30,8 +31,10 @@ { "$ref": "award.json#" } ] } - }, - { + } + }, + { + "properties": { "op": { "enum": [ "delete" ] }, "data": { "type": "object", @@ -42,8 +45,8 @@ "$ref": "common.json#/strictproperties" } } - ] - }, + } + ], "required": ["id", "type", "op", "data"], "$ref": "common.json#/strictproperties" } From a97f951336ec4884b36c51c4f40b5ce3e267dbcb Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Thu, 15 Mar 2018 20:12:01 +0100 Subject: [PATCH 029/107] Add constraint that one of from_team_id and to_team_id must be null. --- json-schema/clarification.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/json-schema/clarification.json b/json-schema/clarification.json index d690cfdc..8a4f81ad 100644 --- a/json-schema/clarification.json +++ b/json-schema/clarification.json @@ -16,6 +16,12 @@ "time": { "$ref": "common.json#/abstime" }, "contest_time": { "$ref": "common.json#/reltime" } }, + "not": { + "properties": { + "from_team_id": { "$ref": "common.json#/identifier" }, + "to_team_id": { "$ref": "common.json#/identifier" } + } + }, "required": ["id", "text", "time", "contest_time"], "$ref": "common.json#/strictproperties" } From 469720f7a3dcd2571e0e6c7ce41f685706f15a5e Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Thu, 15 Mar 2018 20:53:29 +0100 Subject: [PATCH 030/107] Correct name of validate-json binary in comment. --- check-api.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/check-api.sh b/check-api.sh index e3331b22..679c29ab 100755 --- a/check-api.sh +++ b/check-api.sh @@ -3,7 +3,7 @@ # https://clics.ecs.baylor.edu/index.php/Contest_API # Set path to json-validate binary if it's not in PATH: -#VALIDATE_JSON=/path/to/json-validate +#VALIDATE_JSON=/path/to/validate-json ENDPOINTS=' contest From a4c3b56ae3a191760e8315c2602df8a08ae57ae3 Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Sat, 24 Mar 2018 21:52:55 +0100 Subject: [PATCH 031/107] Fix check that clarification does not have {from,to}_team_id set. --- json-schema/clarification.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/json-schema/clarification.json b/json-schema/clarification.json index 8a4f81ad..091f6cab 100644 --- a/json-schema/clarification.json +++ b/json-schema/clarification.json @@ -20,7 +20,8 @@ "properties": { "from_team_id": { "$ref": "common.json#/identifier" }, "to_team_id": { "$ref": "common.json#/identifier" } - } + }, + "required": ["from_team_id", "to_team_id"] }, "required": ["id", "text", "time", "contest_time"], "$ref": "common.json#/strictproperties" From 8cbcc91af2e54c30eecb016b8ce068e0fa7018c4 Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Tue, 24 Jul 2018 00:25:19 +0200 Subject: [PATCH 032/107] Add contest.countdown_pause_time and state.end_of_updates attributes. --- json-schema/contest.json | 6 ++++++ json-schema/state.json | 13 +++++++------ 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/json-schema/contest.json b/json-schema/contest.json index b83048d3..5d39499e 100644 --- a/json-schema/contest.json +++ b/json-schema/contest.json @@ -9,6 +9,12 @@ "name": { "type": "string" }, "formal_name": { "type": "string" }, "start_time": { "$ref": "common.json#/abstimeornull" }, + "countdown_pause_time": { + "oneOf": [ + { "$ref": "common.json#/reltime" }, + { "type": "null" } + ] + }, "duration": { "$ref": "common.json#/reltime" }, "scoreboard_freeze_duration": { "$ref": "common.json#/reltime" }, "penalty_time": { diff --git a/json-schema/state.json b/json-schema/state.json index 47f9754f..03365ec3 100644 --- a/json-schema/state.json +++ b/json-schema/state.json @@ -5,12 +5,13 @@ "type": "object", "properties": { - "started": { "$ref": "common.json#/abstimeornull" }, - "ended": { "$ref": "common.json#/abstimeornull" }, - "frozen": { "$ref": "common.json#/abstimeornull" }, - "thawed": { "$ref": "common.json#/abstimeornull" }, - "finalized": { "$ref": "common.json#/abstimeornull" } + "started": { "$ref": "common.json#/abstimeornull" }, + "ended": { "$ref": "common.json#/abstimeornull" }, + "frozen": { "$ref": "common.json#/abstimeornull" }, + "thawed": { "$ref": "common.json#/abstimeornull" }, + "finalized": { "$ref": "common.json#/abstimeornull" }, + "end_of_updates": { "$ref": "common.json#/abstimeornull" } }, - "required": ["started", "ended", "finalized"], + "required": ["started", "ended", "finalized", "end_of_updates"], "$ref": "common.json#/strictproperties" } From 78bb9c84bdeb7d918eb91c4e0e56f7be81900451 Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Sun, 29 Jul 2018 01:47:39 +0200 Subject: [PATCH 033/107] Use plural 'contests' and store in contest subdirectory. --- check-api.sh | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/check-api.sh b/check-api.sh index 679c29ab..c9d4c43c 100755 --- a/check-api.sh +++ b/check-api.sh @@ -6,7 +6,7 @@ #VALIDATE_JSON=/path/to/validate-json ENDPOINTS=' -contest +contests judgement-types languages problems @@ -226,6 +226,7 @@ EXITCODE=0 for CONTEST in $CONTESTS ; do verbose "Validating contest '$CONTEST'..." CONTEST_URL="${API_URL%/}/contests/$CONTEST" + mkdir -p "$TMP/$CONTEST" for ENDPOINT in $ENDPOINTS ; do if [ "${ENDPOINTS_OPTIONAL/${ENDPOINT}/}" != "$ENDPOINTS_OPTIONAL" ]; then @@ -234,14 +235,15 @@ for CONTEST in $CONTESTS ; do unset OPTIONAL fi - if [ "$ENDPOINT" = 'contest' ]; then + if [ "$ENDPOINT" = 'contests' ]; then URL="$CONTEST_URL" + SCHEMA="$TMP/json-schema/contest.json" else URL="$CONTEST_URL/$ENDPOINT" + SCHEMA="$TMP/json-schema/$ENDPOINT.json" fi - SCHEMA="$TMP/json-schema/$ENDPOINT.json" - OUTPUT="$TMP/${CONTEST}_${ENDPOINT}.json" + OUTPUT="$TMP/$CONTEST/$ENDPOINT.json" if query_endpoint "$OUTPUT" "$URL" $OPTIONAL ; then verbose '%20s: ' "$ENDPOINT" @@ -261,7 +263,7 @@ for CONTEST in $CONTESTS ; do # Now do special case event-feed endpoint ENDPOINT='event-feed' SCHEMA="$MYDIR/json-schema/$ENDPOINT-array.json" - OUTPUT="$TMP/$CONTEST_$ENDPOINT.json" + OUTPUT="$TMP/$CONTEST/$ENDPOINT.json" URL="$CONTEST_URL/$ENDPOINT" if query_endpoint "$OUTPUT" "$URL" ; then From aef6a6e8597cf8be8a6de1a6d0611da08ee2a60f Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Sun, 29 Jul 2018 01:49:10 +0200 Subject: [PATCH 034/107] Add option -C to check REST/feed consistency. We use a separate PHP script since Bash doesn't do JSON parsing well, and PHP sucks at command line option parsing. --- check-api-consistency.php | 128 ++++++++++++++++++++++++++++++++++++++ check-api.sh | 23 ++++++- 2 files changed, 150 insertions(+), 1 deletion(-) create mode 100755 check-api-consistency.php diff --git a/check-api-consistency.php b/check-api-consistency.php new file mode 100755 index 00000000..c6edbdc7 --- /dev/null +++ b/check-api-consistency.php @@ -0,0 +1,128 @@ +#!/usr/bin/env php + $elements) { + if ($endpoint==='state') { + foreach ($elements as $id => $rows) { + if ($id!=='_single_') { + error("'state' cannot have ID '$id' set."); + } + for ($i=0; $i $rows) { + if ($rows[0]['op']!=='create') { + error("'$endpoint/$id' not created first."); + } + for ($i=1; $i $elements) { + foreach ($elements as $id => $rows) { + $last = end($rows); + if ($last['op']!=='delete') { + if (!isset($endpoint_data[$endpoint][$id])) { + error("'$endpoint".($id==='_single_' ? '' : "/$id")."' not found in REST endpoint."); + } elseif ($last['data']!==$endpoint_data[$endpoint][$id]) { + $diff = array_diff_keys($last['data'], $endpoint_data[$endpoint][$id]); + warning("'$endpoint".($id==='_single_' ? '' : "/$id")."' data mismatch betweed feed and REST endpoint: ".implode(',', $diff)); + } + } + } +} + +if ($errors>0) { + echo "Found $errors errors and $warnings warnings.\n"; + exit(1); +} + +if ($warnings>0) { + echo "Found $warnings warnings.\n"; +} diff --git a/check-api.sh b/check-api.sh index c9d4c43c..f36b1f11 100755 --- a/check-api.sh +++ b/check-api.sh @@ -30,6 +30,21 @@ team-members awards ' +ENDPOINTS_CHECK_CONSISTENT=' +contests +judgement-types +languages +problems +groups +organizations +teams +state +submissions +judgements +runs +clarifications +' + error() { echo "Error: $*" @@ -76,6 +91,7 @@ Options: -a ARGS Arguments to pass to the API request URLs. Separate arguments with '&', do not add initial '?'. (default: $URL_ARGS) + -C Check internal consistency between REST endpoints and event feed. -c OPTS Options to pass to curl to request API data (default: $CURL_OPTIONS) -d Turn on shell script debugging. -h Snow this help output. @@ -96,9 +112,10 @@ CURL_OPTIONS='-n -s' URL_ARGS='' # Parse command-line options: -while getopts 'a:c:dhj:npt:q' OPT ; do +while getopts 'a:Cc:dhj:npt:q' OPT ; do case "$OPT" in a) URL_ARGS="$OPTARG" ;; + C) CHECK_CONSISTENCY=1 ;; c) CURL_OPTIONS="$OPTARG" ;; d) DEBUG=1 ;; h) usage ; exit 0 ;; @@ -279,6 +296,10 @@ for CONTEST in $CONTESTS ; do verbose '%20s: Failed to download\n' "$ENDPOINT" fi + if [ -n "$CHECK_CONSISTENCY" ]; then + $MYDIR/check-api-consistency.php "$TMP/$CONTEST" $ENDPOINTS_CHECK_CONSISTENT + fi + done [ -n "$DEBUG" ] || rm -rf $TMP From 1f2ebb15551fc08a5c31f8409b93ee1263ac9cc2 Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Sun, 29 Jul 2018 02:07:46 +0200 Subject: [PATCH 035/107] Make sure we don't list mismatching keys twice. --- check-api-consistency.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/check-api-consistency.php b/check-api-consistency.php index c6edbdc7..306d880b 100755 --- a/check-api-consistency.php +++ b/check-api-consistency.php @@ -40,7 +40,7 @@ function warning($msg) // Given two associative arrays, return the keys of their symmetric difference. function array_diff_keys($a, $b) { - $keys = array_merge(array_keys($a), array_keys($b)); + $keys = array_unique(array_merge(array_keys($a), array_keys($b))); $diff = []; foreach ($keys as $key) { if ((array_key_exists($key, $a) xor array_key_exists($key, $b)) || From 65cd47c153480c5d33af664809cb3a44c7583494 Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Sun, 29 Jul 2018 02:10:41 +0200 Subject: [PATCH 036/107] Use exit code from check-api-consistency sub-script. --- check-api.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/check-api.sh b/check-api.sh index f36b1f11..ec35beda 100755 --- a/check-api.sh +++ b/check-api.sh @@ -298,6 +298,8 @@ for CONTEST in $CONTESTS ; do if [ -n "$CHECK_CONSISTENCY" ]; then $MYDIR/check-api-consistency.php "$TMP/$CONTEST" $ENDPOINTS_CHECK_CONSISTENT + EXIT=$? + [ $EXIT -gt $EXITCODE ] && EXITCODE=$EXIT fi done From 0fe78f08f995e4b817709a07f0fcbd21494b1671 Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Sun, 29 Jul 2018 11:13:51 +0200 Subject: [PATCH 037/107] Remove duplicate specification of endpoints. --- check-api.sh | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/check-api.sh b/check-api.sh index ec35beda..8e8af754 100755 --- a/check-api.sh +++ b/check-api.sh @@ -30,20 +30,10 @@ team-members awards ' -ENDPOINTS_CHECK_CONSISTENT=' -contests -judgement-types -languages -problems -groups -organizations -teams -state -submissions -judgements -runs -clarifications -' +ENDPOINTS_CHECK_CONSISTENT="$ENDPOINTS" +for endpoint in $ENDPOINTS_OPTIONAL scoreboard ; do + ENDPOINTS_CHECK_CONSISTENT="${ENDPOINTS_CHECK_CONSISTENT/$endpoint/}" +done error() { From 8e90cd51e0cedaf48acc28dfb72584013842dcbe Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Sun, 29 Jul 2018 11:14:23 +0200 Subject: [PATCH 038/107] Allow some debugging in check-api-consistency script. --- check-api-consistency.php | 4 ++++ check-api.sh | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/check-api-consistency.php b/check-api-consistency.php index 306d880b..6dee3867 100755 --- a/check-api-consistency.php +++ b/check-api-consistency.php @@ -12,6 +12,8 @@ $feed_json = json_decode(file_get_contents($dir.'/event-feed.json'), true); +$debug = getenv('DEBUG'); + $errors = 0; $warnings = 0; @@ -98,6 +100,7 @@ function array_diff_keys($a, $b) $endpoint_data[$endpoint][$id] = $element; if (!isset($feed_data[$endpoint][$id])) { error("'$endpoint".($id==='_single_' ? '' : "/$id")."' not found in feed."); + if ($debug) var_dump($element); } } } @@ -113,6 +116,7 @@ function array_diff_keys($a, $b) } elseif ($last['data']!==$endpoint_data[$endpoint][$id]) { $diff = array_diff_keys($last['data'], $endpoint_data[$endpoint][$id]); warning("'$endpoint".($id==='_single_' ? '' : "/$id")."' data mismatch betweed feed and REST endpoint: ".implode(',', $diff)); + if (!$debug) var_dump($last['data'], $endpoint_data[$endpoint][$id]); } } } diff --git a/check-api.sh b/check-api.sh index 8e8af754..06345720 100755 --- a/check-api.sh +++ b/check-api.sh @@ -107,7 +107,7 @@ while getopts 'a:Cc:dhj:npt:q' OPT ; do a) URL_ARGS="$OPTARG" ;; C) CHECK_CONSISTENCY=1 ;; c) CURL_OPTIONS="$OPTARG" ;; - d) DEBUG=1 ;; + d) export DEBUG=1 ;; h) usage ; exit 0 ;; j) VALIDATE_JSON="$OPTARG" ;; n) NONEMPTY=1 ;; From 40ca19f894e21c9c2e9f9d1beb6be67e6476b890 Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Sun, 29 Jul 2018 11:41:07 +0200 Subject: [PATCH 039/107] Fix logic typo. --- check-api-consistency.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/check-api-consistency.php b/check-api-consistency.php index 6dee3867..a3d4fd63 100755 --- a/check-api-consistency.php +++ b/check-api-consistency.php @@ -116,7 +116,7 @@ function array_diff_keys($a, $b) } elseif ($last['data']!==$endpoint_data[$endpoint][$id]) { $diff = array_diff_keys($last['data'], $endpoint_data[$endpoint][$id]); warning("'$endpoint".($id==='_single_' ? '' : "/$id")."' data mismatch betweed feed and REST endpoint: ".implode(',', $diff)); - if (!$debug) var_dump($last['data'], $endpoint_data[$endpoint][$id]); + if ($debug) var_dump($last['data'], $endpoint_data[$endpoint][$id]); } } } From d97e37d3cae7f6d7a883575abe07fa5273709705 Mon Sep 17 00:00:00 2001 From: Nicky Gerritsen Date: Sat, 3 Nov 2018 11:45:13 +0100 Subject: [PATCH 040/107] Use new scoreboard endpoint format when validating the CCS API --- json-schema/scoreboard.json | 114 ++++++++++++++++++++---------------- 1 file changed, 62 insertions(+), 52 deletions(-) diff --git a/json-schema/scoreboard.json b/json-schema/scoreboard.json index 76379a47..aeda4e46 100644 --- a/json-schema/scoreboard.json +++ b/json-schema/scoreboard.json @@ -3,64 +3,74 @@ "title": "CLICS Contest API: scoreboard", "description": "JSON response of this API call", - "type": "array", - "uniqueItems": true, - "items": { - "type": "object", - "properties": { - "rank": { - "type": "integer", - "minimum": 1 - }, - "team_id": { "$ref": "common.json#/identifier" }, - "score": { + "type": "object", + "properties": { + "event_id": { "$ref": "common.json#/identifier" }, + "time": { "$ref": "common.json#/abstime" }, + "contest_time": { "$ref": "common.json#/reltime" }, + "state": { "$ref": "state.json#" }, + "rows": { + "type": "array", + "uniqueItems": true, + "items": { "type": "object", "properties": { - "num_solved": { + "rank": { "type": "integer", - "minimum": 0 + "minimum": 1 }, - "total_time": { - "type": "integer", - "minimum": 0 - } - }, - "required": ["num_solved", "total_time"], - "$ref": "common.json#/strictproperties" - }, - "problems": { - "type": "array", - "items": { - "type": "object", - "properties": { - "problem_id": { "$ref": "common.json#/identifier" }, - "num_judged": { - "type": "integer", - "minimum": 0 - }, - "num_pending": { - "type": "integer", - "minimum": 0 + "team_id": { "$ref": "common.json#/identifier" }, + "score": { + "type": "object", + "properties": { + "num_solved": { + "type": "integer", + "minimum": 0 + }, + "total_time": { + "type": "integer", + "minimum": 0 + } }, - "solved": { "type": "boolean" }, - "time": { "type": "integer", "minimum": 0 } + "required": ["num_solved", "total_time"], + "$ref": "common.json#/strictproperties" }, - "oneOf": [ - { - "properties": { "solved": { "enum": [false] } }, - "not": { "required": ["time"] } - }, - { - "properties": { "solved": { "enum": [true] } }, - "required": ["time"] + "problems": { + "type": "array", + "items": { + "type": "object", + "properties": { + "problem_id": { "$ref": "common.json#/identifier" }, + "num_judged": { + "type": "integer", + "minimum": 0 + }, + "num_pending": { + "type": "integer", + "minimum": 0 + }, + "solved": { "type": "boolean" }, + "time": { "type": "integer", "minimum": 0 } + }, + "oneOf": [ + { + "properties": { "solved": { "enum": [false] } }, + "not": { "required": ["time"] } + }, + { + "properties": { "solved": { "enum": [true] } }, + "required": ["time"] + } + ], + "required": ["problem_id", "num_judged", "num_pending", "solved"], + "$ref": "common.json#/strictproperties" } - ], - "required": ["problem_id", "num_judged", "num_pending", "solved"], - "$ref": "common.json#/strictproperties" - } + } + }, + "required": ["rank", "team_id", "score", "problems"], + "$ref": "common.json#/strictproperties" } - }, - "required": ["rank", "team_id", "score", "problems"], - "$ref": "common.json#/strictproperties" - } + } + }, + "required": ["event_id", "time", "contest_time", "state", "rows"] } From a3ab402e00463310b4c6d7474347150b6746d8b6 Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Mon, 21 Jan 2019 00:02:41 +0100 Subject: [PATCH 041/107] Update checker to Contest API: file mime-type is required now. See https://clics.ecs.baylor.edu/index.php?title=Contest_API&diff=3027&oldid=2996 --- json-schema/common.json | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/json-schema/common.json b/json-schema/common.json index 4042070a..b5b39218 100644 --- a/json-schema/common.json +++ b/json-schema/common.json @@ -91,16 +91,11 @@ "type": "object", "properties": { "href": { "type": "string" }, - "mime": { - "oneOf": [ - { "type": "string" }, - { "type": "null" } - ] - }, + "mime": { "type": "string" }, "width": { "type": "integer", "minimum": 1 }, "height": { "type": "integer", "minimum": 1 } }, - "required": ["href"], + "required": ["href", "mime"], "$ref": "#/strictproperties" }, From 8fe6578efdf30f0239faac278a375be21b880d20 Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Sat, 21 Sep 2019 14:55:23 +0200 Subject: [PATCH 042/107] Drop Travis CI hack now that we've moved to Gitlab. --- check-api.sh | 5 ----- 1 file changed, 5 deletions(-) diff --git a/check-api.sh b/check-api.sh index 06345720..e1795e9f 100755 --- a/check-api.sh +++ b/check-api.sh @@ -159,11 +159,6 @@ query_endpoint() if [ "${URL/event-feed/}" != "$URL" ]; then TIMEOUT=1 CURLOPTS="$CURLOPTS -N --max-time ${FEED_TIMEOUT}" - # This is a hack around the --max-time option not working well - # on Travis CI for the DOMjudge event-feed endpoint. - if [ "${URL/domjudge/}" != "$URL" ]; then - ARGS="${ARGS:+$ARGS&}stream=0" - fi fi HTTPCODE=$(curl $CURLOPTS -w "%{http_code}\n" -o "$OUTPUT" "${URL}${ARGS:+?$ARGS}") From 3678f2e98abc84abe127d2b2cfffa4e12d205076 Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Sat, 21 Sep 2019 15:28:54 +0200 Subject: [PATCH 043/107] Fix spelling typo. --- check-api-consistency.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/check-api-consistency.php b/check-api-consistency.php index a3d4fd63..596a9b99 100755 --- a/check-api-consistency.php +++ b/check-api-consistency.php @@ -115,7 +115,7 @@ function array_diff_keys($a, $b) error("'$endpoint".($id==='_single_' ? '' : "/$id")."' not found in REST endpoint."); } elseif ($last['data']!==$endpoint_data[$endpoint][$id]) { $diff = array_diff_keys($last['data'], $endpoint_data[$endpoint][$id]); - warning("'$endpoint".($id==='_single_' ? '' : "/$id")."' data mismatch betweed feed and REST endpoint: ".implode(',', $diff)); + warning("'$endpoint".($id==='_single_' ? '' : "/$id")."' data mismatch between feed and REST endpoint: ".implode(',', $diff)); if ($debug) var_dump($last['data'], $endpoint_data[$endpoint][$id]); } } From f67b4e2de93ca1bebed10ff65192ffe059a3e6b9 Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Sun, 22 Sep 2019 00:07:43 +0200 Subject: [PATCH 044/107] Add option to check that missing endpoints give right errors. --- check-api.sh | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/check-api.sh b/check-api.sh index e1795e9f..2c5b2c2d 100755 --- a/check-api.sh +++ b/check-api.sh @@ -30,6 +30,12 @@ team-members awards ' +ENDPOINTS_TO_FAIL=' +404:doesnt-exist +404:doesnt-exist/42 +404:submissions/999999 +' + ENDPOINTS_CHECK_CONSISTENT="$ENDPOINTS" for endpoint in $ENDPOINTS_OPTIONAL scoreboard ; do ENDPOINTS_CHECK_CONSISTENT="${ENDPOINTS_CHECK_CONSISTENT/$endpoint/}" @@ -84,6 +90,7 @@ Options: -C Check internal consistency between REST endpoints and event feed. -c OPTS Options to pass to curl to request API data (default: $CURL_OPTIONS) -d Turn on shell script debugging. + -e Check correct HTTP error codes for non-existent endpoints. -h Snow this help output. -j PROG Specify the path to the 'validate-json' binary. -n Require that all collection endpoints are non-empty. @@ -102,12 +109,13 @@ CURL_OPTIONS='-n -s' URL_ARGS='' # Parse command-line options: -while getopts 'a:Cc:dhj:npt:q' OPT ; do +while getopts 'a:Cc:dehj:npt:q' OPT ; do case "$OPT" in a) URL_ARGS="$OPTARG" ;; C) CHECK_CONSISTENCY=1 ;; c) CURL_OPTIONS="$OPTARG" ;; d) export DEBUG=1 ;; + e) CHECK_ERRORS=1 ;; h) usage ; exit 0 ;; j) VALIDATE_JSON="$OPTARG" ;; n) NONEMPTY=1 ;; @@ -148,6 +156,8 @@ query_endpoint() local OUTPUT="$1" local URL="$2" local OPTIONAL="$3" + local EXPECTED_HTTPCODE="$4" + local HTTPCODE EXITCODE local CURLOPTS="$CURL_OPTIONS" @@ -163,6 +173,15 @@ query_endpoint() HTTPCODE=$(curl $CURLOPTS -w "%{http_code}\n" -o "$OUTPUT" "${URL}${ARGS:+?$ARGS}") EXITCODE="$?" + + if [ -n "$EXPECTED_HTTPCODE" ]; then + if [ "$HTTPCODE" -ne "$EXPECTED_HTTPCODE" ]; then + verbose "Warning: curl returned HTTP status $HTTPCODE != $EXPECTED_HTTPCODE for '$URL'." + return 1; + fi + return 0 + fi + if [ $EXITCODE -eq 28 ]; then # timeout if [ -z "$TIMEOUT" ]; then verbose "Warning: curl request timed out for '$URL'." @@ -289,6 +308,19 @@ for CONTEST in $CONTESTS ; do done +if [ -n "$CHECK_ERRORS" ]; then + verbose "Validating errors on missing endpoints..." + for i in $ENDPOINTS_TO_FAIL ; do + CODE=${i%%:*} + ENDPOINT=${i#*:} + URL="$CONTEST_URL/$ENDPOINT" + verbose '%20s: ' "$ENDPOINT" + if query_endpoint /dev/null "$URL" '' "$CODE" ; then + verbose 'OK (returned %s)\n' "$CODE" + fi + done +fi + [ -n "$DEBUG" ] || rm -rf $TMP exit $EXITCODE From 74a528e88283922cf028013f86173e382945b2b6 Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Sun, 22 Sep 2019 22:00:46 +0200 Subject: [PATCH 045/107] Add some more relative time types, allowing pos/neg and nullable. --- json-schema/common.json | 19 +++++++++++++++++++ json-schema/contest.json | 7 +------ json-schema/judgement.json | 7 +------ 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/json-schema/common.json b/json-schema/common.json index b5b39218..27e9b8ec 100644 --- a/json-schema/common.json +++ b/json-schema/common.json @@ -41,6 +41,25 @@ "pattern": "^-?([1-9][0-9]*)?[0-9]:[0-5][0-9]:[0-5][0-9](\\.[0-9]{3})?$" }, + "reltimeornull": { + "oneOf": [ + { "$ref": "#/reltime" }, + { "type": "null" } + ] + }, + + "posreltime": { + "type": "string", + "pattern": "^([1-9][0-9]*)?[0-9]:[0-5][0-9]:[0-5][0-9](\\.[0-9]{3})?$" + }, + + "posreltimeornull": { + "oneOf": [ + { "$ref": "#/posreltime" }, + { "type": "null" } + ] + }, + "identifier": { "type": "string", "pattern": "^[A-Za-z0-9_][A-Za-z0-9_-]{0,35}" diff --git a/json-schema/contest.json b/json-schema/contest.json index 5d39499e..66571d08 100644 --- a/json-schema/contest.json +++ b/json-schema/contest.json @@ -9,12 +9,7 @@ "name": { "type": "string" }, "formal_name": { "type": "string" }, "start_time": { "$ref": "common.json#/abstimeornull" }, - "countdown_pause_time": { - "oneOf": [ - { "$ref": "common.json#/reltime" }, - { "type": "null" } - ] - }, + "countdown_pause_time": { "$ref": "common.json#/reltimeornull" }, "duration": { "$ref": "common.json#/reltime" }, "scoreboard_freeze_duration": { "$ref": "common.json#/reltime" }, "penalty_time": { diff --git a/json-schema/judgement.json b/json-schema/judgement.json index c927f809..03342cd2 100644 --- a/json-schema/judgement.json +++ b/json-schema/judgement.json @@ -11,12 +11,7 @@ "start_time": { "$ref": "common.json#/abstime" }, "start_contest_time": { "$ref": "common.json#/reltime" }, "end_time": { "$ref": "common.json#/abstimeornull" }, - "end_contest_time": { - "oneOf": [ - { "$ref": "common.json#/reltime" }, - { "type": "null" } - ] - }, + "end_contest_time": { "$ref": "common.json#/reltimeornull" }, "max_run_time": { "oneOf": [ { From 011d2c9b8b28f6fbacdc9e82550487bb6dd708f0 Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Sun, 22 Sep 2019 22:03:55 +0200 Subject: [PATCH 046/107] Allow contest.scoreboard_freeze_duration to be null. See https://clics.ecs.baylor.edu/index.php?title=Contest_API&diff=3037&oldid=3031 --- json-schema/contest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/json-schema/contest.json b/json-schema/contest.json index 66571d08..f1c920ed 100644 --- a/json-schema/contest.json +++ b/json-schema/contest.json @@ -11,7 +11,7 @@ "start_time": { "$ref": "common.json#/abstimeornull" }, "countdown_pause_time": { "$ref": "common.json#/reltimeornull" }, "duration": { "$ref": "common.json#/reltime" }, - "scoreboard_freeze_duration": { "$ref": "common.json#/reltime" }, + "scoreboard_freeze_duration": { "$ref": "common.json#/reltimeornull" }, "penalty_time": { "type": "integer", "minimum": 0 From e1670d6df5d9138d296e7ca73e67bda71e9ebf53 Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Sun, 22 Sep 2019 22:06:13 +0200 Subject: [PATCH 047/107] Make contest countdown_time, scoreboard_free_duration and duration positive. The first is explicitly enforced since https://clics.ecs.baylor.edu/index.php?title=Contest_API&diff=3042&oldid=3040 the other are obvious implicit requirements. --- json-schema/contest.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/json-schema/contest.json b/json-schema/contest.json index f1c920ed..c09da7a8 100644 --- a/json-schema/contest.json +++ b/json-schema/contest.json @@ -9,9 +9,9 @@ "name": { "type": "string" }, "formal_name": { "type": "string" }, "start_time": { "$ref": "common.json#/abstimeornull" }, - "countdown_pause_time": { "$ref": "common.json#/reltimeornull" }, - "duration": { "$ref": "common.json#/reltime" }, - "scoreboard_freeze_duration": { "$ref": "common.json#/reltimeornull" }, + "countdown_pause_time": { "$ref": "common.json#/posreltimeornull" }, + "duration": { "$ref": "common.json#/posreltime" }, + "scoreboard_freeze_duration": { "$ref": "common.json#/posreltimeornull" }, "penalty_time": { "type": "integer", "minimum": 0 From 462dade0f72bf73c852a36b13b4473e1af4e0e7c Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Sun, 22 Sep 2019 22:23:47 +0200 Subject: [PATCH 048/107] Verify that a 404 is returned for any valid ID characters. --- check-api.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/check-api.sh b/check-api.sh index 2c5b2c2d..c79ae5b7 100755 --- a/check-api.sh +++ b/check-api.sh @@ -34,6 +34,9 @@ ENDPOINTS_TO_FAIL=' 404:doesnt-exist 404:doesnt-exist/42 404:submissions/999999 +404:submissions/xyz9999 +404:submissions/XYZ_999 +404:submissions/XYZ-999 ' ENDPOINTS_CHECK_CONSISTENT="$ENDPOINTS" From 404af3180030bf4ba3cb2820d57c62aa081a9300 Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Sun, 22 Sep 2019 22:24:26 +0200 Subject: [PATCH 049/107] Verify that non-existent since_id's give a 400 error. --- check-api.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/check-api.sh b/check-api.sh index c79ae5b7..acc52d88 100755 --- a/check-api.sh +++ b/check-api.sh @@ -37,6 +37,8 @@ ENDPOINTS_TO_FAIL=' 404:submissions/xyz9999 404:submissions/XYZ_999 404:submissions/XYZ-999 +400:event-feed?since_id=999999 +400:event-feed?since_id=xY-99_ ' ENDPOINTS_CHECK_CONSISTENT="$ENDPOINTS" From e5960e37a31167c87202f43ac90a76adadc0f6f7 Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Sun, 22 Sep 2019 22:32:05 +0200 Subject: [PATCH 050/107] Set nonzero exitcode on incorrect HTTP code. --- check-api.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/check-api.sh b/check-api.sh index acc52d88..f0ebfff1 100755 --- a/check-api.sh +++ b/check-api.sh @@ -322,6 +322,9 @@ if [ -n "$CHECK_ERRORS" ]; then verbose '%20s: ' "$ENDPOINT" if query_endpoint /dev/null "$URL" '' "$CODE" ; then verbose 'OK (returned %s)\n' "$CODE" + else + EXIT=1 + [ $EXIT -gt $EXITCODE ] && EXITCODE=$EXIT fi done fi From f8beb445d1174e72929d99a8e6da91bcbb4aca3b Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Sun, 22 Sep 2019 23:18:44 +0200 Subject: [PATCH 051/107] Be more strict about warnings when we don't allow extra properties. --- check-api-consistency.php | 2 ++ check-api.sh | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/check-api-consistency.php b/check-api-consistency.php index 596a9b99..eebfb44c 100755 --- a/check-api-consistency.php +++ b/check-api-consistency.php @@ -13,6 +13,7 @@ $feed_json = json_decode(file_get_contents($dir.'/event-feed.json'), true); $debug = getenv('DEBUG'); +$strict = getenv('STRICT'); $errors = 0; $warnings = 0; @@ -129,4 +130,5 @@ function array_diff_keys($a, $b) if ($warnings>0) { echo "Found $warnings warnings.\n"; + if ($strict) exit(1); } diff --git a/check-api.sh b/check-api.sh index f0ebfff1..12321229 100755 --- a/check-api.sh +++ b/check-api.sh @@ -306,7 +306,7 @@ for CONTEST in $CONTESTS ; do fi if [ -n "$CHECK_CONSISTENCY" ]; then - $MYDIR/check-api-consistency.php "$TMP/$CONTEST" $ENDPOINTS_CHECK_CONSISTENT + eval ${EXTRAPROP:-STRICT=1} $MYDIR/check-api-consistency.php "$TMP/$CONTEST" $ENDPOINTS_CHECK_CONSISTENT EXIT=$? [ $EXIT -gt $EXITCODE ] && EXITCODE=$EXIT fi From 9000a0fd933dfac58ee88b65216ee3b6b742dd16 Mon Sep 17 00:00:00 2001 From: Nicky Gerritsen Date: Mon, 18 Nov 2019 19:31:59 +0100 Subject: [PATCH 052/107] Add first_to_solve to scoreboard JSON schema. --- json-schema/scoreboard.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/json-schema/scoreboard.json b/json-schema/scoreboard.json index aeda4e46..f17d5046 100644 --- a/json-schema/scoreboard.json +++ b/json-schema/scoreboard.json @@ -50,7 +50,8 @@ "minimum": 0 }, "solved": { "type": "boolean" }, - "time": { "type": "integer", "minimum": 0 } + "time": { "type": "integer", "minimum": 0 }, + "first_to_solve": { "type": "boolean" } }, "oneOf": [ { From 5526d5f0aa586927963e3f999983960395d43884 Mon Sep 17 00:00:00 2001 From: Nicky Gerritsen Date: Tue, 19 Nov 2019 21:46:24 +0100 Subject: [PATCH 053/107] Revert "Add first_to_solve to scoreboard JSON schema." This reverts commit 0c3074eba0e6655953f1928cae9b1e3118bea72b. The first_to_solve field is not in the spec. --- json-schema/scoreboard.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/json-schema/scoreboard.json b/json-schema/scoreboard.json index f17d5046..aeda4e46 100644 --- a/json-schema/scoreboard.json +++ b/json-schema/scoreboard.json @@ -50,8 +50,7 @@ "minimum": 0 }, "solved": { "type": "boolean" }, - "time": { "type": "integer", "minimum": 0 }, - "first_to_solve": { "type": "boolean" } + "time": { "type": "integer", "minimum": 0 } }, "oneOf": [ { From 3ffeffa8ebed4a45f7d667188eeb83a4ea374c2f Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Mon, 2 Dec 2019 23:03:11 +0100 Subject: [PATCH 054/107] Add team display_name as discussed and added to the specification. --- json-schema/team.json | 1 + 1 file changed, 1 insertion(+) diff --git a/json-schema/team.json b/json-schema/team.json index 08e2870d..5005d15b 100644 --- a/json-schema/team.json +++ b/json-schema/team.json @@ -8,6 +8,7 @@ "id": { "$ref": "common.json#/identifier" }, "icpc_id": { "type": [ "string", "null" ] }, "name": { "type": "string" }, + "display_name": { "type": [ "string", "null" ] }, "organization_id": { "$ref": "common.json#/identifierornull" }, "group_ids": { "type": "array", From 556eefd2917e320464d6bae22b9ac91b0b23701e Mon Sep 17 00:00:00 2001 From: Thijs Kinkhorst Date: Wed, 28 Oct 2020 19:38:35 +0000 Subject: [PATCH 055/107] Update ICPC Contest API urls --- check-api.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/check-api.sh b/check-api.sh index 12321229..9ec85b97 100755 --- a/check-api.sh +++ b/check-api.sh @@ -1,6 +1,6 @@ #!/bin/bash # Checks whether a Contest API conforms to the specification -# https://clics.ecs.baylor.edu/index.php/Contest_API +# https://ccs-specs.icpc.io/contest_api # Set path to json-validate binary if it's not in PATH: #VALIDATE_JSON=/path/to/validate-json @@ -71,7 +71,7 @@ $(basename $0) - Validate a Contest API implementation with JSON schema. Usage: $(basename $0) [option]... URL This program validates a Contest API implementation against the -specification: https://clics.ecs.baylor.edu/index.php/Contest_API +specification: https://ccs-specs.icpc.io/contest_api The URL must point to the base of the API, for example: From ca5e9f7a3c2a3047ca871e4aa2140ed787a50204 Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Sun, 10 Oct 2021 17:06:07 +0200 Subject: [PATCH 056/107] Some shell script cleanup: - use POSIX shell where feasible - make script executable - use standard safety options -eu -o pipefail - use $() instead of backticks --- check-api.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/check-api.sh b/check-api.sh index 9ec85b97..74bd80fe 100755 --- a/check-api.sh +++ b/check-api.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/bash -eu -o pipefail # Checks whether a Contest API conforms to the specification # https://ccs-specs.icpc.io/contest_api From 7ed4a854fc0c0ad7b8604c8f178f65cb7de096dd Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Mon, 11 Oct 2021 00:52:19 +0200 Subject: [PATCH 057/107] Somehow -o pipefail doesn't seem to work in the shebang. --- check-api.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/check-api.sh b/check-api.sh index 74bd80fe..eb436d81 100755 --- a/check-api.sh +++ b/check-api.sh @@ -1,4 +1,6 @@ -#!/bin/bash -eu -o pipefail +#!/bin/bash +set -e -o pipefail + # Checks whether a Contest API conforms to the specification # https://ccs-specs.icpc.io/contest_api From 0e3e4f537c3535aeeca95e6b3c16a3c54e2d2c88 Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Mon, 11 Oct 2021 21:48:29 +0200 Subject: [PATCH 058/107] Also check consistency of optional endpoints if they exist. --- check-api.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/check-api.sh b/check-api.sh index eb436d81..0029ddda 100755 --- a/check-api.sh +++ b/check-api.sh @@ -43,6 +43,8 @@ ENDPOINTS_TO_FAIL=' 400:event-feed?since_id=xY-99_ ' +# We later re-add optional endpoints to ENDPOINTS_CHECK_CONSISTENT if +# they were actually found. ENDPOINTS_CHECK_CONSISTENT="$ENDPOINTS" for endpoint in $ENDPOINTS_OPTIONAL scoreboard ; do ENDPOINTS_CHECK_CONSISTENT="${ENDPOINTS_CHECK_CONSISTENT/$endpoint/}" @@ -276,6 +278,10 @@ for CONTEST in $CONTESTS ; do if query_endpoint "$OUTPUT" "$URL" $OPTIONAL ; then verbose '%20s: ' "$ENDPOINT" validate_schema "$OUTPUT" "$SCHEMA" + if [ -n "$OPTIONAL" ]; then + ENDPOINTS_CHECK_CONSISTENT="$ENDPOINTS_CHECK_CONSISTENT +$ENDPOINT" + fi EXIT=$? [ $EXIT -gt $EXITCODE ] && EXITCODE=$EXIT else From eecf484d77a809a7eb8e58735f26fd8cd7f7c98d Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Sun, 17 Oct 2021 01:01:33 +0200 Subject: [PATCH 059/107] Fixes for 876324a81af7c648c: - allow failure of some commands explicitly - make sure VERSION variable is set --- check-api.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/check-api.sh b/check-api.sh index 0029ddda..77759e37 100755 --- a/check-api.sh +++ b/check-api.sh @@ -180,8 +180,10 @@ query_endpoint() CURLOPTS="$CURLOPTS -N --max-time ${FEED_TIMEOUT}" fi + set +e HTTPCODE=$(curl $CURLOPTS -w "%{http_code}\n" -o "$OUTPUT" "${URL}${ARGS:+?$ARGS}") EXITCODE="$?" + set -e if [ -n "$EXPECTED_HTTPCODE" ]; then if [ "$HTTPCODE" -ne "$EXPECTED_HTTPCODE" ]; then @@ -213,8 +215,10 @@ validate_schema() { local DATA="$1" SCHEMA="$2" RESULT EXITCODE + set +e RESULT=$(${VALIDATE_JSON:-validate-json} "$DATA" "$SCHEMA") EXITCODE=$? + set -e verbose '%s' "$RESULT" if [ $EXITCODE -eq 0 ]; then verbose 'OK' From 3e1898aa7829e0bfa623592cb57d1670f27e7e54 Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Sun, 17 Oct 2021 00:09:27 +0200 Subject: [PATCH 060/107] Add attributes key_log, tool_data and audio to team endpoint. --- json-schema/team.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/json-schema/team.json b/json-schema/team.json index 5005d15b..6dfc8e27 100644 --- a/json-schema/team.json +++ b/json-schema/team.json @@ -28,8 +28,11 @@ "photo": { "$ref": "common.json#/filerefs" }, "video": { "$ref": "common.json#/filerefs" }, "backup": { "$ref": "common.json#/filerefs" }, + "key_log": { "$ref": "common.json#/filerefs" }, + "tool_data": { "$ref": "common.json#/filerefs" }, "desktop": { "$ref": "common.json#/filerefs" }, - "webcam": { "$ref": "common.json#/filerefs" } + "webcam": { "$ref": "common.json#/filerefs" }, + "audio": { "$ref": "common.json#/filerefs" } }, "required": ["id", "name"], "$ref": "common.json#/strictproperties" From 87d6d8a882a754485764b94ab5c3796276be5bf5 Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Sun, 17 Oct 2021 00:10:15 +0200 Subject: [PATCH 061/107] Add attributes for entry_point, extensions and compiler/runner to language. --- json-schema/common.json | 11 +++++++++++ json-schema/language.json | 28 ++++++++++++++++++++++++++-- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/json-schema/common.json b/json-schema/common.json index 27e9b8ec..cfea71af 100644 --- a/json-schema/common.json +++ b/json-schema/common.json @@ -124,7 +124,18 @@ "items": { "$ref": "#/fileref" } + }, + "command": { + "type": "object", + "properties": { + "command": { "type": "string" }, + "args": { "type": "string" }, + "version": { "type": "string" }, + "version-command": { "type": "string" } + }, + "required": ["command"], + "$ref": "#/strictproperties" }, "$comment": "Inside here add '\"minItems\": 1' to require all collection endpoints to contain at least one element.", diff --git a/json-schema/language.json b/json-schema/language.json index d66ce78b..beba9675 100644 --- a/json-schema/language.json +++ b/json-schema/language.json @@ -6,8 +6,32 @@ "type": "object", "properties": { "id": { "$ref": "common.json#/identifier" }, - "name": { "type": "string" } + "name": { "type": "string" }, + "entry_point_required": { "type": "boolean" }, + "entry_point_name": { "type": [ "string", "null" ] }, + "extensions": { + "type": "array", + "uniqueItems": true, + "items": { "type": "string" } + }, + "compiler": { "$ref": "common.json#/command" }, + "runner": { "$ref": "common.json#/command" } }, - "required": ["id", "name"], + "oneOf": [ + { + "properties": { "entry_point_required": { "enum": [false] } }, + "not": { "required": ["entry_point_name"] } + }, + { + "properties": { "entry_point_required": { "enum": [false] } }, + "properties": { "entry_point_name": { "enum": [null] } } + }, + { + "properties": { "entry_point_required": { "enum": [true] } }, + "properties": { "entry_point_name": { "type": "string" } }, + "required": ["entry_point_name"] + } + ], + "required": ["id", "name", "entry_point_required", "extensions"], "$ref": "common.json#/strictproperties" } From b7a9da5a2759c79b7527a70d0f1eae2cfe76172f Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Sun, 17 Oct 2021 00:10:34 +0200 Subject: [PATCH 062/107] Allow dot in IDs, but not at start or end. --- json-schema/common.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/json-schema/common.json b/json-schema/common.json index cfea71af..20db3151 100644 --- a/json-schema/common.json +++ b/json-schema/common.json @@ -62,7 +62,7 @@ "identifier": { "type": "string", - "pattern": "^[A-Za-z0-9_][A-Za-z0-9_-]{0,35}" + "pattern": "^[A-Za-z0-9_]([A-Za-z0-9_\\.-]{0,34}[A-Za-z0-9_-]|)" }, "identifierornull": { From 1e0d39e9e1ddbdb237a9197b0da26b304bb98764 Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Sun, 17 Oct 2021 00:10:52 +0200 Subject: [PATCH 063/107] Add new optional commentary endpoint. --- check-api.sh | 2 ++ json-schema/commentaries.json | 12 ++++++++++++ json-schema/commentary.json | 25 +++++++++++++++++++++++++ json-schema/common.json | 1 + json-schema/event-feed.json | 3 ++- 5 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 json-schema/commentaries.json create mode 100644 json-schema/commentary.json diff --git a/check-api.sh b/check-api.sh index 77759e37..38b90ffa 100755 --- a/check-api.sh +++ b/check-api.sh @@ -22,6 +22,7 @@ judgements runs clarifications awards +commentary scoreboard ' @@ -30,6 +31,7 @@ scoreboard ENDPOINTS_OPTIONAL=' team-members awards +commentary ' ENDPOINTS_TO_FAIL=' diff --git a/json-schema/commentaries.json b/json-schema/commentaries.json new file mode 100644 index 00000000..d1d2d33f --- /dev/null +++ b/json-schema/commentaries.json @@ -0,0 +1,12 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "CLICS Contest API: commentary", + "description": "JSON response of this API call", + + "type": "array", + "uniqueItems": true, + "$ref": "common.json#/nonemptyarray", + "items": { + "$ref": "commentary.json#" + } +} diff --git a/json-schema/commentary.json b/json-schema/commentary.json new file mode 100644 index 00000000..6e0a02d9 --- /dev/null +++ b/json-schema/commentary.json @@ -0,0 +1,25 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "CLICS Contest API - commentary", + "description": "Definition of a single commentary object", + + "type": "object", + "properties": { + "id": { "$ref": "common.json#/identifier" }, + "time": { "$ref": "common.json#/abstime" }, + "contest_time": { "$ref": "common.json#/reltime" }, + "message": { "type": "string" }, + "team_ids": { + "type": "array", + "uniqueItems": true, + "items": { "$ref": "common.json#/identifier" } + }, + "problem_ids": { + "type": "array", + "uniqueItems": true, + "items": { "$ref": "common.json#/identifier" } + } + }, + "required": ["id", "time", "contest_time", "message", "team_ids", "problem_ids"], + "$ref": "common.json#/strictproperties" +} diff --git a/json-schema/common.json b/json-schema/common.json index 20db3151..cae920a3 100644 --- a/json-schema/common.json +++ b/json-schema/common.json @@ -19,6 +19,7 @@ "runs", "clarifications", "awards", + "commentary", "scoreboard", "event-feed" ] diff --git a/json-schema/event-feed.json b/json-schema/event-feed.json index 096f72a7..43c4abaa 100644 --- a/json-schema/event-feed.json +++ b/json-schema/event-feed.json @@ -28,7 +28,8 @@ { "$ref": "judgement.json#" }, { "$ref": "run.json#" }, { "$ref": "clarification.json#" }, - { "$ref": "award.json#" } + { "$ref": "award.json#" }, + { "$ref": "commentary.json#" } ] } } From 8354c2decacc5a1fdb8bcaa923b44ec74f8812ca Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Sun, 17 Oct 2021 00:23:14 +0200 Subject: [PATCH 064/107] Removed custom type "decimal". Note that "float" was also removed, but that doesn't impact this code, as it was just using the JSON number type. --- json-schema/common.json | 5 ----- json-schema/judgement.json | 3 ++- json-schema/problem.json | 3 ++- json-schema/run.json | 3 ++- 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/json-schema/common.json b/json-schema/common.json index cae920a3..e7a6a14c 100644 --- a/json-schema/common.json +++ b/json-schema/common.json @@ -102,11 +102,6 @@ "minimum": 0 }, - "decimal": { - "type": "number", - "multipleOf": 0.001 - }, - "fileref": { "type": "object", "properties": { diff --git a/json-schema/judgement.json b/json-schema/judgement.json index 03342cd2..df198047 100644 --- a/json-schema/judgement.json +++ b/json-schema/judgement.json @@ -15,7 +15,8 @@ "max_run_time": { "oneOf": [ { - "$ref": "common.json#/decimal", + "type": "number", + "multipleOf": 0.001, "minimum": 0 }, { "type": "null" } diff --git a/json-schema/problem.json b/json-schema/problem.json index 8943e194..b92d5931 100644 --- a/json-schema/problem.json +++ b/json-schema/problem.json @@ -15,7 +15,8 @@ }, "color": { "type": "string" }, "time_limit": { - "$ref": "common.json#/decimal", + "type": "number", + "multipleOf": 0.001, "minimum": 0 }, "test_data_count": { diff --git a/json-schema/run.json b/json-schema/run.json index eb703e82..13081c83 100644 --- a/json-schema/run.json +++ b/json-schema/run.json @@ -12,7 +12,8 @@ "time": { "$ref": "common.json#/abstime" }, "contest_time": { "$ref": "common.json#/reltime" }, "run_time": { - "$ref": "common.json#/decimal", + "type": "number", + "multipleOf": 0.001, "minimum": 0 } }, From 68679fe7d1f3075b05cc531cbdd72916e36ef6e0 Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Sun, 17 Oct 2021 14:57:07 +0200 Subject: [PATCH 065/107] Move hidden attribute from group to team. --- json-schema/group.json | 3 +-- json-schema/team.json | 1 + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/json-schema/group.json b/json-schema/group.json index 1c70d0a4..1d5e53b9 100644 --- a/json-schema/group.json +++ b/json-schema/group.json @@ -8,8 +8,7 @@ "id": { "$ref": "common.json#/identifier" }, "icpc_id": { "type": [ "string", "null" ] }, "name": { "type": "string" }, - "type": { "type": "string" }, - "hidden": { "type": "boolean" } + "type": { "type": "string" } }, "required": ["id", "name"], "$ref": "common.json#/strictproperties" diff --git a/json-schema/team.json b/json-schema/team.json index 6dfc8e27..f4a81d2a 100644 --- a/json-schema/team.json +++ b/json-schema/team.json @@ -15,6 +15,7 @@ "uniqueItems": true, "items": { "$ref": "common.json#/identifierornull" } }, + "hidden": { "type": [ "boolean", "null" ] }, "location": { "type": "object", "properties": { From a4084c1d56b91fc3a5a66fd673a821d8a41bf186 Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Sun, 17 Oct 2021 15:49:09 +0200 Subject: [PATCH 066/107] Remove old from/to booleans in clarification. --- json-schema/clarification.json | 2 -- 1 file changed, 2 deletions(-) diff --git a/json-schema/clarification.json b/json-schema/clarification.json index 091f6cab..adfe376e 100644 --- a/json-schema/clarification.json +++ b/json-schema/clarification.json @@ -11,8 +11,6 @@ "reply_to_id": { "$ref": "common.json#/identifierornull" }, "problem_id": { "$ref": "common.json#/identifierornull" }, "text": { "type": "string" }, - "from_jury": { "type": "boolean" }, - "to_all_teams": { "type": "boolean" }, "time": { "$ref": "common.json#/abstime" }, "contest_time": { "$ref": "common.json#/reltime" } }, From c59db6985c977e7af668b12fd326767934474787 Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Sun, 17 Oct 2021 15:54:51 +0200 Subject: [PATCH 067/107] Use some more common types. --- json-schema/award.json | 6 +--- json-schema/commentary.json | 12 ++------ json-schema/common.json | 58 +++++++++++++++++++++++++++++++++++ json-schema/contest.json | 4 +-- json-schema/language.json | 4 +-- json-schema/organization.json | 3 +- json-schema/submission.json | 2 +- json-schema/team-member.json | 2 +- json-schema/team.json | 22 ++++++------- 9 files changed, 78 insertions(+), 35 deletions(-) diff --git a/json-schema/award.json b/json-schema/award.json index a149133a..eb919ef7 100644 --- a/json-schema/award.json +++ b/json-schema/award.json @@ -7,11 +7,7 @@ "properties": { "id": { "$ref": "common.json#/identifier" }, "citation": { "type": "string" }, - "team_ids": { - "type": "array", - "uniqueItems": true, - "items": { "$ref": "common.json#/identifier" } - } + "team_ids": { "$ref": "common.json#/identifiers" } }, "required": ["id", "citation", "team_ids"], "$ref": "common.json#/strictproperties" diff --git a/json-schema/commentary.json b/json-schema/commentary.json index 6e0a02d9..c8a29e14 100644 --- a/json-schema/commentary.json +++ b/json-schema/commentary.json @@ -9,16 +9,8 @@ "time": { "$ref": "common.json#/abstime" }, "contest_time": { "$ref": "common.json#/reltime" }, "message": { "type": "string" }, - "team_ids": { - "type": "array", - "uniqueItems": true, - "items": { "$ref": "common.json#/identifier" } - }, - "problem_ids": { - "type": "array", - "uniqueItems": true, - "items": { "$ref": "common.json#/identifier" } - } + "team_ids": { "$ref": "common.json#/identifiersornull" }, + "problem_ids": { "$ref": "common.json#/identifiersornull" } }, "required": ["id", "time", "contest_time", "message", "team_ids", "problem_ids"], "$ref": "common.json#/strictproperties" diff --git a/json-schema/common.json b/json-schema/common.json index e7a6a14c..9250b539 100644 --- a/json-schema/common.json +++ b/json-schema/common.json @@ -73,6 +73,19 @@ ] }, + "identifiers": { + "type": "array", + "uniqueItems": true, + "items": { "$ref": "#/identifier" } + }, + + "identifiersornull": { + "oneOf": [ + { "$ref": "#/identifiers" }, + { "type": "null" } + ] + }, + "judgementtypeid": { "enum": [ "AC", "RE", "WA", "TLE", "RTE", "CE", "APE", "OLE", "PE", "EO", "IO", "NO", @@ -114,6 +127,18 @@ "$ref": "#/strictproperties" }, + "imageref": { + "allOf": [ + { "$ref": "#/fileref" }, + { + "properties": { + "mime": { "enum": ["image/png", "image/jpeg", "image/svg+xml"] } + }, + "required": ["width", "height"] + } + ] + }, + "filerefs": { "type": "array", "uniqueItems": true, @@ -122,6 +147,32 @@ } }, + "filerefsornull": { + "oneOf": [ + { + "type": "array", + "uniqueItems": true, + "items": { + "$ref": "#/fileref" + } + }, + { "type": "null" } + ] + }, + + "imagerefsornull": { + "oneOf": [ + { + "type": "array", + "uniqueItems": true, + "items": { + "$ref": "#/imageref" + } + }, + { "type": "null" } + ] + }, + "command": { "type": "object", "properties": { @@ -134,6 +185,13 @@ "$ref": "#/strictproperties" }, + "commandornull": { + "oneOf": [ + { "$ref": "#/command" }, + { "type": "null" } + ] + }, + "$comment": "Inside here add '\"minItems\": 1' to require all collection endpoints to contain at least one element.", "nonemptyarray": { }, diff --git a/json-schema/contest.json b/json-schema/contest.json index c09da7a8..e2ff4230 100644 --- a/json-schema/contest.json +++ b/json-schema/contest.json @@ -16,8 +16,8 @@ "type": "integer", "minimum": 0 }, - "banner": { "$ref": "common.json#/filerefs" }, - "logo": { "$ref": "common.json#/filerefs" } + "banner": { "$ref": "common.json#/imagerefsornull" }, + "logo": { "$ref": "common.json#/imagerefsornull" } }, "required": ["id", "name", "duration"], "$ref": "common.json#/strictproperties" diff --git a/json-schema/language.json b/json-schema/language.json index beba9675..19d1a1bc 100644 --- a/json-schema/language.json +++ b/json-schema/language.json @@ -14,8 +14,8 @@ "uniqueItems": true, "items": { "type": "string" } }, - "compiler": { "$ref": "common.json#/command" }, - "runner": { "$ref": "common.json#/command" } + "compiler": { "$ref": "common.json#/commandornull" }, + "runner": { "$ref": "common.json#/commandornull" } }, "oneOf": [ { diff --git a/json-schema/organization.json b/json-schema/organization.json index d08b0fb4..497f2e01 100644 --- a/json-schema/organization.json +++ b/json-schema/organization.json @@ -18,6 +18,7 @@ { "type": "null" } ] }, + "country_flag": { "$ref": "common.json#/imagerefsornull" }, "url": { "type": [ "string", "null" ] }, "twitter_hashtag": { "type": [ "string", "null" ] }, "location": { @@ -42,7 +43,7 @@ { "type": "null" } ] }, - "logo": { "$ref": "common.json#/filerefs" } + "logo": { "$ref": "common.json#/imagerefsornull" } }, "required": ["id", "name"], "$ref": "common.json#/strictproperties" diff --git a/json-schema/submission.json b/json-schema/submission.json index e77765ef..8f5c3e66 100644 --- a/json-schema/submission.json +++ b/json-schema/submission.json @@ -13,7 +13,7 @@ "contest_time": { "$ref": "common.json#/reltime" }, "entry_point": { "type": [ "string", "null" ] }, "files": { "$ref": "common.json#/filerefs" }, - "reaction": { "$ref": "common.json#/filerefs" } + "reaction": { "$ref": "common.json#/filerefsornull" } }, "required": ["id", "language_id", "problem_id", "team_id", "time", "contest_time", "files"], "$ref": "common.json#/strictproperties" diff --git a/json-schema/team-member.json b/json-schema/team-member.json index 5ad22504..41281891 100644 --- a/json-schema/team-member.json +++ b/json-schema/team-member.json @@ -17,7 +17,7 @@ ] }, "role": { "enum": [ "contestant", "coach" ] }, - "photo": { "$ref": "common.json#/filerefs" } + "photo": { "$ref": "common.json#/imagerefsornull" } }, "required": ["id", "team_id", "first_name", "last_name"], "$ref": "common.json#/strictproperties" diff --git a/json-schema/team.json b/json-schema/team.json index f4a81d2a..e082b3fd 100644 --- a/json-schema/team.json +++ b/json-schema/team.json @@ -10,11 +10,7 @@ "name": { "type": "string" }, "display_name": { "type": [ "string", "null" ] }, "organization_id": { "$ref": "common.json#/identifierornull" }, - "group_ids": { - "type": "array", - "uniqueItems": true, - "items": { "$ref": "common.json#/identifierornull" } - }, + "group_ids": { "$ref": "common.json#/identifiersornull" }, "hidden": { "type": [ "boolean", "null" ] }, "location": { "type": "object", @@ -26,14 +22,14 @@ "required": ["x", "y", "rotation"], "$ref": "common.json#/strictproperties" }, - "photo": { "$ref": "common.json#/filerefs" }, - "video": { "$ref": "common.json#/filerefs" }, - "backup": { "$ref": "common.json#/filerefs" }, - "key_log": { "$ref": "common.json#/filerefs" }, - "tool_data": { "$ref": "common.json#/filerefs" }, - "desktop": { "$ref": "common.json#/filerefs" }, - "webcam": { "$ref": "common.json#/filerefs" }, - "audio": { "$ref": "common.json#/filerefs" } + "photo": { "$ref": "common.json#/imagerefsornull" }, + "video": { "$ref": "common.json#/filerefsornull" }, + "backup": { "$ref": "common.json#/filerefsornull" }, + "key_log": { "$ref": "common.json#/filerefsornull" }, + "tool_data": { "$ref": "common.json#/filerefsornull" }, + "desktop": { "$ref": "common.json#/filerefsornull" }, + "webcam": { "$ref": "common.json#/filerefsornull" }, + "audio": { "$ref": "common.json#/filerefsornull" } }, "required": ["id", "name"], "$ref": "common.json#/strictproperties" From e1614562a8b6fdc69dab3a421201cc413c252d6e Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Tue, 19 Oct 2021 23:28:14 +0200 Subject: [PATCH 068/107] Fix misc. small attribute requirements. --- json-schema/group.json | 2 +- json-schema/team-member.json | 2 +- json-schema/team.json | 6 +++++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/json-schema/group.json b/json-schema/group.json index 1d5e53b9..b2f34b13 100644 --- a/json-schema/group.json +++ b/json-schema/group.json @@ -8,7 +8,7 @@ "id": { "$ref": "common.json#/identifier" }, "icpc_id": { "type": [ "string", "null" ] }, "name": { "type": "string" }, - "type": { "type": "string" } + "type": { "type": [ "string", "null" ] } }, "required": ["id", "name"], "$ref": "common.json#/strictproperties" diff --git a/json-schema/team-member.json b/json-schema/team-member.json index 41281891..46bed247 100644 --- a/json-schema/team-member.json +++ b/json-schema/team-member.json @@ -19,6 +19,6 @@ "role": { "enum": [ "contestant", "coach" ] }, "photo": { "$ref": "common.json#/imagerefsornull" } }, - "required": ["id", "team_id", "first_name", "last_name"], + "required": ["id", "team_id", "first_name", "last_name", "role"], "$ref": "common.json#/strictproperties" } diff --git a/json-schema/team.json b/json-schema/team.json index e082b3fd..d2d7cf78 100644 --- a/json-schema/team.json +++ b/json-schema/team.json @@ -17,7 +17,11 @@ "properties": { "x": { "type": "number" }, "y": { "type": "number" }, - "rotation": { "type": "number" } + "rotation": { + "type": "number", + "minimum": 0, + "maximum": 360 + } }, "required": ["x", "y", "rotation"], "$ref": "common.json#/strictproperties" From eabd8763e94a0ac898967b089c8c5e62237c4216 Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Tue, 19 Oct 2021 23:29:13 +0200 Subject: [PATCH 069/107] Add problem UUID attribute. Assume it's in standard human readable string format. --- json-schema/problem.json | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/json-schema/problem.json b/json-schema/problem.json index b92d5931..e570d9a4 100644 --- a/json-schema/problem.json +++ b/json-schema/problem.json @@ -6,6 +6,15 @@ "type": "object", "properties": { "id": { "$ref": "common.json#/identifier" }, + "uuid": { + "oneOf": [ + { + "type": "string", + "pattern": "^[A-Fa-f0-9]{8}-([A-Fa-f0-9]{4}-){3}[A-Fa-f0-9]{12}$" + }, + { "type": "null" } + ] + }, "label": { "$ref": "common.json#/label" }, "name": { "type": "string" }, "ordinal": { "$ref": "common.json#/ordinal" }, From 44135c6de48c2abca2a2e78b1f81ee9a25772b62 Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Tue, 19 Oct 2021 23:29:53 +0200 Subject: [PATCH 070/107] Check that submission entry_point is present for Java and absent for C/C++. --- json-schema/submission.json | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/json-schema/submission.json b/json-schema/submission.json index 8f5c3e66..aca0a4ff 100644 --- a/json-schema/submission.json +++ b/json-schema/submission.json @@ -16,5 +16,33 @@ "reaction": { "$ref": "common.json#/filerefsornull" } }, "required": ["id", "language_id", "problem_id", "team_id", "time", "contest_time", "files"], + "oneOf": [ + { + "properties": { + "language_id": { "enum": ["java"] } + }, + "required": ["entry_point"] + }, + { + "properties": { + "language_id": { "enum": ["c", "cpp"] } + }, + "oneOf": [ + { + "not": { "required": ["entry_point"] } + }, + { + "properties": { "entry_point": { "type": "null" } } + } + ] + }, + { + "not": { + "properties": { + "language_id": { "enum": ["java", "c", "cpp"] } + } + } + } + ], "$ref": "common.json#/strictproperties" } From 14f4c4fca19ab28988c1c9061293f40415b1893e Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Sun, 28 Nov 2021 23:57:23 +0100 Subject: [PATCH 071/107] Fix/silence shellcheck warnings for contest-api.sh. --- check-api.sh | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/check-api.sh b/check-api.sh index 38b90ffa..eacfe95e 100755 --- a/check-api.sh +++ b/check-api.sh @@ -64,6 +64,7 @@ verbose() if [ $# -eq 1 ]; then echo "$1" else + # shellcheck disable=SC2059 printf "$@" fi fi @@ -71,17 +72,18 @@ verbose() usage() { + PROGNAME=$(basename "$0") cat < Date: Sat, 9 Apr 2022 11:51:04 +0200 Subject: [PATCH 072/107] Add accounts and persons to JSON API verifier. For now, don't drop team-members yet. --- check-api.sh | 4 ++++ json-schema/account.json | 23 +++++++++++++++++++++++ json-schema/accounts.json | 12 ++++++++++++ json-schema/common.json | 2 ++ json-schema/event-feed.json | 2 ++ json-schema/person.json | 25 +++++++++++++++++++++++++ json-schema/persons.json | 12 ++++++++++++ 7 files changed, 80 insertions(+) create mode 100644 json-schema/account.json create mode 100644 json-schema/accounts.json create mode 100644 json-schema/person.json create mode 100644 json-schema/persons.json diff --git a/check-api.sh b/check-api.sh index eacfe95e..7e611d74 100755 --- a/check-api.sh +++ b/check-api.sh @@ -14,7 +14,9 @@ languages problems groups organizations +persons team-members +accounts teams state submissions @@ -30,6 +32,8 @@ scoreboard ENDPOINTS_OPTIONAL=' team-members +persons +accounts awards commentary ' diff --git a/json-schema/account.json b/json-schema/account.json new file mode 100644 index 00000000..af093e37 --- /dev/null +++ b/json-schema/account.json @@ -0,0 +1,23 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "CLICS Contest API - account", + "description": "Definition of a single account object", + + "type": "object", + "properties": { + "id": { "$ref": "common.json#/identifier" }, + "username": { "type": "string" }, + "password": { "type": ["string", "null"] }, + "type": { + "oneOf": [ + { "enum": [ "team", "judge", "admin", "analyst", "staff" ] }, + { "type": "null" } + ] + }, + "ip": { "type": ["string", "null"] }, + "team_id": { "$ref": "common.json#/identifierornull" }, + "person_id": { "$ref": "common.json#/identifierornull" } + }, + "required": ["id", "username", "type"], + "$ref": "common.json#/strictproperties" +} diff --git a/json-schema/accounts.json b/json-schema/accounts.json new file mode 100644 index 00000000..29cb973a --- /dev/null +++ b/json-schema/accounts.json @@ -0,0 +1,12 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "CLICS Contest API: accounts", + "description": "JSON response of this API call", + + "type": "array", + "uniqueItems": true, + "$ref": "common.json#/nonemptyarray", + "items": { + "$ref": "account.json#" + } +} diff --git a/json-schema/common.json b/json-schema/common.json index 9250b539..f7d0811e 100644 --- a/json-schema/common.json +++ b/json-schema/common.json @@ -11,7 +11,9 @@ "problems", "groups", "organizations", + "persons", "team-members", + "accounts", "teams", "state", "submissions", diff --git a/json-schema/event-feed.json b/json-schema/event-feed.json index 43c4abaa..656f5e05 100644 --- a/json-schema/event-feed.json +++ b/json-schema/event-feed.json @@ -22,7 +22,9 @@ { "$ref": "group.json#" }, { "$ref": "organization.json#" }, { "$ref": "team.json#" }, + { "$ref": "person.json#" }, { "$ref": "team-member.json#" }, + { "$ref": "account.json#" }, { "$ref": "state.json#" }, { "$ref": "submission.json#" }, { "$ref": "judgement.json#" }, diff --git a/json-schema/person.json b/json-schema/person.json new file mode 100644 index 00000000..5ea2cdc4 --- /dev/null +++ b/json-schema/person.json @@ -0,0 +1,25 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "CLICS Contest API - person", + "description": "Definition of a single person object", + + "type": "object", + "properties": { + "id": { "$ref": "common.json#/identifier" }, + "team_id": { "$ref": "common.json#/identifier" }, + "icpc_id": { "type": [ "string", "null" ] }, + "name": { "type": "string" }, + "title": { "type": [ "string", "null" ] }, + "email": { "type": [ "string", "null" ] }, + "sex": { + "oneOf": [ + { "enum": [ "male", "female" ] }, + { "type": "null" } + ] + }, + "role": { "enum": [ "contestant", "coach", "staff" ] }, + "photo": { "$ref": "common.json#/imagerefsornull" } + }, + "required": ["id", "team_id", "name", "role"], + "$ref": "common.json#/strictproperties" +} diff --git a/json-schema/persons.json b/json-schema/persons.json new file mode 100644 index 00000000..0c24e937 --- /dev/null +++ b/json-schema/persons.json @@ -0,0 +1,12 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "CLICS Contest API: persons", + "description": "JSON response of this API call", + + "type": "array", + "uniqueItems": true, + "$ref": "common.json#/nonemptyarray", + "items": { + "$ref": "person.json#" + } +} From 5445a8f4c812564196f4d66fb3a7a08b68c13a4e Mon Sep 17 00:00:00 2001 From: Nicky Gerritsen Date: Thu, 18 Aug 2022 19:06:05 +0200 Subject: [PATCH 073/107] Add package and statement to problem endpoint. --- json-schema/problem.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/json-schema/problem.json b/json-schema/problem.json index e570d9a4..6f250687 100644 --- a/json-schema/problem.json +++ b/json-schema/problem.json @@ -31,7 +31,9 @@ "test_data_count": { "type": "integer", "minimum": 0 - } + }, + "package": { "$ref": "common.json#/filerefsornull" }, + "statement": { "$ref": "common.json#/filerefsornull" } }, "required": ["id", "label", "name", "ordinal", "test_data_count"], "$ref": "common.json#/strictproperties" From d9cc05f6d0c461079688c09b29f5dc9d7772fb5d Mon Sep 17 00:00:00 2001 From: Nicky Gerritsen Date: Thu, 18 Aug 2022 20:41:33 +0200 Subject: [PATCH 074/107] File types now support filename and hash. --- json-schema/common.json | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/json-schema/common.json b/json-schema/common.json index f7d0811e..ce4d3074 100644 --- a/json-schema/common.json +++ b/json-schema/common.json @@ -120,10 +120,12 @@ "fileref": { "type": "object", "properties": { - "href": { "type": "string" }, - "mime": { "type": "string" }, - "width": { "type": "integer", "minimum": 1 }, - "height": { "type": "integer", "minimum": 1 } + "href": { "type": "string" }, + "mime": { "type": "string" }, + "hash": { "type": "string" }, + "filename": { "type": "string" }, + "width": { "type": "integer", "minimum": 1 }, + "height": { "type": "integer", "minimum": 1 } }, "required": ["href", "mime"], "$ref": "#/strictproperties" From b3ec70cd839c4f3e61bc26cf1b6b87af908cb3dd Mon Sep 17 00:00:00 2001 From: Nicky Gerritsen Date: Sun, 24 Jul 2022 19:04:31 +0200 Subject: [PATCH 075/107] Update check-api script to support new event feed format. --- check-api-consistency.php | 37 +++++++++++++------- json-schema/common.json | 24 +++++++++++++ json-schema/event-feed-array.json | 7 ++-- json-schema/event-feed.json | 26 ++++++++------ json-schema/legacy-event-feed.json | 55 ++++++++++++++++++++++++++++++ 5 files changed, 124 insertions(+), 25 deletions(-) create mode 100644 json-schema/legacy-event-feed.json diff --git a/check-api-consistency.php b/check-api-consistency.php index eebfb44c..9229c753 100755 --- a/check-api-consistency.php +++ b/check-api-consistency.php @@ -36,6 +36,10 @@ function warning($msg) foreach ($feed_json as $row) { $endpoint = $row['type']; + if ($endpoint === 'contest') { + // New feed format uses singular for contest + $endpoint = 'contests'; + } $id = isset($row['data']['id']) ? $row['data']['id'] : '_single_'; $feed_data[$endpoint][$id][] = $row; } @@ -62,30 +66,39 @@ function array_diff_keys($a, $b) error("'state' cannot have ID '$id' set."); } for ($i=0; $i $rows) { - if ($rows[0]['op']!=='create') { + if (isset($rows[0]['op']) && $rows[0]['op']!=='create') { error("'$endpoint/$id' not created first."); } for ($i=1; $i $elements) { foreach ($elements as $id => $rows) { $last = end($rows); - if ($last['op']!=='delete') { + if ((isset($last['op']) && $last['op']!=='delete') || (!isset($last['op']) && isset($last['data'])) ) { if (!isset($endpoint_data[$endpoint][$id])) { error("'$endpoint".($id==='_single_' ? '' : "/$id")."' not found in REST endpoint."); } elseif ($last['data']!==$endpoint_data[$endpoint][$id]) { diff --git a/json-schema/common.json b/json-schema/common.json index ce4d3074..e0ed6fd6 100644 --- a/json-schema/common.json +++ b/json-schema/common.json @@ -27,6 +27,30 @@ ] }, + "endpointssingularcontest": { + "enum": [ + "contest", + "judgement-types", + "languages", + "problems", + "groups", + "organizations", + "persons", + "team-members", + "accounts", + "teams", + "state", + "submissions", + "judgements", + "runs", + "clarifications", + "awards", + "commentary", + "scoreboard", + "event-feed" + ] + }, + "abstime": { "type": "string", "pattern": "^[12][0-9]{3}-[01][0-9]-[0-3][0-9]T[0-2][0-9]:[0-6][0-9]:[0-6][0-9](\\.[0-9]{3})?([+-][0-1][0-9](:[0-5][0-9])?|Z)$" diff --git a/json-schema/event-feed-array.json b/json-schema/event-feed-array.json index 69d102c8..0f4d7311 100644 --- a/json-schema/event-feed-array.json +++ b/json-schema/event-feed-array.json @@ -4,9 +4,12 @@ "description": "JSON array of responses of this NDJSON API call", "type": "array", - "uniqueItems": true, "$ref": "common.json#/nonemptyarray", "items": { - "$ref": "event-feed.json#" + "$comment": "Use anyOf since the event type fields overlap between the current and legacy format.", + "anyOf": [ + { "$ref": "event-feed.json#" }, + { "$ref": "legacy-event-feed.json#" } + ] } } diff --git a/json-schema/event-feed.json b/json-schema/event-feed.json index 656f5e05..cce6d633 100644 --- a/json-schema/event-feed.json +++ b/json-schema/event-feed.json @@ -5,13 +5,23 @@ "type": "object", "properties": { - "id": { "$ref": "common.json#/identifier" }, - "type": { "$ref": "common.json#/endpoints" } + "id": { + "oneOf": [ + { "$ref": "common.json#/identifier" }, + { "type": "null" } + ] + }, + "token": { + "oneOf": [ + { "type": "string" }, + { "type": "null" } + ] + }, + "type": { "$ref": "common.json#/endpointssingularcontest" } }, "oneOf": [ { "properties": { - "op": { "enum": [ "create", "update" ] }, "data": { "$comment": "Use anyOf since some types match others without strict attribute checking.", "anyOf": [ @@ -38,18 +48,12 @@ }, { "properties": { - "op": { "enum": [ "delete" ] }, "data": { - "type": "object", - "properties": { - "id": { "$ref": "common.json#/identifier" } - }, - "required": ["id"], - "$ref": "common.json#/strictproperties" + "type": "null" } } } ], - "required": ["id", "type", "op", "data"], + "required": ["id", "type", "data"], "$ref": "common.json#/strictproperties" } diff --git a/json-schema/legacy-event-feed.json b/json-schema/legacy-event-feed.json new file mode 100644 index 00000000..656f5e05 --- /dev/null +++ b/json-schema/legacy-event-feed.json @@ -0,0 +1,55 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "CLICS Contest API: event-feed", + "description": "Single line response of this NDJSON API call", + + "type": "object", + "properties": { + "id": { "$ref": "common.json#/identifier" }, + "type": { "$ref": "common.json#/endpoints" } + }, + "oneOf": [ + { + "properties": { + "op": { "enum": [ "create", "update" ] }, + "data": { + "$comment": "Use anyOf since some types match others without strict attribute checking.", + "anyOf": [ + { "$ref": "contest.json#" }, + { "$ref": "judgement-type.json#" }, + { "$ref": "language.json#" }, + { "$ref": "problem.json#" }, + { "$ref": "group.json#" }, + { "$ref": "organization.json#" }, + { "$ref": "team.json#" }, + { "$ref": "person.json#" }, + { "$ref": "team-member.json#" }, + { "$ref": "account.json#" }, + { "$ref": "state.json#" }, + { "$ref": "submission.json#" }, + { "$ref": "judgement.json#" }, + { "$ref": "run.json#" }, + { "$ref": "clarification.json#" }, + { "$ref": "award.json#" }, + { "$ref": "commentary.json#" } + ] + } + } + }, + { + "properties": { + "op": { "enum": [ "delete" ] }, + "data": { + "type": "object", + "properties": { + "id": { "$ref": "common.json#/identifier" } + }, + "required": ["id"], + "$ref": "common.json#/strictproperties" + } + } + } + ], + "required": ["id", "type", "op", "data"], + "$ref": "common.json#/strictproperties" +} From a77a4f8b58dddc175cf279ef999e5e0ba8a5a469 Mon Sep 17 00:00:00 2001 From: Nicky Gerritsen Date: Mon, 26 Sep 2022 15:09:59 +0200 Subject: [PATCH 076/107] Do not check for accounts consistency for now since we don't expose it in the feed. --- check-api.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/check-api.sh b/check-api.sh index 7e611d74..fafb76ed 100755 --- a/check-api.sh +++ b/check-api.sh @@ -327,6 +327,7 @@ $ENDPOINT" fi if [ -n "$CHECK_CONSISTENCY" ]; then + ENDPOINTS_CHECK_CONSISTENT="${ENDPOINTS_CHECK_CONSISTENT/accounts/}" # shellcheck disable=SC2086 eval ${EXTRAPROP:-STRICT=1} "$MYDIR"/check-api-consistency.php "$TMP/$CONTEST" $ENDPOINTS_CHECK_CONSISTENT EXIT=$? From bf3c0ba7c63a952e78c7a7b3751708cf84e42ff6 Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Fri, 17 Feb 2023 13:30:53 +0100 Subject: [PATCH 077/107] Add version information and document PHP dependency. --- check-api.sh | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/check-api.sh b/check-api.sh index fafb76ed..45741a51 100755 --- a/check-api.sh +++ b/check-api.sh @@ -1,8 +1,9 @@ #!/bin/bash set -e -o pipefail -# Checks whether a Contest API conforms to the specification -# https://ccs-specs.icpc.io/contest_api +# This should match the API version this script tests as found at the +# URL https://ccs-specs.icpc.io/$API_VERSION/contest_api +API_VERSION=draft # Set path to json-validate binary if it's not in PATH: #VALIDATE_JSON=/path/to/validate-json @@ -74,6 +75,12 @@ verbose() fi } +version() +{ + PROGNAME=$(basename "$0") + echo "$PROGNAME for Contest API version $API_VERSION" +} + usage() { PROGNAME=$(basename "$0") @@ -83,7 +90,7 @@ $PROGNAME - Validate a Contest API implementation with JSON schema. Usage: $PROGNAME [option]... URL This program validates a Contest API implementation against the -specification: https://ccs-specs.icpc.io/contest_api +specification at https://ccs-specs.icpc.io/$API_VERSION/contest_api The URL must point to the base of the API, for example: @@ -94,11 +101,12 @@ errors, use ~/.netrc for credentials, and be verbose. The option -a makes that 'strict=1' is appended as argument to each API call. This script requires: -- the curl command line client -- the validate-json binary from https://github.com/justinrainbow/json-schema +- the cURL command line client +- the \`validate-json\` binary from https://github.com/justinrainbow/json-schema which can be installed with \`composer require justinrainbow/json-schema\` - the jq program from https://github.com/stedolan/jq which is available as the \`jq\` package in Debian and Ubuntu. +- the PHP command line executable to run the helper script \`check-api-consistency.php\` Options: @@ -108,12 +116,13 @@ Options: -c OPTS Options to pass to curl to request API data (default: $CURL_OPTIONS) -d Turn on shell script debugging. -e Check correct HTTP error codes for non-existent endpoints. - -h Snow this help output. -j PROG Specify the path to the 'validate-json' binary. -n Require that all collection endpoints are non-empty. -p Allow extra properties beyond those defined in the Contest API. -t TIME Timeout in seconds for downloading event feed (default: $FEED_TIMEOUT) -q Quiet mode: suppress all output except script errors. + -h Show this help output. + -v Show version information including API version. The script reports endpoints checked and validations errors. In quiet mode only the exit code indicates successful validation. @@ -126,19 +135,20 @@ CURL_OPTIONS='-n -s' URL_ARGS='' # Parse command-line options: -while getopts 'a:Cc:dehj:npt:q' OPT ; do +while getopts 'a:Cc:dej:npt:qhv' OPT ; do case "$OPT" in a) URL_ARGS="$OPTARG" ;; C) CHECK_CONSISTENCY=1 ;; c) CURL_OPTIONS="$OPTARG" ;; d) export DEBUG=1 ;; e) CHECK_ERRORS=1 ;; - h) usage ; exit 0 ;; j) VALIDATE_JSON="$OPTARG" ;; n) NONEMPTY=1 ;; p) EXTRAPROP=1 ;; t) FEED_TIMEOUT="$OPTARG" ;; q) QUIET=1 ;; + h) usage ; exit 0 ;; + v) version ; exit 0 ;; :) error "option '$OPTARG' requires an argument." exit 1 From 6f7814899bca78f6f03e054c93760621b504a651 Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Fri, 17 Feb 2023 15:14:10 +0100 Subject: [PATCH 078/107] Remove unused "file" common type. Note that the FILE type in the specification is declared here as the "fileref" common type. --- json-schema/common.json | 4 ---- 1 file changed, 4 deletions(-) diff --git a/json-schema/common.json b/json-schema/common.json index e0ed6fd6..679f3869 100644 --- a/json-schema/common.json +++ b/json-schema/common.json @@ -132,10 +132,6 @@ "pattern": "^[A-Za-z0-9_][A-Za-z0-9_-]{0,9}" }, - "file": { - "type": "string" - }, - "ordinal": { "type": "integer", "minimum": 0 From f6ec35e15f37917fc2b059cdf129665cbb9b2d07 Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Fri, 17 Feb 2023 15:31:55 +0100 Subject: [PATCH 079/107] Move lat/lon location type to common definitions. --- json-schema/common.json | 25 +++++++++++++++++++++++++ json-schema/organization.json | 23 +---------------------- 2 files changed, 26 insertions(+), 22 deletions(-) diff --git a/json-schema/common.json b/json-schema/common.json index 679f3869..f0a70d39 100644 --- a/json-schema/common.json +++ b/json-schema/common.json @@ -197,6 +197,31 @@ ] }, + "location": { + "type": "object", + "properties": { + "latitude": { + "type": "number", + "minimum": -90, + "maximum": 90 + }, + "longitude": { + "type": "number", + "minimum": -180, + "maximum": 180 + } + }, + "required": ["latitude", "longitude"], + "$ref": "common.json#/strictproperties" + }, + + "locationornull": { + "oneOf": [ + { "$ref": "#/location" }, + { "type": "null" } + ] + }, + "command": { "type": "object", "properties": { diff --git a/json-schema/organization.json b/json-schema/organization.json index 497f2e01..c00d0695 100644 --- a/json-schema/organization.json +++ b/json-schema/organization.json @@ -21,28 +21,7 @@ "country_flag": { "$ref": "common.json#/imagerefsornull" }, "url": { "type": [ "string", "null" ] }, "twitter_hashtag": { "type": [ "string", "null" ] }, - "location": { - "oneOf": [ - { - "type": "object", - "properties": { - "latitude": { - "type": "number", - "minimum": -90, - "maximum": 90 - }, - "longitude": { - "type": "number", - "minimum": -180, - "maximum": 180 - } - }, - "required": ["latitude", "longitude"], - "$ref": "common.json#/strictproperties" - }, - { "type": "null" } - ] - }, + "location": { "$ref": "common.json#/locationornull" }, "logo": { "$ref": "common.json#/imagerefsornull" } }, "required": ["id", "name"], From 5ca0857dd5d54557b486fabd20c48a44660d3f68 Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Sun, 19 Feb 2023 10:41:31 +0100 Subject: [PATCH 080/107] Drop unused legacy-event-feed. --- json-schema/event-feed-array.json | 6 +--- json-schema/legacy-event-feed.json | 55 ------------------------------ 2 files changed, 1 insertion(+), 60 deletions(-) delete mode 100644 json-schema/legacy-event-feed.json diff --git a/json-schema/event-feed-array.json b/json-schema/event-feed-array.json index 0f4d7311..a89b3a40 100644 --- a/json-schema/event-feed-array.json +++ b/json-schema/event-feed-array.json @@ -6,10 +6,6 @@ "type": "array", "$ref": "common.json#/nonemptyarray", "items": { - "$comment": "Use anyOf since the event type fields overlap between the current and legacy format.", - "anyOf": [ - { "$ref": "event-feed.json#" }, - { "$ref": "legacy-event-feed.json#" } - ] + "$ref": "event-feed.json#" } } diff --git a/json-schema/legacy-event-feed.json b/json-schema/legacy-event-feed.json deleted file mode 100644 index 656f5e05..00000000 --- a/json-schema/legacy-event-feed.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "CLICS Contest API: event-feed", - "description": "Single line response of this NDJSON API call", - - "type": "object", - "properties": { - "id": { "$ref": "common.json#/identifier" }, - "type": { "$ref": "common.json#/endpoints" } - }, - "oneOf": [ - { - "properties": { - "op": { "enum": [ "create", "update" ] }, - "data": { - "$comment": "Use anyOf since some types match others without strict attribute checking.", - "anyOf": [ - { "$ref": "contest.json#" }, - { "$ref": "judgement-type.json#" }, - { "$ref": "language.json#" }, - { "$ref": "problem.json#" }, - { "$ref": "group.json#" }, - { "$ref": "organization.json#" }, - { "$ref": "team.json#" }, - { "$ref": "person.json#" }, - { "$ref": "team-member.json#" }, - { "$ref": "account.json#" }, - { "$ref": "state.json#" }, - { "$ref": "submission.json#" }, - { "$ref": "judgement.json#" }, - { "$ref": "run.json#" }, - { "$ref": "clarification.json#" }, - { "$ref": "award.json#" }, - { "$ref": "commentary.json#" } - ] - } - } - }, - { - "properties": { - "op": { "enum": [ "delete" ] }, - "data": { - "type": "object", - "properties": { - "id": { "$ref": "common.json#/identifier" } - }, - "required": ["id"], - "$ref": "common.json#/strictproperties" - } - } - } - ], - "required": ["id", "type", "op", "data"], - "$ref": "common.json#/strictproperties" -} From 12ed74cd9ccec856b8d59a2329d7547d8f2fc68f Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Fri, 17 Feb 2023 15:01:34 +0100 Subject: [PATCH 081/107] The "label" type was removed in 7c5e283d75e28046eba6845f7a4. --- json-schema/common.json | 5 ----- json-schema/problem.json | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/json-schema/common.json b/json-schema/common.json index f0a70d39..818b2fc1 100644 --- a/json-schema/common.json +++ b/json-schema/common.json @@ -127,11 +127,6 @@ ] }, - "label": { - "type": "string", - "pattern": "^[A-Za-z0-9_][A-Za-z0-9_-]{0,9}" - }, - "ordinal": { "type": "integer", "minimum": 0 diff --git a/json-schema/problem.json b/json-schema/problem.json index 6f250687..43fda0e0 100644 --- a/json-schema/problem.json +++ b/json-schema/problem.json @@ -15,7 +15,7 @@ { "type": "null" } ] }, - "label": { "$ref": "common.json#/label" }, + "label": { "type": "string" }, "name": { "type": "string" }, "ordinal": { "$ref": "common.json#/ordinal" }, "rgb": { From 82b213e4f187427df34628277ce14500e3989f3c Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Sat, 18 Feb 2023 10:45:13 +0100 Subject: [PATCH 082/107] Judgement type IF was added in c62dc129f57899fbec1. --- json-schema/common.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/json-schema/common.json b/json-schema/common.json index 818b2fc1..6845a2f7 100644 --- a/json-schema/common.json +++ b/json-schema/common.json @@ -115,7 +115,7 @@ "judgementtypeid": { "enum": [ "AC", "RE", "WA", "TLE", "RTE", "CE", "APE", "OLE", "PE", "EO", "IO", "NO", - "WTL", "ILE", "TCO", "TWA", "TPE", "TEO", "TIO", "TNO", "MLE", "SV", + "WTL", "ILE", "TCO", "TWA", "TPE", "TEO", "TIO", "TNO", "MLE", "SV", "IF", "RCO", "RWA", "RPE", "REO", "RIO", "RNO", "CTL", "JE", "SE", "CS" ] }, From 770a00fbd005e6524d4bc24014c71856e79a7481 Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Fri, 17 Feb 2023 17:03:58 +0100 Subject: [PATCH 083/107] Add schema for scoring type contests from 91f903b1c16d9894f0524ab39ad7e --- json-schema/contest.json | 27 ++++++++++++++++++- json-schema/problem.json | 1 + json-schema/scoreboard.json | 54 +++++++++++++++++++++++++++++-------- 3 files changed, 70 insertions(+), 12 deletions(-) diff --git a/json-schema/contest.json b/json-schema/contest.json index e2ff4230..7139545a 100644 --- a/json-schema/contest.json +++ b/json-schema/contest.json @@ -12,6 +12,7 @@ "countdown_pause_time": { "$ref": "common.json#/posreltimeornull" }, "duration": { "$ref": "common.json#/posreltime" }, "scoreboard_freeze_duration": { "$ref": "common.json#/posreltimeornull" }, + "scoreboard_type": { "enum": ["pass-fail", "score"] }, "penalty_time": { "type": "integer", "minimum": 0 @@ -19,6 +20,30 @@ "banner": { "$ref": "common.json#/imagerefsornull" }, "logo": { "$ref": "common.json#/imagerefsornull" } }, - "required": ["id", "name", "duration"], + "allOf": [ + { + "if": { + "properties": { + "scoreboard_type": { "const": "pass-fail" } + }, + "required": ["scoreboard_type"] + }, + "then": { + "required": ["penalty_time"] + } + }, + { + "if": { + "properties": { + "scoreboard_type": { "const": "score" } + }, + "required": ["scoreboard_type"] + }, + "then": { + "not": { "required": ["penalty_time"] } + } + } + ], + "required": ["id", "name", "duration", "scoreboard_type"], "$ref": "common.json#/strictproperties" } diff --git a/json-schema/problem.json b/json-schema/problem.json index 43fda0e0..b27a2621 100644 --- a/json-schema/problem.json +++ b/json-schema/problem.json @@ -32,6 +32,7 @@ "type": "integer", "minimum": 0 }, + "max_score": { "type": "number" }, "package": { "$ref": "common.json#/filerefsornull" }, "statement": { "$ref": "common.json#/filerefsornull" } }, diff --git a/json-schema/scoreboard.json b/json-schema/scoreboard.json index aeda4e46..4e48aff4 100644 --- a/json-schema/scoreboard.json +++ b/json-schema/scoreboard.json @@ -30,9 +30,25 @@ "total_time": { "type": "integer", "minimum": 0 + }, + "score": { + "type": "number" + }, + "time": { + "type": "integer", + "minimum": 0 } }, - "required": ["num_solved", "total_time"], + "oneOf": [ + { + "required": ["num_solved", "total_time"], + "not": { "required": ["score"] } + }, + { + "not": { "required": ["num_solved", "total_time"] }, + "required": ["score"] + } + ], "$ref": "common.json#/strictproperties" }, "problems": { @@ -50,24 +66,40 @@ "minimum": 0 }, "solved": { "type": "boolean" }, + "score": { + "type": "number", + "minimum": 0 + }, "time": { "type": "integer", "minimum": 0 } }, "oneOf": [ - { - "properties": { "solved": { "enum": [false] } }, - "not": { "required": ["time"] } - }, - { - "properties": { "solved": { "enum": [true] } }, - "required": ["time"] - } + { "required": ["solved"] }, + { "required": ["score"] } ], - "required": ["problem_id", "num_judged", "num_pending", "solved"], + "if": { + "oneOf": [ + { + "not": { "properties": { "solved": { "const": true } } }, + "required": ["solved"] + }, + { + "properties": { "score": { "const": 0 } }, + "required": ["score"] + } + ] + }, + "then": { + "not": { "required": ["time"] } + }, + "else": { + "required": ["time"] + }, + "required": ["problem_id", "num_judged", "num_pending"], "$ref": "common.json#/strictproperties" } } }, - "required": ["rank", "team_id", "score", "problems"], + "required": ["rank", "team_id", "score"], "$ref": "common.json#/strictproperties" } } From 5c1fb76d4df4f82c8684952e0e6b93d239457d7e Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Sat, 18 Feb 2023 18:13:21 +0100 Subject: [PATCH 084/107] Only one of contest start and countdown pause can be non-null. --- json-schema/contest.json | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/json-schema/contest.json b/json-schema/contest.json index 7139545a..302e0533 100644 --- a/json-schema/contest.json +++ b/json-schema/contest.json @@ -20,6 +20,13 @@ "banner": { "$ref": "common.json#/imagerefsornull" }, "logo": { "$ref": "common.json#/imagerefsornull" } }, + "not": { + "properties": { + "start_time": { "$ref": "common.json#/abstime" }, + "countdown_pause_time": { "$ref": "common.json#/posreltime" } + }, + "required": ["start_time", "countdown_pause_time"] + }, "allOf": [ { "if": { From 0bd2e3591ad383fbab6327aef88fdf972d8a6394 Mon Sep 17 00:00:00 2001 From: Jaap Eldering Date: Sat, 18 Feb 2023 11:06:53 +0100 Subject: [PATCH 085/107] Upgrade to using latest JSON schema draft 2020-12 specification. --- json-schema/account.json | 2 +- json-schema/accounts.json | 2 +- json-schema/award.json | 2 +- json-schema/awards.json | 2 +- json-schema/clarification.json | 2 +- json-schema/clarifications.json | 2 +- json-schema/commentaries.json | 2 +- json-schema/commentary.json | 2 +- json-schema/common.json | 2 +- json-schema/contest.json | 2 +- json-schema/contests.json | 2 +- json-schema/event-feed-array.json | 2 +- json-schema/event-feed.json | 2 +- json-schema/group.json | 2 +- json-schema/groups.json | 2 +- json-schema/judgement-type.json | 2 +- json-schema/judgement-types.json | 2 +- json-schema/judgement.json | 2 +- json-schema/judgements.json | 2 +- json-schema/language.json | 2 +- json-schema/languages.json | 2 +- json-schema/organization.json | 2 +- json-schema/organizations.json | 2 +- json-schema/person.json | 2 +- json-schema/persons.json | 2 +- json-schema/problem.json | 2 +- json-schema/problems.json | 2 +- json-schema/run.json | 2 +- json-schema/runs.json | 2 +- json-schema/scoreboard.json | 2 +- json-schema/state.json | 2 +- json-schema/submission.json | 2 +- json-schema/submissions.json | 2 +- json-schema/team-member.json | 2 +- json-schema/team-members.json | 2 +- json-schema/team.json | 2 +- json-schema/teams.json | 2 +- 37 files changed, 37 insertions(+), 37 deletions(-) diff --git a/json-schema/account.json b/json-schema/account.json index af093e37..3d110049 100644 --- a/json-schema/account.json +++ b/json-schema/account.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-07/schema#", + "$schema": "http://json-schema.org/draft/2020-12/schema", "title": "CLICS Contest API - account", "description": "Definition of a single account object", diff --git a/json-schema/accounts.json b/json-schema/accounts.json index 29cb973a..6e80b2e9 100644 --- a/json-schema/accounts.json +++ b/json-schema/accounts.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-07/schema#", + "$schema": "http://json-schema.org/draft/2020-12/schema", "title": "CLICS Contest API: accounts", "description": "JSON response of this API call", diff --git a/json-schema/award.json b/json-schema/award.json index eb919ef7..3c84d5b7 100644 --- a/json-schema/award.json +++ b/json-schema/award.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-07/schema#", + "$schema": "http://json-schema.org/draft/2020-12/schema", "title": "CLICS Contest API - award", "description": "Definition of a single award object", diff --git a/json-schema/awards.json b/json-schema/awards.json index 5d2d040f..23a12bf3 100644 --- a/json-schema/awards.json +++ b/json-schema/awards.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-07/schema#", + "$schema": "http://json-schema.org/draft/2020-12/schema", "title": "CLICS Contest API: awards", "description": "JSON response of this API call", diff --git a/json-schema/clarification.json b/json-schema/clarification.json index adfe376e..6c092472 100644 --- a/json-schema/clarification.json +++ b/json-schema/clarification.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-07/schema#", + "$schema": "http://json-schema.org/draft/2020-12/schema", "title": "CLICS Contest API - clarification", "description": "Definition of a single clarification object", diff --git a/json-schema/clarifications.json b/json-schema/clarifications.json index a06137d4..ca88cd2d 100644 --- a/json-schema/clarifications.json +++ b/json-schema/clarifications.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-07/schema#", + "$schema": "http://json-schema.org/draft/2020-12/schema", "title": "CLICS Contest API: clarifications", "description": "JSON response of this API call", diff --git a/json-schema/commentaries.json b/json-schema/commentaries.json index d1d2d33f..196c1934 100644 --- a/json-schema/commentaries.json +++ b/json-schema/commentaries.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-07/schema#", + "$schema": "http://json-schema.org/draft/2020-12/schema", "title": "CLICS Contest API: commentary", "description": "JSON response of this API call", diff --git a/json-schema/commentary.json b/json-schema/commentary.json index c8a29e14..376aa76a 100644 --- a/json-schema/commentary.json +++ b/json-schema/commentary.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-07/schema#", + "$schema": "http://json-schema.org/draft/2020-12/schema", "title": "CLICS Contest API - commentary", "description": "Definition of a single commentary object", diff --git a/json-schema/common.json b/json-schema/common.json index 6845a2f7..3e648205 100644 --- a/json-schema/common.json +++ b/json-schema/common.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-07/schema#", + "$schema": "http://json-schema.org/draft/2020-12/schema", "title": "CLICS Contest API - common definitions", "description": "Common definitions of objects used in the API calls", diff --git a/json-schema/contest.json b/json-schema/contest.json index 302e0533..0100c430 100644 --- a/json-schema/contest.json +++ b/json-schema/contest.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-07/schema#", + "$schema": "http://json-schema.org/draft/2020-12/schema", "title": "CLICS Contest API: contest", "description": "JSON response of this API call", diff --git a/json-schema/contests.json b/json-schema/contests.json index 4c0f2b8a..76b0e8d3 100644 --- a/json-schema/contests.json +++ b/json-schema/contests.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-07/schema#", + "$schema": "http://json-schema.org/draft/2020-12/schema", "title": "CLICS Contest API: contests", "description": "JSON response of this API call", diff --git a/json-schema/event-feed-array.json b/json-schema/event-feed-array.json index a89b3a40..5f82dfad 100644 --- a/json-schema/event-feed-array.json +++ b/json-schema/event-feed-array.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-07/schema#", + "$schema": "http://json-schema.org/draft/2020-12/schema", "title": "CLICS Contest API: event-feed array", "description": "JSON array of responses of this NDJSON API call", diff --git a/json-schema/event-feed.json b/json-schema/event-feed.json index cce6d633..2facda77 100644 --- a/json-schema/event-feed.json +++ b/json-schema/event-feed.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-07/schema#", + "$schema": "http://json-schema.org/draft/2020-12/schema", "title": "CLICS Contest API: event-feed", "description": "Single line response of this NDJSON API call", diff --git a/json-schema/group.json b/json-schema/group.json index b2f34b13..270e54bc 100644 --- a/json-schema/group.json +++ b/json-schema/group.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-07/schema#", + "$schema": "http://json-schema.org/draft/2020-12/schema", "title": "CLICS Contest API - group", "description": "Definition of a single group object", diff --git a/json-schema/groups.json b/json-schema/groups.json index 79d28043..bc460a77 100644 --- a/json-schema/groups.json +++ b/json-schema/groups.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-07/schema#", + "$schema": "http://json-schema.org/draft/2020-12/schema", "title": "CLICS Contest API: groups", "description": "JSON response of this API call", diff --git a/json-schema/judgement-type.json b/json-schema/judgement-type.json index ab121cc4..a3520444 100644 --- a/json-schema/judgement-type.json +++ b/json-schema/judgement-type.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-07/schema#", + "$schema": "http://json-schema.org/draft/2020-12/schema", "title": "CLICS Contest API - judgement_type", "description": "Definition of a single judgement-type object", diff --git a/json-schema/judgement-types.json b/json-schema/judgement-types.json index 4ec484b6..f59021c0 100644 --- a/json-schema/judgement-types.json +++ b/json-schema/judgement-types.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-07/schema#", + "$schema": "http://json-schema.org/draft/2020-12/schema", "title": "CLICS Contest API: judgement_types", "description": "JSON response of this API call", diff --git a/json-schema/judgement.json b/json-schema/judgement.json index df198047..54795dfb 100644 --- a/json-schema/judgement.json +++ b/json-schema/judgement.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-07/schema#", + "$schema": "http://json-schema.org/draft/2020-12/schema", "title": "CLICS Contest API - judgement", "description": "Definition of a single judgement object", diff --git a/json-schema/judgements.json b/json-schema/judgements.json index 9acbbfee..15aec183 100644 --- a/json-schema/judgements.json +++ b/json-schema/judgements.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-07/schema#", + "$schema": "http://json-schema.org/draft/2020-12/schema", "title": "CLICS Contest API: judgements", "description": "JSON response of this API call", diff --git a/json-schema/language.json b/json-schema/language.json index 19d1a1bc..a88b6a8c 100644 --- a/json-schema/language.json +++ b/json-schema/language.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-07/schema#", + "$schema": "http://json-schema.org/draft/2020-12/schema", "title": "CLICS Contest API - language", "description": "Definition of a single language object", diff --git a/json-schema/languages.json b/json-schema/languages.json index 413c4667..66e2fd10 100644 --- a/json-schema/languages.json +++ b/json-schema/languages.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-07/schema#", + "$schema": "http://json-schema.org/draft/2020-12/schema", "title": "CLICS Contest API: languages", "description": "JSON response of this API call", diff --git a/json-schema/organization.json b/json-schema/organization.json index c00d0695..b614a7e7 100644 --- a/json-schema/organization.json +++ b/json-schema/organization.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-07/schema#", + "$schema": "http://json-schema.org/draft/2020-12/schema", "title": "CLICS Contest API - organization", "description": "Definition of a single organization object", diff --git a/json-schema/organizations.json b/json-schema/organizations.json index 9b0bafa2..f5f94f8d 100644 --- a/json-schema/organizations.json +++ b/json-schema/organizations.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-07/schema#", + "$schema": "http://json-schema.org/draft/2020-12/schema", "title": "CLICS Contest API: organizations", "description": "JSON response of this API call", diff --git a/json-schema/person.json b/json-schema/person.json index 5ea2cdc4..083f2d14 100644 --- a/json-schema/person.json +++ b/json-schema/person.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-07/schema#", + "$schema": "http://json-schema.org/draft/2020-12/schema", "title": "CLICS Contest API - person", "description": "Definition of a single person object", diff --git a/json-schema/persons.json b/json-schema/persons.json index 0c24e937..9c448eaf 100644 --- a/json-schema/persons.json +++ b/json-schema/persons.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-07/schema#", + "$schema": "http://json-schema.org/draft/2020-12/schema", "title": "CLICS Contest API: persons", "description": "JSON response of this API call", diff --git a/json-schema/problem.json b/json-schema/problem.json index b27a2621..e9bf7d47 100644 --- a/json-schema/problem.json +++ b/json-schema/problem.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-07/schema#", + "$schema": "http://json-schema.org/draft/2020-12/schema", "title": "CLICS Contest API - problem", "description": "Definition of a single problem object", diff --git a/json-schema/problems.json b/json-schema/problems.json index 6056fa1f..861bcdeb 100644 --- a/json-schema/problems.json +++ b/json-schema/problems.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-07/schema#", + "$schema": "http://json-schema.org/draft/2020-12/schema", "title": "CLICS Contest API: problems", "description": "JSON response of this API call", diff --git a/json-schema/run.json b/json-schema/run.json index 13081c83..a54d4663 100644 --- a/json-schema/run.json +++ b/json-schema/run.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-07/schema#", + "$schema": "http://json-schema.org/draft/2020-12/schema", "title": "CLICS Contest API - run", "description": "Definition of a single run object", diff --git a/json-schema/runs.json b/json-schema/runs.json index 5d51622e..9c0d5b80 100644 --- a/json-schema/runs.json +++ b/json-schema/runs.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-07/schema#", + "$schema": "http://json-schema.org/draft/2020-12/schema", "title": "CLICS Contest API: runs", "description": "JSON response of this API call", diff --git a/json-schema/scoreboard.json b/json-schema/scoreboard.json index 4e48aff4..10fd0e8f 100644 --- a/json-schema/scoreboard.json +++ b/json-schema/scoreboard.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-07/schema#", + "$schema": "http://json-schema.org/draft/2020-12/schema", "title": "CLICS Contest API: scoreboard", "description": "JSON response of this API call", diff --git a/json-schema/state.json b/json-schema/state.json index 03365ec3..3984ee5c 100644 --- a/json-schema/state.json +++ b/json-schema/state.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-07/schema#", + "$schema": "http://json-schema.org/draft/2020-12/schema", "title": "CLICS Contest API: state", "description": "JSON response of this API call", diff --git a/json-schema/submission.json b/json-schema/submission.json index aca0a4ff..dbcd3fec 100644 --- a/json-schema/submission.json +++ b/json-schema/submission.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-07/schema#", + "$schema": "http://json-schema.org/draft/2020-12/schema", "title": "CLICS Contest API - submission", "description": "Definition of a single submission object", diff --git a/json-schema/submissions.json b/json-schema/submissions.json index bb1fa88d..2a0a3b20 100644 --- a/json-schema/submissions.json +++ b/json-schema/submissions.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-07/schema#", + "$schema": "http://json-schema.org/draft/2020-12/schema", "title": "CLICS Contest API: submissions", "description": "JSON response of this API call", diff --git a/json-schema/team-member.json b/json-schema/team-member.json index 46bed247..284d0965 100644 --- a/json-schema/team-member.json +++ b/json-schema/team-member.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-07/schema#", + "$schema": "http://json-schema.org/draft/2020-12/schema", "title": "CLICS Contest API - team-member", "description": "Definition of a single team-member object", diff --git a/json-schema/team-members.json b/json-schema/team-members.json index 074a3b39..1eea490d 100644 --- a/json-schema/team-members.json +++ b/json-schema/team-members.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-07/schema#", + "$schema": "http://json-schema.org/draft/2020-12/schema", "title": "CLICS Contest API: team-members", "description": "JSON response of this API call", diff --git a/json-schema/team.json b/json-schema/team.json index d2d7cf78..5530c14e 100644 --- a/json-schema/team.json +++ b/json-schema/team.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-07/schema#", + "$schema": "http://json-schema.org/draft/2020-12/schema", "title": "CLICS Contest API - team", "description": "Definition of a single team object", diff --git a/json-schema/teams.json b/json-schema/teams.json index 4c88c2a9..710df309 100644 --- a/json-schema/teams.json +++ b/json-schema/teams.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-07/schema#", + "$schema": "http://json-schema.org/draft/2020-12/schema", "title": "CLICS Contest API: teams", "description": "JSON response of this API call", From 523c5eb99a341c053c9e2d5603146180574d4631 Mon Sep 17 00:00:00 2001 From: Nicky Gerritsen Date: Sat, 18 Mar 2023 14:22:20 +0100 Subject: [PATCH 086/107] Rename contest_thaw_time to scoreboard_thaw_time to match object. --- Contest_API.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Contest_API.md b/Contest_API.md index bc8dd96d..dce0e144 100644 --- a/Contest_API.md +++ b/Contest_API.md @@ -766,12 +766,12 @@ Clients with the `contest_thaw` [capability](#capabilities) have the ability to set a time when the contest will be thawed via a PATCH method. The PATCH must include a valid JSON object with two properties: -the contest `id` (used for verification) and a `contest_thaw_time`, a `