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
15 changes: 15 additions & 0 deletions .yamato/_run-all.yml
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,21 @@ run_all_project_tests_console_standalone_default:
{% endfor -%}


# Runs all unified (NGO + N4E) tests
# These run on their own pinned editor (unified_editors) rather than the validation_editors, because
# they need an editor that bundles a com.unity.netcode with the unified API. See unified-tests.yml.
run_all_unified_tests:
name: Run All Unified Tests
dependencies:
{% for project in projects.default -%}
{% for platform in unified_test_platforms -%}
{% for editor in unified_editors.default -%}
- .yamato/unified-tests.yml#unified_test_{{ project.name }}_{{ platform.name }}_{{ editor }}
{% endfor -%}
{% endfor -%}
{% endfor -%}


# Runs all CMB service tests
run_all_project_tests_cmb_service:
name: Run All CMB Service Tests
Expand Down
17 changes: 17 additions & 0 deletions .yamato/_triggers.yml
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ pr_code_changes_checks:
# Note that our daily tests will anyway run both test configurations in "minimal supported" and "trunk" configurations
- .yamato/desktop-standalone-tests.yml#desktop_standalone_test_testproject_ubuntu_il2cpp_{{ pinnedTrunk }}
- .yamato/cmb-service-standalone-tests.yml#cmb_service_standalone_test_testproject_ubuntu_il2cpp_{{ pinnedTrunk }}
- .yamato/_run-all.yml#run_all_unified_tests

# Run code coverage test (PRs use the pinned "safe" trunk)
- .yamato/code-coverage.yml#code_coverage_project_test_testproject_ubuntu_{{ pinnedTrunk }}
triggers:
Expand Down Expand Up @@ -120,6 +122,19 @@ pr_code_changes_checks:



# Unified (NGO + N4E) validation, on demand.
# This job allows the Unified tests to be kicked off by commenting "/ci unified".
# This is useful for PRs where pr_code_changes_checks doesn't trigger.
unified_pr_checks:
name: Unified (NGO + N4E) checks [on demand]
dependencies:
- .yamato/_run-all.yml#run_all_unified_tests
triggers:
expression: |-
pull_request.comment eq "unified"
cancel_old_ci: true


# Run all tests on nightly basis.
# Same subset as pull_request_trigger with addition of mobile/desktop/console tests and webgl builds
# Those tests are all running on trunk and the default editor (since it's daily and running all of them would add a lot of overhead)
Expand Down Expand Up @@ -156,6 +171,8 @@ develop_nightly:
# Run Runtime tests against cmb service on trunk and default editors
- .yamato/_run-all.yml#run_all_project_tests_cmb_service_trunk
- .yamato/_run-all.yml#run_all_project_tests_cmb_service_default
# Run the unified (NGO + N4E) tests on their own pinned editor (see .yamato/unified-tests.yml)
- .yamato/_run-all.yml#run_all_unified_tests
# Build player for webgl platform on trunk and default editors
- .yamato/project-updated-dependencies-test.yml#updated-dependencies_testproject_NGO_ubuntu_trunk
- .yamato/project-updated-dependencies-test.yml#updated-dependencies_testproject_NGO_win_{{ validation_editors.default }}
Expand Down
30 changes: 30 additions & 0 deletions .yamato/project.metafile
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,36 @@ validation_editors:
pinnedTrunk: 5fe7931aab8c4fff9274e15ef0800125c68b8d6a


# UNIFIED (NGO + N4E) CONFIGURATION---------------------------------------------------------------------
# The unified test job validates NGO running against Netcode for Entities (N4E) through the unified API.
# It is deliberately kept separate from every other job in this repo because it needs an editor that
# bundles com.unity.netcode with the unified API, and that editor is NOT one of the validation_editors.
#
# WHY THIS IS PINNED TO 6000.7.0a5 (and not 6000.7.0a2):
# UnifiedNetcodeTransport is compiled behind "#if UNIFIED_NETCODE && OUT_OF_BAND_RPC" and needs the
# N4E out-of-band RPC API (IOutOfBandRpcCommand / OutgoingOutOfBandRpcDataStreamBuffer).
# Both 6000.7.0a2 and 6000.7.0a5 bundle com.unity.netcode 6.7.0, but that API only landed in the a5
# snapshot. On a2 the unified transport does not compile, so the unified tests cannot run there.
# Bump this pin (and unified_netcode_version below) together whenever the required N4E API moves.
#
# An explicit alpha version is used instead of a trunk revision hash because published alphas are
# already immutable, so there is nothing to pin against.
unified_editors:
default:
- 6000.7.0a5

# Version of com.unity.netcode (N4E) bundled with unified_editors.default.
# It resolves as a "builtin" package out of the editor install, so it must match the editor exactly.
unified_netcode_version: 6.7.0

# The unified job runs in Editor context only, so a single fast platform is enough.
unified_test_platforms:
- name: ubuntu
type: Unity::VM
image: package-ci/ubuntu-22.04:v4.87.0
flavor: b1.large


# Scripting backends used by Standalone RunTimeTests---------------------------------------------------

scripting_backends:
Expand Down
55 changes: 55 additions & 0 deletions .yamato/unified-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
{% metadata_file .yamato/project.metafile %} # All configuration that is used to create different configurations (used in for loops) is taken from this file.
---

# DESCRIPTION--------------------------------------------------------------------------
# The NGO job that runs unified netcode hybrid prefab based integration tests.

# CONFIGURATION STRUCTURE--------------------------------------------------------------
# Jobs are generated using nested loops:
# 1. For all unified test platforms (currently Ubuntu only, see project.metafile)
# 2. For all unified editors (currently a single pinned alpha, see project.metafile)

# QUALITY CONSIDERATIONS--------------------------------------------------------------------
# TODO: the manifest swap means testproject/Packages/manifest-unified.json has to be kept in sync
# with manifest.json by hand. Revisit once N4E is a hard dependency of NGO and one manifest
# can cover both cases.

#------------------------------------------------------------------------------------

{% for project in projects.default -%}
{% for platform in unified_test_platforms -%}
{% for editor in unified_editors.default -%}
unified_test_{{ project.name }}_{{ platform.name }}_{{ editor }}:
name : Unified Test - NGO {{ project.name }} [{{ platform.name }}, {{ editor }}]
agent:
type: {{ platform.type }}
image: {{ platform.image }}
flavor: {{ platform.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 %}

variables:
# When UNIFIED_TESTS is set, only integration tests that opt in via overriding NetcodeIntegrationTest.UseUnifiedTests and returning true will run during this job.
# NetcodeIntegrationTest.UseUnifiedTests defaults to returning false (for now) making this an opt-in mode.
# Note: If USE_CMB_SERVICE is set along with UNIFIED_TESTS, then UNIFIED_TESTS is ignored until distributed authority is supported.
UNIFIED_TESTS: "true"

commands:
# Swap in the manifest that has the unified packages and versions required.
# Without the N4E package, UNIFIED_NETCODE is undefined and the unified API excluded.
- cp {{ project.path }}/Packages/manifest-unified.json {{ project.path }}/Packages/manifest.json
# Remove the committed lock as it is configured for 6000.6 which does not contain the unified API required.
- rm -f {{ project.path }}/Packages/packages-lock.json

- unity-downloader-cli --fast --wait -u {{ editor }} -c Editor
- UnifiedTestRunner --testproject={{ project.path }} --suite=playmode --artifacts-path=test-results --editor-location=.Editor --rerun-strategy=Test --retry={{ num_test_retries }} --clean-library-on-rerun --timeout={{ test_timeout }}
artifacts:
logs:
paths:
- "test-results/**/*"
dependencies:
- .yamato/_run-all.yml#run_quick_checks
{% endfor -%}
{% endfor -%}
{% endfor -%}
Original file line number Diff line number Diff line change
Expand Up @@ -1412,12 +1412,12 @@ private bool UnifiedIsConfiguredCorrectly()
{
if (NetCodeConfig.Global == null)
{
Log.Error(new Context(LogLevel.Error, "You must create a {nameof(NetCodeConfig)} and set it to a single world in order to run in hybrid mode!").AddTag("Unified"));
Log.Error(new Context(LogLevel.Error, $"You must create a {nameof(NetCodeConfig)} and set it to a single world in order to run in hybrid mode!").AddTag("Unified"));
return false;
}
if (NetCodeConfig.Global.HostWorldModeSelection != NetCodeConfig.HostWorldMode.SingleWorld)
{
Log.Error(new Context(LogLevel.Error, "You must configure {nameof(NetCodeConfig)} to only use a single world in order to run in hybrid mode!").AddTag("Unified"));
Log.Error(new Context(LogLevel.Error, $"You must configure {nameof(NetCodeConfig)} to only use a single world in order to run in hybrid mode!").AddTag("Unified"));
return false;
}
return true;
Expand Down
11 changes: 11 additions & 0 deletions com.unity.netcode.gameobjects/Runtime/Core/NetworkObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3968,6 +3968,17 @@ private void Start()

private void InitGhost()
{
// Note: If hybrid prefabs are created prior to any NetworkManager instances,
// then the next line throws and exception. This avoids that issue.
// We might come up with some global way to verify if we are running integration
// tests and add additional logic within to determine if we should log an error
// or not.
if (NetworkManager == null)
{
return;
}


if (!NetworkManager.IsListening)
{
if (NetworkManager.LogLevel == LogLevel.Developer)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,10 +124,11 @@ public void OnUpdate(ref SystemState state)
[UpdateBefore(typeof(RpcSystem))]
internal partial class UnifiedNetcodeUpdateSystem : SystemBase
{
public void OnCreate(ref SystemState state)
protected override void OnCreate()
{
state.RequireForUpdate<RpcCollection>();
state.RequireForUpdate<NetworkId>();
RequireForUpdate<RpcCollection>();
RequireForUpdate<NetworkId>();
base.OnCreate();
}

public UnifiedNetcodeTransport Transport;
Expand Down Expand Up @@ -155,6 +156,11 @@ public void SendRpc(TransportRpc rpc, Entity connectionEntity)

protected override void OnUpdate()
{
if (NetworkManager == null || Transport == null)
{
return;
}

NetworkManager.MessageManager.ProcessSendQueues();

using var commandBuffer = new EntityCommandBuffer(Allocator.Temp);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ public void OneTimeSetup()
{
// TODO: [CmbServiceTests] if this test is deemed needed to test against the CMB server then update this test.
NetcodeIntegrationTestHelpers.IgnoreIfServiceEnviromentVariableSet();
// Excluding from unified tests. If deemed needed, update test, then remove.
NetcodeIntegrationTestHelpers.IgnoreIfUnifiedTestsEnvironmentVariableSet();
}

[SetUp]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ public void OneTimeSetup()
{
// TODO: [CmbServiceTests] if this test is deemed needed to test against the CMB server then update this test.
NetcodeIntegrationTestHelpers.IgnoreIfServiceEnviromentVariableSet();
// Excluding from unified tests. If deemed needed, update test, then remove.
NetcodeIntegrationTestHelpers.IgnoreIfUnifiedTestsEnvironmentVariableSet();
}

[Test]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ public void OneTimeSetup()
{
// This test does not need to run against the Rust server.
NetcodeIntegrationTestHelpers.IgnoreIfServiceEnviromentVariableSet();
// Excluding from unified tests. If deemed needed, update test, then remove.
NetcodeIntegrationTestHelpers.IgnoreIfUnifiedTestsEnvironmentVariableSet();
}

[Test]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ public void OneTimeSetup()
{
// TODO: [CmbServiceTests] if this test is deemed needed to test against the CMB server then update this test.
NetcodeIntegrationTestHelpers.IgnoreIfServiceEnviromentVariableSet();
// Excluding from unified tests. If deemed needed, update test, then remove.
NetcodeIntegrationTestHelpers.IgnoreIfUnifiedTestsEnvironmentVariableSet();
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ public void OneTimeSetup()
{
// This test does not need to run against the Rust server.
NetcodeIntegrationTestHelpers.IgnoreIfServiceEnviromentVariableSet();
// Excluding from unified tests. If deemed needed, update test, then remove.
NetcodeIntegrationTestHelpers.IgnoreIfUnifiedTestsEnvironmentVariableSet();
}

[Test]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ public void OneTimeSetup()
{
// This test does not need to run against the Rust server.
NetcodeIntegrationTestHelpers.IgnoreIfServiceEnviromentVariableSet();
// Excluding from unified tests. If deemed needed, update test, then remove.
NetcodeIntegrationTestHelpers.IgnoreIfUnifiedTestsEnvironmentVariableSet();
}

[Test]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ namespace Unity.Netcode.RuntimeTests
{
// These tests do not need to run against the Rust server.
[IgnoreIfServiceEnvironmentVariableSet]
// These tests do not exercise hybrid prefabs.
[IgnoreIfUnifiedTestsEnvironmentVariableSet]
internal class NetworkTransformStateTests
{
[Test]
Expand Down Expand Up @@ -199,6 +201,8 @@ private void AssertTransformStateEquals(bool[] expected, NetworkTransformState a

// These tests do not need to run against the Rust server.
[IgnoreIfServiceEnvironmentVariableSet]
// These tests do not exercise hybrid prefabs.
[IgnoreIfUnifiedTestsEnvironmentVariableSet]
[TestFixture(TransformSpace.World, Precision.Full, Rotation.Euler)]
[TestFixture(TransformSpace.World, Precision.Half, Rotation.Euler)]
[TestFixture(TransformSpace.Local, Precision.Full, Rotation.Euler)]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#if UNIFIED_NETCODE
using System.Collections;
using System.Text;
using NUnit.Framework;
using Unity.Netcode.Components;
using Unity.Netcode.TestHelpers.Runtime;
Expand Down Expand Up @@ -39,6 +40,12 @@ public UnifiedNetworkTransformTest(HostOrServer hostOrServer) : base(hostOrServe
{
}

// This is the validation test for the unified API, so it always runs during a unified test pass.
protected override bool UseUnifiedTests()
{
return true;
}

protected override bool OnSetVerboseDebug()
{
return false;
Expand All @@ -52,38 +59,45 @@ protected override IEnumerator OnSetup()
return base.OnSetup();
}

private bool ValidatePosition(StringBuilder errorLog)
{
var authorityPosition = m_AuthorityInstanceTransform.position;
foreach (var client in m_ClientNetworkManagers)
{
var instancePosition = client.SpawnManager.SpawnedObjects[m_Instance.NetworkObjectId].transform.position;
if (!Approximately(authorityPosition, instancePosition))
{
errorLog.AppendLine($"[Client-{client.LocalClientId}] Clone instance position {GetVector3Values(instancePosition)} " +
$"does not equal the authority's {GetVector3Values(authorityPosition)}");
}
}
return errorLog.Length == 0;
}

private Transform m_AuthorityInstanceTransform;

[UnityTest]
public IEnumerator BasicMovementTest()
{
var authority = GetAuthorityNetworkManager();
m_Instance = SpawnObject(m_Prefab, m_ServerNetworkManager).GetComponent<NetworkObject>();

// Wait 5 seconds so we will dump any deferred messages if it failed on clients
// when checking to see if it spawned or not on the clients next.
// Enable this to debug deferred
//yield return new WaitForSeconds(5);
m_AuthorityInstanceTransform = m_Instance.transform;

yield return WaitForSpawnedOnAllOrTimeOut(m_Instance);
AssertOnTimeout($"Failed to spawn {m_Instance.name} on all clients!");

VerboseDebug("All clients spawned instance!");

yield return WaitForConditionOrTimeOut(ValidatePosition);
AssertOnTimeout($"A client failed to synchronize the position on the initial spawn!");

var originalPos = authority.LocalClient.PlayerObject.transform.position;
var newPos = originalPos + new Vector3(1, 1, 1);

m_Instance.transform.position = newPos;

foreach (var client in m_ClientNetworkManagers)
{
Assert.IsTrue(Approximately(originalPos, s_GlobalNetworkObjects[client.LocalClientId][m_Instance.NetworkObjectId].transform.position));
}

yield return new WaitForSeconds(1);

foreach (var client in m_ClientNetworkManagers)
{
Assert.IsTrue(Approximately(newPos, s_GlobalNetworkObjects[client.LocalClientId][m_Instance.NetworkObjectId].transform.position));
}
yield return WaitForConditionOrTimeOut(ValidatePosition);
AssertOnTimeout($"A client failed to synchronize the changed position: {GetVector3Values(newPos)}!");
VerboseDebug("Test Passed!");
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ public void OneTimeSetup()
{
// This test does not need to run against the Rust server.
NetcodeIntegrationTestHelpers.IgnoreIfServiceEnviromentVariableSet();
// Excluding from unified tests. If deemed needed, update test, then remove.
NetcodeIntegrationTestHelpers.IgnoreIfUnifiedTestsEnvironmentVariableSet();
}

[Test]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,11 @@ protected override void OnOneTimeTearDown()
/// </summary>
private void InitializeServerAndClients(HostOrServer useHost)
{
#if UNIFIED_NETCODE
// HostOrServer arrives as a test method parameter here, so the base class cannot filter the
// hybrid prefab cases NUnit generates from the enum. Do it before anything is started.
ApplyUnifiedTestFilter(useHost);
#endif
s_ClientNetworkVariableTestInstances.Clear();
m_PlayerPrefab.AddComponent<NetworkVariableTest>();

Expand Down Expand Up @@ -351,6 +356,10 @@ private void InitializeServerAndClients(HostOrServer useHost)
[Test]
public void AllNetworkVariableTypes([Values] HostOrServer useHost)
{
#if UNIFIED_NETCODE
// Filter before CreateNetworkObjectPrefab, which routes to CreateHybridPrefab for hybrid cases.
ApplyUnifiedTestFilter(useHost);
#endif
var prefabToSpawn = CreateNetworkObjectPrefab("NetVarTest");
prefabToSpawn.AddComponent<NetworkVariableTestComponent>();

Expand Down
Loading
Loading