Entitas
Entitas copied to clipboard
Race conditions in unit tests
When using Matcher
s 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));
}
Are you executing your tests in parallel on different threads? Otherwise I don't understand why there should be race conditions
I believe that is what Rider does, yes.
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.
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.
Probably fixed by #919