public async Task SecretToken_test() { var isRequestFinished = new TaskCompletionSource <object>(); AuthenticationHeaderValue authHeader = null; var handler = new MockHttpMessageHandler((r, c) => { authHeader = r.Headers.Authorization; isRequestFinished.SetResult(null); return(Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK))); }); const string secretToken = "SecretToken"; var noopLogger = new NoopLogger(); var mockConfig = new MockConfigSnapshot(_logger, secretToken: secretToken, maxBatchEventCount: "1"); var payloadSender = new PayloadSenderV2(_logger, mockConfig, Service.GetDefaultService(mockConfig, noopLogger), new Api.System(), handler, /* dbgName: */ TestDisplayName); using (var agent = new ApmAgent(new TestAgentComponents(LoggerBase, mockConfig, payloadSender))) { agent.PayloadSender.QueueTransaction(new Transaction(agent, "TestName", "TestType")); await isRequestFinished.Task; } authHeader.Should().NotBeNull(); authHeader.Scheme.Should().Be("Bearer"); authHeader.Parameter.Should().Be(secretToken); }
public async Task CheckAuthorizationHeader(string authorizationHeader) { var isRequestFinished = new TaskCompletionSource <object>(); AuthenticationHeaderValue authHeader = null; var handler = new MockHttpMessageHandler((r, c) => { authHeader = r.Headers.Authorization; isRequestFinished.SetResult(null); return(Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK))); }); var logger = new NoopLogger(); var mockConfig = new MockConfigSnapshot(logger, secretToken: _secretToken, apiKey: _apiKey, flushInterval: "1s"); var payloadSender = new PayloadSenderV2(logger, mockConfig, Api.Service.GetDefaultService(mockConfig, logger), new Api.System(), handler, /* dbgName: */ nameof(ApiKeyFeatureContext)); using (var agent = new ApmAgent(new TestAgentComponents(logger, mockConfig, payloadSender))) { agent.PayloadSender.QueueTransaction(new Transaction(agent, "TestName", "TestType")); await isRequestFinished.Task; } authHeader.Should().NotBeNull(); authHeader.ToString().Should().Be(authorizationHeader); }
public void ErrorContextSanitizerFilterDoesNotThrowWhenTransactionNotSampled() { var waitHandle = new ManualResetEventSlim(); using var localServer = LocalServer.Create(context => { context.Response.StatusCode = 200; waitHandle.Set(); }); var config = new MockConfiguration(transactionSampleRate: "0", serverUrl: localServer.Uri, flushInterval: "0"); var logger = new InMemoryBlockingLogger(LogLevel.Warning); var payloadSender = new PayloadSenderV2(logger, config, Service.GetDefaultService(config, logger), new Api.System(), MockApmServerInfo.Version710); using var agent = new ApmAgent(new AgentComponents(payloadSender: payloadSender, configurationReader: config)); agent.Tracer.CaptureTransaction("Test", "Test", t => { t.CaptureException(new Exception("boom!")); }); waitHandle.Wait(); logger.Lines.Should().NotContain(line => line.Contains("Exception during execution of the filter on transaction")); }
public async Task PayloadSentWithBearerToken() { var isRequestFinished = new TaskCompletionSource <object>(); AuthenticationHeaderValue authHeader = null; var handler = new MockHttpMessageHandler((r, c) => { authHeader = r.Headers.Authorization; isRequestFinished.SetResult(null); return(Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK))); }); const string secretToken = "SecretToken"; var logger = ConsoleLogger.Instance; var payloadSender = new PayloadSenderV2(logger, new TestAgentConfigurationReader(logger, secretToken: secretToken), Service.GetDefaultService(new TestAgentConfigurationReader(logger), logger), new Api.System(), handler); using (var agent = new ApmAgent(new TestAgentComponents(payloadSender: payloadSender, configurationReader: new TestAgentConfigurationReader(secretToken: secretToken)))) { agent.PayloadSender.QueueTransaction(new Transaction(agent, "TestName", "TestType")); } await isRequestFinished.Task; authHeader.Should().NotBeNull(); authHeader.Scheme.Should().Be("Bearer"); authHeader.Parameter.Should().Be(secretToken); }
public MockPayloadSender(IApmLogger logger = null) { _waitHandles = new[] { new AutoResetEvent(false), new AutoResetEvent(false), new AutoResetEvent(false), new AutoResetEvent(false) }; _transactionWaitHandle = _waitHandles[0]; _spanWaitHandle = _waitHandles[1]; _errorWaitHandle = _waitHandles[2]; _metricSetWaitHandle = _waitHandles[3]; PayloadSenderV2.SetUpFilters(_transactionFilters, _spanFilters, _errorFilters, MockApmServerInfo.Version710, logger ?? new NoopLogger()); }
private void CreateSutEnvAndTest(Action <ApmAgent, PayloadSenderV2> doAction) { var configReader = new MockConfigSnapshot(_logger); var mockHttpMessageHandler = new MockHttpMessageHandler((r, c) => Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK))); var service = Service.GetDefaultService(configReader, _logger); var payloadSender = new PayloadSenderV2(_logger, configReader, service, new Api.System(), mockHttpMessageHandler , /* dbgName: */ TestDisplayName); payloadSender.IsRunning.Should().BeTrue(); using (var agent = new ApmAgent(new TestAgentComponents(LoggerBase, payloadSender: payloadSender))) doAction(agent, payloadSender); payloadSender.IsRunning.Should().BeFalse(); }
public void RequestTimeoutTest() { var waitHandle = new ManualResetEvent(false); using var localServer = LocalServer.Create(context => { Thread.Sleep(500000); context.Response.StatusCode = 200; }); var iterCount = 0; var handler = new MockHttpMessageHandler((r, c) => { // 1. request times out if (iterCount == 0) { throw new OperationCanceledException(); } // 2. request returns OK iterCount++; waitHandle.Set(); return(Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK))); }); var config = new MockConfiguration(serverUrl: localServer.Uri, flushInterval: "1ms"); var logger = new InMemoryBlockingLogger(LogLevel.Trace); var payloadSender = new PayloadSenderV2(logger, config, Service.GetDefaultService(config, logger), new Api.System(), MockApmServerInfo.Version710, handler); using var agent = new ApmAgent(new AgentComponents(payloadSender: payloadSender, configurationReader: config)); // This won't be sent due to timeout agent.Tracer.CaptureTransaction("Test", "Test", t => { }); Thread.Sleep(500); // This will be sent agent.Tracer.CaptureTransaction("Test2", "Test", t => { }); Thread.Sleep(500); waitHandle.WaitOne(TimeSpan.FromMilliseconds(1000)); logger.Lines.Should().NotContain(l => l.Contains("WorkLoop is about to exit because it was cancelled")); }
public void calling_after_Dispose_throws() { PayloadSenderV2 payloadSender = null; Transaction dummyTx = null; CreateSutEnvAndTest((agent, payloadSenderArg) => { payloadSender = payloadSenderArg; dummyTx = new Transaction(agent, "TestName", "TestType"); payloadSender.QueueTransaction(dummyTx); }); AsAction(() => payloadSender.QueueTransaction(dummyTx)) .Should() .ThrowExactly <ObjectDisposedException>() .WithMessage($"*{nameof(PayloadSenderV2)}*"); }
internal async Task MaxBatchEventCount_test(TestArgs args, int expectedNumberOfBatches) { var expectedNumberOfBatchesSentTcs = new TaskCompletionSource <object>(); var actualNumberOfBatches = 0; var handler = new MockHttpMessageHandler((r, c) => { if (Interlocked.Increment(ref actualNumberOfBatches) == expectedNumberOfBatches) { expectedNumberOfBatchesSentTcs.SetResult(null); } return(Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK))); }); var configurationReader = args.BuildConfig(_logger); var service = Service.GetDefaultService(configurationReader, _logger); var payloadSender = new PayloadSenderV2(_logger, configurationReader, service, new Api.System(), handler , /* dbgName: */ TestDisplayName); using (var agent = new ApmAgent(new TestAgentComponents(_logger, payloadSender: payloadSender))) { var numberOfEventsEnqueuedSuccessfully = 0; for (var txIndex = 1;; ++txIndex) { if (EnqueueDummyEvent(payloadSender, agent, txIndex)) { ++numberOfEventsEnqueuedSuccessfully; } else { Thread.Yield(); } if (numberOfEventsEnqueuedSuccessfully == expectedNumberOfBatches * args.MaxBatchEventCount) { break; } } (await Task.WhenAny(expectedNumberOfBatchesSentTcs.Task, Task.Delay(30.Seconds()))) .Should() .Be(expectedNumberOfBatchesSentTcs.Task , $"because numberOfEventsEnqueuedSuccessfully: {numberOfEventsEnqueuedSuccessfully}"); } }
internal void MaxQueueEventCount_should_be_enforced_before_send(TestArgs args) { var sendTcs = new TaskCompletionSource <object>(); var handler = new MockHttpMessageHandler(async(r, c) => { await sendTcs.Task; return(new HttpResponseMessage(HttpStatusCode.OK)); }); var configurationReader = args.BuildConfig(_logger); var service = Service.GetDefaultService(configurationReader, _logger); var payloadSender = new PayloadSenderV2(_logger, configurationReader, service, new Api.System(), handler, /* dbgName: */ TestDisplayName); using (var agent = new ApmAgent(new TestAgentComponents(_logger, payloadSender: payloadSender))) { int?txIndexResumedEnqueuing = null; for (var txIndex = 1; txIndex <= args.MaxQueueEventCount + args.MaxBatchEventCount + 10; ++txIndex) { var enqueuedSuccessfully = EnqueueDummyEvent(payloadSender, agent, txIndex); if (txIndex <= args.MaxQueueEventCount) { enqueuedSuccessfully.Should().BeTrue($"txIndex: {txIndex}, args: {args}"); continue; } // It's possible that the events for the first batch have already been dequeued // so we can be sure that queue doesn't have any free space left only after MaxQueueEventCount + MaxBatchEventCount events if (enqueuedSuccessfully && !txIndexResumedEnqueuing.HasValue) { txIndexResumedEnqueuing = txIndex; } enqueuedSuccessfully.Should() .Be(txIndex - txIndexResumedEnqueuing < args.MaxBatchEventCount , $"txIndex: {txIndex}, txIndexResumedEnqueuing: {txIndexResumedEnqueuing}, args: {args}"); } sendTcs.SetResult(null); } }
public void PayloadSenderNoUserNamePwPrintedForServerUrl() { var userName = "******"; var pw = "def"; var inMemoryLogger = new InMemoryBlockingLogger(LogLevel.Warning); var configReader = new MockConfiguration(serverUrls: $"http://{userName}:{pw}@localhost:8234", maxBatchEventCount: "0", flushInterval: "0"); using var payloadSender = new PayloadSenderV2(inMemoryLogger, configReader, Service.GetDefaultService(configReader, inMemoryLogger), new Api.System(), MockApmServerInfo.Version710); using var agent = new ApmAgent(new TestAgentComponents(payloadSender: payloadSender)); agent.Tracer.CaptureTransaction("Test", "TestTransaction", () => { }); inMemoryLogger.Lines.Should().HaveCount(1); inMemoryLogger.Lines.Should().NotContain(n => n.Contains($"{userName}:{pw}")); inMemoryLogger.Lines.Should().Contain(n => n.Contains("http://[REDACTED]:[REDACTED]@localhost:8234")); }
public void Dispose_stops_the_thread() { PayloadSenderV2 lastPayloadSender = null; CreateSutEnvAndTest((agent, payloadSender) => { lastPayloadSender = payloadSender; lastPayloadSender.IsRunning.Should().BeTrue(); }); lastPayloadSender.IsRunning.Should().BeFalse(); CreateSutEnvAndTest((agent, payloadSender) => { lastPayloadSender = payloadSender; lastPayloadSender.IsRunning.Should().BeTrue(); payloadSender.QueueTransaction(new Transaction(agent, "TestName", "TestType")); }); lastPayloadSender.IsRunning.Should().BeFalse(); }
internal async Task MaxQueueEventCount_should_be_enforced_after_send(TestArgs args) { // LoggerBase.Level = LogLevel.Debug; var sendTcs = new TaskCompletionSource <object>(); var firstBatchDequeuedTcs = new TaskCompletionSource <object>(); var handler = new MockHttpMessageHandler(async(r, c) => { firstBatchDequeuedTcs.SetResult(null); await sendTcs.Task; return(new HttpResponseMessage(HttpStatusCode.OK)); }); var configurationReader = args.BuildConfig(_logger); var service = Service.GetDefaultService(configurationReader, _logger); var payloadSender = new PayloadSenderV2(_logger, configurationReader, service, new Api.System(), handler, /* dbgName: */ TestDisplayName); using (var agent = new ApmAgent(new TestAgentComponents(_logger, payloadSender: payloadSender))) { var txIndex = 1; for (; txIndex <= args.MaxQueueEventCount; ++txIndex) { EnqueueDummyEvent(payloadSender, agent, txIndex).Should().BeTrue($"txIndex: {txIndex}, args: {args}"); } await firstBatchDequeuedTcs.Task; for (; txIndex <= args.MaxQueueEventCount + args.MaxBatchEventCount + 10; ++txIndex) { EnqueueDummyEvent(payloadSender, agent, txIndex) .Should() .Be(txIndex <= args.MaxQueueEventCount + args.MaxBatchEventCount , $"txIndex: {txIndex}, args: {args}"); } sendTcs.SetResult(null); } }
public async Task PayloadSentWithProperUserAgent() { var isRequestFinished = new TaskCompletionSource <object>(); HttpHeaderValueCollection <ProductInfoHeaderValue> userAgentHeader = null; var handler = new MockHttpMessageHandler((r, c) => { userAgentHeader = r.Headers.UserAgent; isRequestFinished.SetResult(null); return(Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK))); }); var logger = new NoopLogger(); var service = Service.GetDefaultService(new TestAgentConfigurationReader(logger), logger); var payloadSender = new PayloadSenderV2(logger, new TestAgentConfigurationReader(logger), service, new Api.System(), handler); using (var agent = new ApmAgent(new TestAgentComponents(payloadSender: payloadSender))) { agent.PayloadSender.QueueTransaction(new Transaction(agent, "TestName", "TestType")); } await isRequestFinished.Task; userAgentHeader .Should() .NotBeEmpty() .And.HaveCount(3); userAgentHeader.First().Product.Name.Should().Be($"elasticapm-{Consts.AgentName}"); userAgentHeader.First().Product.Version.Should().NotBeEmpty(); userAgentHeader.Skip(1).First().Product.Name.Should().Be("System.Net.Http"); userAgentHeader.Skip(1).First().Product.Version.Should().NotBeEmpty(); userAgentHeader.Skip(2).First().Product.Name.Should().NotBeEmpty(); userAgentHeader.Skip(2).First().Product.Version.Should().NotBeEmpty(); }
public void PayloadSenderNoUserNamePwPrintedForServerUrlWithServerReturn() { var userName = "******"; var pw = "def"; var inMemoryLogger = new InMemoryBlockingLogger(LogLevel.Error); var port = new Random(DateTime.UtcNow.Millisecond).Next(8100, 65535); var configReader = new MockConfigSnapshot(serverUrls: $"http://{userName}:{pw}@localhost:{port}", maxBatchEventCount: "0", flushInterval: "0"); using var payloadSender = new PayloadSenderV2(inMemoryLogger, configReader, Service.GetDefaultService(configReader, inMemoryLogger), new Api.System()); using var localServer = new LocalServer(httpListenerContext => { httpListenerContext.Response.StatusCode = 500; }, $"http://*****:*****@localhost:{port}")); }
public void PayloadSenderNoUserNamePwPrintedForServerUrlWithServerReturn() { var userName = "******"; var pw = "def"; var inMemoryLogger = new InMemoryBlockingLogger(LogLevel.Error); using var localServer = LocalServer.Create(httpListenerContext => { httpListenerContext.Response.StatusCode = 500; }); var uri = new Uri(localServer.Uri); var configReader = new MockConfiguration(serverUrls: $"http://{userName}:{pw}@{uri.Authority}", maxBatchEventCount: "0", flushInterval: "0"); using var payloadSender = new PayloadSenderV2(inMemoryLogger, configReader, Service.GetDefaultService(configReader, inMemoryLogger), new Api.System(), MockApmServerInfo.Version710); using var agent = new ApmAgent(new TestAgentComponents(payloadSender: payloadSender)); agent.Tracer.CaptureTransaction("Test", "TestTransaction", () => { }); inMemoryLogger.Lines.Should().HaveCount(1); inMemoryLogger.Lines.Should().NotContain(n => n.Contains($"{userName}:{pw}")); inMemoryLogger.Lines.Should().Contain(n => n.Contains($"http://[REDACTED]:[REDACTED]@{uri.Authority}")); }
public async Task PayloadSentWithBearerToken() { AuthenticationHeaderValue authHeader = null; var handler = new MockHttpMessageHandler((r, c) => { authHeader = r.Headers.Authorization; return(Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK))); }); const string secretToken = "SecretToken"; var logger = ConsoleLogger.Instance; var payloadSender = new PayloadSenderV2(logger, new TestAgentConfigurationReader(logger, secretToken: secretToken), Service.GetDefaultService(new TestAgentConfigurationReader(logger)), handler); using (var agent = new ApmAgent(new TestAgentComponents(secretToken: secretToken, payloadSender: payloadSender))) { agent.PayloadSender.QueueTransaction(new Transaction(agent, "TestName", "TestType")); await payloadSender.FlushAndFinishAsync(); } authHeader.Should().NotBeNull(); authHeader.Scheme.Should().Be("Bearer"); authHeader.Parameter.Should().Be(secretToken); }
internal void FlushInterval_test(TestArgs args, int numberOfEventsToSend) { var batchSentBarrier = new Barrier(2); var barrierTimeout = 30.Seconds(); var handler = new MockHttpMessageHandler((r, c) => { batchSentBarrier.SignalAndWait(barrierTimeout).Should().BeTrue(); return(Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK))); }); var configurationReader = args.BuildConfig(_logger); var service = Service.GetDefaultService(configurationReader, _logger); var payloadSender = new PayloadSenderV2(_logger, configurationReader, service, new Api.System(), handler, /* dbgName: */ TestDisplayName); using (var agent = new ApmAgent(new TestAgentComponents(_logger, payloadSender: payloadSender))) { for (var eventIndex = 1; eventIndex <= numberOfEventsToSend; ++eventIndex) { EnqueueDummyEvent(payloadSender, agent, eventIndex).Should().BeTrue($"eventIndex: {eventIndex}, args: {args}"); batchSentBarrier.SignalAndWait(barrierTimeout).Should().BeTrue($"eventIndex: {eventIndex}, args: {args}"); } } }
private static bool EnqueueDummyEvent(PayloadSenderV2 payloadSender, ApmAgent agent, int txIndex) => payloadSender.EnqueueEvent(new Transaction(agent, $"Tx #{txIndex}", "TestType"), "Transaction");