Unit testing parallel scheduled jobs?

I am trying to set up the most basic unit test possible. I have similar tests for existing code already for Unity3D OOP. All I want to do is run a job once and check and see if it works.

Game/Physics/GasHeatDiffusionSystem.cs

using System.Diagnostics;
using Unity.Collections;
using Unity.Entities;
using Unity.Jobs;

namespace Game.Physics
{
    /// <summary>
    /// System that evenly distributes heat between gas elements in an entity.
    /// </summary>
    public class GasHeatDiffusionSystem : SystemBase
    {
        EndSimulationEntityCommandBufferSystem m_EndSimulationEcbSystem;
        protected override void OnCreate() {
            base.OnCreate();
            m_EndSimulationEcbSystem = World.GetOrCreateSystem<EndSimulationEntityCommandBufferSystem>();
        }

        protected override void OnUpdate() {
            var entityCommandBuffer = m_EndSimulationEcbSystem.CreateCommandBuffer().AsParallelWriter();

            // find all jars that have been made inhomogenous by content changes
            Entities
                .WithAll<GasHeatInhomogeneousTag>()
                .ForEach((Entity entity, int entityInQueryIndex, DynamicBuffer<ChemicalComposition> contents) => {
                    // Removed code for sake of testing.
                    // Heat is now homogenous, queue entity to remove tag.
                    entityCommandBuffer.RemoveComponent<GasHeatInhomogeneousTag>(entityInQueryIndex, entity);
                })
                .ScheduleParallel();

            m_EndSimulationEcbSystem.AddJobHandleForProducer(this.Dependency);
        }
    }
}

Tests/ChemicalTestScript.cs

using NUnit.Framework;
using Unity.Entities.Tests;
using Game.Physics;
using Unity.Entities;

namespace Tests
{
    [TestFixture]
    public class ChemicalTestScript : ECSTestsFixture
    {
        const float MolesInLiterOfWater = 55.5084343f;

        #region Chemical References
        Chemical Nitrogen() {
            return new Chemical {
                MeltingPoint = 63.15f,
                BoilingPoint = 77.355f,
                MolarMass = 28.014f,
                RelativeDensity = 0.804f,
                HeatCapacity = 29.124f,
                ThermalConductivity = 0.02583f
            };
        }

        Chemical Oxygen() {
            return new Chemical {
                MeltingPoint = 54.36f,
                BoilingPoint = 90.188f,
                MolarMass = 31.988f,
                RelativeDensity = 1.14f,
                HeatCapacity = 29.378f,
                ThermalConductivity = 0.02658f
            };
        }

        Chemical Water() {
            return new Chemical {
                MeltingPoint = 273.15f,
                BoilingPoint = 373.13f,
                MolarMass = 18.01528f,
                RelativeDensity = 1f,
                HeatCapacity = 75.385f,
                ThermalConductivity = 0.6065f
            };
        }
        #endregion

        [Test]
        public void GasHeatDiffusionSystemDiffusionPasses() {
            var entity = m_Manager.CreateEntity(
                typeof(GasHeatInhomogeneousTag),
                typeof(ChemicalComposition)
            );

            var buffer = m_Manager.GetBuffer<ChemicalComposition>(entity);
            buffer.Add(new ChemicalComposition {
                Chemical = Nitrogen(),
                Matter = 79f,
                Temp = Temp.Boiling
            });
            buffer.Add(new ChemicalComposition {
                Chemical = Oxygen(),
                Matter = 21f,
                Temp = Temp.Room
            });

            m_Manager.World.CreateSystem<GasHeatDiffusionSystem>();
            m_Manager.World.Update();

            Assert.IsFalse(m_Manager.HasComponent<GasHeatInhomogeneousTag>(entity));
            Assert.AreEqual(buffer[0].Temp, buffer[1].Temp);
        }
    }
}

This fails right at the first hurdle. The GasHeatInhomogenousTag is not removed from the entity. I have tried many different system types and ways of calling the update, none work.

m_Manager.World.CreateSystem().Update;
World.CreateSystem().Update();
World.Update();

etc. nothing works. I cannot make a system run, conclude it, and see the results. Why? This was so easy to do before.

1 Like

You need to explicitly update the EndSimulationEntityCommandBufferSystem, because thats where the ECB you are registering will be played back.

3 Likes