Exemple #1
0
        public void CanSerializeCircularObjectGraphs()
        {
            var charlie = new EntityWithChildren()
            {
                Name = "Charlie"
            };
            var bravo = new EntityWithChildren("Bravo", new EntityWithChildren[] { charlie });
            var alpha = new EntityWithChildren("Alpha", new EntityWithChildren[] { bravo });

            charlie.Children.Add(alpha); // Establish a cycle Alpha -> Bravo -> Charlie -> Alpha

            // Also form a cycle of direct "Sibling" references the other way round, i.e Charlie -> Bravo -> Alpha -> Charlie
            charlie.Sibling = bravo;
            bravo.Sibling   = alpha;
            alpha.Sibling   = charlie;

            var healthReporterMock = new Mock <IHealthReporter>();
            var observer           = new Mock <IObserver <EventData> >();
            IDictionary <string, object> spiedPayload = null;

            observer.Setup(p => p.OnNext(It.IsAny <EventData>()))
            .Callback <EventData>((p) => { spiedPayload = p.Payload; });

            SerilogInputConfiguration configuration = new SerilogInputConfiguration()
            {
                UseSerilogDepthLevel = true
            };

            const int MaxDepth = 10;

            using (var serilogInput = new SerilogInput(configuration, healthReporterMock.Object))
                using (serilogInput.Subscribe(observer.Object))
                {
                    var logger = new LoggerConfiguration().WriteTo.Sink(serilogInput).Destructure.ToMaximumDepth(MaxDepth).CreateLogger();

                    logger.Information("Here is an {@entity}", alpha);
                }

            // The fact that the loging of alpha succeeds at all (instead of going into an infinite loop) is already a good sign :-)

            IDictionary <string, object> entity = (IDictionary <string, object>)spiedPayload["entity"];

            object[] children = null;
            int      depth    = 0;

            while (entity != null && entity.ContainsKey("Children"))
            {
                children = entity["Children"] as object[];
                entity   = null;
                if (children != null && children.Length > 0)
                {
                    entity = children[0] as IDictionary <string, object>;
                }

                depth++;
            }

            // Every child increases depth by two because the Children property is and array.
            Assert.Equal(MaxDepth / 2, depth);
        }
        public async void AuditChanges_InsertEntityWithChildrenAndAddChildren_AddsAuditLogWithExpectedForeignKeyJson()
        {
            using (DatabaseWrapper database = new DatabaseWrapper())
            {
                //Arrange
                Guid         userId = Guid.Parse("F37FEB8F-A364-47F6-86A5-02E191E8AF20");
                SimpleEntity sA     = new SimpleEntity("Simple A");
                SimpleEntity sB     = new SimpleEntity("Simple B");
                database.TestContext.SimpleEntities.AddRange(new List <SimpleEntity> {
                    sA, sB
                });

                EntityWithChildren ewc = new EntityWithChildren(sA, sB);
                database.TestContext.ParentEntities.Add(ewc);
                database.TestContext.SetEntityId();

                //Act
                database.TestContext.AuditChanges(userId);
                await database.TestContext.SaveChangesAsync();

                //Assert
                //Audit Log stores correct json, with foreign keys
                Guid   ewcId        = database.TestContext.ParentEntities.Single().Id;
                Guid   sBId         = database.TestContext.SimpleEntities.Single(se => se.Data == "Simple B").Id;
                String expectedJson =
                    "{\\\"Id\\\":\\\"" + ewcId + "\\\",\\\"SimpleEntityBId\\\":\\\"" + sBId + "\\\",\\\"RowVersion\\\":null}";
                Assert.Matches(expectedJson,
                               database.TestContext.AuditLogs.Single(al => al.RecordId == ewcId).NewValue);
            }
        }
        public async void AuditChanges_InsertEntityWithChildrenAndUpdateChildren_AddsAuditLogWithExpectedOriginalForeignKeyJson()
        {
            using (DatabaseWrapper database = new DatabaseWrapper())
            {
                //Arrange
                //Add initial entities
                Guid         userId = Guid.Parse("F37FEB8F-A364-47F6-86A5-02E191E8AF20");
                SimpleEntity sA     = new SimpleEntity("Simple A");
                SimpleEntity sB     = new SimpleEntity("Simple B");
                database.TestContext.SimpleEntities.AddRange(new List <SimpleEntity> {
                    sA, sB
                });
                EntityWithChildren ewc = new EntityWithChildren(sA, sB);
                database.TestContext.ParentEntities.Add(ewc);
                database.TestContext.SetEntityId();
                database.TestContext.AuditChanges(userId);
                await database.TestContext.SaveChangesAsync();

                // Update exisiting EntityWithChildren with new child entity
                SimpleEntity sBv2 = new SimpleEntity("Simple B Version 2");
                database.TestContext.SimpleEntities.Add(sBv2);
                ewc.UpdateSimpleEntityB(sBv2);
                database.TestContext.SetEntityId();

                //Act
                database.TestContext.AuditChanges(userId);
                await database.TestContext.SaveChangesAsync();

                //Assert
                //Audit Log stores correct original json, with foreign keys
                Guid   ewcId = database.TestContext.ParentEntities.Single().Id;
                Guid   sBId  = database.TestContext.SimpleEntities.Single(se => se.Data == "Simple B").Id;
                String expectedOriginalJson =
                    "{\\\"Id\\\":\\\"" + ewcId + "\\\",\\\"SimpleEntityBId\\\":\\\"" + sBId + "\\\",\\\"RowVersion\\\":.*}";
                List <AuditLog> orderedLogs = database.TestContext.AuditLogs.OrderBy(a => a.EventDate).ToList();
                Assert.Matches(expectedOriginalJson, orderedLogs.Last(al => al.RecordId == ewcId).OriginalValue);
            }
        }
Exemple #4
0
        public void UsesSerilogMaxDestructuringDepth()
        {
            // Create object structure 5 levels deep
            var bravo = new EntityWithChildren()
            {
                Name = "Bravo"
            };
            var alpha = new EntityWithChildren("Alpha", new EntityWithChildren[] { bravo });

            var healthReporterMock = new Mock <IHealthReporter>();
            var observer           = new Mock <IObserver <EventData> >();
            IDictionary <string, object> spiedPayload = null;

            observer.Setup(p => p.OnNext(It.IsAny <EventData>()))
            .Callback <EventData>((p) => { spiedPayload = p.Payload; });

            SerilogInputConfiguration configuration = new SerilogInputConfiguration()
            {
                UseSerilogDepthLevel = true
            };


            using (var serilogInput = new SerilogInput(configuration, healthReporterMock.Object))
                using (serilogInput.Subscribe(observer.Object))
                {
                    var logger = new LoggerConfiguration().WriteTo.Sink(serilogInput).Destructure.ToMaximumDepth(2).CreateLogger();

                    logger.Information("Here is an {@entity}", alpha);
                }

            // At depth 2 there should be no children (only a null child placeholder)
            var e = (IDictionary <string, object>)spiedPayload["entity"];

            Assert.Equal("Alpha", e["Name"]);
            Assert.Collection((object[])e["Children"], c => Assert.Null(c));


            using (var serilogInput = new SerilogInput(configuration, healthReporterMock.Object))
                using (serilogInput.Subscribe(observer.Object))
                {
                    var logger = new LoggerConfiguration().WriteTo.Sink(serilogInput).Destructure.ToMaximumDepth(3).CreateLogger();

                    logger.Information("Here is an {@entity}", alpha);
                }

            // At depth 3 there should be one child of Alpha, but all its properties should be blank
            Assert.Equal("Alpha", ((IDictionary <string, object>)spiedPayload["entity"])["Name"]);
            var childrenOfAlpha = ((IDictionary <string, object>)spiedPayload["entity"])["Children"] as object[];

            Assert.Single(childrenOfAlpha);
            var b = childrenOfAlpha.First() as IDictionary <string, object>;

            Assert.True(b.ContainsKey("Name"));
            Assert.Null(b["Name"]);
            Assert.True(b.ContainsKey("Children"));
            Assert.Null(b["Children"]);


            using (var serilogInput = new SerilogInput(configuration, healthReporterMock.Object))
                using (serilogInput.Subscribe(observer.Object))
                {
                    var logger = new LoggerConfiguration().WriteTo.Sink(serilogInput).Destructure.ToMaximumDepth(4).CreateLogger();

                    logger.Information("Here is an {@entity}", alpha);
                }

            // At depth 4 the child of Alpha (Bravo) should have its properties set, "Name" in particular.
            Assert.Equal("Alpha", ((IDictionary <string, object>)spiedPayload["entity"])["Name"]);
            childrenOfAlpha = ((IDictionary <string, object>)spiedPayload["entity"])["Children"] as object[];
            Assert.Single(childrenOfAlpha);
            b = childrenOfAlpha.First() as IDictionary <string, object>;
            Assert.Equal("Bravo", b["Name"]);
        }