private async Task <AuthenticationResult> AcquireTokenAsync(int userIndex) { 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(Log, LogLevel.Info, false); } var msalPublicClient = builder.Build(); ScalableTokenCacheHelper.EnableSerialization(msalPublicClient.UserTokenCache); AuthenticationResult authResult = null; try { try { var identifier = _userAccountIdentifiers[userIndex]; IAccount account = null; if (identifier != null) { DateTime start = DateTime.Now; account = await msalPublicClient.GetAccountAsync(identifier).ConfigureAwait(false); elapsedTimeInMsalCacheLookup += DateTime.Now - start; } authResult = await msalPublicClient.AcquireTokenSilent(scopes, account).ExecuteAsync(CancellationToken.None).ConfigureAwait(false); return(authResult); } catch (MsalUiRequiredException) { 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); }
public async Task Run() { Console.WriteLine($"Starting test with {_options.NumberOfUsersToTest} users from {_options.StartUserIndex} to {_options.StartUserIndex + _options.NumberOfUsersToTest - 1}."); if (_options.RunIndefinitely) { Console.WriteLine("Running indefinitely."); } else { Console.WriteLine($"Running for {_options.RuntimeInMinutes} minutes."); } // Try loading from cache ScalableTokenCacheHelper.LoadCache(); IDictionary <int, string> accounts = ScalableTokenCacheHelper.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()); }
private async Task SendRequestsAsync(int userStartIndex, int userEndIndex, CancellationToken cancellationToken) { Console.WriteLine($"Task started for users {userStartIndex} to {userEndIndex}."); DateTime startOverall = DateTime.Now; TimeSpan elapsedTime = TimeSpan.Zero; int requestsCounter = 0; int authRequestFailureCount = 0; int catchAllFailureCount = 0; int tokenReturnedFromCache = 0; StringBuilder exceptionsDuringRun = new StringBuilder(); int loop = 0; while (!cancellationToken.IsCancellationRequested) { loop++; for (int i = userStartIndex; i <= userEndIndex && !cancellationToken.IsCancellationRequested; i++) { try { HttpResponseMessage response; using (HttpRequestMessage httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, _options.TestUri)) { AuthenticationResult authResult = await AcquireTokenAsync(i); if (authResult == null) { authRequestFailureCount++; } else { httpRequestMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("text/plain")); httpRequestMessage.Headers.Add( "Authorization", string.Format( CultureInfo.InvariantCulture, "{0} {1}", "Bearer", authResult?.AccessToken)); DateTime start = DateTime.Now; response = await _httpClient.SendAsync(httpRequestMessage).ConfigureAwait(false); elapsedTime += DateTime.Now - start; requestsCounter++; if (authResult?.AuthenticationResultMetadata.TokenSource == TokenSource.Cache) { tokenReturnedFromCache++; } else { if (i % 10 == 0) { ScalableTokenCacheHelper.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) { catchAllFailureCount++; Console.WriteLine($"Exception in TestRunner at {i} of {userEndIndex} - {userStartIndex}: {ex.Message}"); exceptionsDuringRun.AppendLine($"Exception in TestRunner at {i} of {userEndIndex} - {userStartIndex}: {ex.Message}"); exceptionsDuringRun.AppendLine($"{ex}"); } } UpdateConsoleProgress(startOverall, elapsedTime, requestsCounter, tokenReturnedFromCache, authRequestFailureCount, catchAllFailureCount, userStartIndex, userEndIndex, loop); ScalableTokenCacheHelper.PersistCache(); //File.AppendAllText(System.Reflection.Assembly.GetExecutingAssembly().Location + ".exceptions.log", exceptionsDuringRun.ToString()); } }
public async Task Run() { Console.WriteLine($"Starting testing with {userEndIndex - userStartIndex} users."); // Try loading from cache ScalableTokenCacheHelper.LoadCache(); IDictionary <int, string> accounts = ScalableTokenCacheHelper.GetAccountIdsByUserNumber(); foreach (var account in accounts) { if (account.Key < _userAccountIdentifiers.Length) { _userAccountIdentifiers[account.Key] = account.Value; } } // Configuring the http client to trust the self-signed certificate var httpClientHandler = new HttpClientHandler(); httpClientHandler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator; var client = new HttpClient(httpClientHandler); client.BaseAddress = new Uri(_options.TestServiceBaseUri); DateTime startOverall = DateTime.Now; var finishTime = DateTime.Now.AddMinutes(_options.RuntimeInMinutes); TimeSpan elapsedTime = TimeSpan.Zero; int requestsCounter = 0; int authRequestFailureCount = 0; int catchAllFailureCount = 0; int loop = 0; int tokenReturnedFromCache = 0; bool cancelProcessing = false; StringBuilder exceptionsDuringRun = new StringBuilder(); while (!cancelProcessing) { loop++; for (int i = userStartIndex; i <= userEndIndex; i++) { bool fromCache = false; try { HttpResponseMessage response; using (HttpRequestMessage httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, _options.TestUri)) { AuthenticationResult authResult = await AcquireTokenAsync(i); if (authResult == null) { authRequestFailureCount++; } else { httpRequestMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("text/plain")); httpRequestMessage.Headers.Add( "Authorization", string.Format( CultureInfo.InvariantCulture, "{0} {1}", "Bearer", authResult?.AccessToken)); DateTime start = DateTime.Now; response = await client.SendAsync(httpRequestMessage).ConfigureAwait(false); elapsedTime += DateTime.Now - start; requestsCounter++; if (authResult?.AuthenticationResultMetadata.TokenSource == TokenSource.Cache) { tokenReturnedFromCache++; fromCache = true; } else { if (i % 10 == 0) { ScalableTokenCacheHelper.PersistCache(); } } if (!response.IsSuccessStatusCode) { Console.WriteLine($"Response was not successful. Status code: {response.StatusCode}. {response.ReasonPhrase}"); Console.WriteLine(response.ReasonPhrase); Console.WriteLine(await response.Content.ReadAsStringAsync()); } } } } catch (Exception ex) { catchAllFailureCount++; Console.WriteLine($"Exception in TestRunner at {i} of {userEndIndex} - {userStartIndex}: {ex.Message}"); exceptionsDuringRun.AppendLine($"Exception in TestRunner at {i} of {userEndIndex} - {userStartIndex}: {ex.Message}"); exceptionsDuringRun.AppendLine($"{ex}"); } Console.Title = $"[{userStartIndex} - {userEndIndex}] #: {i}, Loop: {loop}, " + $"Time: {(DateTime.Now - startOverall).TotalMinutes:0.00}, " + $"Req: {requestsCounter}, Cache: {tokenReturnedFromCache}: {fromCache}, " + $"AuthFail: {authRequestFailureCount}, Fail: {catchAllFailureCount}"; if (Console.KeyAvailable) { ConsoleKeyInfo keyInfo = Console.ReadKey(); if ((keyInfo.Modifiers == ConsoleModifiers.Control && (keyInfo.Key == ConsoleKey.X || keyInfo.Key == ConsoleKey.C)) || keyInfo.Key == ConsoleKey.Escape) { cancelProcessing = true; break; } } } UpdateConsoleProgress(startOverall, elapsedTime, requestsCounter, tokenReturnedFromCache, authRequestFailureCount, catchAllFailureCount); ScalableTokenCacheHelper.PersistCache(); if (DateTime.Now >= finishTime) { cancelProcessing = true; } } File.AppendAllText(System.Reflection.Assembly.GetExecutingAssembly().Location + ".exceptions.log", exceptionsDuringRun.ToString()); Console.WriteLine("Test run complete"); }