Skip to main content

Exams (events)

An event is a temporary context attached to an activity, during which part of that activity becomes reachable only through a dedicated, restricted environment. The only event type available today is EXAM.

Setting up an exam always takes two steps, in two different places:

  1. In activity.yml: you declare the event and you mark which groups are restricted to it. This describes what the exam is. It is versioned with your activity.
  2. In Operator: you create one or more scheduled events (instances of the exam). This describes when and from where the exam runs: token, opening and closing dates, duration, allowed subnets. These are not versioned and can be changed up to the last minute.

How it works​

A student can take the exam only if all of these are true:

  • They are a member of a group that carries an eventRestrictions entry for the event.
  • That group is subscribed to at least one submission of the activity.
  • A scheduled event exists for the event, and it is open.
  • Their machine's IP address is in one of the subnets allowed on that scheduled event.
  • They know the token of the scheduled event.

Configuring the activity​

Declaring the event​

Events are declared at the root of the activity, under the events key:

events:
- slug: exam
name: Exam
type: EXAM
managers:
- alpha.manager
- beta.manager
PropertyDescriptionRequired?
slugUnique name within the activity, without spaces or slashes.Yes
nameName of the event.Yes
typeType of the event. Only EXAM exists today.No (always EXAM)
managersForge logins of the people allowed to configure the exam in Operator.No (default [])
caution

events[].managers is the only thing that grants access to the exam configuration in Operator. Being an activity manager is not enough: if your login is not in this list, the event will not show up in Operator for you.

Restricting groups to the event​

An event on its own does nothing. What ties students to the exam is the eventRestrictions key, which is set on groups declared at the root of the activity:

groups:
- slug: xavier.login
logins:
- xavier.login
eventRestrictions:
- exam
- slug: john.doe
logins:
- john.doe
eventRestrictions:
- exam

A group that carries at least one eventRestrictions entry stops being a regular group:

  • Everything that group is subscribed to disappears from intra.forge.epita.fr and only shows up on exam.forge.epita.fr.
  • The repository of that group is only reachable through the exam Git host (git.exam.forge.epita.fr). Cloning or pushing it from the regular Git server is refused.
  • During a scheduled event, the student is additionally gated by the token, the time window and the allowed subnets.
One group per student, declared in groups

Even for an exam where every student works alone, you must declare one group per student under the top-level groups key, because eventRestrictions can only be set there.

This also means you must not use subscriptions.logins (nor subscriptions.criGroups) anywhere in an exam activity.

When the intranet ingests the activity, every login found in a subscriptions.logins or subscriptions.criGroups list gets a solo group generated automatically, named after the login and with no event restriction. That generated group takes precedence over the group you declared yourself, so it is the unrestricted one that ends up attached to the submission. The result is an activity that looks correctly configured, but whose students are not registered for the exam at all: they get The given token is invalid or you are not enrolled in this exam on the exam portal, while the subject stays visible on the regular intranet.

Always subscribe your groups with subscriptions.groups, referencing the slug of the group (not the login).

Subscribing the groups​

Groups must be subscribed to at least one submission. A group that carries eventRestrictions but is not subscribed anywhere is simply ignored and produces no exam registration.

subscriptions:
groups:
- xavier.login # the slug of the group, not the login
- john.doe

Complete example​

---
tenantSlug: example-tenant
slug: example-slug
name: "Example Exam Activity"

managers:
- example-manager

groups:
- slug: xavier.login
logins:
- xavier.login
eventRestrictions:
- exam
- slug: xavier.login2
logins:
- xavier.login2
eventRestrictions:
- exam

events:
- slug: exam
name: Exam
type: EXAM
managers:
- example-manager

assignments:
- maxLearners: 1
name: dummy assignment (can be deleted)
slug: dummy-assignment
submissions:
- handoffType: REGISTRATION_ONLY
slug: dummy-submission
dates:
closingAt: "2024-10-04T17:05:56+02:00"
openingAt: "2024-09-04T17:05:56+02:00"
publishingAt: "2024-09-04T17:05:56+02:00"
subscriptions:
groups:
- xavier.login # this is the slug of the group, not the login
- xavier.login2
tip

Generating one group block per student is tedious. Since the group slug is free-form, using the student's login as the slug (as above) keeps the file readable and makes it easy to generate from a list of logins.

Once the file is written, deploy the activity as usual. The event only appears in Operator after the activity has been ingested.

Scheduling the exam in Operator​

The dates in activity.yml control when the assignment is open. They do not control the exam session. The actual exam window, its duration, its token and the rooms it can be taken from are configured in Operator, under:

https://operator.forge.epita.fr/{tenantSlug}/{activitySlug}/events

That page lists the events declared in your activity.yml. Click one to get the list of its scheduled events.

An event can hold several scheduled events. This is how you run the same exam several times: one per session, per room or per promotion, each with its own token, window and subnets.

Creating a scheduled event​

Use Schedule new instance. The dialog asks for:

FieldDescription
Event SlugSlug of this scheduled event. It cannot be changed afterwards.
Event TokenThe string students type on the exam portal to start their session.
Opening AtStart of the window during which the exam can be taken.
Closing AtEnd of that window. Nobody can start or keep working after this date.
DurationHow long a student gets, in minutes, once they redeem the token.

The following rules are enforced:

  • Opening At must be before Closing At.
  • Duration must be positive and must fit in the window: Opening At plus the duration cannot be after Closing At.
  • The token must be unique across every non-archived scheduled event on the whole intranet. If the token you picked is already used elsewhere, the form reports a duplicate value — pick another one.
caution

A freshly created scheduled event has no allowed subnet, which means nobody can use it. Open it and select the subnets before the exam, otherwise every student is rejected with Client IP not in allowed subnet.

Editing a scheduled event​

Clicking a scheduled event opens its details, with two tabs: Details and Submission Shifts.

The Details tab lets you change the token, the window, the duration, the allowed subnets, and two flags:

FlagEffect
ClosedAdministratively closes the exam. Every access is refused with Exam is administratively closed, regardless of the dates. Use it as an emergency stop.
ArchivedRetires the scheduled event. An archived scheduled event no longer reserves its token, so the token becomes reusable elsewhere.

Allowed subnets​

The Subnets section lists the networks known to the Forge, by room or zone. A student can only start and keep an exam session if the IP address their machine is seen with belongs to one of the subnets you enabled here.

The list itself is maintained by the Forge. If a room you need is missing, contact us.

Submission shifts​

A submission shift gives extra time to a specific group on a specific scheduled event — typically for students entitled to extended exam time.

In the Submission Shifts tab, use Add Submission Shift, pick the group in the list and give a duration in minutes. That duration is added to the scheduled event's duration for this group only; the opening and closing dates are unchanged, so a shift cannot push a student past Closing At.

To remove a shift, edit it and set its duration to 0.

What students do on exam day​

  1. They go to https://exam.forge.epita.fr and sign in with their Forge account.
  2. They are asked for the token of the scheduled event. You give it to them at the start of the exam.
  3. Once the token is accepted, the session starts and they get a page showing the time remaining. The activity is then browsable on that host, and their repository can be cloned from git.exam.forge.epita.fr.

The countdown starts on the first token redemption and is shared by the whole group. The session ends at the earliest of start + duration (plus any submission shift) and the scheduled event's Closing At.

The session is bound to the login and IP address used to redeem the token. Git operations are authorized against that session, so a student has to open their session on the exam portal before they can clone or push.

Troubleshooting​

What the student seesWhat to check
The given token is invalid or you are not enrolled in this examThe token, and the registration. Most of the time this is the subscriptions.logins mistake described above: make sure every student is in a top-level group that has the right eventRestrictions, and that this group is subscribed to a submission.
Client IP not in allowed subnetThe subnets enabled on the scheduled event, and the room the student is actually in.
Too Early, exam not opened yetOpening At.
Exam is closedClosing At.
No time remainingThe duration is over for that group, or Closing At has been reached. A submission shift can give more time.
Exam is administratively closedThe Closed flag on the scheduled event.
Failed to find a session linked to your user / machineThe student tried to use Git before opening their session on the exam portal, or from another machine.
The subject shows up on intra.forge.epita.frThe group is not restricted to the event. Check eventRestrictions and redeploy.
The event does not show up in OperatorYour login is not in events[].managers, or the activity has not been deployed since the event was added.