Search Unity

[Bug] Unit Test for generic JobComponentSystems

Discussion in 'Entity Component System' started by Spy-Shifty, Nov 11, 2018.

  1. Spy-Shifty

    Spy-Shifty

    Joined:
    May 5, 2011
    Posts:
    546
    Hi I want to write a Unit Test for my JobComponentSystems

    But It fails without any message...

    Here is my Test class:
    Code (CSharp):
    1.  public class NetworkSerializationTest {
    2.  
    3.         private World networkWorld;
    4.         private EntityManager entityManager;
    5.  
    6.         [NetSync]
    7.         struct TestSyncComponent : IComponentData {
    8.             [NetSyncMember]
    9.             public int IntegerValue;
    10.         }
    11.  
    12.         [SetUp]
    13.         public void TestSetup() {
    14.             networkWorld = new World("NetworkWorld");
    15.             entityManager = networkWorld.GetOrCreateManager<EntityManager>();
    16.         }
    17.  
    18.         [TearDown]
    19.         public void TestTearDown() {
    20.             networkWorld.Dispose();
    21.         }
    22.  
    23.         [Test]
    24.         public void TypeDescriptor_GetValue_Integer() {
    25.             int integerValue = 5;
    26.  
    27.             var entity = entityManager.CreateEntity(typeof(TestSyncComponent));
    28.             entityManager.SetComponentData(entity, new TestSyncComponent { IntegerValue = integerValue });
    29.             NativeList<byte> dataStream = new NativeList<byte>(Allocator.Persistent);
    30.  
    31.             var testSystem = networkWorld.CreateManager<NetworkComponentDataSerializationSystem<TestSyncComponent>>(dataStream);
    32.  
    33.             testSystem.Update();
    34.  
    35.             var expectedValues = new byte[] { (byte)integerValue };
    36.  
    37.             Assert.AreEqual(expectedValues.Length, dataStream.Length);
    38.             for (int i = 0; i < dataStream.Length; i++) {
    39.                 Assert.AreEqual(expectedValues[i], dataStream[i]);
    40.             }
    41.  
    42.             dataStream.Dispose();
    43.         }
    44.     }

    Class to test:

    Code (CSharp):
    1.     class NetworkComponentDataSerializationSystem<TComponent> : JobComponentSystem where  TComponent : struct, IComponentData {
    2.  
    3.         NativeList<byte> stream;
    4.  
    5.         public NetworkComponentDataSerializationSystem(NativeList<byte> dataStream) {
    6.             stream = dataStream;
    7.         }
    8.  
    9.  
    10.         struct ComponentNetworkSerializationJob : IJobProcessComponentData<TComponent> {
    11.  
    12.             [WriteOnly] public NativeList<byte> Stream;
    13.             public void Execute([ReadOnly]ref TComponent data) {
    14.                 Stream.Add(5);
    15.             }
    16.         }
    17.  
    18.         protected override JobHandle OnUpdate(JobHandle inputDeps) {
    19.             var componentNetworkSerializationJob = new ComponentNetworkSerializationJob {
    20.                 Stream = stream,
    21.             };
    22.             componentNetworkSerializationJob.Schedule(this, inputDeps);
    23.             return inputDeps;
    24.         }
    25.     }

    Some notes by the way:
    Debugger runs till:
    Code (CSharp):
    1.  
    2. var testSystem = networkWorld.CreateManager<NetworkComponentDataSerializationSystem<TestSyncComponent>>(dataStream);
    This line breaks the execution! No message, no error...

    If I do something like that:
    Code (CSharp):
    1. class Test : NetworkComponentDataSerializationSystem<TestSyncComponent> {
    2.             public Test(NativeList<byte> dataStream) : base(dataStream) {
    3.             }
    4.         }
    5.  
    6. // In combination of:
    7. var testSystem = networkWorld.CreateManager<Test>(dataStream);
    8.  
    the debugger runs till:
    testSystem.Update();


    No Message no error!

    Can someone help me?
    Thank you!



    EDIT:

    I also tried the following:
    Code (CSharp):
    1. class Test : JobComponentSystem {
    2.  
    3.             NativeList<byte> stream;
    4.  
    5.             public Test(NativeList<byte> dataStream) {
    6.                 stream = dataStream;
    7.             }
    8.  
    9.  
    10.             struct ComponentNetworkSerializationJob : IJobProcessComponentData<TestSyncComponent> {
    11.  
    12.                 [WriteOnly] public NativeList<byte> Stream;
    13.                 public void Execute([ReadOnly]ref TestSyncComponent data) {
    14.                     Stream.Add(5);
    15.                 }
    16.             }
    17.  
    18.             protected override JobHandle OnUpdate(JobHandle inputDeps) {
    19.                 var componentNetworkSerializationJob = new ComponentNetworkSerializationJob {
    20.                     Stream = stream,
    21.                 };
    22.                 componentNetworkSerializationJob.Schedule(this, inputDeps);
    23.                 return inputDeps;
    24.             }
    25.         }

    Same behaviour! No error, No exception!
    Debugger runs till

    Code (CSharp):
    1. var testSystem = networkWorld.CreateManager<Test>(dataStream);
     
  2. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    3,759
    Firstly, it's kind of convenient to make your unit tests inherit from ECSTestsFixture
    It handles all that world and manager setup and disposing for you.

    Onto the actual problem, I think the problem here is you're making an assumption that calling
    testSystem.Update()
    will cause your jobs to run straight away. But I don't think it will, you'd need a barrier or something afterwards to force a sync.
     
  3. 5argon

    5argon

    Joined:
    Jun 10, 2013
    Posts:
    1,555
    Use EntityManager.CompleteAllJobs() after the Update to force a sync in unit tests.
     
    recursive likes this.
  4. Spy-Shifty

    Spy-Shifty

    Joined:
    May 5, 2011
    Posts:
    546
    Thank you for your help!

    Both tips solved my problem!

    Thank you!