public async Task GrpcOpenCensusInputTests_StopsAndRestarts()
        {
            // ARRANGE
            int batchesReceived             = 0;
            ExportSpanRequest receivedBatch = null;

            int port  = GetPort();
            var input = new GrpcOpenCensusInput("localhost", port);

            input.Start(exportSpanRequest =>
            {
                batchesReceived++;
                receivedBatch = exportSpanRequest;
            });

            Assert.IsTrue(SpinWait.SpinUntil(() => input.IsRunning, GrpcOpenCensusInputTests.DefaultTimeout));

            var grpcWriter = new GrpcWriter(false, port);

            ExportSpanRequest batch = new ExportSpanRequest();

            batch.Spans.Add(new Span()
            {
                Name = new TruncatableString()
                {
                    Value = "Event1"
                }
            });

            await grpcWriter.Write(batch).ConfigureAwait(false);

            Common.AssertIsTrueEventually(
                () => input.GetStats().BatchesReceived == 1 && batchesReceived == 1 &&
                receivedBatch.Spans.Single().Name.Value == "Event1", GrpcOpenCensusInputTests.DefaultTimeout);

            // ACT
            input.Stop();

            Common.AssertIsTrueEventually(
                () => !input.IsRunning && input.GetStats().BatchesReceived == 1 && batchesReceived == 1 &&
                receivedBatch.Spans.Single().Name.Value == "Event1", GrpcOpenCensusInputTests.DefaultTimeout);

            input.Start(exportSpanRequest =>
            {
                batchesReceived++;
                receivedBatch = exportSpanRequest;
            });

            Assert.IsTrue(SpinWait.SpinUntil(() => input.IsRunning, GrpcOpenCensusInputTests.DefaultTimeout));

            grpcWriter = new GrpcWriter(false, port);
            batch.Spans.Single().Name.Value = "Event2";
            await grpcWriter.Write(batch).ConfigureAwait(false);

            // ASSERT
            Common.AssertIsTrueEventually(
                () => input.IsRunning && input.GetStats().BatchesReceived == 1 && batchesReceived == 2 &&
                receivedBatch.Spans.Single().Name.Value == "Event2", GrpcOpenCensusInputTests.DefaultTimeout);
        }
        public async Task GrpcOpenCensusInputTests_HandlesExceptionsInProcessingHandler()
        {
            // ARRANGE
            int port  = GetPort();
            var input = new GrpcOpenCensusInput("localhost", port);

            input.Start(exportSpanRequest => throw new InvalidOperationException());

            Assert.IsTrue(SpinWait.SpinUntil(() => input.IsRunning, GrpcOpenCensusInputTests.DefaultTimeout));

            var grpcWriter = new GrpcWriter(false, port);

            ExportSpanRequest batch = new ExportSpanRequest();

            batch.Spans.Add(new Span()
            {
                Name = new TruncatableString()
                {
                    Value = "Event1"
                }
            });

            // ACT
            await grpcWriter.Write(batch).ConfigureAwait(false);

            // ASSERT

            // must have handled the exception by logging it
            // should still be able to process items
            Common.AssertIsTrueEventually(
                () => input.IsRunning && input.GetStats().BatchesReceived == 0 && input.GetStats().BatchesFailed == 1,
                GrpcOpenCensusInputTests.DefaultTimeout);

            await grpcWriter.Write(batch).ConfigureAwait(false);

            Common.AssertIsTrueEventually(
                () => input.IsRunning && input.GetStats().BatchesReceived == 0 && input.GetStats().BatchesFailed == 2,
                GrpcOpenCensusInputTests.DefaultTimeout);
        }
        public async Task GrpcOpenCensusInputTests_HandlesExceptionsInConfigRequestsProcessingHandler()
        {
            // ARRANGE
            int port  = GetPort();
            var input = new GrpcOpenCensusInput("localhost", port);

            input.Start((exportSpanRequest, callContext) => { }, (cr, cc) => throw new InvalidOperationException());

            Assert.IsTrue(SpinWait.SpinUntil(() => input.IsRunning, GrpcOpenCensusInputTests.DefaultTimeout));

            var grpcWriter = new GrpcWriter(false, port);

            CurrentLibraryConfig configRequest = new CurrentLibraryConfig
            {
                Config = new TraceConfig {
                    RateLimitingSampler = new RateLimitingSampler {
                        Qps = 1
                    }
                }
            };

            // ACT
            await grpcWriter.Write(configRequest).ConfigureAwait(false);

            // ASSERT

            // must have handled the exception by logging it
            // should still be able to process items
            Common.AssertIsTrueEventually(
                () => input.IsRunning && input.GetStats().ConfigsReceived == 0 && input.GetStats().ConfigsFailed == 1,
                GrpcOpenCensusInputTests.DefaultTimeout);

            await grpcWriter.Write(configRequest).ConfigureAwait(false);

            Common.AssertIsTrueEventually(
                () => input.IsRunning && input.GetStats().ConfigsReceived == 0 && input.GetStats().ConfigsFailed == 2,
                GrpcOpenCensusInputTests.DefaultTimeout);
        }
        public async Task GrpcOpenCensusInputTests_ReceivesConfigWithNode()
        {
            // ARRANGE
            int configsReceived = 0;
            CurrentLibraryConfig receivedConfigRequest = null;

            int port  = GetPort();
            var input = new GrpcOpenCensusInput("localhost", port);

            input.Start(
                (telemetryBatch, callContext) => { },
                (configRequest, callContext) =>
            {
                configsReceived++;
                receivedConfigRequest = configRequest;
                return(ConfigResponse);
            });
            Assert.IsTrue(SpinWait.SpinUntil(() => input.IsRunning, GrpcOpenCensusInputTests.DefaultTimeout));

            var grpcWriter = new GrpcWriter(false, port);

            // ACT
            CurrentLibraryConfig request =
                new CurrentLibraryConfig
            {
                Config = new TraceConfig {
                    RateLimitingSampler = new RateLimitingSampler {
                        Qps = 1
                    }
                },
                Node = new Node {
                    Identifier = new ProcessIdentifier {
                        Pid = 2
                    }
                }
            };

            await grpcWriter.Write(request).ConfigureAwait(false);

            // ASSERT
            Common.AssertIsTrueEventually(
                () => input.GetStats().ConfigsReceived == 1 && configsReceived == 1 &&
                receivedConfigRequest.Node.Identifier.Pid == 2 &&
                receivedConfigRequest.Config.RateLimitingSampler.Qps == 1,
                GrpcOpenCensusInputTests.DefaultTimeout);

            input.Stop();
            Assert.IsTrue(SpinWait.SpinUntil(() => !input.IsRunning, GrpcOpenCensusInputTests.DefaultTimeout));
        }
        public void GrpcOpenCensusInputTests_ReceivesDataFromMultipleClients()
        {
            // ARRANGE
            int batchesReceived = 0;
            ExportTraceServiceRequest receivedBatch = null;

            int port  = GetPort();
            var input = new GrpcOpenCensusInput("localhost", port);

            input.Start(
                (exportSpanRequest, callContext) =>
            {
                Interlocked.Increment(ref batchesReceived);
                receivedBatch = exportSpanRequest;
            },
                (configRequest, callContext) => ConfigResponse);
            Assert.IsTrue(SpinWait.SpinUntil(() => input.IsRunning, GrpcOpenCensusInputTests.DefaultTimeout));

            // ACT
            ExportTraceServiceRequest batch = new ExportTraceServiceRequest();

            batch.Spans.Add(new Span()
            {
                Name = new TruncatableString()
                {
                    Value = "Event1"
                }
            });

            Parallel.For(0, 1000, new ParallelOptions()
            {
                MaxDegreeOfParallelism = 1000
            }, async i =>
            {
                var grpcWriter = new GrpcWriter(false, port);

                await grpcWriter.Write(batch).ConfigureAwait(false);
            });

            // ASSERT
            Common.AssertIsTrueEventually(
                () => input.GetStats().BatchesReceived == 1000 && batchesReceived == 1000, GrpcOpenCensusInputTests.DefaultTimeout);

            input.Stop();
            Assert.IsTrue(SpinWait.SpinUntil(() => !input.IsRunning, GrpcOpenCensusInputTests.DefaultTimeout));
        }
        public async Task GrpcOpenCensusInputTests_ReceivesSpansWithNode()
        {
            // ARRANGE
            int batchesReceived = 0;
            ExportTraceServiceRequest receivedBatch = null;

            int port  = GetPort();
            var input = new GrpcOpenCensusInput("localhost", port);

            input.Start(
                (telemetryBatch, callContext) =>
            {
                batchesReceived++;
                receivedBatch = telemetryBatch;
            },
                null);
            Assert.IsTrue(SpinWait.SpinUntil(() => input.IsRunning, GrpcOpenCensusInputTests.DefaultTimeout));

            var grpcWriter = new GrpcWriter(false, port);

            // ACT
            ExportTraceServiceRequest batch = new ExportTraceServiceRequest();

            batch.Spans.Add(new Span {
                Name = new TruncatableString {
                    Value = "Event1"
                }
            });
            batch.Node = new Node {
                Identifier = new ProcessIdentifier {
                    Pid = 2
                }
            };

            await grpcWriter.Write(batch).ConfigureAwait(false);

            // ASSERT
            Common.AssertIsTrueEventually(
                () => input.GetStats().BatchesReceived == 1 && batchesReceived == 1 &&
                receivedBatch.Node.Identifier.Pid == 2 &&
                receivedBatch.Spans.Single().Name.Value == "Event1",
                GrpcOpenCensusInputTests.DefaultTimeout);

            input.Stop();
            Assert.IsTrue(SpinWait.SpinUntil(() => !input.IsRunning, GrpcOpenCensusInputTests.DefaultTimeout));
        }