public void Should_LogFiveTimes_When_ThereAreMoreThanFiveErrorsOnStartupMessageSend()
        {
            _listener = new TestTraceListener();
            Trace.Listeners.Add(_listener);
            Cassandra.Diagnostics.CassandraTraceSwitch.Level = TraceLevel.Verbose;

            var cluster = GetCluster(false);
            var session = GetSession(cluster);

            using (var target = InsightsClientTests.GetInsightsClient(cluster, session))
            {
                Expression <Func <IControlConnection, Task <Response> > > mockExpression =
                    cc => cc.UnsafeSendQueryRequestAsync(
                        "CALL InsightsRpc.reportInsight(?)",
                        It.IsAny <QueryProtocolOptions>());
                Mock.Get(cluster.Metadata.ControlConnection).Setup(mockExpression).ReturnsAsync((Response)null);

                target.Init();

                TestHelper.RetryAssert(
                    () =>
                {
                    Mock.Get(cluster.Metadata.ControlConnection).Verify(mockExpression, Times.AtLeast(10));
                },
                    30);

                Trace.Flush();
                Assert.AreEqual(5, _listener.Queue.Count, string.Join(" ; ", _listener.Queue.ToArray()));
                var messages = _listener.Queue.ToArray();
                Assert.AreEqual(messages.Count(m => m.Contains("Could not send insights startup event. Exception:")), 5);
            }
        }
        public void Should_InvokeRpcCallCorrectlyAndPeriodically_When_SendStatusMessageIsInvoked()
        {
            const string expectedJson =
                "{\"metadata\":{" +
                "\"name\":\"driver.status\"," +
                "\"timestamp\":124219041," +
                "\"tags\":{\"language\":\"csharp\"}," +
                "\"insightType\":\"EVENT\"," +
                "\"insightMappingId\":\"v1\"}," +
                "\"data\":{" +
                "\"clientId\":\"becfe098-e462-47e7-b6a7-a21cd316d4c0\"," +
                "\"sessionId\":\"e21eab96-d91e-4790-80bd-1d5fb5472258\"," +
                "\"controlConnection\":\"10.10.10.10:9011\"," +
                "\"connectedNodes\":{" +
                "\"127.0.0.1:9042\":{\"connections\":3,\"inFlightQueries\":1}," +
                "\"127.0.0.2:9042\":{\"connections\":4,\"inFlightQueries\":2}}}}";
            var cluster = GetCluster(false);
            var session = GetSession(cluster);

            using (var target = InsightsClientTests.GetInsightsClient(cluster, session))
            {
                var queryProtocolOptions = new ConcurrentQueue <QueryProtocolOptions>();
                Mock.Get(cluster.Metadata.ControlConnection).Setup(cc => cc.UnsafeSendQueryRequestAsync(
                                                                       "CALL InsightsRpc.reportInsight(?)",
                                                                       It.IsAny <QueryProtocolOptions>()))
                .ReturnsAsync(new FakeResultResponse(ResultResponse.ResultResponseKind.Void))
                .Callback <string, QueryProtocolOptions>((query, opts) => { queryProtocolOptions.Enqueue(opts); });

                target.Init();

                TestHelper.RetryAssert(() => { Assert.GreaterOrEqual(queryProtocolOptions.Count, 5); }, 5, 400);
                queryProtocolOptions.TryDequeue(out var result); // ignore startup message
                queryProtocolOptions.TryPeek(out result);
                Assert.AreEqual(expectedJson, result.Values[0], "Actual: " + Environment.NewLine + result.Values[0]);
            }
        }
        public void Should_InvokeRpcCallCorrectlyAndImmediatelyWithExecutionProfiles_When_SendStartupMessageIsInvoked()
        {
            const string expectedJson =
                "{\"metadata\":{" +
                "\"name\":\"driver.startup\"," +
                "\"timestamp\":124219041," +
                "\"tags\":{\"language\":\"csharp\"}," +
                "\"insightType\":\"EVENT\"," +
                "\"insightMappingId\":\"v1\"}," +
                "\"data\":{" +
                "\"clientId\":\"becfe098-e462-47e7-b6a7-a21cd316d4c0\"," +
                "\"sessionId\":\"e21eab96-d91e-4790-80bd-1d5fb5472258\"," +
                "\"applicationName\":\"appname\"," +
                "\"applicationVersion\":\"appv1\"," +
                "\"contactPoints\":{\"localhost\":[\"127.0.0.1:9042\"]}," +
                "\"initialControlConnection\":\"10.10.10.10:9011\"," +
                "\"protocolVersion\":4," +
                "\"localAddress\":\"10.10.10.2:9015\"," +
                "\"executionProfiles\":{" +
                "\"default\":{" +
                "\"readTimeout\":1505," +
                "\"retry\":{" +
                "\"type\":\"DowngradingConsistencyRetryPolicy\"," +
                "\"namespace\":\"Cassandra\"}," +
                "\"loadBalancing\":{" +
                "\"type\":\"RoundRobinPolicy\"," +
                "\"namespace\":\"Cassandra\"}," +
                "\"speculativeExecution\":{" +
                "\"type\":\"ConstantSpeculativeExecutionPolicy\"," +
                "\"namespace\":\"Cassandra\"," +
                "\"options\":{" +
                "\"delay\":1213," +
                "\"maxSpeculativeExecutions\":10}}," +
                "\"consistency\":\"ALL\"," +
                "\"serialConsistency\":\"LOCAL_SERIAL\"," +
                "\"graphOptions\":{" +
                "\"language\":\"gremlin-groovy\"," +
                "\"source\":\"g\"," +
                "\"name\":\"testGraphName\"," +
                "\"readConsistency\":\"ALL\"," +
                "\"writeConsistency\":null," +
                "\"readTimeout\":-1}}," +
                "\"profile2\":{" +
                "\"readTimeout\":501," +
                "\"retry\":{" +
                "\"type\":\"IdempotenceAwareRetryPolicy\"," +
                "\"namespace\":\"Cassandra\"," +
                "\"options\":{" +
                "\"childPolicy\":{" +
                "\"type\":\"DefaultRetryPolicy\"," +
                "\"namespace\":\"Cassandra\"}}}," +
                "\"loadBalancing\":{" +
                "\"type\":\"TokenAwarePolicy\"," +
                "\"namespace\":\"Cassandra\"," +
                "\"options\":{" +
                "\"childPolicy\":{" +
                "\"type\":\"RoundRobinPolicy\"," +
                "\"namespace\":\"Cassandra\"}}}," +
                "\"speculativeExecution\":{" +
                "\"type\":\"ConstantSpeculativeExecutionPolicy\"," +
                "\"namespace\":\"Cassandra\"," +
                "\"options\":{" +
                "\"delay\":230," +
                "\"maxSpeculativeExecutions\":5}}," +
                "\"serialConsistency\":\"SERIAL\"" +
                "}," +
                "\"profile3\":{" +
                "\"consistency\":\"EACH_QUORUM\"" +
                "}" +
                "}," +
                "\"poolSizeByHostDistance\":{" +
                "\"local\":1," +
                "\"remote\":5}," +
                "\"heartbeatInterval\":10000," +
                "\"compression\":\"SNAPPY\"," +
                "\"reconnectionPolicy\":{" +
                "\"type\":\"ConstantReconnectionPolicy\"," +
                "\"namespace\":\"Cassandra\"," +
                "\"options\":{" +
                "\"constantDelayMs\":150}}," +
                "\"ssl\":{\"enabled\":false}," +
                "\"authProvider\":{" +
                "\"type\":\"NoneAuthProvider\"," +
                "\"namespace\":\"Cassandra\"}," +
                "\"configAntiPatterns\":{" +
                "\"downgradingConsistency\":\"Downgrading consistency retry policy in use\"}," +
                "\"periodicStatusInterval\":5," +
                "\"platformInfo\":{" +
                "\"os\":{\"name\":\"os name\",\"version\":\"os version\",\"arch\":\"os arch\"}," +
                "\"cpus\":{\"length\":2,\"model\":\"Awesome CPU\"}," +
                "\"runtime\":{" +
                "\"runtimeFramework\":\"runtime-framework\"," +
                "\"targetFramework\":\"target-framework\"," +
                "\"dependencies\":{" +
                "\"Assembly1\":{" +
                "\"fullName\":\"Assembly1FullName\"," +
                "\"name\":\"Assembly1\"," +
                "\"version\":\"1.2.0\"}}}}," +
                "\"hostName\":\"awesome_hostname\"," +
                "\"driverName\":\"Driver Name\"," +
                "\"applicationNameWasGenerated\":false," +
                "\"driverVersion\":\"1.1.2\"," +
                "\"dataCenters\":[\"dc123\"]}}";
            var cluster = GetCluster(true, eventDelayMilliseconds: 5000);
            var session = GetSession(cluster);

            using (var target = InsightsClientTests.GetInsightsClient(cluster, session))
            {
                var queryProtocolOptions = new ConcurrentQueue <QueryProtocolOptions>();
                Mock.Get(cluster.Metadata.ControlConnection).Setup(cc => cc.UnsafeSendQueryRequestAsync(
                                                                       "CALL InsightsRpc.reportInsight(?)",
                                                                       It.IsAny <QueryProtocolOptions>()))
                .ReturnsAsync(new FakeResultResponse(ResultResponse.ResultResponseKind.Void))
                .Callback <string, QueryProtocolOptions>((query, opts) => { queryProtocolOptions.Enqueue(opts); });

                target.Init();

                TestHelper.RetryAssert(
                    () => { Assert.GreaterOrEqual(queryProtocolOptions.Count, 1); }, 10, 50);
                queryProtocolOptions.TryPeek(out var result);
                Assert.AreEqual(expectedJson, result.Values[0], "Actual: " + Environment.NewLine + result.Values[0]);
            }
        }