예제 #1
0
        public void CompareMatchReturnsBreakingWhenOrdinalArgumentValueChanged()
        {
            var oldArgument = Model.UsingModule <ConfigurationModule>().Create <TestArgumentDefinition>()
                              .Set(x => x.ArgumentType = ArgumentType.Ordinal);
            var oldArguments = new[]
            {
                oldArgument
            };
            var oldAttribute = Model.UsingModule <ConfigurationModule>().Create <TestAttributeDefinition>()
                               .Set(x => x.Arguments = oldArguments);
            var newArgument = Model.UsingModule <ConfigurationModule>().Create <TestArgumentDefinition>().Set(
                x => { x.ArgumentType = ArgumentType.Ordinal; });
            var newArguments = new[]
            {
                newArgument
            };
            var newAttribute = Model.UsingModule <ConfigurationModule>().Create <TestAttributeDefinition>()
                               .Set(x => x.Arguments = newArguments);
            var match   = new ItemMatch <IAttributeDefinition>(oldAttribute, newAttribute);
            var options = OptionsFactory.BuildOptions();

            var sut = new AttributeComparer();

            var actual = sut.CompareMatch(match, options).ToList();

            _output.WriteResults(actual);

            actual.Should().HaveCount(1);

            actual[0].ChangeType.Should().Be(SemVerChangeType.Breaking);
            actual[0].OldItem.Should().BeAssignableTo <IArgumentDefinition>();
            actual[0].NewItem.Should().BeAssignableTo <IArgumentDefinition>();
        }
예제 #2
0
        private void Visit(ElementMapping <AttributeGroup> attribute)
        {
            WriteElement(attribute,
                         ag =>
            {
                foreach (var attr in ag.Attributes)
                {
                    _formatter.WriteAttribute(attr);
                }
            },
                         (ag1, ag2) =>
            {
                // TODO: Need to insert the newlines and indentions, perhaps support GetTokenList(IEnumerable<ICustomAttribute>)
                var attributeComparer = new AttributeComparer();
                var ag1Tokens         = ag1.Attributes.OrderBy(c => c, attributeComparer)
                                        .SelectMany(c => _declHelper.GetTokenList(c));
                var ag2Tokens = ag2.Attributes.OrderBy(c => c, attributeComparer)
                                .SelectMany(c => _declHelper.GetTokenList(c));

                foreach (var token in ListMerger.MergeLists(ag1Tokens, ag2Tokens))
                {
                    WriteElement(token, t =>
                    {
                        _syntaxWriter.WriteSyntaxToken(t);
                    },
                                 (t1, t2) =>
                    {
                        using (_syntaxWriter.StartStyle(SyntaxStyle.Removed))
                            _syntaxWriter.WriteSyntaxToken(t1);
                        using (_syntaxWriter.StartStyle(SyntaxStyle.Added))
                            _syntaxWriter.WriteSyntaxToken(t2);
                    }, false);
                }
            }, true);
        }
예제 #3
0
        public void SpanEventWireModelTests_MultipleEvents_Serialization()
        {
            const float priority = 1.975676f;
            var         duration = TimeSpan.FromSeconds(4.81);

            var expectedSerialization = new List <Dictionary <string, object>[]>
            {
                new[] {
                    new Dictionary <string, object>
                    {
                        { "type", "Span" },
                        { "priority", priority },
                        { "traceId", "ed5bbf27f28ebef3" },
                        { "duration", duration.TotalSeconds }
                    },
                    new Dictionary <string, object>
                    {
                    },
                    new Dictionary <string, object>
                    {
                        { "http.method", "GET" }
                    }
                },
                new[] {
                    new Dictionary <string, object>
                    {
                        { "type", "Span" },
                        { "priority", priority - 1 },
                        { "traceId", "fa5bbf27f28ebef3" },
                        { "duration", duration.TotalSeconds - 1 }
                    },
                    new Dictionary <string, object>
                    {
                    },
                    new Dictionary <string, object>
                    {
                        { "http.method", "POST" }
                    }
                }
            };

            var spanEvents = new[]
            {
                CreateSpanEvent(priority, duration, "ed5bbf27f28ebef3", "GET"),
                CreateSpanEvent(priority - 1, duration.Subtract(TimeSpan.FromSeconds(1)), "fa5bbf27f28ebef3", "POST")
            };

            var serialized = JsonConvert.SerializeObject(spanEvents);

            Assert.That(serialized, Is.Not.Null);

            var deserialized = JsonConvert.DeserializeObject <List <Dictionary <string, object>[]> >(serialized);

            Assert.That(deserialized, Is.Not.Null);

            Assert.AreEqual(expectedSerialization.Count, deserialized.Count);
            AttributeComparer.CompareDictionaries(expectedSerialization[0], deserialized[0]);
            AttributeComparer.CompareDictionaries(expectedSerialization[1], deserialized[1]);
        }
예제 #4
0
        public void CompareMatchThrowsExceptionWithNullMatch()
        {
            var options = OptionsFactory.BuildOptions();

            var sut = new AttributeComparer();

            Action action = () => sut.CompareMatch(null !, options);

            action.Should().Throw <ArgumentNullException>();
        }
        public void CustomEvents_MultipleEvents_Serialization()
        {
            const int countEvents = 2;

            var customEvents           = new CustomEventWireModel[countEvents];
            var expectedSerializations = new List <Dictionary <string, object>[]>();

            for (var i = 0; i < countEvents; i++)
            {
                var timestampVal  = DateTime.UtcNow;
                var typeVal       = $"CustomEvent{i}";
                var userAttribKey = $"foo{i}";
                var userAttribVal = $"bar{i}";


                var expectedSerialization = new Dictionary <string, object>[]
                {
                    new Dictionary <string, object>()
                    {
                        { _attribDefs.CustomEventType.Name, typeVal },
                        { _attribDefs.Timestamp.Name, timestampVal.ToUnixTimeMilliseconds() }
                    },

                    new Dictionary <string, object>()
                    {
                        { userAttribKey, userAttribVal }
                    },

                    new Dictionary <string, object>()
                };

                var attribVals = new AttributeValueCollection(AttributeDestinations.CustomEvent);

                _attribDefs.Timestamp.TrySetValue(attribVals, timestampVal);
                _attribDefs.CustomEventType.TrySetValue(attribVals, typeVal);
                _attribDefs.GetCustomAttributeForCustomEvent(userAttribKey).TrySetValue(attribVals, userAttribVal);

                var customEvent = new CustomEventWireModel(.5f, attribVals);

                customEvents[i] = customEvent;
                expectedSerializations.Add(expectedSerialization);
            }

            var serialized = JsonConvert.SerializeObject(customEvents);

            Assert.That(serialized, Is.Not.Null);

            var deserialized = JsonConvert.DeserializeObject <List <Dictionary <string, object>[]> >(serialized);

            Assert.That(deserialized, Is.Not.Null);

            Assert.AreEqual(customEvents.Length, deserialized.Count);
            AttributeComparer.CompareDictionaries(expectedSerializations[0], deserialized[0]);
            AttributeComparer.CompareDictionaries(expectedSerializations[1], deserialized[1]);
        }
예제 #6
0
        public void All_attribute_value_types_in_an_event_do_serialize_correctly()
        {
            var attribValues = new AttributeValueCollection(AttributeDestinations.ErrorEvent);


            // ARRANGE
            var userAttributes = new ReadOnlyDictionary <string, object>(new Dictionary <string, object>
            {
                { "identity.user", "samw" },
                { "identity.product", "product" }
            });

            _attribDefs.GetCustomAttributeForError("identity.user").TrySetValue(attribValues, "samw");
            _attribDefs.GetCustomAttributeForError("identity.product").TrySetValue(attribValues, "product");

            var agentAttributes = new ReadOnlyDictionary <string, object>(new Dictionary <string, object>
            {
                { "queue_wait_time_ms", "2000" },
                { "original_url", "www.test.com" },
            });

            _attribDefs.QueueWaitTime.TrySetValue(attribValues, TimeSpan.FromSeconds(2));
            _attribDefs.OriginalUrl.TrySetValue(attribValues, "www.test.com");

            var intrinsicAttributes = new ReadOnlyDictionary <string, object>(new Dictionary <string, object>
            {
                { "databaseCallCount", 10d },
                { "error.message", "This is the error message" },
                { "nr.referringTransactionGuid", "DCBA43211234ABCD" },
            });

            _attribDefs.DatabaseCallCount.TrySetValue(attribValues, 10);
            _attribDefs.ErrorDotMessage.TrySetValue(attribValues, "This is the error message");
            _attribDefs.CatNrPathHash.TrySetValue(attribValues, "DCBA4321");
            _attribDefs.CatReferringPathHash.TrySetValue(attribValues, "1234ABCD");
            _attribDefs.CatReferringTransactionGuidForEvents.TrySetValue(attribValues, "DCBA43211234ABCD");
            _attribDefs.CatAlternativePathHashes.TrySetValue(attribValues, new[] { "55f97a7f", "6fc8d18f", "72827114", "9a3ed934", "a1744603", "a7d2798f", "be1039f5", "ccadfd2c", "da7edf2e", "eaca716b" });

            var isSyntheticsEvent = false;

            // ACT
            float priority            = 0.5f;
            var   errorEventWireModel = new ErrorEventWireModel(attribValues, isSyntheticsEvent, priority);
            var   serialized          = JsonConvert.SerializeObject(errorEventWireModel);
            var   deserialized        = JsonConvert.DeserializeObject <IDictionary <string, object>[]>(serialized);

            // ASSERT
            var expected = new IDictionary <string, object>[3] {
                intrinsicAttributes,
                userAttributes,
                agentAttributes
            };

            AttributeComparer.CompareDictionaries(expected, deserialized);
        }
            public void all_fields_serializes_correctly()
            {
                var attribValues = new AttributeValueCollection(AttributeDestinations.TransactionEvent);

                // ARRANGE
                var userAttributes = new Dictionary <string, object>
                {
                    { "identity.user", "user" },
                    { "identity.product", "product" },
                };

                _attribDefs.GetCustomAttributeForTransaction("identity.user").TrySetValue(attribValues, "user");
                _attribDefs.GetCustomAttributeForTransaction("identity.product").TrySetValue(attribValues, "product");

                var agentAttributes = new Dictionary <string, object>
                {
                    { "request.uri", "www.test.com" },
                };

                _attribDefs.RequestUri.TrySetValue(attribValues, "www.test.com");

                var intrinsicAttributes = new Dictionary <string, object>
                {
                    { "nr.tripId", "1234ABCD1234ABCD" },
                    { "nr.pathHash", "DCBA4321" },
                    { "nr.referringPathHash", "1234ABCD" },
                    { "nr.referringTransactionGuid", "DCBA43211234ABCD" },
                    { "nr.alternatePathHashes", "55f97a7f,6fc8d18f,72827114,9a3ed934,a1744603,a7d2798f,be1039f5,ccadfd2c,da7edf2e,eaca716b" },
                };

                _attribDefs.CatNrTripId.TrySetValue(attribValues, "1234ABCD1234ABCD");
                _attribDefs.CatNrPathHash.TrySetValue(attribValues, "DCBA4321");
                _attribDefs.CatReferringPathHash.TrySetValue(attribValues, "1234ABCD");
                _attribDefs.CatReferringTransactionGuidForEvents.TrySetValue(attribValues, "DCBA43211234ABCD");
                _attribDefs.CatAlternativePathHashes.TrySetValue(attribValues, new[] { "55f97a7f", "6fc8d18f", "72827114", "9a3ed934", "a1744603", "a7d2798f", "be1039f5", "ccadfd2c", "da7edf2e", "eaca716b" });

                var isSytheticsEvent = false;

                var expectedDictionaries = new Dictionary <string, object>[]
                {
                    intrinsicAttributes,
                    userAttributes,
                    agentAttributes
                };

                // ACT
                float priority = 0.5f;
                var   transactionEventWireModel = new TransactionEventWireModel(attribValues, isSytheticsEvent, priority);
                var   actualResult = JsonConvert.SerializeObject(transactionEventWireModel);
                var   deserialized = JsonConvert.DeserializeObject <Dictionary <string, object>[]>(actualResult);

                // ASSERT
                AttributeComparer.CompareDictionaries(expectedDictionaries, deserialized);
            }
예제 #8
0
        public void CompareMatchThrowsExceptionWithNullOptions()
        {
            var oldItem = new TestAttributeDefinition();
            var newItem = new TestAttributeDefinition();
            var match   = new ItemMatch <IAttributeDefinition>(oldItem, newItem);

            var sut = new AttributeComparer();

            Action action = () => sut.CompareMatch(match, null !);

            action.Should().Throw <ArgumentNullException>();
        }
        public void SpansAttributes()
        {
            foreach (var span in SenderAppSpanEvents)
            {
                Assert.Equal(TestTraceId, span.IntrinsicAttributes["traceId"]);
                Assert.True(AttributeComparer.IsEqualTo(SenderAppTxEvent.IntrinsicAttributes["priority"], span.IntrinsicAttributes["priority"]));
            }

            foreach (var span in ReceiverAppSpanEvents)
            {
                Assert.Equal(TestTraceId, span.IntrinsicAttributes["traceId"]);
                Assert.True(AttributeComparer.IsEqualTo(SenderAppTxEvent.IntrinsicAttributes["priority"], span.IntrinsicAttributes["priority"]));
            }
        }
예제 #10
0
        public void CompareMatchReturnsEmptyChangesWhenAttributesDoNotHaveArguments()
        {
            var oldItem = Model.UsingModule <ConfigurationModule>().Ignoring <TestAttributeDefinition>(x => x.Arguments)
                          .Create <TestAttributeDefinition>();
            var newItem = Model.UsingModule <ConfigurationModule>().Ignoring <TestAttributeDefinition>(x => x.Arguments)
                          .Create <TestAttributeDefinition>();
            var match   = new ItemMatch <IAttributeDefinition>(oldItem, newItem);
            var options = OptionsFactory.BuildOptions();

            var sut = new AttributeComparer();

            var actual = sut.CompareMatch(match, options);

            actual.Should().BeEmpty();
        }
예제 #11
0
        public void SpanEventWireModelTests_Serialization()
        {
            const float priority = 1.975676f;
            var         duration = TimeSpan.FromSeconds(4.81);

            var expectedSerialization = new Dictionary <string, object>[3]
            {
                new Dictionary <string, object>
                {
                    { "type", "Span" },
                    { "priority", priority },
                    { "traceId", "ed5bbf27f28ebef3" },
                    { "duration", duration.TotalSeconds }
                },
                new Dictionary <string, object>
                {
                },
                new Dictionary <string, object>
                {
                    { "http.method", "GET" }
                }
            };

            var spanEventWireModel = new SpanAttributeValueCollection();

            spanEventWireModel.Priority = priority;
            _attribDefs.GetTypeAttribute(TypeAttributeValue.Span).TrySetDefault(spanEventWireModel);
            _attribDefs.Priority.TrySetValue(spanEventWireModel, priority);
            _attribDefs.Duration.TrySetValue(spanEventWireModel, duration);
            _attribDefs.DistributedTraceId.TrySetValue(spanEventWireModel, "ed5bbf27f28ebef3");
            _attribDefs.HttpMethod.TrySetValue(spanEventWireModel, "GET");

            var serialized = JsonConvert.SerializeObject(spanEventWireModel);

            Assert.That(serialized, Is.Not.Null);

            var deserialized = JsonConvert.DeserializeObject <Dictionary <string, object>[]>(serialized);

            Assert.That(deserialized, Is.Not.Null);

            AttributeComparer.CompareDictionaries(expectedSerialization, deserialized);
        }
예제 #12
0
        public void CompareMatchReturnsBreakingWhenArgumentsRemoved()
        {
            var oldItem = Model.UsingModule <ConfigurationModule>().Create <TestAttributeDefinition>();
            var newItem = Model.UsingModule <ConfigurationModule>().Ignoring <TestAttributeDefinition>(x => x.Arguments)
                          .Create <IAttributeDefinition>();
            var match   = new ItemMatch <IAttributeDefinition>(oldItem, newItem);
            var options = OptionsFactory.BuildOptions();

            var sut = new AttributeComparer();

            var actual = sut.CompareMatch(match, options).ToList();

            _output.WriteResults(actual);

            actual.Should().HaveCount(1);

            actual[0].ChangeType.Should().Be(SemVerChangeType.Breaking);
            actual[0].OldItem.Should().Be(oldItem);
            actual[0].NewItem.Should().Be(newItem);
        }
        public void Test()
        {
            // attributes

            var headerValueTx = _fixture.AgentLog.TryGetTransactionEvent("WebTransaction/MVC/RabbitMQController/RabbitMQ_SendReceive_HeaderValue");

            var spanEvents = _fixture.AgentLog.GetSpanEvents();

            var produceSpan = spanEvents.Where(@event => @event.IntrinsicAttributes["name"].ToString().Contains("MessageBroker/RabbitMQ/Queue/Produce/Named/"))
                              .FirstOrDefault();

            var consumeSpan = spanEvents.Where(@event => @event.IntrinsicAttributes["name"].ToString().Contains("MessageBroker/RabbitMQ/Queue/Consume/Named/"))
                              .FirstOrDefault();

            Assert.Equal(headerValueTx.IntrinsicAttributes["guid"], produceSpan.IntrinsicAttributes["transactionId"]);
            Assert.Equal(headerValueTx.IntrinsicAttributes["traceId"], produceSpan.IntrinsicAttributes["traceId"]);
            Assert.True(AttributeComparer.IsEqualTo(headerValueTx.IntrinsicAttributes["priority"], produceSpan.IntrinsicAttributes["priority"]),
                        $"priority: expected: {headerValueTx.IntrinsicAttributes["priority"]}, actual: {produceSpan.IntrinsicAttributes["priority"]}");

            Assert.Equal(headerValueTx.IntrinsicAttributes["guid"], consumeSpan.IntrinsicAttributes["transactionId"]);
            Assert.Equal(headerValueTx.IntrinsicAttributes["traceId"], consumeSpan.IntrinsicAttributes["traceId"]);
            Assert.True(AttributeComparer.IsEqualTo(headerValueTx.IntrinsicAttributes["priority"], consumeSpan.IntrinsicAttributes["priority"]),
                        $"priority: expected: {headerValueTx.IntrinsicAttributes["priority"]}, actual: {consumeSpan.IntrinsicAttributes["priority"]}");

            // metrics

            var expectedMetrics = new List <Assertions.ExpectedMetric>
            {
                new Assertions.ExpectedMetric {
                    metricName = $"Supportability/DistributedTrace/CreatePayload/Success", callCount = 1
                },
                new Assertions.ExpectedMetric {
                    metricName = $"Supportability/TraceContext/Create/Success", callCount = 1
                },
            };

            var metrics = _fixture.AgentLog.GetMetrics();

            Assertions.MetricsExist(expectedMetrics, metrics);
        }
예제 #14
0
        public void CompareMatchReturnsEmptyResultsWhenNoChangeFound()
        {
            var ordinalArgument = Model.UsingModule <ConfigurationModule>().Create <TestArgumentDefinition>()
                                  .Set(x => x.ArgumentType = ArgumentType.Ordinal);
            var namedArgument = Model.UsingModule <ConfigurationModule>().Create <TestArgumentDefinition>()
                                .Set(x => x.ArgumentType = ArgumentType.Named);
            var oldArguments = new[]
            {
                ordinalArgument,
                namedArgument
            };
            var attribute = Model.UsingModule <ConfigurationModule>().Create <TestAttributeDefinition>()
                            .Set(x => x.Arguments = oldArguments);
            var match   = new ItemMatch <IAttributeDefinition>(attribute, attribute);
            var options = OptionsFactory.BuildOptions();

            var sut = new AttributeComparer();

            var actual = sut.CompareMatch(match, options).ToList();

            actual.Should().BeEmpty();
        }
            public void only_required_fields_serialize_correctly()
            {
                // Arrange
                var attribValues = new AttributeValueCollection(AttributeDestinations.ErrorEvent);

                var isSytheticsEvent = false;

                var expectedDictionaries = new IDictionary <string, object>[]
                {
                    new Dictionary <string, object>(),
                    new Dictionary <string, object>(),
                    new Dictionary <string, object>()
                };

                // Act
                float priority = 0.5f;
                var   transactionEventWireModel = new TransactionEventWireModel(attribValues, isSytheticsEvent, priority);
                var   actualResult = JsonConvert.SerializeObject(transactionEventWireModel);
                var   deserialized = JsonConvert.DeserializeObject <Dictionary <string, object>[]>(actualResult);

                // Assert
                AttributeComparer.CompareDictionaries(expectedDictionaries, deserialized);
            }
예제 #16
0
        private static void TestPayloadInfoMatchesSpanInfo(DistributedTracePayload payload, ISpanEventWireModel rootSpan, ISpanEventWireModel actualSpan)
        {
            Assert.NotNull(rootSpan);

            var rootSpanIntrinsicAttributes = rootSpan.IntrinsicAttributes();

            Assert.IsTrue(AttributeComparer.IsEqualTo(payload.TraceId, rootSpanIntrinsicAttributes["traceId"]));
            Assert.IsTrue(AttributeComparer.IsEqualTo(payload.Priority, rootSpanIntrinsicAttributes["priority"]));
            Assert.IsTrue(AttributeComparer.IsEqualTo(payload.Sampled, rootSpanIntrinsicAttributes["sampled"]));
            Assert.IsTrue(AttributeComparer.IsEqualTo(payload.Guid, rootSpanIntrinsicAttributes["parentId"]));
            Assert.IsTrue(AttributeComparer.IsEqualTo("generic", rootSpanIntrinsicAttributes["category"]));
            Assert.IsTrue(AttributeComparer.IsEqualTo(true, rootSpanIntrinsicAttributes["nr.entryPoint"]));

            Assert.NotNull(actualSpan);

            var actualSpanIntrinsicAttributes = actualSpan.IntrinsicAttributes();

            Assert.IsTrue(AttributeComparer.IsEqualTo(payload.TraceId, actualSpanIntrinsicAttributes["traceId"]));
            Assert.IsTrue(AttributeComparer.IsEqualTo(payload.Priority, actualSpanIntrinsicAttributes["priority"]));
            Assert.IsTrue(AttributeComparer.IsEqualTo(payload.Sampled, actualSpanIntrinsicAttributes["sampled"]));
            Assert.IsTrue(AttributeComparer.IsEqualTo(rootSpanIntrinsicAttributes["guid"], actualSpanIntrinsicAttributes["parentId"]));
            Assert.IsTrue(AttributeComparer.IsEqualTo(rootSpanIntrinsicAttributes["transactionId"], actualSpanIntrinsicAttributes["transactionId"]));
            Assert.IsTrue(AttributeComparer.IsEqualTo("datastore", actualSpanIntrinsicAttributes["category"]));
        }
        private void ValidateAttributeSettings(AttributesSettings testDataAttributesSettings, IDictionary <string, object> actualEventAttributes)
        {
            testDataAttributesSettings?.Exact?.Keys.ToList().ForEach(attr =>
            {
                Assert.That(actualEventAttributes.ContainsKey(attr), $"Exact attribute not present: {attr}");
                testDataAttributesSettings.Exact.TryGetValue(attr, out var expectedValue);

                var attrValue          = actualEventAttributes[attr];
                var attrType           = attrValue.GetType();
                var typedExpectedValue = Convert.ChangeType(expectedValue, attrType);

                Assert.That(AttributeComparer.IsEqualTo(typedExpectedValue, attrValue), $"{attr}, expected: {typedExpectedValue}, actual: {attrValue}");
            });

            testDataAttributesSettings?.Expected?.ToList().ForEach(attr =>
            {
                Assert.That(actualEventAttributes.ContainsKey(attr), $"{attr}");
            });

            testDataAttributesSettings?.Unexpected?.ToList().ForEach(attr =>
            {
                Assert.That(!actualEventAttributes.ContainsKey(attr), $"{attr}");
            });
        }
        public void Test()
        {
            var senderAppTxEvent = _fixture.FirstCallApplication.AgentLog.GetTransactionEvents().FirstOrDefault();

            Assert.NotNull(senderAppTxEvent);

            var receiverAppTxEvents = _fixture.SecondCallApplication.AgentLog.GetTransactionEvents().FirstOrDefault();

            Assert.NotNull(receiverAppTxEvents);

            var senderAppSpanEvents   = _fixture.FirstCallApplication.AgentLog.GetSpanEvents();
            var receiverAppSpanEvents = _fixture.SecondCallApplication.AgentLog.GetSpanEvents();

            Assert.Equal(senderAppTxEvent.IntrinsicAttributes["guid"], receiverAppTxEvents.IntrinsicAttributes["parentId"]);

            foreach (var span in senderAppSpanEvents)
            {
                Assert.Equal(TestTraceId, span.IntrinsicAttributes["traceId"]);
            }

            foreach (var span in receiverAppSpanEvents)
            {
                Assert.Equal(TestTraceId, span.IntrinsicAttributes["traceId"]);
            }

            var senderRootSpanEvent = senderAppSpanEvents.Where(@event => @event?.IntrinsicAttributes?["name"]?.ToString() == "WebTransaction/MVC/FirstCall/WebRequestCallNext/{nextUrl}").FirstOrDefault();
            var externalSpanEvent   = senderAppSpanEvents.Where(@event => @event?.IntrinsicAttributes?["name"]?.ToString() == "External/localhost/Stream/GET").FirstOrDefault();

            var receiverRootSpanEvent = receiverAppSpanEvents.Where(@event => @event?.IntrinsicAttributes?["name"]?.ToString() == "WebTransaction/MVC/SecondCall/WebRequestCallNext/{nextUrl}").FirstOrDefault();

            Assert.NotNull(senderRootSpanEvent);
            Assert.Equal(TestTracingVendors, senderRootSpanEvent.IntrinsicAttributes["tracingVendors"]);
            Assert.Equal(TestTraceParent, senderRootSpanEvent.IntrinsicAttributes["parentId"]);
            Assert.False(senderRootSpanEvent.IntrinsicAttributes.ContainsKey("trustedParentId"));

            Assert.NotNull(receiverRootSpanEvent);
            Assert.Equal(TestTracingVendors, receiverRootSpanEvent.IntrinsicAttributes["tracingVendors"]);
            Assert.Equal(externalSpanEvent.IntrinsicAttributes["guid"], receiverRootSpanEvent.IntrinsicAttributes["parentId"]);
            Assert.Equal(externalSpanEvent.IntrinsicAttributes["guid"], receiverAppTxEvents.IntrinsicAttributes["parentSpanId"]);
            Assert.Equal(externalSpanEvent.IntrinsicAttributes["guid"], receiverRootSpanEvent.IntrinsicAttributes["trustedParentId"]);
            Assert.True(AttributeComparer.IsEqualTo(senderAppTxEvent.IntrinsicAttributes["priority"], receiverRootSpanEvent.IntrinsicAttributes["priority"]));

            var senderExpectedMetrics = new List <Assertions.ExpectedMetric>
            {
                new Assertions.ExpectedMetric {
                    metricName = @"Supportability/DistributedTrace/CreatePayload/Success", callCount = 1
                },
                new Assertions.ExpectedMetric {
                    metricName = @"Supportability/TraceContext/Accept/Success", callCount = 1
                },
                new Assertions.ExpectedMetric {
                    metricName = @"Supportability/TraceContext/Create/Success", callCount = 1
                },
                new Assertions.ExpectedMetric {
                    metricName = @"Supportability/TraceContext/TraceState/NoNrEntry", callCount = 1
                }
            };

            var accountId = _fixture.SecondCallApplication.AgentLog.GetAccountId();
            var appId     = _fixture.SecondCallApplication.AgentLog.GetApplicationId();

            var receiverExpectedMetrics = new List <Assertions.ExpectedMetric>
            {
                new Assertions.ExpectedMetric {
                    metricName = @"Supportability/TraceContext/Accept/Success", callCount = 1
                },
                new Assertions.ExpectedMetric {
                    metricName = @"Supportability/TraceContext/Create/Success", callCount = 1
                },
                new Assertions.ExpectedMetric {
                    metricName = $@"DurationByCaller/App/{accountId}/{appId}/HTTP/all", callCount = 1
                },
                new Assertions.ExpectedMetric {
                    metricName = $@"DurationByCaller/App/{accountId}/{appId}/HTTP/allWeb", callCount = 1
                },
                new Assertions.ExpectedMetric {
                    metricName = $@"TransportDuration/App/{accountId}/{appId}/HTTP/all", callCount = 1
                },
                new Assertions.ExpectedMetric {
                    metricName = $@"TransportDuration/App/{accountId}/{appId}/HTTP/allWeb", callCount = 1
                }
            };

            var receiverUnexpectedMetrics = new List <Assertions.ExpectedMetric>
            {
                new Assertions.ExpectedMetric {
                    metricName = @"Supportability/TraceContext/TraceState/NoNrEntry", callCount = 1
                }
            };

            var senderActualMetrics   = _fixture.FirstCallApplication.AgentLog.GetMetrics();
            var receiverActualMetrics = _fixture.SecondCallApplication.AgentLog.GetMetrics();

            NrAssert.Multiple(
                () => Assertions.MetricsExist(senderExpectedMetrics, senderActualMetrics),
                () => Assertions.MetricsExist(receiverExpectedMetrics, receiverActualMetrics),
                () => Assertions.MetricsDoNotExist(receiverUnexpectedMetrics, receiverActualMetrics)
                );
        }
예제 #19
0
        public static IChangeCalculator BuildCalculator(ILogger?logger)
        {
            var attributeComparer  = new AttributeComparer();
            var attributeMatcher   = new AttributeEvaluator();
            var attributeProcessor = new AttributeMatchProcessor(attributeMatcher, attributeComparer, logger);

            var accessModifierChangeTable  = new AccessModifiersChangeTable();
            var accessModifiersComparer    = new AccessModifiersComparer(accessModifierChangeTable);
            var memberModifiersChangeTable = new PropertyModifiersChangeTable();
            var memberModifiersComparer    = new PropertyModifiersComparer(memberModifiersChangeTable);

            var genericTypeElementComparer = new GenericTypeElementComparer();

            var fieldModifiersChangeTable = new FieldModifiersChangeTable();
            var fieldModifiersComparer    = new FieldModifiersComparer(fieldModifiersChangeTable);
            var fieldComparer             = new FieldComparer(accessModifiersComparer, fieldModifiersComparer, attributeProcessor);
            var fieldMatcher   = new FieldEvaluator();
            var fieldProcessor = new FieldMatchProcessor(fieldMatcher, fieldComparer, logger);

            var propertyAccessorAccessModifiersChangeTable = new PropertyAccessorAccessModifiersChangeTable();
            var propertyAccessorAccessModifiersComparer    = new PropertyAccessorAccessModifiersComparer(propertyAccessorAccessModifiersChangeTable);
            var propertyAccessorComparer  = new PropertyAccessorComparer(propertyAccessorAccessModifiersComparer, attributeProcessor);
            var propertyAccessorEvaluator = new PropertyAccessorEvaluator();
            var propertyAccessorProcessor =
                new PropertyAccessorMatchProcessor(propertyAccessorEvaluator, propertyAccessorComparer, logger);
            var propertyComparer  = new PropertyComparer(accessModifiersComparer, memberModifiersComparer, propertyAccessorProcessor, attributeProcessor);
            var propertyMatcher   = new PropertyEvaluator();
            var propertyProcessor = new PropertyMatchProcessor(propertyMatcher, propertyComparer, logger);

            var methodEvaluator               = new MethodEvaluator();
            var methodModifiersChangeTable    = new MethodModifiersChangeTable();
            var methodModifiersComparer       = new MethodModifiersComparer(methodModifiersChangeTable);
            var parameterModifiersChangeTable = new ParameterModifiersChangeTable();
            var parameterModifiersComparer    = new ParameterModifiersComparer(parameterModifiersChangeTable);
            var parameterComparer             = new ParameterComparer(parameterModifiersComparer, attributeProcessor);
            var methodComparer  = new MethodComparer(accessModifiersComparer, methodModifiersComparer, genericTypeElementComparer, parameterComparer, attributeProcessor);
            var methodProcessor = new MethodMatchProcessor(methodEvaluator, methodComparer, logger);

            var classModifiersChangeTable = new ClassModifiersChangeTable();
            var classModifiersComparer    = new ClassModifiersComparer(classModifiersChangeTable);
            var classComparer             = new ClassComparer(
                accessModifiersComparer,
                classModifiersComparer,
                genericTypeElementComparer,
                fieldProcessor,
                propertyProcessor,
                methodProcessor, attributeProcessor);

            var interfaceComparer = new InterfaceComparer(
                accessModifiersComparer,
                genericTypeElementComparer,
                propertyProcessor,
                methodProcessor,
                attributeProcessor);

            var structModifiersChangeTable = new StructModifiersChangeTable();
            var structModifiersComparer    = new StructModifiersComparer(structModifiersChangeTable);
            var structComparer             = new StructComparer(
                accessModifiersComparer,
                structModifiersComparer,
                genericTypeElementComparer,
                fieldProcessor,
                propertyProcessor,
                methodProcessor,
                attributeProcessor);

            var aggregateTypeComparer = new AggregateTypeComparer(classComparer, interfaceComparer, structComparer);

            var typeEvaluator = new TypeEvaluator();
            var typeProcessor = new TypeMatchProcessor(typeEvaluator, aggregateTypeComparer, logger);

            return(new ChangeCalculator(typeProcessor, logger));
        }
예제 #20
0
        private DifferenceType CheckAttributeDifferences(IDifferences differences, IReference target, IEnumerable <ICustomAttribute> implAttributes, IEnumerable <ICustomAttribute> contractAttributes)
        {
            DifferenceType difference = DifferenceType.Unchanged;
            AttributesMapping <IEnumerable <ICustomAttribute> > attributeMapping = new AttributesMapping <IEnumerable <ICustomAttribute> >(_settings);
            AttributeComparer attributeComparer = new AttributeComparer();

            attributeMapping.AddMapping(0, contractAttributes.OrderBy(a => a, attributeComparer));
            attributeMapping.AddMapping(1, implAttributes.OrderBy(a => a, attributeComparer));

            foreach (var group in attributeMapping.Attributes)
            {
                switch (group.Difference)
                {
                case DifferenceType.Added:
                {
                    ITypeReference type = group.Representative.Attributes.First().Type;

                    if (AttributeFilter.ShouldExclude(type.DocId()))
                    {
                        break;
                    }

                    // Allow for additions
                    differences.Add(new Difference("AddedAttribute",
                                                   $"Attribute '{type.FullName()}' exists on '{target.FullName()}' in the {Implementation} but not the {Contract}."));

                    break;
                }

                case DifferenceType.Changed:
                {
                    ITypeReference type = group.Representative.Attributes.First().Type;

                    if (AttributeFilter.ShouldExclude(type.DocId()))
                    {
                        break;
                    }

                    string contractKey       = attributeComparer.GetKey(group[0].Attributes.First());
                    string implementationKey = attributeComparer.GetKey(group[1].Attributes.First());

                    differences.AddIncompatibleDifference("CannotChangeAttribute",
                                                          $"Attribute '{type.FullName()}' on '{target.FullName()}' changed from '{contractKey}' in the {Contract} to '{implementationKey}' in the {Implementation}.");

                    difference = DifferenceType.Changed;
                    break;
                }

                case DifferenceType.Removed:
                {
                    ITypeReference type = group.Representative.Attributes.First().Type;

                    if (AttributeFilter.ShouldExclude(type.DocId()))
                    {
                        break;
                    }

                    differences.AddIncompatibleDifference("CannotRemoveAttribute",
                                                          $"Attribute '{type.FullName()}' exists on '{target.FullName()}' in the {Contract} but not the {Implementation}.");


                    // removals of an attribute are considered a "change" of the type
                    difference = DifferenceType.Changed;
                    break;
                }
                }
            }
            return(difference);
        }
예제 #21
0
        private bool CheckAttributeDifferences(IDifferences differences, IReference target, IEnumerable <ICustomAttribute> implAttributes, IEnumerable <ICustomAttribute> contractAttributes, IReference member = null)
        {
            AttributesMapping <IEnumerable <ICustomAttribute> > attributeMapping = new AttributesMapping <IEnumerable <ICustomAttribute> >(_settings);
            AttributeComparer attributeComparer = new AttributeComparer();

            attributeMapping.AddMapping(0, contractAttributes.OrderBy(a => a, attributeComparer));
            attributeMapping.AddMapping(1, implAttributes.OrderBy(a => a, attributeComparer));

            string errString = $"'{target.FullName()}'";

            if (target is IParameterDefinition || target is IGenericParameter)
            {
                errString  = target is IGenericParameter ? "generic param" : "parameter";
                errString += $" '{target.FullName()}' on member '{member?.FullName()}'";
            }

            bool changed = false;

            foreach (var group in attributeMapping.Attributes)
            {
                switch (group.Difference)
                {
                case DifferenceType.Added:
                {
                    ITypeReference type = group.Representative.Attributes.First().Type;

                    if (AttributeFilter.ShouldExclude(type.DocId()))
                    {
                        break;
                    }

                    // Allow for additions
                    differences.Add(new Difference("AddedAttribute",
                                                   $"Attribute '{type.FullName()}' exists on {errString} in the {Implementation} but not the {Contract}."));

                    changed = true;
                    break;
                }

                case DifferenceType.Changed:
                {
                    ITypeReference type = group.Representative.Attributes.First().Type;

                    if (AttributeFilter.ShouldExclude(type.DocId()))
                    {
                        break;
                    }

                    string contractKey       = attributeComparer.GetKey(group[0].Attributes.First());
                    string implementationKey = attributeComparer.GetKey(group[1].Attributes.First());

                    differences.AddIncompatibleDifference("CannotChangeAttribute",
                                                          $"Attribute '{type.FullName()}' on {errString} changed from '{contractKey}' in the {Contract} to '{implementationKey}' in the {Implementation}.");

                    changed = true;
                    break;
                }

                case DifferenceType.Removed:
                {
                    ITypeReference type = group.Representative.Attributes.First().Type;

                    if (AttributeFilter.ShouldExclude(type.DocId()))
                    {
                        break;
                    }

                    differences.AddIncompatibleDifference("CannotRemoveAttribute",
                                                          $"Attribute '{type.FullName()}' exists on {errString} in the {Contract} but not the {Implementation}.");


                    // removals of an attribute are considered a "change" of the type
                    changed = true;
                    break;
                }
                }
            }
            return(changed);
        }
        public void Test()
        {
            // transaction attributes

            var produceTx = _fixture.AgentLog.TryGetTransactionEvent("WebTransaction/MVC/RabbitMQController/RabbitMQ_SendReceiveWithEventingConsumer");
            var consumeTx = _fixture.AgentLog.TryGetTransactionEvent($"OtherTransaction/Message/RabbitMQ/Queue/Named/{_queueName}");

            Assert.Equal(consumeTx.IntrinsicAttributes["traceId"], produceTx.IntrinsicAttributes["traceId"]);
            Assert.True(AttributeComparer.IsEqualTo(produceTx.IntrinsicAttributes["priority"], consumeTx.IntrinsicAttributes["priority"]),
                        $"priority: expected: {produceTx.IntrinsicAttributes["priority"]}, actual: {consumeTx.IntrinsicAttributes["priority"]}");
            Assert.Equal(consumeTx.IntrinsicAttributes["parentId"], produceTx.IntrinsicAttributes["guid"]);
            Assert.Equal("AMQP", consumeTx.IntrinsicAttributes["parent.transportType"]);

            // span attributes

            _fixture.AgentLog.GetSpanEvents().ToList().ForEach
                (span =>
            {
                Assert.Equal(produceTx.IntrinsicAttributes["traceId"], span.IntrinsicAttributes["traceId"]);
                Assert.True(AttributeComparer.IsEqualTo(produceTx.IntrinsicAttributes["priority"], span.IntrinsicAttributes["priority"]),
                            $"priority: expected: {produceTx.IntrinsicAttributes["priority"]}, actual: {span.IntrinsicAttributes["priority"]}");
            });

            var produceSpan = _fixture.AgentLog.TryGetSpanEvent($"MessageBroker/RabbitMQ/Queue/Produce/Named/{_queueName}");
            var consumeSpan = _fixture.AgentLog.TryGetSpanEvent($"MessageBroker/RabbitMQ/Queue/Consume/Named/{_queueName}");

            Assert.Equal(produceTx.IntrinsicAttributes["guid"], produceSpan.IntrinsicAttributes["transactionId"]);
            Assert.Equal(consumeTx.IntrinsicAttributes["guid"], consumeSpan.IntrinsicAttributes["transactionId"]);

            Assert.Equal(consumeTx.IntrinsicAttributes["parentSpanId"], produceSpan.IntrinsicAttributes["guid"]);

            // metrics
            var acctId = _fixture.AgentLog.GetAccountId();
            var appId  = _fixture.AgentLog.GetApplicationId();

            var expectedMetrics = new List <Assertions.ExpectedMetric>
            {
                new Assertions.ExpectedMetric {
                    metricName = $"DurationByCaller/App/{acctId}/{appId}/AMQP/all", callCount = 1
                },
                new Assertions.ExpectedMetric {
                    metricName = $"DurationByCaller/App/{acctId}/{appId}/AMQP/allOther", callCount = 1
                },

                new Assertions.ExpectedMetric {
                    metricName = $"TransportDuration/App/{acctId}/{appId}/AMQP/all", callCount = 1
                },
                new Assertions.ExpectedMetric {
                    metricName = $"TransportDuration/App/{acctId}/{appId}/AMQP/allOther", callCount = 1
                },

                new Assertions.ExpectedMetric {
                    metricName = $"Supportability/DistributedTrace/CreatePayload/Success", callCount = 2
                },
                new Assertions.ExpectedMetric {
                    metricName = $"Supportability/TraceContext/Create/Success", callCount = 2
                },
                new Assertions.ExpectedMetric {
                    metricName = $"Supportability/TraceContext/Accept/Success", callCount = 2
                }
            };

            var metrics = _fixture.AgentLog.GetMetrics();

            Assertions.MetricsExist(expectedMetrics, metrics);
        }