public void Multi_Threaded_ApiFactory_Tasks(int quoteCount, int threadCount) { var config = ApiConfigurationBuilder.Build("secrets.json"); var provider = new ClientCredentialsFlowTokenProvider(config); var date = new DateTimeOffset(2018, 1, 1, 0, 0, 0, TimeSpan.Zero); var request = Enumerable.Range(0, quoteCount).Select(i => new UpsertQuoteRequest( new QuoteId( new QuoteSeriesId( provider: "DataScope", priceSource: "BankA", instrumentId: "BBG000B9XRY4", instrumentIdType: QuoteSeriesId.InstrumentIdTypeEnum.Figi, quoteType: QuoteSeriesId.QuoteTypeEnum.Price, field: "mid"), effectiveAt: date.AddDays(i)), metricValue: new MetricValue( value: 199.23m, unit: "USD"), lineage: "InternalSystem")).ToDictionary(k => k.QuoteId.EffectiveAt.ToString(), v => v); var tasks = Enumerable.Range(0, threadCount).Select(x => Task.Run(() => { var factory = LusidApiFactoryBuilder.Build(config.ApiUrl, provider); var result = factory.Api <IQuotesApi>().UpsertQuotes("mt-scope", request); Assert.That(result.Failed, Is.Empty); Console.WriteLine($"{DateTimeOffset.UtcNow} {Thread.CurrentThread.ManagedThreadId} {result.Values.Count}"); })); Task.WaitAll(tasks.ToArray()); }
public async Task CanGetToken() { // GIVEN a token provider initialised with required secrets var provider = new ClientCredentialsFlowTokenProvider(ApiConfig.Value); // WHEN the token is requested var token = await provider.GetAuthenticationTokenAsync(); // THEN it is populated Assert.That(token, Is.Not.Empty); }
public async Task CanRefreshWithoutToken() { // GIVEN a token from the TokenProvider that DOES NOT contain a refresh token var provider = new ClientCredentialsFlowTokenProvider(ApiConfig.Value); var _ = await provider.GetAuthenticationTokenAsync(); var firstTokenDetails = provider.GetLastToken(); Assert.That(firstTokenDetails.RefreshToken, Is.Null, "refresh_token was returned so unable to verify refresh behaviour with a token. This requires the userid defined in secrets.json to be set to NOT 'allow offline access' in Okta"); // WHEN we pretend to delay until the original token has expired (for expediency update the expires_on on the token) provider.ExpireToken(); Assert.That(DateTimeOffset.UtcNow, Is.GreaterThan(firstTokenDetails.ExpiresOn)); var refreshedToken = await provider.GetAuthenticationTokenAsync(); // THEN it should be populated, and the ExpiresOn should be in the future Assert.That(refreshedToken, Is.Not.Empty); Assert.That(provider.GetLastToken().ExpiresOn, Is.GreaterThan(DateTimeOffset.UtcNow)); }
public void LinuxSocketLeakTest() // See DEV-7152 { ApiConfiguration config = ApiConfigurationBuilder.Build("secrets.json"); var provider = new ClientCredentialsFlowTokenProvider(config); var api = BuildApi(); api.CreatePortfolioGroup("sdktest", new CreatePortfolioGroupRequest("TestGroup", displayName: "TestGroup")); // This loop should eventually throw a SocketException: "Address already in use" once all the sockets have been exhausted for (int i = 0; i < 50_000; i++) { api = BuildApi(); PortfolioGroup result = api.GetPortfolioGroup("sdktest", "TestGroup"); Assert.That(result, Is.Not.Null); // Option 1: force dispose of ApiClient //api.Configuration.ApiClient.Dispose(); // Option 2: force all finalizers to run if (i % 100 == 0) { GC.Collect(); GC.WaitForPendingFinalizers(); } } /*** Local Functions ***/ IPortfolioGroupsApi BuildApi() { // An instance of HttpClient is created within LusidApiFactory.Configuration.ApiClient.RestClient // which wasn't being disposed ILusidApiFactory factory = LusidApiFactoryBuilder.Build(config.ApiUrl, provider); IPortfolioGroupsApi api = factory.Api <IPortfolioGroupsApi>(); return(api); } }
public async Task CanGetNewTokenWhenRefreshTokenExpired() { var provider = new ClientCredentialsFlowTokenProvider(ApiConfig.Value); var _ = await provider.GetAuthenticationTokenAsync(); var firstTokenDetails = provider.GetLastToken(); Assert.That(firstTokenDetails.RefreshToken, Is.Not.Null.And.Not.Empty, "refresh_token not returned so unable to verify refresh behaviour."); Console.WriteLine($"Token expiring at {firstTokenDetails.ExpiresOn:o}"); // WHEN we pretend to delay until both... // (1) the original token has expired (for expediency update the expires_on on the token) provider.ExpireToken(); // (2) the refresh token has expired (for expediency update the refresh_token to an invalid value that will not be found) provider.GetLastToken().RefreshToken = "InvalidRefreshToken"; Assert.That(DateTimeOffset.UtcNow, Is.GreaterThan(firstTokenDetails.ExpiresOn)); var refreshedToken = await provider.GetAuthenticationTokenAsync(); // THEN it should be populated, and the ExpiresOn should be in the future Assert.That(refreshedToken, Is.Not.Empty); Assert.That(provider.GetLastToken().ExpiresOn, Is.GreaterThan(DateTimeOffset.UtcNow)); }