コード例 #1
0
ファイル: LogsProviderTest.cs プロジェクト: nlcamp/iotedge
        public async Task GetLogsAsTextTest()
        {
            // Arrange
            string            iotHub            = "foo.azure-devices.net";
            string            deviceId          = "dev1";
            string            moduleId          = "mod1";
            Option <int>      tail              = Option.None <int>();
            Option <string>   since             = Option.None <string>();
            Option <string>   until             = Option.None <string>();
            Option <bool>     includeTimestamp  = Option.None <bool>();
            CancellationToken cancellationToken = CancellationToken.None;
            string            expectedLogText   = TestLogTexts.Join(string.Empty);

            var runtimeInfoProvider = new Mock <IRuntimeInfoProvider>();

            runtimeInfoProvider.Setup(r => r.GetModuleLogs(moduleId, false, tail, since, until, includeTimestamp, cancellationToken))
            .ReturnsAsync(new MemoryStream(DockerFraming.Frame(TestLogTexts)));

            var logsProcessor = new LogsProcessor(new LogMessageParser(iotHub, deviceId));
            var logsProvider  = new LogsProvider(runtimeInfoProvider.Object, logsProcessor);

            var logOptions = new ModuleLogOptions(LogsContentEncoding.None, LogsContentType.Text, ModuleLogFilter.Empty, LogOutputFraming.None, Option.None <LogsOutputGroupingConfig>(), false);

            // Act
            byte[] bytes = await logsProvider.GetLogs(moduleId, logOptions, cancellationToken);

            // Assert
            string logsText = Encoding.UTF8.GetString(bytes);

            Assert.Equal(expectedLogText, logsText);
        }
コード例 #2
0
        protected override async Task <Option <object> > HandleRequestInternal(Option <LogsUploadRequest> payloadOption, CancellationToken cancellationToken)
        {
            LogsUploadRequest payload = payloadOption.Expect(() => new ArgumentException("Request payload not found"));

            async Task <IList <string> > GetModuleIds()
            {
                if (payload.Id == Constants.AllModulesIdentifier)
                {
                    IEnumerable <ModuleRuntimeInfo> modules = await this.runtimeInfoProvider.GetModules(cancellationToken);

                    return(modules.Select(m => m.Name).ToList());
                }
                else
                {
                    return(new List <string> {
                        payload.Id
                    });
                }
            }

            var            moduleLogOptions = new ModuleLogOptions(payload.Encoding, payload.ContentType, payload.Filter);
            IList <string> moduleIds        = await GetModuleIds();

            IEnumerable <Task> uploadTasks = moduleIds.Select(m => this.UploadLogs(payload.SasUrl, m, moduleLogOptions, cancellationToken));
            await Task.WhenAll(uploadTasks);

            return(Option.None <object>());
        }
コード例 #3
0
        public async Task TestLogsUploadAllTaskRequest()
        {
            // Arrange
            string sasUrl = $"https://test1.blob.core.windows.net/cont2?st={Guid.NewGuid()}";
            var    filter = new ModuleLogFilter(Option.Some(100), Option.Some(1501000), Option.Some(3), Option.Some("ERR"));
            LogsContentEncoding contentEncoding = LogsContentEncoding.None;
            LogsContentType     contentType     = LogsContentType.Json;
            string payload = @"{""id"": ""all"",  ""sasUrl"": ""<sasurl>"", ""filter"": <filter>}".Replace("<sasurl>", sasUrl).Replace("<filter>", filter.ToJson());

            string mod1 = "m1";
            string mod2 = "m2";
            string mod3 = "m3";
            var    moduleRuntimeInfoList = new List <ModuleRuntimeInfo>
            {
                new ModuleRuntimeInfo(mod1, "docker", ModuleStatus.Running, string.Empty, 0, Option.None <DateTime>(), Option.None <DateTime>()),
                new ModuleRuntimeInfo(mod2, "docker", ModuleStatus.Running, string.Empty, 0, Option.None <DateTime>(), Option.None <DateTime>()),
                new ModuleRuntimeInfo(mod3, "docker", ModuleStatus.Running, string.Empty, 0, Option.None <DateTime>(), Option.None <DateTime>())
            };
            var runtimeInfoProvider = new Mock <IRuntimeInfoProvider>();

            runtimeInfoProvider.Setup(r => r.GetModules(It.IsAny <CancellationToken>()))
            .ReturnsAsync(moduleRuntimeInfoList);

            var logsUploader = new Mock <ILogsUploader>();
            var logsProvider = new Mock <ILogsProvider>();

            var module1LogOptions = new ModuleLogOptions(contentEncoding, contentType, filter);
            var mod1LogBytes      = new byte[100];

            logsProvider.Setup(l => l.GetLogs(mod1, module1LogOptions, It.IsAny <CancellationToken>()))
            .ReturnsAsync(mod1LogBytes);
            logsUploader.Setup(l => l.Upload(sasUrl, mod1, mod1LogBytes, contentEncoding, contentType))
            .Returns(Task.CompletedTask);

            var module2LogOptions = new ModuleLogOptions(contentEncoding, contentType, filter);
            var mod2LogBytes      = new byte[80];

            logsProvider.Setup(l => l.GetLogs(mod2, module2LogOptions, It.IsAny <CancellationToken>()))
            .ReturnsAsync(mod2LogBytes);
            logsUploader.Setup(l => l.Upload(sasUrl, mod2, mod2LogBytes, contentEncoding, contentType))
            .Returns(Task.CompletedTask);

            var module3LogOptions = new ModuleLogOptions(contentEncoding, contentType, filter);
            var mod3LogBytes      = new byte[120];

            logsProvider.Setup(l => l.GetLogs(mod3, module3LogOptions, It.IsAny <CancellationToken>()))
            .ReturnsAsync(mod3LogBytes);
            logsUploader.Setup(l => l.Upload(sasUrl, mod3, mod3LogBytes, contentEncoding, contentType))
            .Returns(Task.CompletedTask);

            // Act
            var             logsUploadRequestHandler = new LogsUploadRequestHandler(logsUploader.Object, logsProvider.Object, runtimeInfoProvider.Object);
            Option <string> response = await logsUploadRequestHandler.HandleRequest(Option.Maybe(payload), CancellationToken.None);

            // Assert
            Assert.False(response.HasValue);
            logsProvider.VerifyAll();
            logsUploader.VerifyAll();
            runtimeInfoProvider.VerifyAll();
        }
コード例 #4
0
        public async Task GetLogsAsTextWithCompressionTest()
        {
            // Arrange
            string            iotHub            = "foo.azure-devices.net";
            string            deviceId          = "dev1";
            string            moduleId          = "mod1";
            Option <int>      tail              = Option.None <int>();
            Option <int>      since             = Option.None <int>();
            CancellationToken cancellationToken = CancellationToken.None;
            string            expectedLogText   = TestLogTexts.Join(string.Empty);

            var runtimeInfoProvider = new Mock <IRuntimeInfoProvider>();

            runtimeInfoProvider.Setup(r => r.GetModuleLogs(moduleId, false, tail, since, cancellationToken))
            .ReturnsAsync(new MemoryStream(DockerFraming.Frame(TestLogTexts)));

            var logsProcessor = new LogsProcessor(new LogMessageParser(iotHub, deviceId));
            var logsProvider  = new LogsProvider(runtimeInfoProvider.Object, logsProcessor);

            var logOptions = new ModuleLogOptions(LogsContentEncoding.Gzip, LogsContentType.Text, ModuleLogFilter.Empty);

            // Act
            byte[] bytes = await logsProvider.GetLogs(moduleId, logOptions, cancellationToken);

            // Assert
            byte[] decompressedBytes = Compression.DecompressFromGzip(bytes);
            string logsText          = Encoding.UTF8.GetString(decompressedBytes);

            Assert.Equal(expectedLogText, logsText);
        }
コード例 #5
0
        public async Task TestLogsUploadRequest(string payload, string id, string sasUrl, LogsContentEncoding contentEncoding, LogsContentType contentType, ModuleLogFilter filter)
        {
            // Arrange
            var logsUploader     = new Mock <IRequestsUploader>();
            var logsProvider     = new Mock <ILogsProvider>();
            var uploadBytes      = new byte[100];
            var moduleLogOptions = new ModuleLogOptions(contentEncoding, contentType, filter, LogOutputFraming.None, Option.None <LogsOutputGroupingConfig>(), false);

            if (contentType == LogsContentType.Text)
            {
                Func <ArraySegment <byte>, Task> getLogsCallback = bytes => Task.CompletedTask;
                logsUploader.Setup(l => l.GetLogsUploaderCallback(sasUrl, id, contentEncoding, contentType))
                .ReturnsAsync(getLogsCallback);
                logsProvider.Setup(l => l.GetLogsStream(id, moduleLogOptions, getLogsCallback, It.IsAny <CancellationToken>()))
                .Returns(Task.CompletedTask);
            }
            else
            {
                logsProvider.Setup(l => l.GetLogs(id, It.IsAny <ModuleLogOptions>(), It.IsAny <CancellationToken>()))
                .ReturnsAsync(uploadBytes);
                logsUploader.Setup(l => l.UploadLogs(sasUrl, id, uploadBytes, contentEncoding, contentType))
                .Returns(Task.CompletedTask);
            }

            IEnumerable <ModuleRuntimeInfo> moduleRuntimeInfoList = new List <ModuleRuntimeInfo>
            {
                new ModuleRuntimeInfo(id, "docker", ModuleStatus.Running, string.Empty, 0, Option.None <DateTime>(), Option.None <DateTime>())
            };

            var runtimeInfoProvider = Mock.Of <IRuntimeInfoProvider>(r => r.GetModules(It.IsAny <CancellationToken>()) == Task.FromResult(moduleRuntimeInfoList));

            // Act
            var             logsUploadRequestHandler = new ModuleLogsUploadRequestHandler(logsUploader.Object, logsProvider.Object, runtimeInfoProvider);
            Option <string> response = await logsUploadRequestHandler.HandleRequest(Option.Maybe(payload), CancellationToken.None);

            // Assert
            Assert.True(response.HasValue);
            var taskStatusResponse = response.OrDefault().FromJson <TaskStatusResponse>();

            Assert.NotNull(taskStatusResponse);
            Assert.NotEmpty(taskStatusResponse.CorrelationId);
            Assert.Equal(string.Empty, taskStatusResponse.Message);

            await WaitForBackgroundTaskCompletion(taskStatusResponse.CorrelationId).TimeoutAfter(TimeSpan.FromSeconds(5));

            logsProvider.VerifyAll();
            logsUploader.VerifyAll();
            Mock.Get(runtimeInfoProvider).VerifyAll();
        }
コード例 #6
0
        async Task UploadLogs(string sasUrl, string id, ModuleLogOptions moduleLogOptions, CancellationToken token)
        {
            if (moduleLogOptions.ContentType == LogsContentType.Json)
            {
                byte[] logBytes = await this.logsProvider.GetLogs(id, moduleLogOptions, token);

                await this.logsUploader.Upload(sasUrl, id, logBytes, moduleLogOptions.ContentEncoding, moduleLogOptions.ContentType);
            }
            else if (moduleLogOptions.ContentType == LogsContentType.Text)
            {
                Func <ArraySegment <byte>, Task> uploaderCallback = await this.logsUploader.GetUploaderCallback(sasUrl, id, moduleLogOptions.ContentEncoding, moduleLogOptions.ContentType);

                await this.logsProvider.GetLogsStream(id, moduleLogOptions, uploaderCallback, token);
            }
        }
コード例 #7
0
        public async Task GetLogsStreamWithFiltersTest()
        {
            // Arrange
            string            iotHub            = "foo.azure-devices.net";
            string            deviceId          = "dev1";
            string            moduleId          = "mod1";
            Option <int>      tail              = Option.Some(10);
            Option <int>      since             = Option.Some(1552887267);
            CancellationToken cancellationToken = CancellationToken.None;

            byte[] dockerLogsStreamBytes = DockerFraming.Frame(TestLogTexts);
            var    runtimeInfoProvider   = new Mock <IRuntimeInfoProvider>();

            runtimeInfoProvider.Setup(r => r.GetModuleLogs(moduleId, true, tail, since, cancellationToken))
            .ReturnsAsync(new MemoryStream(dockerLogsStreamBytes));
            runtimeInfoProvider.Setup(r => r.GetModules(It.IsAny <CancellationToken>()))
            .ReturnsAsync(new[] { new ModuleRuntimeInfo(moduleId, "docker", ModuleStatus.Running, "foo", 0, Option.None <DateTime>(), Option.None <DateTime>()) });

            var logsProcessor = new LogsProcessor(new LogMessageParser(iotHub, deviceId));
            var logsProvider  = new LogsProvider(runtimeInfoProvider.Object, logsProcessor);

            var filter     = new ModuleLogFilter(tail, since, Option.Some(6), Option.Some("Starting"));
            var logOptions = new ModuleLogOptions(LogsContentEncoding.Gzip, LogsContentType.Text, filter);

            var receivedBytes = new List <byte>();

            Task Callback(ArraySegment <byte> bytes)
            {
                receivedBytes.AddRange(bytes.ToArray());
                return(Task.CompletedTask);
            }

            // Act
            await logsProvider.GetLogsStream(moduleId, logOptions, Callback, cancellationToken);

            await Task.Delay(TimeSpan.FromSeconds(3));

            // Assert
            Assert.NotEmpty(receivedBytes);
            string receivedText = Compression.DecompressFromGzip(receivedBytes.ToArray())
                                  .Skip(8)
                                  .ToArray()
                                  .FromBytes();

            Assert.Equal(TestLogTexts[0], receivedText);
        }
コード例 #8
0
        protected override async Task <Option <IEnumerable <ModuleLogsResponse> > > HandleRequestInternal(Option <ModuleLogsRequest> payloadOption, CancellationToken cancellationToken)
        {
            ModuleLogsRequest payload = payloadOption.Expect(() => new ArgumentException("Request payload not found"));

            if (ExpectedSchemaVersion.CompareMajorVersion(payload.SchemaVersion, "logs upload request schema") != 0)
            {
                Events.MismatchedMinorVersions(payload.SchemaVersion, ExpectedSchemaVersion);
            }

            Events.ProcessingRequest(payload);

            ILogsRequestToOptionsMapper requestToOptionsMapper = new LogsRequestToOptionsMapper(
                this.runtimeInfoProvider,
                payload.Encoding,
                payload.ContentType,
                LogOutputFraming.None,
                Option.None <LogsOutputGroupingConfig>(),
                false);

            IList <(string id, ModuleLogOptions logOptions)> logOptionsList = await requestToOptionsMapper.MapToLogOptions(payload.Items, cancellationToken);

            IEnumerable <Task <ModuleLogsResponse> > uploadLogsTasks = logOptionsList.Select(
                async l =>
            {
                Events.ReceivedLogOptions(l);
                ModuleLogOptions logOptions = l.logOptions.Filter.Tail
                                              .Filter(t => t < MaxTailValue)
                                              .Map(t => l.logOptions)
                                              .GetOrElse(
                    () =>
                {
                    var filter = new ModuleLogFilter(Option.Some(MaxTailValue), l.logOptions.Filter.Since, l.logOptions.Filter.Until, l.logOptions.Filter.LogLevel, l.logOptions.Filter.RegexString);
                    return(new ModuleLogOptions(l.logOptions.ContentEncoding, l.logOptions.ContentType, filter, l.logOptions.OutputFraming, l.logOptions.OutputGroupingConfig, l.logOptions.Follow));
                });

                byte[] moduleLogs = await this.logsProvider.GetLogs(l.id, logOptions, cancellationToken);

                Events.ReceivedModuleLogs(moduleLogs, l.id);
                return(logOptions.ContentEncoding == LogsContentEncoding.Gzip
                        ? new ModuleLogsResponse(l.id, moduleLogs)
                        : new ModuleLogsResponse(l.id, moduleLogs.FromBytes()));
            });
            IEnumerable <ModuleLogsResponse> response = await Task.WhenAll(uploadLogsTasks);

            return(Option.Some(response));
        }
コード例 #9
0
ファイル: LogsProviderTest.cs プロジェクト: nlcamp/iotedge
        public async Task GetLogsAsJsonWithCompressionTest()
        {
            // Arrange
            string            iotHub            = "foo.azure-devices.net";
            string            deviceId          = "dev1";
            string            moduleId          = "mod1";
            Option <int>      tail              = Option.None <int>();
            Option <string>   since             = Option.None <string>();
            Option <string>   until             = Option.None <string>();
            Option <bool>     includeTimestamp  = Option.Some(true);
            CancellationToken cancellationToken = CancellationToken.None;

            var runtimeInfoProvider = new Mock <IRuntimeInfoProvider>();

            // Note: EdgeAgent automatically includes the timestamp for log parsing by default for content type JSON
            runtimeInfoProvider.Setup(r => r.GetModuleLogs(moduleId, false, tail, since, until, includeTimestamp, cancellationToken))
            .ReturnsAsync(new MemoryStream(DockerFraming.Frame(TestLogTexts)));

            var logsProcessor = new LogsProcessor(new LogMessageParser(iotHub, deviceId));
            var logsProvider  = new LogsProvider(runtimeInfoProvider.Object, logsProcessor);

            ModuleLogFilter filter     = new ModuleLogFilter(tail, since, until, Option.None <int>(), includeTimestamp, Option.None <string>());
            var             logOptions = new ModuleLogOptions(LogsContentEncoding.Gzip, LogsContentType.Json, filter, LogOutputFraming.None, Option.None <LogsOutputGroupingConfig>(), false);

            // Act
            byte[] bytes = await logsProvider.GetLogs(moduleId, logOptions, cancellationToken);

            // Assert
            byte[] decompressedBytes = Compression.DecompressFromGzip(bytes);
            var    logMessages       = decompressedBytes.FromBytes <List <ModuleLogMessage> >();

            Assert.NotNull(logMessages);
            Assert.Equal(TestLogTexts.Length, logMessages.Count);
            for (int i = 0; i < logMessages.Count; i++)
            {
                ModuleLogMessage logMessage = logMessages[i];
                (int logLevel, Option <DateTime> timeStamp, string text) = LogMessageParser.ParseLogText(TestLogTexts[i]);
                Assert.Equal(logLevel, logMessage.LogLevel);
                Assert.Equal(timeStamp.HasValue, logMessage.TimeStamp.HasValue);
                Assert.Equal(timeStamp.OrDefault(), logMessage.TimeStamp.OrDefault());
                Assert.Equal(text, logMessage.Text);
                Assert.Equal(iotHub, logMessage.IoTHub);
                Assert.Equal(deviceId, logMessage.DeviceId);
                Assert.Equal(moduleId, logMessage.ModuleId);
            }
        }
コード例 #10
0
        public async Task GetLogsAsJsonWithCompressionTest()
        {
            // Arrange
            string            iotHub            = "foo.azure-devices.net";
            string            deviceId          = "dev1";
            string            moduleId          = "mod1";
            Option <int>      tail              = Option.None <int>();
            CancellationToken cancellationToken = CancellationToken.None;
            string            expectedLogText   = TestLogTexts.Join(string.Empty);

            var runtimeInfoProvider = new Mock <IRuntimeInfoProvider>();

            runtimeInfoProvider.Setup(r => r.GetModuleLogs(moduleId, false, tail, cancellationToken))
            .ReturnsAsync(new MemoryStream(GetDockerLogsStream(TestLogTexts)));

            var logsProcessor = new LogsProcessor(new LogMessageParser(iotHub, deviceId));
            var logsProvider  = new LogsProvider(runtimeInfoProvider.Object, logsProcessor);

            var logOptions = new ModuleLogOptions(moduleId, LogsContentEncoding.Gzip, LogsContentType.Json);

            // Act
            byte[] bytes = await logsProvider.GetLogs(logOptions, cancellationToken);

            // Assert
            byte[] decompressedBytes = Compression.DecompressFromGzip(bytes);
            var    logMessages       = decompressedBytes.FromBytes <List <ModuleLogMessage> >();

            Assert.NotNull(logMessages);
            Assert.Equal(TestLogTexts.Length, logMessages.Count);
            for (int i = 0; i < logMessages.Count; i++)
            {
                ModuleLogMessage logMessage = logMessages[i];
                (int logLevel, Option <DateTime> timeStamp, string text) = LogMessageParser.ParseLogText(TestLogTexts[i]);
                Assert.Equal(logLevel, logMessage.LogLevel);
                Assert.Equal(timeStamp.HasValue, logMessage.TimeStamp.HasValue);
                Assert.Equal(timeStamp.OrDefault(), logMessage.TimeStamp.OrDefault());
                Assert.Equal(text, logMessage.Text);
                Assert.Equal(iotHub, logMessage.IoTHub);
                Assert.Equal(deviceId, logMessage.DeviceId);
                Assert.Equal(moduleId, logMessage.ModuleId);
            }
        }
コード例 #11
0
        public async Task GetLogsAsJsonTest()
        {
            // Arrange
            string            iotHub            = "foo.azure-devices.net";
            string            deviceId          = "dev1";
            string            moduleId          = "mod1";
            Option <int>      tail              = Option.None <int>();
            Option <int>      since             = Option.None <int>();
            CancellationToken cancellationToken = CancellationToken.None;

            var runtimeInfoProvider = new Mock <IRuntimeInfoProvider>();

            runtimeInfoProvider.Setup(r => r.GetModuleLogs(moduleId, false, tail, since, cancellationToken))
            .ReturnsAsync(new MemoryStream(DockerFraming.Frame(TestLogTexts)));

            var logsProcessor = new LogsProcessor(new LogMessageParser(iotHub, deviceId));
            var logsProvider  = new LogsProvider(runtimeInfoProvider.Object, logsProcessor);

            var logOptions = new ModuleLogOptions(LogsContentEncoding.None, LogsContentType.Json, ModuleLogFilter.Empty, LogOutputFraming.None, Option.None <LogsOutputGroupingConfig>(), false);

            // Act
            byte[] bytes = await logsProvider.GetLogs(moduleId, logOptions, cancellationToken);

            // Assert
            var logMessages = bytes.FromBytes <List <ModuleLogMessage> >();

            Assert.NotNull(logMessages);
            Assert.Equal(TestLogTexts.Length, logMessages.Count);
            for (int i = 0; i < logMessages.Count; i++)
            {
                ModuleLogMessage logMessage = logMessages[i];
                (int logLevel, Option <DateTime> timeStamp, string text) = LogMessageParser.ParseLogText(TestLogTexts[i]);
                Assert.Equal(logLevel, logMessage.LogLevel);
                Assert.Equal(timeStamp.HasValue, logMessage.TimeStamp.HasValue);
                Assert.Equal(timeStamp.OrDefault(), logMessage.TimeStamp.OrDefault());
                Assert.Equal(text, logMessage.Text);
                Assert.Equal(iotHub, logMessage.IoTHub);
                Assert.Equal(deviceId, logMessage.DeviceId);
                Assert.Equal(moduleId, logMessage.ModuleId);
            }
        }
コード例 #12
0
ファイル: LogsProviderTest.cs プロジェクト: nlcamp/iotedge
        public async Task GetLogsStreamTest()
        {
            // Arrange
            string            iotHub            = "foo.azure-devices.net";
            string            deviceId          = "dev3";
            string            moduleId          = "mod3";
            Option <int>      tail              = Option.None <int>();
            Option <string>   since             = Option.None <string>();
            Option <string>   until             = Option.None <string>();
            Option <bool>     includeTimestamp  = Option.None <bool>();
            CancellationToken cancellationToken = CancellationToken.None;

            byte[] dockerLogsStreamBytes = DockerFraming.Frame(TestLogTexts);
            var    runtimeInfoProvider   = new Mock <IRuntimeInfoProvider>();

            runtimeInfoProvider.Setup(r => r.GetModuleLogs(moduleId, true, tail, since, until, includeTimestamp, cancellationToken))
            .ReturnsAsync(new MemoryStream(dockerLogsStreamBytes));
            runtimeInfoProvider.Setup(r => r.GetModules(It.IsAny <CancellationToken>()))
            .ReturnsAsync(new[] { new ModuleRuntimeInfo(moduleId, "docker", ModuleStatus.Running, "foo", 0, Option.None <DateTime>(), Option.None <DateTime>()) });

            var logsProcessor = new LogsProcessor(new LogMessageParser(iotHub, deviceId));
            var logsProvider  = new LogsProvider(runtimeInfoProvider.Object, logsProcessor);

            var logOptions = new ModuleLogOptions(LogsContentEncoding.None, LogsContentType.Text, ModuleLogFilter.Empty, LogOutputFraming.None, Option.None <LogsOutputGroupingConfig>(), true);

            var receivedBytes = new List <byte>();

            Task Callback(ArraySegment <byte> bytes)
            {
                receivedBytes.AddRange(bytes.ToArray());
                return(Task.CompletedTask);
            }

            // Act
            await logsProvider.GetLogsStream(moduleId, logOptions, Callback, cancellationToken);

            // Assert
            Assert.NotEmpty(receivedBytes);
            Assert.Equal(string.Join(string.Empty, TestLogTexts).ToBytes(), receivedBytes);
        }
コード例 #13
0
        public async Task TestLogsUploadRequest(string payload, string id, string sasUrl, LogsContentEncoding contentEncoding, LogsContentType contentType, ModuleLogFilter filter)
        {
            // Arrange
            var logsUploader     = new Mock <ILogsUploader>();
            var logsProvider     = new Mock <ILogsProvider>();
            var uploadBytes      = new byte[100];
            var moduleLogOptions = new ModuleLogOptions(contentEncoding, contentType, filter);

            logsProvider.Setup(l => l.GetLogs(id, moduleLogOptions, It.IsAny <CancellationToken>()))
            .ReturnsAsync(uploadBytes);
            logsUploader.Setup(l => l.Upload(sasUrl, id, uploadBytes, contentEncoding, contentType))
            .Returns(Task.CompletedTask);

            // Act
            var             logsUploadRequestHandler = new LogsUploadRequestHandler(logsUploader.Object, logsProvider.Object, Mock.Of <IRuntimeInfoProvider>());
            Option <string> response = await logsUploadRequestHandler.HandleRequest(Option.Maybe(payload), CancellationToken.None);

            // Assert
            Assert.False(response.HasValue);
            logsProvider.VerifyAll();
            logsUploader.VerifyAll();
        }
コード例 #14
0
        public static IEnumerable <object[]> GetIdsToProcessTestData()
        {
            var logOptions1 = new ModuleLogOptions(LogsContentEncoding.Gzip, LogsContentType.Json, ModuleLogFilter.Empty, LogOutputFraming.None, Option.None <LogsOutputGroupingConfig>(), false);
            var logOptions2 = new ModuleLogOptions(LogsContentEncoding.None, LogsContentType.Text, ModuleLogFilter.Empty, LogOutputFraming.None, Option.None <LogsOutputGroupingConfig>(), false);
            var logOptions3 = new ModuleLogOptions(LogsContentEncoding.None, LogsContentType.Text, new ModuleLogFilter(Option.Some(100), Option.None <string>(), Option.None <string>(), Option.None <int>(), Option.None <bool>(), Option.None <string>()), LogOutputFraming.None, Option.None <LogsOutputGroupingConfig>(), false);

            yield return(new object[]
            {
                new List <(string id, ModuleLogOptions logOptions)>
                {
                    ("edgeAgent", logOptions1),
                    ("edgeHub", logOptions2),
                    ("tempSensor", logOptions3)
                },
                new List <string> {
                    "edgeAgent", "edgeHub", "tempSensor", "eModule2"
                },
                new Dictionary <string, ModuleLogOptions>
                {
                    ["edgeAgent"] = logOptions1,
                    ["edgeHub"] = logOptions2,
                    ["tempSensor"] = logOptions3
                }
            });
コード例 #15
0
        public async Task GetTextLogsTest()
        {
            var filter = new ModuleLogFilter(Option.Some(100), Option.Some(1501000), Option.Some(3), Option.Some("ERR"));
            LogsContentEncoding contentEncoding = LogsContentEncoding.None;
            LogsContentType     contentType     = LogsContentType.Text;

            string payload =
                @"{
                    ""schemaVersion"": ""1.0"",
                    ""items"": {
                        ""id"": ""m1"",
                        ""filter"": <filter>
                    },
                    ""encoding"": ""none"",
                    ""contentType"": ""text""
                }"
                .Replace("<filter>", filter.ToJson());

            string mod1 = "m1";
            string mod2 = "m2";
            string mod3 = "m3";
            var    moduleRuntimeInfoList = new List <ModuleRuntimeInfo>
            {
                new ModuleRuntimeInfo(mod1, "docker", ModuleStatus.Running, string.Empty, 0, Option.None <DateTime>(), Option.None <DateTime>()),
                new ModuleRuntimeInfo(mod2, "docker", ModuleStatus.Running, string.Empty, 0, Option.None <DateTime>(), Option.None <DateTime>()),
                new ModuleRuntimeInfo(mod3, "docker", ModuleStatus.Running, string.Empty, 0, Option.None <DateTime>(), Option.None <DateTime>())
            };
            var runtimeInfoProvider = new Mock <IRuntimeInfoProvider>();

            runtimeInfoProvider.Setup(r => r.GetModules(It.IsAny <CancellationToken>()))
            .ReturnsAsync(moduleRuntimeInfoList);

            var logsProvider = new Mock <ILogsProvider>();

            var    module1LogOptions = new ModuleLogOptions(contentEncoding, contentType, filter, LogOutputFraming.None, Option.None <LogsOutputGroupingConfig>(), false);
            string mod1Logs          = new[]
            {
                "Log line 1\n",
                "Log line 2\n",
                "Log line 3\n"
            }.Join(string.Empty);

            logsProvider.Setup(l => l.GetLogs(mod1, module1LogOptions, It.IsAny <CancellationToken>()))
            .ReturnsAsync(mod1Logs.ToBytes());

            // Act
            var             logsRequestHandler = new LogsRequestHandler(logsProvider.Object, runtimeInfoProvider.Object);
            Option <string> response           = await logsRequestHandler.HandleRequest(Option.Maybe(payload), CancellationToken.None);

            // Assert
            Assert.True(response.HasValue);
            logsProvider.VerifyAll();
            runtimeInfoProvider.VerifyAll();
            var logsResponseList = response.OrDefault().FromJson <List <LogsResponse> >();

            Assert.NotNull(logsResponseList);
            Assert.Single(logsResponseList);
            LogsResponse logsResponse = logsResponseList[0];

            Assert.Equal(mod1, logsResponse.Id);
            Assert.True(logsResponse.Payload.HasValue);
            Assert.False(logsResponse.PayloadBytes.HasValue);
            Assert.Equal(mod1Logs, logsResponse.Payload.OrDefault());
        }
コード例 #16
0
        public async Task TestLogsUploadAllTaskRequest()
        {
            // Arrange
            string sasUrl = $"https://test1.blob.core.windows.net/cont2?st={Guid.NewGuid()}";
            var    filter = new ModuleLogFilter(Option.Some(100), Option.Some(1501000), Option.Some(3), Option.Some("ERR"));
            LogsContentEncoding contentEncoding = LogsContentEncoding.None;
            LogsContentType     contentType     = LogsContentType.Json;

            string payload =
                @"{
                    ""schemaVersion"": ""1.0"",
                    ""sasUrl"": ""<sasurl>"",
                    ""items"": {
                        ""id"": "".*"",
                        ""filter"": <filter>
                    },
                    ""encoding"": ""none"",
                    ""contentType"": ""json""
                }"
                .Replace("<sasurl>", sasUrl)
                .Replace("<filter>", filter.ToJson());

            string mod1 = "m1";
            string mod2 = "m2";
            string mod3 = "m3";
            var    moduleRuntimeInfoList = new List <ModuleRuntimeInfo>
            {
                new ModuleRuntimeInfo(mod1, "docker", ModuleStatus.Running, string.Empty, 0, Option.None <DateTime>(), Option.None <DateTime>()),
                new ModuleRuntimeInfo(mod2, "docker", ModuleStatus.Running, string.Empty, 0, Option.None <DateTime>(), Option.None <DateTime>()),
                new ModuleRuntimeInfo(mod3, "docker", ModuleStatus.Running, string.Empty, 0, Option.None <DateTime>(), Option.None <DateTime>())
            };
            var runtimeInfoProvider = new Mock <IRuntimeInfoProvider>();

            runtimeInfoProvider.Setup(r => r.GetModules(It.IsAny <CancellationToken>()))
            .ReturnsAsync(moduleRuntimeInfoList);

            var logsUploader = new Mock <ILogsUploader>();
            var logsProvider = new Mock <ILogsProvider>();

            var module1LogOptions = new ModuleLogOptions(contentEncoding, contentType, filter, LogOutputFraming.None, Option.None <LogsOutputGroupingConfig>(), false);
            var mod1LogBytes      = new byte[100];

            logsProvider.Setup(l => l.GetLogs(mod1, module1LogOptions, It.IsAny <CancellationToken>()))
            .ReturnsAsync(mod1LogBytes);
            logsUploader.Setup(l => l.Upload(sasUrl, mod1, mod1LogBytes, contentEncoding, contentType))
            .Returns(Task.CompletedTask);

            var module2LogOptions = new ModuleLogOptions(contentEncoding, contentType, filter, LogOutputFraming.None, Option.None <LogsOutputGroupingConfig>(), false);
            var mod2LogBytes      = new byte[80];

            logsProvider.Setup(l => l.GetLogs(mod2, module2LogOptions, It.IsAny <CancellationToken>()))
            .ReturnsAsync(mod2LogBytes);
            logsUploader.Setup(l => l.Upload(sasUrl, mod2, mod2LogBytes, contentEncoding, contentType))
            .Returns(Task.CompletedTask);

            var module3LogOptions = new ModuleLogOptions(contentEncoding, contentType, filter, LogOutputFraming.None, Option.None <LogsOutputGroupingConfig>(), false);
            var mod3LogBytes      = new byte[120];

            logsProvider.Setup(l => l.GetLogs(mod3, module3LogOptions, It.IsAny <CancellationToken>()))
            .ReturnsAsync(mod3LogBytes);
            logsUploader.Setup(l => l.Upload(sasUrl, mod3, mod3LogBytes, contentEncoding, contentType))
            .Returns(Task.CompletedTask);

            // Act
            var             logsUploadRequestHandler = new LogsUploadRequestHandler(logsUploader.Object, logsProvider.Object, runtimeInfoProvider.Object);
            Option <string> response = await logsUploadRequestHandler.HandleRequest(Option.Maybe(payload), CancellationToken.None);

            // Assert
            Assert.True(response.HasValue);
            var taskStatusResponse = response.OrDefault().FromJson <TaskStatusResponse>();

            Assert.NotNull(taskStatusResponse);
            Assert.NotEmpty(taskStatusResponse.CorrelationId);
            Assert.Equal(string.Empty, taskStatusResponse.Message);

            await WaitForBackgroundTaskCompletion(taskStatusResponse.CorrelationId).TimeoutAfter(TimeSpan.FromSeconds(5));

            logsProvider.VerifyAll();
            logsUploader.VerifyAll();
            runtimeInfoProvider.VerifyAll();
        }
コード例 #17
0
        async Task UploadLogs(string sasUrl, string id, ModuleLogOptions moduleLogOptions, CancellationToken token)
        {
            byte[] logBytes = await this.logsProvider.GetLogs(id, moduleLogOptions, token);

            await this.logsUploader.Upload(sasUrl, id, logBytes, moduleLogOptions.ContentEncoding, moduleLogOptions.ContentType);
        }
コード例 #18
0
        public async Task GetLogsStreamWithMultipleModulesWithRegexMatchTest()
        {
            // Arrange
            string            iotHub            = "foo.azure-devices.net";
            string            deviceId          = "dev1";
            Option <int>      tail              = Option.None <int>();
            Option <int>      since             = Option.None <int>();
            CancellationToken cancellationToken = CancellationToken.None;

            string moduleId1 = "mod1";
            string moduleId2 = "mod2";

            var filter = new ModuleLogFilter(tail, since, Option.None <int>(), Option.Some("bad"));

            byte[] dockerLogsStreamBytes1 = DockerFraming.Frame(TestLogTexts);
            byte[] dockerLogsStreamBytes2 = DockerFraming.Frame(TestLogTexts);

            var modulesList = new List <ModuleRuntimeInfo>
            {
                new ModuleRuntimeInfo(moduleId1, "docker", ModuleStatus.Running, "foo", 0, Option.None <DateTime>(), Option.None <DateTime>()),
                new ModuleRuntimeInfo(moduleId2, "docker", ModuleStatus.Running, "foo", 0, Option.None <DateTime>(), Option.None <DateTime>())
            };

            var runtimeInfoProvider = new Mock <IRuntimeInfoProvider>();

            runtimeInfoProvider.Setup(r => r.GetModuleLogs(moduleId1, true, tail, since, cancellationToken))
            .ReturnsAsync(new MemoryStream(dockerLogsStreamBytes1));
            runtimeInfoProvider.Setup(r => r.GetModuleLogs(moduleId2, true, tail, since, cancellationToken))
            .ReturnsAsync(new MemoryStream(dockerLogsStreamBytes2));
            runtimeInfoProvider.Setup(r => r.GetModules(It.IsAny <CancellationToken>()))
            .ReturnsAsync(modulesList);

            var logsProcessor = new LogsProcessor(new LogMessageParser(iotHub, deviceId));
            var logsProvider  = new LogsProvider(runtimeInfoProvider.Object, logsProcessor);

            string regex      = "mod";
            var    logOptions = new ModuleLogOptions(LogsContentEncoding.Gzip, LogsContentType.Text, filter);

            var receivedBytes = new List <byte[]>();

            Task Callback(ArraySegment <byte> bytes)
            {
                receivedBytes.Add(bytes.ToArray());
                return(Task.CompletedTask);
            }

            var expectedTextLines = new List <string> {
                TestLogTexts[3], TestLogTexts[4], TestLogTexts[3], TestLogTexts[4]
            };

            expectedTextLines.Sort();

            // Act
            await logsProvider.GetLogsStream(regex, logOptions, Callback, cancellationToken);

            await Task.Delay(TimeSpan.FromSeconds(6));

            // Assert
            Assert.NotEmpty(receivedBytes);
            List <string> receivedText = receivedBytes
                                         .Select(
                r =>
                Compression.DecompressFromGzip(r)
                .Skip(8)
                .ToArray()
                .FromBytes())
                                         .ToList();

            receivedText.Sort();

            Assert.Equal(expectedTextLines, receivedText);
        }
コード例 #19
0
        public async Task GetJsonGzipLogsTest()
        {
            var filter = new ModuleLogFilter(Option.Some(100), Option.Some("1501000"), Option.None <string>(), Option.Some(3), Option.None <bool>(), Option.Some("ERR"));
            LogsContentEncoding contentEncoding = LogsContentEncoding.Gzip;
            LogsContentType     contentType     = LogsContentType.Json;

            string payload =
                @"{
                    ""schemaVersion"": ""1.0"",
                    ""items"": {
                        ""id"": ""m1"",
                        ""filter"": <filter>
                    },
                    ""encoding"": ""gzip"",
                    ""contentType"": ""json""
                }"
                .Replace("<filter>", filter.ToJson());

            string iotHub   = "foo.azure-devices.net";
            string deviceId = "d1";
            string mod1     = "m1";
            string mod2     = "m2";
            string mod3     = "m3";
            var    moduleRuntimeInfoList = new List <ModuleRuntimeInfo>
            {
                new ModuleRuntimeInfo(mod1, "docker", ModuleStatus.Running, string.Empty, 0, Option.None <DateTime>(), Option.None <DateTime>()),
                new ModuleRuntimeInfo(mod2, "docker", ModuleStatus.Running, string.Empty, 0, Option.None <DateTime>(), Option.None <DateTime>()),
                new ModuleRuntimeInfo(mod3, "docker", ModuleStatus.Running, string.Empty, 0, Option.None <DateTime>(), Option.None <DateTime>())
            };
            var runtimeInfoProvider = new Mock <IRuntimeInfoProvider>();

            runtimeInfoProvider.Setup(r => r.GetModules(It.IsAny <CancellationToken>()))
            .ReturnsAsync(moduleRuntimeInfoList);

            var logsProvider = new Mock <ILogsProvider>();

            var module1LogOptions = new ModuleLogOptions(contentEncoding, contentType, filter, LogOutputFraming.None, Option.None <LogsOutputGroupingConfig>(), false);
            var mod1Logs          = new List <ModuleLogMessage>
            {
                new ModuleLogMessage(iotHub, deviceId, mod1, "0", 6, Option.None <DateTime>(), "log line 1"),
                new ModuleLogMessage(iotHub, deviceId, mod1, "0", 6, Option.None <DateTime>(), "log line 2"),
                new ModuleLogMessage(iotHub, deviceId, mod1, "0", 6, Option.None <DateTime>(), "log line 3")
            };

            byte[] mod1LogBytes = Compression.CompressToGzip(mod1Logs.ToBytes());
            logsProvider.Setup(l => l.GetLogs(mod1, module1LogOptions, It.IsAny <CancellationToken>()))
            .ReturnsAsync(mod1LogBytes);

            // Act
            var             logsRequestHandler = new ModuleLogsRequestHandler(logsProvider.Object, runtimeInfoProvider.Object);
            Option <string> response           = await logsRequestHandler.HandleRequest(Option.Maybe(payload), CancellationToken.None);

            // Assert
            Assert.True(response.HasValue);
            logsProvider.VerifyAll();
            runtimeInfoProvider.VerifyAll();
            var logsResponseList = response.OrDefault().FromJson <List <ModuleLogsResponse> >();

            Assert.NotNull(logsResponseList);
            Assert.Single(logsResponseList);
            ModuleLogsResponse logsResponse = logsResponseList[0];

            Assert.Equal(mod1, logsResponse.Id);
            Assert.False(logsResponse.Payload.HasValue);
            Assert.True(logsResponse.PayloadBytes.HasValue);
            Assert.Equal(mod1LogBytes, logsResponse.PayloadBytes.OrDefault());
        }
コード例 #20
0
 public void NeedToProcessStreamTest(ModuleLogOptions logOptions, bool expectedResult)
 {
     Assert.Equal(expectedResult, LogsProvider.NeedToProcessStream(logOptions));
 }