Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Travis CI run throws a concurrent access exception for HashSets HashSet<ProductInfoHeaderValue> #8491

Closed
ankushbindlish2 opened this issue Feb 6, 2019 · 3 comments

Comments

@ankushbindlish2
Copy link
Member

ankushbindlish2 commented Feb 6, 2019

Description

Travis Build CI

This is an intentional new exception that is being thrown by the Dictionary in newer .NET Core (issue #28123, PR dotnet/coreclr#16991) which indicates the dictionary is being incorrectly modified concurrently by multiple threads (it wouldn't have been detected previously and could lead to infinite loops, or incorrect data returned)

Also applies now to HashSets (issue #28209, PR #28225)

Dictionary and HashSet are not safe for concurrent readers and writers. Dictionaries/Hashsets that are not written to after set-up are safe for concurrent readers. They are never safe for a write and any other operation (read or write).

from call stack : azure-powershell\tools\ScenarioTest.ResourceManager\Mocks\MockClientFactory.cs

  • Microsoft.WindowsAzure.Commands.Common.Test.Mocks.MockClientFactory.AddUserAgent(String productName, String productVersion)
  • this.UniqueUserAgents.Add(new ProductInfoHeaderValue(productName, productVersion));
  • public HashSet UniqueUserAgents { get; set; }

System.Management.Automation.CmdletInvocationException : Operations that change non-concurrent collections must have exclusive access. A concurrent update was performed on this collection and corrupted its state. The collection's state is no longer correct.
---- System.InvalidOperationException : Operations that change non-concurrent collections must have exclusive access. A concurrent update was performed on this collection and corrupted its state. The collection's state is no longer correct.
Stack Trace:
at System.Management.Automation.Runspaces.PipelineBase.Invoke(IEnumerable input)
at System.Management.Automation.Runspaces.Pipeline.Invoke()
at System.Management.Automation.PowerShell.Worker.ConstructPipelineAndDoWork(Runspace rs, Boolean performSyncInvoke)
at System.Management.Automation.PowerShell.Worker.CreateRunspaceIfNeededAndDoWork(Runspace rsToUse, Boolean isSync)
at System.Management.Automation.PowerShell.CoreInvokeHelper[TInput,TOutput](PSDataCollection1 input, PSDataCollection1 output, PSInvocationSettings settings)
at System.Management.Automation.PowerShell.CoreInvoke[TInput,TOutput](PSDataCollection1 input, PSDataCollection1 output, PSInvocationSettings settings)
at System.Management.Automation.PowerShell.CoreInvoke[TOutput](IEnumerable input, PSDataCollection1 output, PSInvocationSettings settings) at System.Management.Automation.PowerShell.Invoke(IEnumerable input, PSInvocationSettings settings) at System.Management.Automation.PowerShell.Invoke() at Microsoft.WindowsAzure.Commands.ScenarioTest.EnvironmentSetupHelper.RunPowerShellTest(String[] scripts) in /home/travis/build/Azure/azure-powershell/tools/ScenarioTest.ResourceManager/EnvironmentSetupHelper.cs:line 559 at Microsoft.Azure.Commands.StorageSync.Test.ScenarioTests.TestController.RunPsTestWorkflow(Func1 scriptBuilder, Action cleanup, String callingClassType, String mockName) in /home/travis/build/Azure/azure-powershell/src/StorageSync/StorageSync.Test/TestController.cs:line 113
at Microsoft.Azure.Commands.StorageSync.Test.ScenarioTests.TestController.RunPsTest(XunitTracingInterceptor logger, String[] scripts) in /home/travis/build/Azure/azure-powershell/src/StorageSync/StorageSync.Test/TestController.cs:line 61
at StorageSync.Test.ScenarioTests.StorageSyncServiceTests.TestNewStorageSyncService() in /home/travis/build/Azure/azure-powershell/src/StorageSync/StorageSync.Test/ScenarioTests/StorageSyncServiceTests.cs:line 44
----- Inner Stack Trace -----
at System.Collections.Generic.HashSet1.AddIfNotPresent(T value) at System.Collections.Generic.HashSet1.Add(T item)
at Microsoft.WindowsAzure.Commands.Common.Test.Mocks.MockClientFactory.AddUserAgent(String productName, String productVersion) in /home/travis/build/Azure/azure-powershell/tools/ScenarioTest.ResourceManager/Mocks/MockClientFactory.cs:line 212
at Microsoft.WindowsAzure.Commands.Utilities.Common.AzurePSCmdlet.SetupHttpClientPipeline()
at Microsoft.WindowsAzure.Commands.Utilities.Common.AzurePSCmdlet.BeginProcessing()
at System.Management.Automation.Cmdlet.DoBeginProcessing()
at System.Management.Automation.CommandProcessorBase.DoBegin()

Script/Steps for Reproduction

Module Version

Get-Module -ListAvailable

Environment Data

$PSVersionTable

Debug Output


@markcowl
Copy link
Member

markcowl commented Feb 6, 2019

Can you try adding this attribute to the AssemblyInfo.cs for your test assembly:

[assembly: CollectionBehavior(DisableTestParallelization = true)]

This is set for nearly all the test assemblies in the repo.

On the above, HashSet is an inappropriate type for unique collections - generally a ConcurrentCollection liek ConcurrentDIctionary would be a better choice for this (as is used in the production ClientFactory).

We should fix that regardless - in general, it is not really necessary to play out UserAgents in the tests, so we likely don't need to store the values in any collection at all.

@ankushbindlish2
Copy link
Member Author

Thanks for acknowledging the issue. Will use this workaround for now.

@maddieclayton
Copy link
Contributor

Closing as we do not plan to support parallelization yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants