googleforgames / agones

Dedicated Game Server Hosting and Scaling for Multiplayer Games on Kubernetes
https://agones.dev
Apache License 2.0
6.08k stars 808 forks source link

[Agones Unity SDK] Add instructions to run tests using a Container Image(s) #3926

Closed aallbrig closed 1 month ago

aallbrig commented 3 months ago

Is your feature request related to a problem? Please describe. A discussion started in https://github.com/googleforgames/agones/pull/3887 over the idea of using GameCI's images (docs, docker hub) to run the Agones Unity SDK tests as a way of making things easier.

Describe the solution you'd like I'd like to see documentation additions that include how one may use docker commands to run the Agones Unity SDK tests.

Describe alternatives you've considered 🤔 Perhaps a script with OS specific commands would also serve the purpose of making running tests for Agones Unity SDK easier as well.

Additional context Previous experience: https://github.com/aallbrig/getting-started-with-game-ci-docker

aallbrig commented 3 months ago

Going to add some current notes here.

The way Unity handles licenses changed since I set up aallbrig/getting-started-with-game-ci-docker. Before one would generate a .alf file, navigate to a Unity webpage, then receive a .ulf file in return. Now it appears the Unity license file is generated in the Unity Hub app (Unity License activation docs).

This .ulf Unity License file is generated for the detected OS; if one is on an M2 Macbook and generates the license, that license will only allow the Unity Editor to work on that particular OS. That's a problem because the GameCI container image is based on Ubuntu. Feeding in the .ulf file from host M2 will result in a gameCI failure.

E.g. command:

repo_root=$(git rev-parse --show-toplevel)
unity_version="2021.3.13f1"
base_version="3.1.0"
cat << 'HERE' > /tmp/create-script.sh
unity-editor \
    -logFile /dev/stdout \
    -quit \
    -manualLicenseFile /UnityLicense.ulf
unity-editor \
    -logFile /dev/stdout \
    -quit \
    -createProject $(pwd)
HERE
chmod +x /tmp/create-script.sh
docker run \
  --interactive \
  --platform linux/amd64 \
  --tty \
  --rm \
  --env UNITY_EMAIL \
  --env UNITY_PASSWORD \
  --volume "/Library/Application Support/Unity/Unity_lic.ulf:/UnityLicense.ulf" \
  --volume "$(mktemp -d):/unity" \
  --workdir /unity \
  --volume "/tmp/create-script.sh:/create-script.sh" \
  "unityci/editor:ubuntu-${unity_version}-base-${base_version}" \
  bash -c '/create-script.sh'

Output:

Unity Editor version:    2021.3.13f1 (9e7d58001ecf)
Branch:                  2021.3/staging
Build type:              Release
Batch mode:              YES
System name:             Linux
Distro version:          #1 SMP Thu May 23 08:36:57 UTC 2024
Kernel version:          6.6.31-linuxkit
Architecture:            x86_64
Available memory:        7840 MB
[LicensingClient] Channel doesn't exist: "LicenseClient-root"
[Licensing::Module] Successfully launched the LicensingClient (PId: 35)
[Licensing::Module] Warning: LicensingClient has failed validation; ignoring
[LicensingClient] Handshaking with LicensingClient (version: 1.9.0+249add7)
[Licensing::Module] Successfully connected to LicensingClient on channel: "LicenseClient-root" (connect: 1.07s, validation: 0.20s, handshake: 0.00s)
[Licensing::Module] Connected to LicensingClient (PId: 35, launch time: 0.00, total connection time: 1.27s)
Entitlement-based licensing initiated
[Licensing::Module] Error: Access token is unavailable
[LicensingClient] Licenses updated successfully

 Load manual activation license file.

LICENSE SYSTEM [2024730 12:44:0] Load license file from: /UnityLicense.ulf

LICENSE SYSTEM [2024730 12:44:0] Next license update check is after 2024-07-27T23:44:45

LICENSE SYSTEM [2024730 12:44:0] Machine binding 1 mismatch: (value of current machine) 576562626572264761624c65526f7578 != 527236A0-0965-578E-977F-D206EDEFB215 (value in license file). Reason might be there is a hardware change on this machine after the license was activated.

LICENSE SYSTEM [2024730 12:44:0] Machine binding 2 mismatch: (value of current machine) 576562626572264761624c65526f7578 != RQFG6M9KVY (value in license file). Reason might be there is a hardware change on this machine after the license was activated.

LICENSE SYSTEM [2024730 12:44:0] Machine identification is invalid for current license.

 License file loaded.
Checking for leaked weakptr:
  Found no leaked weakptrs.
Memory Statistics:
[ALLOC_TEMP_TLS] TLS Allocator
  StackAllocators :
    [ALLOC_TEMP_CurlRequest]
      Initial Block Size 64.0 KB
      Current Block Size 64.0 KB
      Peak Allocated Bytes 0 B
      Overflow Count 0
    [ALLOC_TEMP_CoreBusinessMetricsCache]
      Initial Block Size 64.0 KB
      Current Block Size 64.0 KB
      Peak Allocated Bytes 0 B
      Overflow Count 0
    [ALLOC_TEMP_Profiler.Dispatcher]
      Initial Block Size 64.0 KB
      Current Block Size 64.0 KB
      Peak Allocated Bytes 0 B
      Overflow Count 0
    [ALLOC_TEMP_AssetGarbageCollectorHelper] x 11
      Initial Block Size 64.0 KB
      Current Block Size 64.0 KB
      Peak Allocated Bytes 0 B
      Overflow Count 0
[ALLOC_MEMORYPROFILER]
  Requested Block Size 1.0 MB
  Peak Block count 1
  Peak Allocated memory 4.0 KB
  Peak Large allocation bytes 0 B
##utp:{"type":"MemoryLeaks","version":2,"phase":"Immediate","time":1722343440852,"processId":21,"allocatedMemory":88575,"memoryLabels":[{"Default":122},{"Thread":64},{"Manager":7098},{"Serialization":40},{"BaseObject":12216},{"String":7824},{"DynamicArray":432},{"HashMap":3668},{"Utility":1024},{"Curl":1112},{"PoolAlloc":120},{"GI":3248},{"VR":80},{"RestService":1022},{"License":288},{"UnityConnect":29664},{"Collab":25},{"LocalIPC":99},{"ProfilerEditor":20021},{"Licensing":408}]}

(repeated text omitted)

Reading more from gameCI source code, you realize that the is a new value UNITY_SERIAL that gets obtained in the JS parts of gameCI (see src/model/input.ts#L91, src/model/input.ts#L193, src/model/input.ts#L203, src/model/input.ts#L206 from the game-ci/unity-test-runner repo).

export UNITY_USERNAME=""
export UNITY_PASSWORD=""
# unity license file location found on page: https://game.ci/docs/github/activation
export UNITY_LICENSE=$(cat "/Library/Application Support/Unity/Unity_lic.ulf")
export UNITY_SERIAL=$(echo $UNITY_LICENSE | sed -n 's/.*<SerialMasked Value="\([^"]*\)".*/\1/p')

repo_root=$(git rev-parse --show-toplevel)
unity_version="2021.3.13f1"
base_version="3.1.0"

cat << 'HERE' > /tmp/create-script.sh
unity-editor \
    -logFile /dev/stdout \
    -quit \
    -createProject $(pwd) \
    -username "$UNITY_USERNAME" -password "$UNITY_PASSWORD" -serial "$UNITY_SERIAL"
HERE
chmod +x /tmp/create-script.sh
docker run \
  --interactive \
  --platform linux/amd64 \
  --network host \
  --tty \
  --rm \
  --env UNITY_USERNAME \
  --env UNITY_PASSWORD \
  --env UNITY_SERIAL \
  --volume "$(mktemp -d):/unity" \
  --workdir /unity \
  --volume "/tmp/create-script.sh:/create-script.sh" \
  "unityci/editor:ubuntu-${unity_version}-base-${base_version}" \
  bash -c '/create-script.sh'

Experimentation command I use:

export UNITY_LICENSE=$(cat "/Library/Application Support/Unity/Unity_lic.ulf")
export UNITY_SERIAL=$(echo $UNITY_LICENSE | sed -n 's/.*<SerialMasked Value="\([^"]*\)".*/\1/p')

unity_version="2021.3.13f1"
base_version="3.1.0"

docker run \
  --interactive \
  --platform linux/amd64 \
  --network host \
  --tty \
  --rm \
  --env UNITY_USERNAME \
  --env UNITY_PASSWORD \
  --env UNITY_SERIAL \
  --volume "$(mktemp -d):/unity" \
  --workdir /unity \
  "unityci/editor:ubuntu-${unity_version}-base-${base_version}" \
  bash

This way I can run any unity-editor commands I want. Note: unity-editor is a decorator script that calls out to the "real" Unity Editor (ubuntu) command line.

$ which unity-editor
/usr/bin/unity-editor

$ cat /usr/bin/unity-editor
#!/bin/bash

if [ -d /usr/bin/unity-editor.d ] ; then
  for i in /usr/bin/unity-editor.d/*.sh; do
    if [ -r $i ]; then
      . $i
    fi
  done
fi

xvfb-run -ae /dev/stdout "$UNITY_PATH/Editor/Unity" -batchmode "$@"

You can find the "real" Unity Editor command line docs here and the test commands in the Test Framework docs here.


Currently I have two issues. (1) username/password combination doesn't seem to be working? (2) license steps probably aren't complete. I think solving problem 2 will solve problem 1 because I guarantee my credentials are correct.

Sample output from inside an "experiment" container

$ unity-editor \
    -logFile /dev/stdout \
    -quit \
    -createProject $(pwd) \
    -username "$UNITY_USERNAME" -password "$UNITY_PASSWORD" -serial "$UNITY_SERIAL"

Unity Editor version:    2021.3.13f1 (9e7d58001ecf)
Branch:                  2021.3/staging
Build type:              Release
Batch mode:              YES
System name:             Linux
Distro version:          #1 SMP Thu May 23 08:36:57 UTC 2024
Kernel version:          6.6.31-linuxkit
Architecture:            x86_64
Available memory:        7840 MB
UnityConnectLoginRequest: Failed to login - please check your username or password
No sufficient permissions while processing request "https://core.cloud.unity3d.com/api/login", HTTP error code 401
.[LicensingClient] Channel doesn't exist: "LicenseClient-root"
[Licensing::Module] Successfully launched the LicensingClient (PId: 102)
[Licensing::Module] Warning: LicensingClient has failed validation; ignoring
[LicensingClient] Handshaking with LicensingClient (version: 1.9.0+249add7)
[Licensing::Module] Successfully connected to LicensingClient on channel: "LicenseClient-root" (connect: 1.03s, validation: 0.16s, handshake: 0.00s)
[Licensing::Module] Connected to LicensingClient (PId: 102, launch time: 0.00, total connection time: 1.19s)
Entitlement-based licensing initiated
[Licensing::Module] Error: Access token is unavailable
[Licensing::Module] Error: Failed to activate entitlement license
Cancelling DisplayDialog: Failed to activate/update license Timeout occured while trying to update license. Please try again later or contact support@unity3d.com
This should not be called in batch mode.
Checking for leaked weakptr:
  Found no leaked weakptrs.
Memory Statistics:
[ALLOC_TEMP_TLS] TLS Allocator
  StackAllocators :
    [ALLOC_TEMP_CurlRequest]
      Initial Block Size 64.0 KB
      Current Block Size 64.0 KB
      Peak Allocated Bytes 0 B
      Overflow Count 0
    [ALLOC_TEMP_CoreBusinessMetricsCache]
      Initial Block Size 64.0 KB
      Current Block Size 64.0 KB
      Peak Allocated Bytes 0 B
      Overflow Count 0
    [ALLOC_TEMP_Profiler.Dispatcher]
      Initial Block Size 64.0 KB
      Current Block Size 64.0 KB
      Peak Allocated Bytes 0 B
      Overflow Count 0
    [ALLOC_TEMP_AssetGarbageCollectorHelper] x 11
      Initial Block Size 64.0 KB
      Current Block Size 64.0 KB
      Peak Allocated Bytes 0 B
      Overflow Count 0
[ALLOC_MEMORYPROFILER]
  Requested Block Size 1.0 MB
  Peak Block count 1
  Peak Allocated memory 4.0 KB
  Peak Large allocation bytes 0 B
##utp:{"type":"MemoryLeaks","version":2,"phase":"Immediate","time":1722294444852,"processId":86,"allocatedMemory":86136,"memoryLabels":[{"Default":226},{"Thread":64},{"Manager":7098},{"Serialization":40},{"BaseObject":12216},{"String":5361},{"DynamicArray":432},{"HashMap":3668},{"Utility":1024},{"Curl":1112},{"PoolAlloc":120},{"GI":3248},{"VR":80},{"RestService":1022},{"License":288},{"UnityConnect":29688},{"Collab":25},{"LocalIPC":99},{"ProfilerEditor":20021},{"Licensing":304}]}

Next steps: continue reading through various GameCI bash scripts such as those found in https://github.com/game-ci/unity-test-runner/tree/main/dist/platforms/ubuntu

markmandel commented 3 months ago

Maybe a silly question - but if you are running into issues, have you tried the gameci discord?

aallbrig commented 3 months ago

@markmandel Not yet! Wanted to spent a little more time on this research/due diligence.

aallbrig commented 3 months ago

Here's the linux based docker run command that gets assembled in the GameCI's JS/TS: src/model/docker.ts#L77

    return `docker run \
            --workdir /github/workspace \
            --cidfile "${cidfile}" \
            --rm \
            ${ImageEnvironmentFactory.getEnvVarString(parameters)} \
            --env GIT_CONFIG_EXTENSIONS \
            --env TEST_PLATFORMS="${testPlatforms}" \
            --env GITHUB_WORKSPACE="/github/workspace" \
            ${sshAgent ? '--env SSH_AUTH_SOCK=/ssh-agent' : ''} \
            --volume "${githubHome}:/root:z" \
            --volume "${githubWorkflow}:/github/workflow:z" \
            --volume "${workspace}:/github/workspace:z" \
            --volume "${actionFolder}/test-standalone-scripts:/UnityStandaloneScripts:z" \
            --volume "${actionFolder}/platforms/ubuntu:/steps:z" \
            --volume "${actionFolder}/unity-config:/usr/share/unity3d/config/:z" \
            --volume "${actionFolder}/BlankProject":"/BlankProject:z" \
            --cpus=${dockerCpuLimit} \
            --memory=${dockerMemoryLimit} \
            ${sshAgent ? `--volume ${sshAgent}:/ssh-agent` : ''} \
            ${
              sshAgent && !sshPublicKeysDirectoryPath
                ? `--volume /home/runner/.ssh/known_hosts:/root/.ssh/known_hosts:ro`
                : ''
            } \
            ${
              sshPublicKeysDirectoryPath
                ? `--volume ${sshPublicKeysDirectoryPath}:/root/.ssh:ro`
                : ''
            } \
            ${useHostNetwork ? '--net=host' : ''} \
            ${githubToken ? '--env USE_EXIT_CODE=false' : '--env USE_EXIT_CODE=true'} \
            ${image} \
            /bin/bash -c "/steps/entrypoint.sh`;

The UNITY_SERIAL is set from the ${ImageEnvironmentFactory.getEnvVarString(parameters)} bit from above. It consumes the parameters passed back from Input class.


await Docker.run(baseImage, {
        actionFolder,
        editorVersion,
        workspace,
        projectPath,
        customParameters,
        testMode,
        coverageOptions,
        artifactsPath,
        useHostNetwork,
        sshAgent,
        sshPublicKeysDirectoryPath,
        packageMode,
        packageName,
        scopedRegistryUrl,
        registryScopes,
        gitPrivateToken,
        githubToken,
        chownFilesTo,
        dockerCpuLimit,
        dockerMemoryLimit,
        dockerIsolationMode,
        unityLicensingServer,
        runAsHostUser,
        unitySerial,
        ...runnerContext,
      });

src/main.ts#L46


I should probably see how I can run the JS outside the context of a github action.

aallbrig commented 3 months ago

Opened up a help post on GameCI's discord channel: https://discord.com/channels/710946343828455455/1268225581267550323

aallbrig commented 2 months ago

Investigating chat logs from the GameCI discord I remember seeing a suggestion that '...after activation github actions steps, there is no reason to pass in username/password combination.'

export UNITY_LICENSE=$(cat "/Library/Application Support/Unity/Unity_lic.ulf")
export UNITY_SERIAL=$(echo $UNITY_LICENSE | sed -n 's/.*<SerialMasked Value="\([^"]*\)".*/\1/p')
repo_root=$(git rev-parse --show-toplevel)
unity_version="2021.3.13f1"
base_version="3.1.0"

cat << 'HERE' > /tmp/create-script.sh
unity-editor \
    -logFile /dev/stdout \
    -quit \
    -createProject $(pwd) \
    -serial "$UNITY_SERIAL"
HERE
chmod +x /tmp/create-script.sh
docker run \
  --interactive \
  --platform linux/amd64 \
  --network host \
  --tty \
  --rm \
  --env UNITY_SERIAL \
  --volume "$(mktemp -d):/unity" \
  --workdir /unity \
  --volume "/tmp/create-script.sh:/create-script.sh" \
  "unityci/editor:ubuntu-${unity_version}-base-${base_version}" \
  bash -c '/create-script.sh'
Unity Editor version:    2021.3.13f1 (9e7d58001ecf)
Branch:                  2021.3/staging
Build type:              Release
Batch mode:              YES
System name:             Linux
Distro version:          #1 SMP Thu May 23 08:36:57 UTC 2024
Kernel version:          6.6.31-linuxkit
Architecture:            x86_64
Available memory:        7840 MB
[LicensingClient] Channel doesn't exist: "LicenseClient-root"
[Licensing::Module] Successfully launched the LicensingClient (PId: 35)
[Licensing::Module] Warning: LicensingClient has failed validation; ignoring
[LicensingClient] Handshaking with LicensingClient (version: 1.9.0+249add7)
[Licensing::Module] Successfully connected to LicensingClient on channel: "LicenseClient-root" (connect: 1.27s, validation: 0.16s, handshake: 0.00s)
[Licensing::Module] Connected to LicensingClient (PId: 35, launch time: 0.00, total connection time: 1.43s)
Entitlement-based licensing initiated
[Licensing::Module] Error: Access token is unavailable
[Licensing::Module] Error: Failed to activate entitlement license
[UnityConnectServicesConfig] config is NOT valid, switching to default
Cancelling DisplayDialog: Failed to activate/update license Missing or bad username or password. Please try again using valid credentials or contact support@unity3d.com
This should not be called in batch mode.
Checking for leaked weakptr:
  Found no leaked weakptrs.
Memory Statistics:
[ALLOC_TEMP_TLS] TLS Allocator
  StackAllocators :
    [ALLOC_TEMP_CurlRequest]
      Initial Block Size 64.0 KB
      Current Block Size 64.0 KB
      Peak Allocated Bytes 0 B
      Overflow Count 0
    [ALLOC_TEMP_CoreBusinessMetricsCache]
      Initial Block Size 64.0 KB
      Current Block Size 64.0 KB
      Peak Allocated Bytes 0 B
      Overflow Count 0
    [ALLOC_TEMP_Profiler.Dispatcher]
      Initial Block Size 64.0 KB
      Current Block Size 64.0 KB
      Peak Allocated Bytes 0 B
      Overflow Count 0
    [ALLOC_TEMP_AssetGarbageCollectorHelper] x 11
      Initial Block Size 64.0 KB
      Current Block Size 64.0 KB
      Peak Allocated Bytes 0 B
      Overflow Count 0
[ALLOC_MEMORYPROFILER]
  Requested Block Size 1.0 MB
  Peak Block count 1
  Peak Allocated memory 4.0 KB
  Peak Large allocation bytes 0 B
##utp:{"type":"MemoryLeaks","version":2,"phase":"Immediate","time":1722476597987,"processId":21,"allocatedMemory":114751,"memoryLabels":[{"Default":226},{"Thread":64},{"Manager":7098},{"Serialization":40},{"BaseObject":12216},{"String":5457},{"DynamicArray":432},{"HashMap":3668},{"Utility":1024},{"Curl":1112},{"PoolAlloc":120},{"GI":3248},{"VR":80},{"Secure":19600},{"RestService":1022},{"License":288},{"UnityConnect":29664},{"Collab":25},{"LocalIPC":99},{"ProfilerEditor":20021},{"TLS":8943},{"Licensing":304}]}

The parts that jump out to me:

[Licensing::Module] Error: Access token is unavailable
[Licensing::Module] Error: Failed to activate entitlement license
...
Cancelling DisplayDialog: Failed to activate/update license Missing or bad username or password. Please try again using valid credentials or contact support@unity3d.com

It is implied that user credentials are required.


I've been using my M2 MacBook Pro (MBP)'s generated license and attempting to use that inside the GameCI Unity Editor container. In the previous Unity license flow, the Unity Editor app is used to generate a .alf file. However; the new Unity license flow is managed by the Unity Hub app. Here is the Unity Hub app's command line docs. GameCI has the Hub App as a docker container (Unity Hub GameCI container on Docker Hub).

$ /Applications/Unity\ Hub.app/Contents/MacOS/Unity\ Hub -- --headless help

Global flags:
  --errors     will enable hidden error logging
Commands:
  editors
    description: list the releases and installed editors
    alias: e
    example: Unity\ Hub.app/Contents/MacOS/Unity\ Hub -- --headless editors -r
    options:
      [default]         list of available releases and installed editors on your machine combined
      --releases|-r     only list of available releases promoted by Unity
      --installed|-i    only list of installed editors on your machine
      --add <path>      locating and associating an editor from a stipulated path

  install-path
    description: set/get the path where the Unity editors will be installed
    alias: ip
    example: Unity\ Hub.app/Contents/MacOS/Unity\ Hub -- --headless ip -s /Applications/Unity/Hub/Editor/
    options:
      --set|-s <path>   set the install path to the given path
      --get|-g                  returns the install path

  install
    description:
      installs a new editor either from the releases list or archive
    alias: i
    example: Unity\ Hub.app/Contents/MacOS/Unity\ Hub -- --headless install --version 2019.1.11f1 --changeset 9b001d489a54
    options:
      --version|-v <version>            editor version to be installed (e.g. 2019.1.11f1) - required
      --changeset|-c    <changeset> changeset of the editor if it is not in the release list (e.g. 9b001d489a54)
                    - required if the version is not in the releases. see editors -r
      --module|-m <moduleid>            see install-modules for more information
      --childModules|--cm     automatically installs all child modules of selected modules
      --architecture|-a <architecture>          editor architecture to install (x86_64 or arm64)

  install-modules
    description:
      download and install a module (e.g. build support) to an installed editor
    alias: im
      example: Unity\ Hub.app/Contents/MacOS/Unity\ Hub -- --headless install-modules --version 2019.1.11f1 -m ios android
    options:
      --version|-v <version>    version of the editor to add the module to - required
      --module|-m  <moduleid> the module id. The followings are the available values depending on version. You can specify multiple values, separated by spaces.
            For a full list, please visit https://docs.unity3d.com/hub/manual/HubCLI.html

            Android Build Support: android
            Android SDK & NDK Tools: android-sdk-ndk-tools
            OpenJDK: android-open-jdk
            Visual Studio for Mac: visualstudio
            iOS Build Support: ios
            tvOS Build Support: appletv
            Linux Build Support: linux
            Linux Build Support (Mono): linux-mono
            Linux Build Support (IL2CPP): linux-il2cpp
            Mac Build Support (IL2CPP): mac-il2cpp
            Windows Build Support (Mono): windows-mono
            WebGL Build Support: webgl
            Lumin OS (Magic Leap) Build Support: lumin
            Facebook Gameroom Build Support: facebook-games
            Vuforia Augmented Reality Support: vuforia-ar
            Documentation: documentation
            Language packs: language-ja, language-ko, language-zh-cn, language-zh-hant, language-zh-hans
      --childModules|--cm     automatically installs all child modules of selected modules

Consulted w/ GPT & Claude. Recommends using Unity Editor app still to create .ulf license file.

temp_dir=$(mktemp -d)
unity_version="2021.3.13f1"
base_version="3.1.0"

cat << 'HERE' > /tmp/activate-and-create.sh
unity-editor \
    -batchmode \
    -nographics \
    -quit \
    -logFile /dev/stdout \
    -username "$UNITY_USERNAME" \
    -password "$UNITY_PASSWORD" \
    -createManualActivationFile

unity-editor \
    -batchmode \
    -nographics \
    -quit \
    -logFile /dev/stdout \
    -createProject $(pwd)
HERE
chmod +x /tmp/activate-and-create.sh
docker run \
  --interactive \
  --platform linux/amd64 \
  --network host \
  --tty \
  --rm \
  --env UNITY_USERNAME \
  --env UNITY_PASSWORD \
  --volume "$temp_dir:/unity" \
  --workdir /unity \
  --volume "/tmp/activate-and-create.sh:/activate-and-create.sh" \
  "unityci/editor:ubuntu-${unity_version}-base-${base_version}" \
  bash -c '/activate-and-create.sh'

ls -ll $temp_dir
Unity Editor version:    2021.3.13f1 (9e7d58001ecf)
Branch:                  2021.3/staging
Build type:              Release
Batch mode:              YES
System name:             Linux
Distro version:          #1 SMP Thu May 23 08:36:57 UTC 2024
Kernel version:          6.6.31-linuxkit
Architecture:            x86_64
Available memory:        7840 MB
UnityConnectLoginRequest: Failed to login - please check your username or password
No sufficient permissions while processing request "https://core.cloud.unity3d.com/api/login", HTTP error code 401
.[LicensingClient] Channel doesn't exist: "LicenseClient-root"
[Licensing::Module] Successfully launched the LicensingClient (PId: 37)
[Licensing::Module] Warning: LicensingClient has failed validation; ignoring
[LicensingClient] Handshaking with LicensingClient (version: 1.9.0+249add7)
[Licensing::Module] Successfully connected to LicensingClient on channel: "LicenseClient-root" (connect: 1.01s, validation: 0.15s, handshake: 0.00s)
[Licensing::Module] Connected to LicensingClient (PId: 37, launch time: 0.00, total connection time: 1.16s)
Entitlement-based licensing initiated
[Licensing::Module] Error: Access token is unavailable
[LicensingClient] Licenses updated successfully

 Generating manual activation license file.

LICENSE SYSTEM [202481 2:11:57] License activate file written to: Unity_v2021.3.13f1.alf

 Manual activation license file saved.
Checking for leaked weakptr:
  Found no leaked weakptrs.
Memory Statistics:
[ALLOC_TEMP_TLS] TLS Allocator
  StackAllocators :
    [ALLOC_TEMP_CurlRequest]
      Initial Block Size 64.0 KB
      Current Block Size 64.0 KB
      Peak Allocated Bytes 0 B
      Overflow Count 0
    [ALLOC_TEMP_CoreBusinessMetricsCache]
      Initial Block Size 64.0 KB
      Current Block Size 64.0 KB
      Peak Allocated Bytes 0 B
      Overflow Count 0
    [ALLOC_TEMP_Profiler.Dispatcher]
      Initial Block Size 64.0 KB
      Current Block Size 64.0 KB
      Peak Allocated Bytes 0 B
      Overflow Count 0
    [ALLOC_TEMP_AssetGarbageCollectorHelper] x 11
      Initial Block Size 64.0 KB
      Current Block Size 64.0 KB
      Peak Allocated Bytes 0 B
      Overflow Count 0
[ALLOC_MEMORYPROFILER]
  Requested Block Size 1.0 MB
  Peak Block count 1
  Peak Allocated memory 4.0 KB
  Peak Large allocation bytes 0 B
##utp:{"type":"MemoryLeaks","version":2,"phase":"Immediate","time":1722478317343,"processId":21,"allocatedMemory":87521,"memoryLabels":[{"Default":122},{"Thread":64},{"Manager":7098},{"Serialization":40},{"BaseObject":12216},{"String":6770},{"DynamicArray":432},{"HashMap":3668},{"Utility":1024},{"Curl":1112},{"PoolAlloc":120},{"GI":3248},{"VR":80},{"RestService":1022},{"License":288},{"UnityConnect":29664},{"Collab":25},{"LocalIPC":99},{"ProfilerEditor":20021},{"Licensing":408}]}
Unity Editor version:    2021.3.13f1 (9e7d58001ecf)
Branch:                  2021.3/staging
Build type:              Release
Batch mode:              YES
System name:             Linux
Distro version:          #1 SMP Thu May 23 08:36:57 UTC 2024
Kernel version:          6.6.31-linuxkit
Architecture:            x86_64
Available memory:        7840 MB
[LicensingClient] Channel doesn't exist: "LicenseClient-root"
[Licensing::Module] Successfully launched the LicensingClient (PId: 90)
[Licensing::Module] Warning: LicensingClient has failed validation; ignoring
[LicensingClient] Handshaking with LicensingClient (version: 1.9.0+249add7)
[Licensing::Module] Successfully connected to LicensingClient on channel: "LicenseClient-root" (connect: 1.06s, validation: 0.20s, handshake: 0.00s)
[Licensing::Module] Connected to LicensingClient (PId: 90, launch time: 0.00, total connection time: 1.26s)
Entitlement-based licensing initiated
[Licensing::Module] Error: Access token is unavailable
[LicensingClient] Licenses updated successfully
[UnityConnectServicesConfig] config is NOT valid, switching to default
Cancelling DisplayDialog: Failed to activate/update license Missing or bad username or password. Please try again using valid credentials or contact support@unity3d.com
This should not be called in batch mode.
Checking for leaked weakptr:
  Found no leaked weakptrs.
Memory Statistics:
[ALLOC_TEMP_TLS] TLS Allocator
  StackAllocators :
    [ALLOC_TEMP_CurlRequest]
      Initial Block Size 64.0 KB
      Current Block Size 64.0 KB
      Peak Allocated Bytes 0 B
      Overflow Count 0
    [ALLOC_TEMP_CoreBusinessMetricsCache]
      Initial Block Size 64.0 KB
      Current Block Size 64.0 KB
      Peak Allocated Bytes 0 B
      Overflow Count 0
    [ALLOC_TEMP_Profiler.Dispatcher]
      Initial Block Size 64.0 KB
      Current Block Size 64.0 KB
      Peak Allocated Bytes 0 B
      Overflow Count 0
    [ALLOC_TEMP_AssetGarbageCollectorHelper] x 11
      Initial Block Size 64.0 KB
      Current Block Size 64.0 KB
      Peak Allocated Bytes 0 B
      Overflow Count 0
[ALLOC_MEMORYPROFILER]
  Requested Block Size 1.0 MB
  Peak Block count 1
  Peak Allocated memory 4.0 KB
  Peak Large allocation bytes 0 B
##utp:{"type":"MemoryLeaks","version":2,"phase":"Immediate","time":1722478359948,"processId":76,"allocatedMemory":114751,"memoryLabels":[{"Default":122},{"Thread":64},{"Manager":7098},{"Serialization":40},{"BaseObject":12216},{"String":5457},{"DynamicArray":432},{"HashMap":3668},{"Utility":1024},{"Curl":1112},{"PoolAlloc":120},{"GI":3248},{"VR":80},{"Secure":19600},{"RestService":1022},{"License":288},{"UnityConnect":29664},{"Collab":25},{"LocalIPC":99},{"ProfilerEditor":20021},{"TLS":8943},{"Licensing":408}]}
total 8
-rw-r--r--  1 $USERNAME  staff  860 Jul 31 22:11 Unity_v2021.3.13f1.alf

I see an .alf file but I obviously need the .ulf file.

aallbrig commented 2 months ago

Going to focus on this GameCI repo (game-ci/unity-activate) instead of the GameCI test runner repo (game-ci/unity-test-runner). From dist/entrypoint.sh it looks like there's a couple unity-editor commands; one for personal licenses and one for professional licenses.

# personal
unity-editor \
    -logFile /dev/stdout \
    -quit \
    -manualLicenseFile $FILE_PATH
...
# professional
unity-editor \
    -logFile /dev/stdout \
    -quit \
    -serial "$UNITY_SERIAL" \
    -username "$UNITY_EMAIL" \
    -password "$UNITY_PASSWORD"

Going to try out this command using the entire UNITY_LICENSE file.

export UNITY_LICENSE=$(cat "/Library/Application Support/Unity/Unity_lic.ulf")
unity_version="2021.3.13f1"
base_version="3.1.0"
temp_dir=$(mktemp -d)

cat << 'HERE' > /tmp/activate.sh
FILE_PATH=UnityLicenseFile.ulf

if [[ -n "$UNITY_LICENSE" ]]; then
  # Copy license file from Github variables
  echo "$UNITY_LICENSE" | tr -d '\r' > $FILE_PATH
elif [[ -n "$UNITY_LICENSE_FILE" ]]; then
  # Copy license file from file system
  cat "$UNITY_LICENSE_FILE" | tr -d '\r' > $FILE_PATH
fi
unity-editor \
    -logFile /dev/stdout \
    -quit \
    -manualLicenseFile $FILE_PATH
HERE
chmod +x /tmp/activate.sh

docker run \
  --interactive \
  --platform linux/amd64 \
  --network host \
  --tty \
  --rm \
  --env UNITY_LICENSE \
  --volume "$temp_dir:/unity" \
  --workdir /unity \
  --volume "/tmp/activate.sh:/activate.sh" \
  "unityci/editor:ubuntu-${unity_version}-base-${base_version}" \
  bash -c '/activate.sh'
Unity Editor version:    2021.3.13f1 (9e7d58001ecf)
Branch:                  2021.3/staging
Build type:              Release
Batch mode:              YES
System name:             Linux
Distro version:          #1 SMP Thu May 23 08:36:57 UTC 2024
Kernel version:          6.6.31-linuxkit
Architecture:            x86_64
Available memory:        7840 MB
[LicensingClient] Channel doesn't exist: "LicenseClient-root"
[Licensing::Module] Successfully launched the LicensingClient (PId: 37)
[Licensing::Module] Warning: LicensingClient has failed validation; ignoring
[LicensingClient] Handshaking with LicensingClient (version: 1.9.0+249add7)
[Licensing::Module] Successfully connected to LicensingClient on channel: "LicenseClient-root" (connect: 1.01s, validation: 0.19s, handshake: 0.00s)
[Licensing::Module] Connected to LicensingClient (PId: 37, launch time: 0.00, total connection time: 1.20s)
Entitlement-based licensing initiated
[Licensing::Module] Error: Access token is unavailable
[LicensingClient] Licenses updated successfully

 Load manual activation license file.

LICENSE SYSTEM [202481 11:21:51] Load license file from: UnityLicenseFile.ulf

LICENSE SYSTEM [202481 11:21:51] Next license update check is after 2024-08-02T02:36:41

LICENSE SYSTEM [202481 11:21:51] Machine binding 1 mismatch: (value of current machine) 576562626572264761624c65526f7578 != 527236A0-0965-578E-977F-D206EDEFB215 (value in license file). Reason might be there is a hardware change on this machine after the license was activated.

LICENSE SYSTEM [202481 11:21:51] Machine binding 2 mismatch: (value of current machine) 576562626572264761624c65526f7578 != RQFG6M9KVY (value in license file). Reason might be there is a hardware change on this machine after the license was activated.

LICENSE SYSTEM [202481 11:21:51] Machine identification is invalid for current license.

 License file loaded.

export UNITY_LICENSE=$(cat "/Library/Application Support/Unity/Unity_lic.ulf")

echo "UNITY_SERIAL (normal): $(echo "$UNITY_LICENSE" | sed -n 's/.*<DeveloperData Value="\([^"]*\)".*/\1/p' | base64 -D)"
# 
echo "UNITY_SERIAL (with 'junk taken off'): $(echo "$UNITY_LICENSE" | sed -n 's/.*<DeveloperData Value="\([^"]*\)".*/\1/p' | base64 -D | dd bs=1 skip=4 2>/dev/null)"

Re-reading https://game.ci/docs/github/activation I see that indeed one is encouraged to generate this .ulf license file on one's local developer machine (either osx, windows, linux) and then run it through a GameCI container. I'm inspired to revoke my personal license and then re-request it, just to see if that helps? Revoked it and now Unity Hub is on the fritz (lol). Restarting laptop.

No dice, even when I recycle my license I get the same "machine mismatch" error.


Starting to think that maybe the bash script proposed in the original issue text might be the quicker way to generating value for the project 😓 . Curses that running Unity project tests as a docker command isn't straight forward shakes fist in air .

aallbrig commented 2 months ago

Drafted up a bash script that uses the "native" installed Unity Editor app to run tests instead of going through the container image -- check it out here: https://github.com/googleforgames/agones/pull/3931

I still want to run these tests through a container image. Will probably want some help because I'm getting stuck. Maybe splunking the GameCI discord history more thoroughly may reveal more information.

aallbrig commented 1 month ago

I'm no longer interested in Unity at all. Maybe this issue helps someone in the future. If this is something relevant to your work I just have to say: good luck 🫡