Entitas icon indicating copy to clipboard operation
Entitas copied to clipboard

Race conditions in unit tests

Open ribbanya opened this issue 5 years ago • 5 comments

When using Matchers in unit tests, a race condition will often occur that causes tests using a matcher to fail. Rerunning the tests repeatedly causes them to all eventually pass. Each rerun causes one or two more tests to pass.

System.ArgumentException
Source array was not long enough. Check srcIndex and length, and the array's lower bounds.
   at System.Array.Copy(Array sourceArray, Int32 sourceIndex, Array destinationArray, Int32 destinationIndex, Int32 length, Boolean reliable)
   at System.Collections.Generic.List`1.set_Capacity(Int32 value)
   at System.Collections.Generic.List`1.EnsureCapacity(Int32 min)
   at System.Collections.Generic.List`1.InsertRange(Int32 index, IEnumerable`1 collection)
   at Entitas.Matcher`1.mergeIndices(Int32[] allOfIndices, Int32[] anyOfIndices, Int32[] noneOfIndices)
   at Entitas.Matcher`1.get_indices()
   at Entitas.Context`1.GetGroup(IMatcher`1 matcher)
   at Contexts.InitializeEntityIndices() in Path\To\My\UnityProject\Assets\Generated\Contexts.cs:line 76

EDIT: Also getting this sometimes:

System.InvalidOperationException
Collection was modified; enumeration operation may not execute.
   at System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource)
   at System.Collections.Generic.List`1.Enumerator.MoveNextRare()
   at Entitas.Matcher`1.distinctIndices(IList`1 indices)
   at Entitas.Matcher`1.mergeIndices(Int32[] allOfIndices, Int32[] anyOfIndices, Int32[] noneOfIndices)
   at Entitas.Matcher`1.get_indices()
   at Entitas.Context`1.GetGroup(IMatcher`1 matcher)
   at Contexts.InitializeEntityIndices() in Path\To\My\UnityProject\Assets\Generated\Contexts.cs:line 76

This is the line being referenced:

    [Entitas.CodeGeneration.Attributes.PostConstructor]
    public void InitializeEntityIndices() {
/*->*/  input.AddEntityIndex(new Entitas.EntityIndex<InputEntity, Input.ButtonLabel>(
            ButtonLabel,
            input.GetGroup(InputMatcher.ButtonLabel),
            (e, c) => ((Input.ButtonLabelComponent)c).value));

        config.AddEntityIndex(new Entitas.EntityIndex<ConfigEntity, int>(
            DeviceIndex,
            config.GetGroup(ConfigMatcher.DeviceIndex),
            (e, c) => ((Input.DeviceIndexComponent)c).value));
        input.AddEntityIndex(new Entitas.EntityIndex<InputEntity, int>(
            DeviceIndex,
            input.GetGroup(InputMatcher.DeviceIndex),
            (e, c) => ((Input.DeviceIndexComponent)c).value));
        physics.AddEntityIndex(new Entitas.EntityIndex<PhysicsEntity, int>(
            DeviceIndex,
            physics.GetGroup(PhysicsMatcher.DeviceIndex),
            (e, c) => ((Input.DeviceIndexComponent)c).value));

        config.AddEntityIndex(new Entitas.PrimaryEntityIndex<ConfigEntity, int>(
            PlayerPreferencesIndex,
            config.GetGroup(ConfigMatcher.PlayerPreferencesIndex),
            (e, c) => ((Config.PlayerPreferencesIndexComponent)c).value));
        input.AddEntityIndex(new Entitas.PrimaryEntityIndex<InputEntity, int>(
            PlayerPreferencesIndex,
            input.GetGroup(InputMatcher.PlayerPreferencesIndex),
            (e, c) => ((Config.PlayerPreferencesIndexComponent)c).value));

        input.AddEntityIndex(new Entitas.EntityIndex<InputEntity, Input.StickLabel>(
            StickLabel,
            input.GetGroup(InputMatcher.StickLabel),
            (e, c) => ((Input.StickLabelComponent)c).value));
    }

ribbanya avatar Mar 13 '19 07:03 ribbanya

Are you executing your tests in parallel on different threads? Otherwise I don't understand why there should be race conditions

sschmid avatar Mar 14 '19 19:03 sschmid

I believe that is what Rider does, yes.

ribbanya avatar Mar 14 '19 22:03 ribbanya

I checked my settings. In theory, Rider should only be using one thread for unit testing. Not sure what's causing the race, if that's true.

ribbanya avatar Mar 15 '19 07:03 ribbanya

Hey ribbanya, can you provide some code from a test that is have a race condition? Never had race condition problems with entitas and unit tests.

ghost avatar Mar 24 '19 10:03 ghost

Probably fixed by #919

sschmid avatar Sep 08 '22 21:09 sschmid