public async Task ReadNoTable()
        {
            ILogReader reader = LogFactory.NewReader(this);

            Assert.Empty(_tables); // no tables yet.

            var segmentDef = await reader.GetFunctionDefinitionsAsync(null, null);

            Assert.Empty(segmentDef.Results);

            var segmentTimeline = await reader.GetActiveContainerTimelineAsync(DateTime.MinValue, DateTime.MaxValue, null);

            Assert.Empty(segmentTimeline.Results);

            var segmentRecent = await reader.GetRecentFunctionInstancesAsync(new RecentFunctionQuery
            {
                FunctionId     = FunctionId.Parse("abc"),
                Start          = DateTime.MinValue,
                End            = DateTime.MaxValue,
                MaximumResults = 1000
            }, null);

            Assert.Empty(segmentRecent.Results);

            var item = await reader.LookupFunctionInstanceAsync(Guid.NewGuid());

            Assert.Null(item);
        }
        public async Task ReadNoTable()
        {
            var        table  = GetNewLoggingTable();
            ILogReader reader = LogFactory.NewReader(table);

            Assert.False(table.Exists());

            var segmentDef = await reader.GetFunctionDefinitionsAsync(null);

            Assert.Equal(0, segmentDef.Results.Length);

            var segmentTimeline = await reader.GetActiveContainerTimelineAsync(DateTime.MinValue, DateTime.MaxValue, null);

            Assert.Equal(0, segmentTimeline.Results.Length);

            var segmentRecent = await reader.GetRecentFunctionInstancesAsync(new RecentFunctionQuery
            {
                FunctionName   = "abc",
                Start          = DateTime.MinValue,
                End            = DateTime.MaxValue,
                MaximumResults = 1000
            }, null);

            Assert.Equal(0, segmentRecent.Results.Length);

            var item = await reader.LookupFunctionInstanceAsync(Guid.NewGuid());

            Assert.Null(item);
        }
Exemple #3
0
        private async Task <FunctionInstanceSnapshot> LookupAsync(Guid id)
        {
            var t = await _reader.LookupFunctionInstanceAsync(id);

            if (t == null)
            {
                return(null);
            }
            return(t.ConvertToSnapshot());
        }
        public async Task LargeWritesWithParametersAreTruncated()
        {
            ILogWriter writer = LogFactory.NewWriter(defaultHost, "c1", this);
            ILogReader reader = LogFactory.NewReader(this);

            // Max table request size is 4mb. That gives roughly 40kb per row.
            string largeValue      = new string('x', 100 * 1000);
            string truncatedPrefix = largeValue.Substring(0, 100);

            List <Guid> functionIds = new List <Guid>();

            for (int i = 0; i < 90; i++)
            {
                var functionId = Guid.NewGuid();
                functionIds.Add(functionId);
                var now  = DateTime.UtcNow;
                var item = new FunctionInstanceLogItem
                {
                    FunctionInstanceId = functionId,
                    Arguments          = new Dictionary <string, string>(),
                    StartTime          = now,
                    EndTime            = now.AddSeconds(3),
                    FunctionName       = "tst2",
                    LogOutput          = largeValue,
                    ErrorDetails       = largeValue,
                    TriggerReason      = largeValue
                };
                for (int j = 0; j < 1000; j++)
                {
                    string paramName = "p" + j.ToString();
                    item.Arguments[paramName] = largeValue;
                }

                await writer.AddAsync(item);
            }

            // If we didn't truncate, then this would throw with a 413 "too large" exception.
            await writer.FlushAsync();

            // If we got here without an exception, then we successfully truncated the rows.
            // Lookup and verify
            var instance = await reader.LookupFunctionInstanceAsync(functionIds[0]);

            Assert.True(instance.LogOutput.StartsWith(truncatedPrefix));
            Assert.True(instance.ErrorDetails.StartsWith(truncatedPrefix));
            Assert.True(instance.TriggerReason.StartsWith(truncatedPrefix));

            Assert.Equal(0, instance.Arguments.Count); // totally truncated.
        }
        public async Task DifferentHosts()
        {
            // 1a & 1b are 2 instances (different machines) of the same host. They share.
            // 2 is a separate host.
            string     host1    = "h1-1"; // includes an tricky character that requires escaping.
            string     host2    = "h22";
            ILogWriter writer1a = LogFactory.NewWriter(host1, "c1", this);
            ILogWriter writer1b = LogFactory.NewWriter(host1, "c2", this);
            ILogWriter writer2  = LogFactory.NewWriter(host2, "c3", this);

            ILogReader reader1 = LogFactory.NewReader(this);
            ILogReader reader2 = LogFactory.NewReader(this);

            string Func1 = "alpha";

            var f1a = await QuickWriteAsync(writer1a, Func1); // first

            var f1b = await QuickWriteAsync(writer1b, Func1);

            var f1aa = await QuickWriteAsync(writer1a, Func1); // second write

            var f2 = await QuickWriteAsync(writer2, Func1);

            // Verify readers
            // Function definitions. Search all hosts if no host specified
            {
                var segment = await reader1.GetFunctionDefinitionsAsync(null, null);

                Assert.Equal(2, segment.Results.Length);
                var allDefinitions = segment.Results;

                segment = await reader1.GetFunctionDefinitionsAsync(host1, null);

                Assert.Single(segment.Results);
                var host1Defs = segment.Results[0];
                Assert.Equal(Func1, host1Defs.Name);
                Assert.Equal(FunctionId.Build(host1, Func1), host1Defs.FunctionId);

                segment = await reader1.GetFunctionDefinitionsAsync(host2, null);

                Assert.Single(segment.Results);
                var host2Defs = segment.Results[0];
                Assert.Equal(Func1, host2Defs.Name);
                Assert.Equal(FunctionId.Build(host2, Func1), host2Defs.FunctionId);

                Assert.Equal(Func1, allDefinitions[0].Name);
                Assert.Equal(Func1, allDefinitions[1].Name);
                Assert.Equal(host1Defs.FunctionId, allDefinitions[0].FunctionId);
                Assert.Equal(host2Defs.FunctionId, allDefinitions[1].FunctionId);
            }

            // Recent list
            {
                var segment = await reader1.GetRecentFunctionInstancesAsync(new RecentFunctionQuery
                {
                    FunctionId = FunctionId.Build(host1, Func1),
                    End        = DateTime.MaxValue,
                }, null);

                Guid[] guids = Array.ConvertAll(segment.Results, x => x.FunctionInstanceId);

                Assert.Equal(3, guids.Length); // Only include host 1
                Assert.Equal(f1a, guids[2]);   // reverse chronological
                Assert.Equal(f1b, guids[1]);
                Assert.Equal(f1aa, guids[0]);
            }

            // cross polination. Lookup across hosts.
            {
                var entry = await reader2.LookupFunctionInstanceAsync(f1a);

                Assert.NotNull(entry);
                Assert.Equal(entry.FunctionName, Func1);
            }
        }
        public async Task TimeRangeAcrossEpochs()
        {
            // Make some very precise writes and verify we read exactly what we'd expect.
            ILogWriter writer = LogFactory.NewWriter(defaultHost, "c1", this);
            ILogReader reader = LogFactory.NewReader(this);

            // Time that functios are called.
            DateTime[] times = new DateTime[] {
                // Epoch 37
                new DateTime(2012, 3, 6, 10, 11, 20, DateTimeKind.Utc),
                new DateTime(2012, 3, 7, 10, 11, 20, DateTimeKind.Utc),

                // consecutive Epoch 38
                new DateTime(2012, 4, 8, 10, 11, 20, DateTimeKind.Utc),

                // Skip to Epoch  41
                new DateTime(2012, 7, 9, 10, 11, 20, DateTimeKind.Utc)
            };

            var logs = Array.ConvertAll(times, time => new FunctionInstanceLogItem
            {
                FunctionInstanceId = Guid.NewGuid(),
                FunctionName       = commonFuncName1,
                StartTime          = time,
            });

            var tasks = Array.ConvertAll(logs, log => WriteAsync(writer, log));
            await Task.WhenAll(tasks);

            await writer.FlushAsync();

            // Test point lookups for individual function instances.
            foreach (var log in logs)
            {
                var entry = await reader.LookupFunctionInstanceAsync(log.FunctionInstanceId);

                Assert.NotNull(entry);

                Assert.Equal(log.FunctionInstanceId, entry.FunctionInstanceId);
                Assert.Equal(log.FunctionName, entry.FunctionName);
                Assert.Equal(log.StartTime, entry.StartTime);
                Assert.Equal(log.EndTime, entry.EndTime);
            }

            // Try various combinations.
            await Verify(reader, DateTime.MinValue, DateTime.MaxValue, logs[3], logs[2], logs[1], logs[0]); // Infinite range, includes all.

            // Various combinations of straddling an epoch boundary
            await Verify(reader, Before(times[1]), After(times[2]), logs[2], logs[1]);
            await Verify(reader, Before(times[1]), Before(times[2]), logs[1]);
            await Verify(reader, After(times[1]), Before(times[2]));

            // Skipping over an empty epoch
            await Verify(reader, Before(times[1]), Before(times[3]), logs[2], logs[1]);

            // Now... delete the middle table; and verify the other data is still there.
            ILogTableProvider provider = this;
            var table = provider.GetTable("201204");

            Assert.True(await table.ExistsAsync());
            await table.DeleteAsync();

            await Verify(reader, DateTime.MinValue, DateTime.MaxValue, logs[3], logs[1], logs[0]); // Infinite range, includes all.

            // function instance entry from the table we deleted is now missing.
            var entry2 = await reader.LookupFunctionInstanceAsync(logs[2].FunctionInstanceId);

            Assert.Null(entry2);
        }