Search code examples
dependency-injectiongithub-actionsxunitazure-ad-msaldataverse

Multiple calls to token creation in Dependency Injection causing Github Runner to timeout during parallel tests


I am injecting Microsoft.PowerPlatform.Dataverse.Client in Dependency Injection with a tokenProviderFunction

sc.AddSingleton<IOrganizationServiceAsync2, ServiceClient>(provider =>
{
    var config ...
    var factory ...
    var client = new ServiceClient(
        new Uri(config....),
        factory.GetTokenAsync, true, provider.GetService<ILogger<ServiceClient>>())
    {
        MaxRetryCount = 5
    };
    return client;
});

The token factory uses multiple ConfidentialClientApplications, one for each "user" so the ServiceClient has a connection pool

return (await _generator
                .AcquireTokenForClient(new[] { $"{resource}/.default" })
                .ExecuteAsync(cancellationToken)).AccessToken;

This works in my local vm, in local tests, and when deployed in dev environment. The issue is when integration tests (xunit) run on the Github Runner. The tests run in parallel and when multiple fixtures or test classes are created, the tests hang at the _generator.AcquireTokenForClient(...).ExecuteAsync step.

  • Tests work on the GitHub runner when they are run sequentially
  • The issue occurs when using class fixtures, or spinning the di services up in the test class constructor
  • I used lots of logging and nothing happens after the generator executes
  • When i add .ConfigureAwait(false), it gets to the next step but still hangs (ie it reaches the next line of code to log "done" but then nothing)
  • I created a new test project and replicated the above, it works ok with a single test class and fails when more than one, but it WORKS if the token work is in each test case, not the constructor of the test class or the class fixture
  • I tried the github action on ubuntu-latest and windows-latest but the effect is the same
  • Timeout is set on the github action workflow file

Solution

  • For those who came here with similar issues, to get this working the github workflow job runner was set to ubuntu-latest-8-cores

    We tried with 4-cores but found it timed out intermittently. We will probably split the integration tests so we can use the 4-core runner in parallel jobs