Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions .yamato/_triggers.yml
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,8 @@ pr_code_changes_checks:
# Coverage on other standalone machines is present in Nightly job so it's enough to not run all of them for PRs
# desktop_standalone_test and cmb_service_standalone_test are both reusing desktop_standalone_build dependency so we run those in the same configuration on PRs to reduce waiting time.
# Note that our daily tests will anyway run both test configurations in "minimal supported" and "trunk" configurations

# TODO: Move these tests back to trunk once CMB Service has addressed https://jira.unity3d.com/browse/MTTB-1680
- .yamato/desktop-standalone-tests.yml#desktop_standalone_test_testproject_ubuntu_il2cpp_6000.4
- .yamato/cmb-service-standalone-tests.yml#cmb_service_standalone_test_testproject_ubuntu_il2cpp_6000.4
- .yamato/desktop-standalone-tests.yml#desktop_standalone_test_testproject_ubuntu_il2cpp_trunk
- .yamato/cmb-service-standalone-tests.yml#cmb_service_standalone_test_testproject_ubuntu_il2cpp_trunk
triggers:
expression: |-
(pull_request.comment eq "ngo" OR
Expand Down
2 changes: 1 addition & 1 deletion .yamato/cmb-service-standalone-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ cmb_service_standalone_test_{{ project.name }}_{{ platform.name }}_{{ backend }}

commands:
# run_cmb_service.sh builds and starts a release version of the full CMB service (along with the limited echo server)
- ./Tools/CI/service.cmb/run_cmb_service.sh -e $ECHO_SERVER_PORT -s $CMB_SERVICE_PORT
- ./Tools/CI/service.cmb/run_cmb_service.sh -e $ECHO_SERVER_PORT -s $CMB_SERVICE_PORT -l artifacts

- unity-downloader-cli --fast --wait -u {{ editor }} -c Editor {% if backend == "il2cpp" %} -c il2cpp {% endif %} {% if platform.name == "mac" %} --arch arm64 {% endif %} # For macOS we use ARM64 models
- UnifiedTestRunner --suite=playmode --player-load-path=build/players --artifacts-path=test-results --testproject={{ project.path }} --editor-location=.Editor --playergraphicsapi=Null --fail-on-assert --rerun-strategy=Test --retry={{ num_test_retries }} --clean-library-on-rerun --timeout={{ test_timeout }}
Expand Down
2 changes: 1 addition & 1 deletion .yamato/console-standalone-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ console_standalone_build_{{ project.name }}_{{ platform.name }}_{{ editor }}:
agent:
type: {{ platform.type }}
image: {{ platform.image }}
flavor: {{ platform.flavor }}
flavor: {{ platform.larger_flavor }}
{% if platform.model %}
model: {{ platform.model }} # This is set only in platforms where we want non-default model to use (more information in project.metafile)
{% endif %}
Expand Down
2 changes: 1 addition & 1 deletion .yamato/desktop-standalone-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ desktop_standalone_build_{{ project.name }}_{{ platform.name }}_{{ backend }}_{{
agent:
type: {% if platform.name == "mac" %} {{ platform.type }} {% else %} {{ platform.type }} {% endif %}
image: {{ platform.image }}
flavor: {{ platform.flavor }}
flavor: {{ platform.larger_flavor }}
{% if platform.name == "mac" %}
model: {{ platform.model }} # This is set only in platforms where we want non-default model to use (more information in project.metafile)
{% endif %}
Expand Down
2 changes: 1 addition & 1 deletion .yamato/mobile-standalone-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ mobile_standalone_build_{{ project.name }}_{{ platform.name }}_{{ editor }}:
agent:
type: {{ platform.type }}
image: {{ platform.image }}
flavor: {{ platform.flavor }}
flavor: {{ platform.larger_flavor }}
{% if platform.model %}
model: {{ platform.model }} # This is set only in platforms where we want non-default model to use (more information in project.metafile)
{% endif %}
Expand Down
20 changes: 19 additions & 1 deletion .yamato/project.metafile
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
# image --> Defines the package-ci Bokken image to use for the environment (e.g., package-ci/ubuntu-22.04:v4). This is basically a device configuration
# flavor --> Determines the VM size/resources (e.g., b1.small, b1.large, m1.mac)
# smaller_flavor --> An override for flavor that determines the VM size/resources for lighter weight jobs that can run on a smaller vm
# larger_flavor --> An override for flavor that determines the VM size/resources for heavier weight jobs that can need a bigger vm
# standalone --> Specifies the build target platform (e.g., StandaloneLinux64, Android, IOS)
# model --> Defines specific hardware model requirements (e.g., rtx2080, iPhone model 13). Notice that trunk currently (19.08.2025) has 13.0 as minimal iOS version which devices below this are not supporting
# base --> Indicates the base operating system for build operations (e.g., win, mac)
Expand Down Expand Up @@ -47,20 +48,24 @@ test_platforms:
image: package-ci/ubuntu-22.04:v4.77.0
flavor: b1.large
smaller_flavor: b1.medium
larger_flavor: b1.xlarge
standalone: StandaloneLinux64
model: rtx2080
- name: win
type: Unity::VM
image: package-ci/win10:v4
flavor: b1.large
smaller_flavor: b1.medium
larger_flavor: b1.xlarge
standalone: StandaloneWindows64
model: rtx2080
- name: mac
type: Unity::VM::osx
image: package-ci/macos-13-arm64:v4 # ARM64 to support M1 model (below)
flavor: m1.mac
smaller_flavor: m1.mac # mac doesn't have a smaller vm size. We define it anyway as it simplifies the yaml templating to have it defined.
# mac doesn't have a different vm sizes. We define it anyway as it simplifies the yaml templating to have it defined.
smaller_flavor: m1.mac
larger_flavor: m1.mac
standalone: StandaloneOSX
model: M1 # The default model (an x64 Intel Mac VM) quite often caused a known issue of doing all the bitflips in packages resulting in failures
# For mobile devices there is a split between the build and run phase so there is a need of splitting specification for both
Expand All @@ -70,6 +75,7 @@ test_platforms:
type: Unity::VM
image: package-ci/win10:v4
flavor: b1.large
larger_flavor: b1.xlarge
standalone: Android
base: win
architecture: armv7
Expand All @@ -86,13 +92,15 @@ test_platforms:
type: Unity::mobile::shield
image: package-ci/win10:v4
flavor: b1.large
larger_flavor: b1.xlarge
standalone: Android
base: win
architecture: armv7
- name: ios-arm64
type: Unity::mobile::iPhone
image: package-ci/macos-13-arm64:v4
flavor: m1.mac
larger_flavor: m1.mac
model: 13
standalone: IOS
base: mac
Expand All @@ -102,53 +110,63 @@ test_platforms:
type: Unity::VM
image: package-ci/win10-ps4:v4
flavor: b1.large
larger_flavor: b1.xlarge
standalone: PS4
# - name: ps5 --> SEE MTT-12118
# type: Unity::VM
# image: package-ci/win10-ps5:v4
# flavor: b1.large
# larger_flavor: b1.xlarge
# standalone: PS5
- name: switch
type: Unity::VM
image: package-ci/win10-switch:v4
flavor: b1.large
larger_flavor: b1.xlarge
standalone: Switch
- name: GameCoreXboxOne
type: Unity::VM
image: package-ci/win10-xbox:v4
flavor: b1.large
larger_flavor: b1.xlarge
standalone: GameCoreXboxOne
- name: GameCoreScarlett
type: Unity::VM
image: package-ci/win10-xbox:v4
flavor: b1.large
larger_flavor: b1.xlarge
standalone: GameCoreScarlett
console_test:
- name: ps4
type: Unity::console::ps4
image: package-ci/win10-ps4:v4
flavor: b1.large
larger_flavor: b1.xlarge
standalone: PS4
#- name: ps5 --> SEE MTT-12118
# type: Unity::console::ps5
# image: package-ci/win10-ps5:v4
# flavor: b1.large
# larger_flavor: b1.xlarge
# standalone: PS5
- name: switch
type: Unity::console::switch
image: package-ci/win10-switch:v4
flavor: b1.large
larger_flavor: b1.xlarge
standalone: Switch
base: win
- name: GameCoreXboxOne
type: Unity::console::xbox
image: package-ci/win10-xbox:v4
flavor: b1.large
larger_flavor: b1.xlarge
standalone: GameCoreXboxOne
- name: GameCoreScarlett
type: Unity::console::scarlett
image: package-ci/win10-xbox:v4
flavor: b1.large
larger_flavor: b1.xlarge
standalone: GameCoreScarlett

# EDITOR CONFIGURATIONS-------------------------------------------------------------------------------
Expand Down
22 changes: 20 additions & 2 deletions Tools/CI/service.cmb/run_cmb_service.sh
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,11 @@ ERROR="Error: Expected ports to be defined! Example script usage:"
EXAMPLE="run_cmb_service.sh -e <echo-server-port> -s <cmb-service-port>"

# get arguments passed to the script
while getopts 'e:s:' flag; do
while getopts 'e:s:l:' flag; do
case "${flag}" in
e) echo_port="${OPTARG}" ;;
s) service_port="${OPTARG}" ;;
l) build_logs="${OPTARG}" ;;
*) printf "%s\n" "$ERROR" "$EXAMPLE"
exit 1 ;;
esac
Expand Down Expand Up @@ -89,6 +90,21 @@ logError(){
printf "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"
}

# Unity Version -----------------------------------------------------------------

# This is the path to the logs from the standalone build job
FILE="$build_logs/TestResults.js"

unity_version=$(sed -n 's/.*"editorVersion": *"\([^" (]*\).*/\1/p' $FILE)

# ensure arguments were passed and the ports are defined
if [ -z "$unity_version" ]; then
logMessage "Failed to find unity version! Exiting...";
exit 1;
else
logMessage "Found Unity version: $unity_version";
fi

# Protocol Buffer Compiler ------------------------------------------------------

# Apply any updates
Expand Down Expand Up @@ -152,6 +168,8 @@ cargo build --release --locked
# The infinite loop is required as the service will exit each time all connected clients disconnect.
# This means the service will exit after each test. The infinite loop will immediately restart the service each time it exits.
logMessage "Running service integration tests..."
echo "comb-server -l error --metrics-port 5000 standalone --port $service_port -t 60m --unity-version $unity_version"

while :; do
./target/release/comb-server -l error --metrics-port 5000 standalone --port $service_port -t 60m;
./target/release/comb-server -l error --metrics-port 5000 standalone --port $service_port -t 60m --unity-version $unity_version;
done & # <- use & to run the entire loop in the background
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,6 @@ public RpcInvocationTests(NetworkTopologyTypes topologyType) : base(topologyType

private Dictionary<NetworkManager, InvokePermissionBehaviour> m_InvokeInstances = new();

// TODO: [CmbServiceTests] Enable once the CMB service fixes the client spoofing issue.
protected override bool UseCMBService() => false;

protected override void OnServerAndClientsCreated()
{
m_Prefab = CreateNetworkObjectPrefab("RpcInvokePermissionTest");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,25 @@

namespace TestProject.RuntimeTests
{
[TestFixture(NetworkTopologyTypes.ClientServer)]
[TestFixture(NetworkTopologyTypes.DistributedAuthority)]
public class SceneObjectsNotDestroyedOnShutdownTest : NetcodeIntegrationTest
{
protected override int NumberOfClients => 0;

private const string k_TestScene = "InSceneNetworkObject";
private const string k_SceneObjectName = "InSceneObject";
private Scene m_TestScene;
private WaitForSeconds m_DefaultWaitForTick = new WaitForSeconds(1.0f / 30);
private WaitForSeconds m_DefaultWaitForTick = new(1.0f / 30);

// TODO: [CmbServiceTests] Adapt to run with the service
protected override bool UseCMBService()
{
return false;
}
public SceneObjectsNotDestroyedOnShutdownTest(NetworkTopologyTypes topology) : base(topology) { }

[UnityTest]
public IEnumerator SceneObjectsNotDestroyedOnShutdown()
{
m_ServerNetworkManager.SceneManager.OnSceneEvent += SceneManager_OnSceneEvent;
m_ServerNetworkManager.SceneManager.LoadScene(k_TestScene, LoadSceneMode.Additive);
var authority = GetAuthorityNetworkManager();
authority.SceneManager.OnSceneEvent += SceneManager_OnSceneEvent;
authority.SceneManager.LoadScene(k_TestScene, LoadSceneMode.Additive);

yield return WaitForConditionOrTimeOut(() => m_TestScene.IsValid() && m_TestScene.isLoaded);
AssertOnTimeout($"Timed out waiting for scene {k_TestScene} to load!");
Expand All @@ -38,11 +37,12 @@ public IEnumerator SceneObjectsNotDestroyedOnShutdown()

AssertOnTimeout($"Timed out waiting to find {k_SceneObjectName} after scene load and before starting client!\"");

yield return CreateAndStartNewClient();
var lateJoin = CreateNewClient();
yield return StartClient(lateJoin);

var loadedInSceneObjects = Object.FindObjectsByType<NetworkObject>(FindObjectsSortMode.InstanceID).Where((c) => c.name.Contains(k_SceneObjectName));
Assert.IsTrue(loadedInSceneObjects.Count() > 1, $"Only found one instance of {k_SceneObjectName} after client connected!");
m_ClientNetworkManagers[0].Shutdown();
lateJoin.Shutdown();
yield return m_DefaultWaitForTick;
loadedInSceneObjects = Object.FindObjectsByType<NetworkObject>(FindObjectsSortMode.InstanceID).Where((c) => c.name.Contains(k_SceneObjectName));

Expand All @@ -52,36 +52,39 @@ public IEnumerator SceneObjectsNotDestroyedOnShutdown()
[UnityTest]
public IEnumerator ChildSceneObjectsDoNotDestroyOnShutdown()
{
m_ServerNetworkManager.SceneManager.OnSceneEvent += SceneManager_OnSceneEvent;
m_ServerNetworkManager.SceneManager.LoadScene(k_TestScene, LoadSceneMode.Additive);
var authority = GetAuthorityNetworkManager();
authority.SceneManager.OnSceneEvent += SceneManager_OnSceneEvent;
authority.SceneManager.LoadScene(k_TestScene, LoadSceneMode.Additive);

yield return WaitForConditionOrTimeOut(() => m_TestScene.IsValid() && m_TestScene.isLoaded);
AssertOnTimeout($"Timed out waiting for scene {k_TestScene} to load!");

var loadedInSceneObject = Object.FindObjectsByType<NetworkObject>(FindObjectsSortMode.InstanceID).Where((c) => c.name.Contains(k_SceneObjectName)).FirstOrDefault();
Assert.IsNotNull(loadedInSceneObject, $"Failed to find {k_SceneObjectName} before starting client!");
yield return CreateAndStartNewClient();

var clientId = m_ClientNetworkManagers[0].LocalClientId;
Assert.IsTrue(loadedInSceneObject.TrySetParent(m_PlayerNetworkObjects[0][clientId]), $"Failed to parent in-scene object under client player");
var lateJoin = CreateNewClient();
yield return StartClient(lateJoin);

var clientId = lateJoin.LocalClientId;
Assert.IsTrue(loadedInSceneObject.TrySetParent(m_PlayerNetworkObjects[authority.LocalClientId][clientId]), $"Failed to parent in-scene object under client player");

yield return WaitForConditionOrTimeOut(() => PlayerHasChildren(clientId));
AssertOnTimeout($"Client-{clientId} player never parented {k_SceneObjectName}!");

var loadedInSceneObjects = Object.FindObjectsByType<NetworkObject>(FindObjectsSortMode.InstanceID).Where((c) => c.name.Contains(k_SceneObjectName));
Assert.IsTrue(loadedInSceneObjects.Count() > 1, $"Only found one instance of {k_SceneObjectName} after client connected!");
m_ClientNetworkManagers[0].Shutdown();
lateJoin.Shutdown();
yield return m_DefaultWaitForTick;

// Sanity check to make sure the client's player no longer has any children
yield return WaitForConditionOrTimeOut(() => PlayerNoLongerExistsWithChildren(clientId));
AssertOnTimeout($"Client-{clientId} player still exits with children after client shutdown!");

loadedInSceneObjects = Object.FindObjectsByType<NetworkObject>(FindObjectsSortMode.InstanceID).Where((c) => c.name.Contains(k_SceneObjectName));
loadedInSceneObjects = Object.FindObjectsByType<NetworkObject>(FindObjectsSortMode.InstanceID).Where(o => o.name.Contains(k_SceneObjectName)).ToArray();
// Make sure any in-scene placed NetworkObject instantiated has no parent
foreach (var insceneObject in loadedInSceneObjects)
foreach (var inSceneObject in loadedInSceneObjects)
{
Assert.IsTrue(insceneObject.transform.parent == null, $"{insceneObject.name} is still parented!");
Assert.IsTrue(inSceneObject.transform.parent == null, $"{inSceneObject.name} is still parented!");
}

// We should have exactly 2 in-scene placed NetworkObjects remaining:
Expand All @@ -100,16 +103,17 @@ private bool PlayerHasChildren(ulong clientId)

private bool PlayerNoLongerExistsWithChildren(ulong clientId)
{
if (m_PlayerNetworkObjects[0].ContainsKey(clientId) && m_PlayerNetworkObjects[0][clientId] != null)
var authorityId = GetAuthorityNetworkManager().LocalClientId;
if (m_PlayerNetworkObjects[authorityId].ContainsKey(clientId) && m_PlayerNetworkObjects[authorityId][clientId] != null)
{
return m_PlayerNetworkObjects[0][clientId].transform.childCount == 0;
return m_PlayerNetworkObjects[authorityId][clientId].transform.childCount == 0;
}
return true;
}

private void SceneManager_OnSceneEvent(SceneEvent sceneEvent)
{
if (sceneEvent.ClientId != m_ServerNetworkManager.LocalClientId)
if (sceneEvent.ClientId != GetAuthorityNetworkManager().LocalClientId)
{
return;
}
Expand Down
11 changes: 0 additions & 11 deletions testproject/Assets/Tests/Runtime/SenderIdTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,13 @@

namespace TestProject.RuntimeTests
{

[TestFixture(NetworkTopologyTypes.DistributedAuthority)]
[TestFixture(NetworkTopologyTypes.ClientServer)]
public class SenderIdTests : NetcodeIntegrationTest
{
protected override int NumberOfClients => 2;

// TODO: [CmbServiceTests] Adapt to run with the service
protected override bool UseCMBService()
{
return false;
}

private NetworkManager FirstClient => m_ClientNetworkManagers[0];
private NetworkManager SecondClient => m_ClientNetworkManagers[1];

public SenderIdTests(NetworkTopologyTypes networkTopologyType) : base(networkTopologyType) { }

[UnityTest]
public IEnumerator WhenSendingMessageFromServerToClient_SenderIdIsCorrect()
{
Expand Down
Loading