Exemple #1
0
        public async Task Run()
        {
            Console.WriteLine($"Starting test with {_options.NumberOfUsersToTest} users from {_options.StartUserIndex} to {_options.StartUserIndex + _options.NumberOfUsersToTest - 1} using {_options.NumberOfParallelTasks} parallel tasks.");

            if (_options.RunIndefinitely)
            {
                Console.WriteLine("Running indefinitely.");
            }
            else
            {
                Console.WriteLine($"Running for {_options.RuntimeInMinutes} minutes.");
            }

            // Try loading from cache
            TokenCacheHelper.LoadCache();
            IDictionary <int, string> accounts = TokenCacheHelper.GetAccountIdsByUserNumber();

            foreach (var account in accounts)
            {
                if (account.Key < _userAccountIdentifiers.Length)
                {
                    _userAccountIdentifiers[account.Key] = account.Value;
                }
            }

            IEnumerable <Task> CreateTasks()
            {
                var tokenSource = new CancellationTokenSource();

                if (!_options.RunIndefinitely)
                {
                    yield return(CreateStopProcessingByTimeoutTask(tokenSource));
                }
                yield return(CreateStopProcessingByUserRequestTask(tokenSource));

                foreach (Task task in CreateSendRequestsTasks(tokenSource))
                {
                    yield return(task);
                }
            }

            await Task.WhenAll(CreateTasks());
        }
Exemple #2
0
        private async Task <AuthenticationResult> AcquireTokenAsync(int userIndex, Metrics localMetrics)
        {
            var scopes = new string[] { _options.ApiScopes };
            var upn    = $"{_options.UsernamePrefix}{userIndex}@{_options.TenantDomain}";

            var builder = PublicClientApplicationBuilder
                          .Create(_options.ClientId)
                          .WithAuthority(TestConstants.AadInstance, TestConstants.Organizations);

            if (_options.EnableMsalLogging)
            {
                builder.WithLogging(Logger.Log, LogLevel.Error, false);
            }

            var msalPublicClient = builder.Build();

            TokenCacheHelper.EnableSerialization(msalPublicClient.UserTokenCache);

            AuthenticationResult authResult = null;

            try
            {
                try
                {
                    var      identifier = _userAccountIdentifiers[userIndex];
                    IAccount account    = null;
                    if (identifier != null)
                    {
                        var stopwatch = new Stopwatch();
                        stopwatch.Start();
                        account = await msalPublicClient.GetAccountAsync(identifier).ConfigureAwait(false);

                        stopwatch.Stop();
                        localMetrics.TotalMsalLookupTimeInMilliseconds += stopwatch.Elapsed.TotalMilliseconds;
                    }

                    authResult = await msalPublicClient.AcquireTokenSilent(scopes, account).ExecuteAsync(CancellationToken.None).ConfigureAwait(false);

                    return(authResult);
                }
                catch (MsalUiRequiredException)
                {
                    // Delay to prevent spamming the STS with calls.
                    await Task.Delay(_options.RequestDelayInMilliseconds);

                    authResult = await msalPublicClient.AcquireTokenByUsernamePassword(
                        scopes,
                        upn,
                        new NetworkCredential(
                            upn,
                            _options.UserPassword).SecurePassword)
                                 .ExecuteAsync(CancellationToken.None)
                                 .ConfigureAwait(false);

                    _userAccountIdentifiers[userIndex] = authResult.Account.HomeAccountId.Identifier;
                    return(authResult);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Exception in AcquireTokenAsync: {ex}");
            }
            return(authResult);
        }
Exemple #3
0
        private async Task SendRequestsAsync(int userStartIndex, int userEndIndex, CancellationToken cancellationToken)
        {
            while (!cancellationToken.IsCancellationRequested)
            {
                var localMetrics        = new Metrics();
                var stopwatch           = new Stopwatch();
                var exceptionsDuringRun = new StringBuilder();

                for (int userIndex = userStartIndex; userIndex <= userEndIndex && !cancellationToken.IsCancellationRequested; userIndex++)
                {
                    try
                    {
                        HttpResponseMessage response;
                        using (HttpRequestMessage httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, _options.TestUri))
                        {
                            AuthenticationResult authResult = await AcquireTokenAsync(userIndex, localMetrics);

                            if (authResult == null)
                            {
                                localMetrics.TotalAcquireTokenFailures++;
                            }
                            else
                            {
                                httpRequestMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("text/plain"));
                                httpRequestMessage.Headers.Add(
                                    "Authorization",
                                    string.Format(
                                        CultureInfo.InvariantCulture,
                                        "{0} {1}",
                                        "Bearer",
                                        authResult?.AccessToken));

                                stopwatch.Start();
                                response = await _httpClient.SendAsync(httpRequestMessage).ConfigureAwait(false);

                                stopwatch.Stop();
                                localMetrics.TotalRequests++;
                                if (authResult?.AuthenticationResultMetadata.TokenSource == TokenSource.Cache)
                                {
                                    localMetrics.TotalTokensReturnedFromCache++;
                                }
                                else
                                {
                                    if (userIndex % 10 == 0)
                                    {
                                        TokenCacheHelper.PersistCache();
                                    }
                                }

                                if (!response.IsSuccessStatusCode)
                                {
                                    var sb = new StringBuilder();
                                    sb.AppendLine($"Response was not successful. Status code: {response.StatusCode}. {response.ReasonPhrase}");
                                    sb.AppendLine(await response.Content.ReadAsStringAsync());
                                    Console.WriteLine(sb);
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        localMetrics.TotalExceptions++;
                        Console.WriteLine($"Exception in TestRunner at {userIndex} of {userEndIndex} - {userStartIndex}: {ex.Message}");

                        exceptionsDuringRun.AppendLine($"Exception in TestRunner at {userIndex} of {userEndIndex} - {userStartIndex}: {ex.Message}");
                        exceptionsDuringRun.AppendLine($"{ex}");
                    }
                }
                localMetrics.TotalRequestTimeInMilliseconds += stopwatch.Elapsed.TotalMilliseconds;

                UpdateGlobalMetrics(localMetrics);
                DisplayProgress();

                TokenCacheHelper.PersistCache();

                Logger.PersistExceptions(exceptionsDuringRun);
            }
        }