Skip to content

M4.2 — Configuration & context

What you'll learn

  • How UnrealTestConfiguration declares the roles and arguments a test needs.
  • What UnrealTestContext provides at runtime (build, devices, options).
  • The split between declaring intent (config) and reacting to reality (context).

How it applies (QA)

This is where the role layout you designed on paper in M3.2 becomes code. The configuration is the single most edited part of a real test — adding a client, changing a server arg, bumping the timeout. Reading and writing it fluently is most of day-to-day Gauntlet authoring.

Concepts

UnrealTestConfiguration — declaring intent

Your test exposes its configuration by overriding GetConfiguration(). The returned UnrealTestConfiguration (your TConfig) declares what the session must contain:

  • Roles — request each participant and its type (client, server, editor). Requesting a role hands you back a role object whose command line and options you can tune.
  • Per-role arguments — append game args to a specific role (the server gets the host switch and map; clients get the connect target).
  • Global test options — most importantly MaxDuration (the timeout after which the run is abandoned), plus other knobs the base exposes.

This is the declare intent step from M3.1: you describe the UnrealSession you want; the base class builds and launches it.

public class MyBootTestConfig : UnrealTestConfiguration { }

public class MyBootTest : UnrealTestNode<MyBootTestConfig>
{
    public MyBootTest(UnrealTestContext context) : base(context) { }

    public override MyBootTestConfig GetConfiguration()
    {
        var Config = base.GetConfiguration();

        // Declare one client role and tune it.
        var Client = Config.RequireRole(UnrealTargetRole.Client);
        Client.CommandLine += " -windowed -resx=1280 -resy=720";

        // Global: give boot up to 120s before declaring a timeout.
        Config.MaxDuration = 120;

        return Config;
    }
}

For the 2-clients + 1-server layout, you'd RequireRole a Server and two Clients and set each one's args. Verify on a real build: the exact role-request API (RequireRole, the UnrealTargetRole names) and config property names vary by version; the structure — request roles, set args, set duration — is stable.

UnrealTestContext — the reality handed to you

Where the configuration says what you want, the UnrealTestContext (passed to your constructor) carries what you actually got for this run:

  • The build to run (resolved by UnrealBuildSource).
  • The device(s) the roles will run on.
  • The options/parameters the run was invoked with.

The base class uses the context to realize your configuration into a live UnrealSessionInstance. You read the context when your logic needs to know about the concrete run — which build, which platform, which device — rather than the abstract intent.

Intent vs. reality, side by side

UnrealTestConfiguration UnrealTestContext
Answers "What does this test need?" "What did this run actually get?"
You write it (declare roles/args/duration) read it (build/devices/options)
Timing before launch at/through the run
Analogy the blueprint the site survey

Pitfall: a too-short MaxDuration reads as a product bug

If MaxDuration is shorter than the legitimate boot/load time on a slow target (a cold console, a big map), the run times out and goes red while the game was fine, just slow. Before filing "boot is broken on PS5," check whether the timeout is realistic for that device/build. Set durations against the slowest target you run, not your dev PC.

Worked example — declaring the 1-server/2-client layout

public override MyMatchTestConfig GetConfiguration()
{
    var Config = base.GetConfiguration();

    var Server  = Config.RequireRole(UnrealTargetRole.Server);
    Server.CommandLine += " /Game/Maps/TestArena?listen";

    var Client0 = Config.RequireRole(UnrealTargetRole.Client);
    var Client1 = Config.RequireRole(UnrealTargetRole.Client);
    // Clients connect to the server; Gauntlet wires the address (M3.2).

    Config.MaxDuration = 300;   // a full short match on the slowest target
    return Config;
}

This is M3.2's table expressed in code: three roles requested, the server given a map + listen switch, a duration sized for a real match. The base class turns it into the launched session.

Exercise 1 — Config or context?

For each need, say whether you'd write it into UnrealTestConfiguration or read it from UnrealTestContext:

  1. "This test needs a dedicated server and two clients."
  2. "Which platform am I actually running on right now?"
  3. "The server should host TestArena with ?listen."
  4. "Where is the build that got resolved for this run?"
  5. "Abandon the run after 5 minutes."

Lab — Turn your M3.3 layout into a GetConfiguration()

Take the scaled layout from the M3.3 lab (server on host, clients on devices). Write the GetConfiguration() for it: request the roles, give the server its map/listen args, set a MaxDuration justified for the slowest device. Mark every line you're unsure of with verify on a real build.

Self-check — answers

Exercise 1: 1 config (declare roles), 2 context (the run's actual platform), 3 config (server args), 4 context (resolved build location), 5 config (MaxDuration).

Lab: Expect three RequireRole calls (1 Server, 2 Client), the server's CommandLine += " /Game/Maps/...?listen", and Config.MaxDuration set generously for the console clients (e.g. 300+). The device placement itself comes from the run/pool config, not GetConfiguration() — a good thing to have flagged as verify on a real build, since how a role is pinned to a specific device is studio-/version-specific.

Done when

  • [ ] You can write a GetConfiguration() that requests roles, sets per-role args, and sets MaxDuration.
  • [ ] You can explain what UnrealTestContext carries and when you read it.
  • [ ] You can sort a given need into config (intent) vs. context (reality).
  • [ ] You can explain how a bad MaxDuration masquerades as a product failure.

Next: M4.3 — Lifecycle & build-your-own boot test.