Beispiel #1
0
        public async Task PublishesAllFunctionExecutionActivities()
        {
            _handlerMock.Protected().Setup <Task <HttpResponseMessage> >("SendAsync",
                                                                         ItExpr.IsAny <HttpRequestMessage>(),
                                                                         ItExpr.IsAny <CancellationToken>()).ReturnsAsync(new HttpResponseMessage
            {
                StatusCode = HttpStatusCode.OK
            });

            var activity1 = new ContainerFunctionExecutionActivity(DateTime.UtcNow, "func1", ExecutionStage.InProgress,
                                                                   "QueueTrigger", false);

            var activity2 = new ContainerFunctionExecutionActivity(DateTime.UtcNow, "func2", ExecutionStage.Finished,
                                                                   "QueueTrigger", true);

            var activities = new List <ContainerFunctionExecutionActivity> {
                activity1, activity2
            };

            await _meshServiceClient.PublishContainerActivity(activities);

            _handlerMock.Protected().Verify <Task <HttpResponseMessage> >("SendAsync", Times.Exactly(1),
                                                                          ItExpr.Is <HttpRequestMessage>(r => IsPublishExecutionStatusRequest(r, activity1, activity2)),
                                                                          ItExpr.IsAny <CancellationToken>());
        }
        public async Task DoesNotPublishExecutionActivityInStandbyMode()
        {
            var activity = new ContainerFunctionExecutionActivity(DateTime.MinValue, "func-1",
                                                                  ExecutionStage.InProgress, "trigger-1", false);

            var environment = new TestEnvironment();

            environment.SetEnvironmentVariable(EnvironmentSettingNames.AzureWebsitePlaceholderMode, "1");
            environment.SetEnvironmentVariable(EnvironmentSettingNames.ContainerName, "Container-Name");

            var meshClient     = new Mock <IMeshServiceClient>();
            var standbyOptions = new TestOptionsMonitor <StandbyOptions>(new StandbyOptions {
                InStandbyMode = true
            });

            using (var publisher = new LinuxContainerActivityPublisher(standbyOptions, meshClient.Object,
                                                                       environment, NullLogger <LinuxContainerActivityPublisher> .Instance, FlushIntervalMs))
            {
                await publisher.StartAsync(CancellationToken.None);

                publisher.PublishFunctionExecutionActivity(activity);
                await Task.Delay(DelayIntervalMs);

                await publisher.StopAsync(CancellationToken.None);

                meshClient.Verify(c =>
                                  c.PublishContainerActivity(It.IsAny <IEnumerable <ContainerFunctionExecutionActivity> >()), Times.Never);
            }
        }
        public void Comparison_Ignores_EventTime()
        {
            var activity1 = new ContainerFunctionExecutionActivity(DateTime.UtcNow, "func-1", ExecutionStage.InProgress, "QueueTrigger", false);
            var activity2 = new ContainerFunctionExecutionActivity(DateTime.UtcNow.Subtract(TimeSpan.FromSeconds(1)), "func-1", ExecutionStage.InProgress, "QueueTrigger", false);

            Assert.Equal(activity1, activity2);
        }
        public async Task PublishesFunctionExecutionActivity()
        {
            var activity = new ContainerFunctionExecutionActivity(DateTime.MinValue, "func-1",
                                                                  ExecutionStage.InProgress, "trigger-1", false);

            var environment = new TestEnvironment();

            environment.SetEnvironmentVariable(EnvironmentSettingNames.ContainerName, "Container-Name");

            var meshClient = new Mock <IMeshServiceClient>();

            meshClient.Setup(c =>
                             c.PublishContainerActivity(
                                 It.IsAny <IEnumerable <ContainerFunctionExecutionActivity> >())).Returns(Task.FromResult(true));

            var standbyOptions = new TestOptionsMonitor <StandbyOptions>(new StandbyOptions {
                InStandbyMode = false
            });

            using (var publisher = new LinuxContainerActivityPublisher(standbyOptions, meshClient.Object,
                                                                       environment, NullLogger <LinuxContainerActivityPublisher> .Instance, FlushIntervalMs))
            {
                await publisher.StartAsync(CancellationToken.None);

                publisher.PublishFunctionExecutionActivity(activity);
                await Task.Delay(DelayIntervalMs);

                await publisher.StopAsync(CancellationToken.None);

                meshClient.Verify(
                    c => c.PublishContainerActivity(
                        It.Is <IEnumerable <ContainerFunctionExecutionActivity> >(e =>
                                                                                  MatchesFunctionActivities(e, activity))), Times.Once);
            }
        }
Beispiel #5
0
 public void PublishFunctionExecutionActivity(ContainerFunctionExecutionActivity activity)
 {
     if (!_standbyOptions.CurrentValue.InStandbyMode)
     {
         if (!PublishActivity(activity))
         {
             _logger.LogWarning($"Failed to add activity {activity}");
         }
     }
 }
            private void RaiseFunctionMetricEvent(FunctionStartedEvent runningFunctionInfo, int concurrency, DateTime currentTime)
            {
                double         executionTimespan = 0;
                ExecutionStage executionStage;

                if (!runningFunctionInfo.Completed)
                {
                    executionStage    = ExecutionStage.InProgress;
                    executionTimespan = (currentTime - runningFunctionInfo.Timestamp).TotalMilliseconds;
                }
                else
                {
                    // regardless of the actual Failed/Succeeded status, we always raise the final event
                    // with stage Finished
                    executionStage    = ExecutionStage.Finished;
                    executionTimespan = runningFunctionInfo.Duration.TotalMilliseconds;
                }

                // Don't allocate the GUID string twice, though we can probably optimize this further upstream.
                var invocationId = runningFunctionInfo.InvocationId.ToString();

                MetricsEventGenerator.LogFunctionExecutionEvent(
                    _executionId,
                    _appServiceOptions.AppName,
                    concurrency,
                    runningFunctionInfo.FunctionMetadata.Name,
                    invocationId,
                    executionStage.ToString(),
                    (long)executionTimespan,
                    runningFunctionInfo.Success);

                if (_metricsPublisher != null)
                {
                    _metricsPublisher.AddFunctionExecutionActivity(
                        runningFunctionInfo.FunctionMetadata.Name,
                        invocationId,
                        concurrency,
                        executionStage.ToString(),
                        runningFunctionInfo.Success,
                        (long)executionTimespan,
                        _executionId,
                        currentTime,
                        runningFunctionInfo.Timestamp);
                }

                if (_linuxContainerActivityPublisher != null)
                {
                    var triggerType = runningFunctionInfo.FunctionMetadata.Trigger?.Type;
                    var activity    = new ContainerFunctionExecutionActivity(DateTime.UtcNow, runningFunctionInfo.FunctionMetadata.Name,
                                                                             executionStage, triggerType,
                                                                             runningFunctionInfo.Success);
                    _linuxContainerActivityPublisher.PublishFunctionExecutionActivity(activity);
                }
            }
        public void Comparison_Returns_Expected_Results(bool expected, string functionName1, string functionName2, ExecutionStage stage1, ExecutionStage stage2, string triggerType1, string triggerType2, bool success1, bool success2)
        {
            var activity1 = new ContainerFunctionExecutionActivity(DateTime.MinValue, functionName1, stage1, triggerType1, success1);
            var activity2 = new ContainerFunctionExecutionActivity(DateTime.MaxValue, functionName2, stage2, triggerType2, success2);

            var hashSet = new HashSet <ContainerFunctionExecutionActivity> {
                activity1, activity2
            };

            Assert.Equal(expected, activity1.Equals(activity2));
            Assert.Equal(expected ? 1 : 2, hashSet.Count);
        }
Beispiel #8
0
        private bool PublishActivity(ContainerFunctionExecutionActivity activity)
        {
            if (_activitiesLock.TryEnterWriteLock(LockTimeOutMs))
            {
                try
                {
                    _uniqueActivities.Add(activity);
                }
                finally
                {
                    _activitiesLock.ExitWriteLock();
                }
                return(true);
            }

            return(false);
        }
            private void RaiseFunctionMetricEvent(RunningFunctionInfo runningFunctionInfo, int concurrency, DateTime currentTime)
            {
                double executionTimespan = 0;

                if (runningFunctionInfo.ExecutionStage == ExecutionStage.Finished)
                {
                    executionTimespan = (runningFunctionInfo.EndTime - runningFunctionInfo.StartTime).TotalMilliseconds;
                }
                else
                {
                    executionTimespan = (currentTime - runningFunctionInfo.StartTime).TotalMilliseconds;
                }

                MetricsEventGenerator.LogFunctionExecutionEvent(
                    _executionId,
                    _appServiceOptions.CurrentValue.AppName,
                    concurrency,
                    runningFunctionInfo.Name,
                    runningFunctionInfo.InvocationId.ToString(),
                    runningFunctionInfo.ExecutionStage.ToString(),
                    (long)executionTimespan,
                    runningFunctionInfo.Success);

                if (_metricsPublisher != null)
                {
                    _metricsPublisher.AddFunctionExecutionActivity(
                        runningFunctionInfo.Name,
                        runningFunctionInfo.InvocationId.ToString(),
                        concurrency,
                        runningFunctionInfo.ExecutionStage.ToString(),
                        runningFunctionInfo.Success,
                        (long)executionTimespan,
                        _executionId,
                        currentTime,
                        runningFunctionInfo.StartTime);
                }

                if (_linuxContainerActivityPublisher != null)
                {
                    var activity = new ContainerFunctionExecutionActivity(DateTime.UtcNow, runningFunctionInfo.Name,
                                                                          runningFunctionInfo.ExecutionStage, runningFunctionInfo.TriggerType,
                                                                          runningFunctionInfo.Success);
                    _linuxContainerActivityPublisher.PublishFunctionExecutionActivity(activity);
                }
            }
        public async Task PublishesUniqueFunctionExecutionActivitiesOnly()
        {
            // activity1 and activity2 are duplicates. so only activity2 will be published
            var activity1 = new ContainerFunctionExecutionActivity(DateTime.MinValue, "func-1",
                                                                   ExecutionStage.InProgress, "trigger-1", false);
            var activity2 = new ContainerFunctionExecutionActivity(DateTime.MaxValue, "func-1",
                                                                   ExecutionStage.InProgress, "trigger-1", false);
            var activity3 = new ContainerFunctionExecutionActivity(DateTime.MaxValue, "func-1", ExecutionStage.Finished,
                                                                   "trigger-1", true);
            var activity4 = new ContainerFunctionExecutionActivity(DateTime.MaxValue, "func-1", ExecutionStage.Finished,
                                                                   "trigger-1", false);

            var environment = new TestEnvironment();

            environment.SetEnvironmentVariable(EnvironmentSettingNames.ContainerName, "Container-Name");

            var meshClient = new Mock <IMeshServiceClient>();

            var standbyOptions = new TestOptionsMonitor <StandbyOptions>(new StandbyOptions {
                InStandbyMode = false
            });

            using (var publisher = new LinuxContainerActivityPublisher(standbyOptions, meshClient.Object,
                                                                       environment, NullLogger <LinuxContainerActivityPublisher> .Instance, FlushIntervalMs))
            {
                await publisher.StartAsync(CancellationToken.None);

                publisher.PublishFunctionExecutionActivity(activity1);
                publisher.PublishFunctionExecutionActivity(activity2);
                publisher.PublishFunctionExecutionActivity(activity3);
                publisher.PublishFunctionExecutionActivity(activity4);
                await Task.Delay(DelayIntervalMs);

                await publisher.StopAsync(CancellationToken.None);

                meshClient.Verify(
                    c => c.PublishContainerActivity(
                        It.Is <IEnumerable <ContainerFunctionExecutionActivity> >(e =>
                                                                                  MatchesFunctionActivities(e, activity2, activity3, activity4))), Times.Once);
            }
        }
Beispiel #11
0
        public async Task IgnoresGlobalSerializer()
        {
            Func <JsonSerializerSettings> defaultSettings = null;

            try
            {
                defaultSettings = JsonConvert.DefaultSettings;

                JsonConvert.DefaultSettings = () => new JsonSerializerSettings()
                {
                    Converters = new JsonConverter[] { new HelloWorldConverter() }
                };

                _handlerMock.Protected().Setup <Task <HttpResponseMessage> >("SendAsync",
                                                                             ItExpr.IsAny <HttpRequestMessage>(),
                                                                             ItExpr.IsAny <CancellationToken>()).ReturnsAsync(new HttpResponseMessage
                {
                    StatusCode = HttpStatusCode.OK
                });

                var activity1 = new ContainerFunctionExecutionActivity(DateTime.UtcNow, "func1", ExecutionStage.InProgress,
                                                                       "QueueTrigger", false);

                var activity2 = new ContainerFunctionExecutionActivity(DateTime.UtcNow, "func2", ExecutionStage.Finished,
                                                                       "QueueTrigger", true);

                var activities = new List <ContainerFunctionExecutionActivity> {
                    activity1, activity2
                };

                await _meshServiceClient.PublishContainerActivity(activities);

                _handlerMock.Protected().Verify <Task <HttpResponseMessage> >("SendAsync", Times.Exactly(1),
                                                                              ItExpr.Is <HttpRequestMessage>(r => ContainsActivities(r, activity1, activity2)),
                                                                              ItExpr.IsAny <CancellationToken>());
            }
            finally
            {
                JsonConvert.DefaultSettings = defaultSettings;
            }
        }
Beispiel #12
0
        public async Task PublishesSpecializationCompleteEvent()
        {
            var activity = new ContainerFunctionExecutionActivity(DateTime.MinValue, "func-1",
                                                                  ExecutionStage.InProgress, "trigger-1", false);

            var environment = new TestEnvironment();

            environment.SetEnvironmentVariable(EnvironmentSettingNames.ContainerName, "Container-Name");

            var meshClient = new Mock <IMeshServiceClient>(MockBehavior.Strict);

            meshClient.Setup(c => c.NotifyHealthEvent(ContainerHealthEventType.Informational, It.IsAny <Type>(),
                                                      LinuxContainerActivityPublisher.SpecializationCompleteEvent)).Returns(Task.FromResult(true));

            var standbyOptions = new TestOptionsMonitor <StandbyOptions>(new StandbyOptions {
                InStandbyMode = false
            });

            using (var publisher = new LinuxContainerActivityPublisher(standbyOptions, meshClient.Object,
                                                                       environment, NullLogger <LinuxContainerActivityPublisher> .Instance, 1000, InitialFlushIntervalMs))
            {
                await publisher.StartAsync(CancellationToken.None);

                publisher.PublishFunctionExecutionActivity(activity);
                await Task.Delay(100);

                await publisher.StopAsync(CancellationToken.None);

                meshClient.Verify(c => c.NotifyHealthEvent(ContainerHealthEventType.Informational, It.IsAny <Type>(),
                                                           LinuxContainerActivityPublisher.SpecializationCompleteEvent), Times.Once);

                // Since test is waiting for 100ms and Flush interval is 1000ms, there will be no PublishContainerActivity
                meshClient.Verify(
                    c => c.PublishContainerActivity(
                        It.Is <IEnumerable <ContainerFunctionExecutionActivity> >(e =>
                                                                                  MatchesFunctionActivities(e, activity))), Times.Never);
            }
        }
Beispiel #13
0
        public async Task PublishesAllFunctionExecutionActivitiesEvenInCaseOfExceptions()
        {
            _handlerMock.Protected().Setup <Task <HttpResponseMessage> >("SendAsync",
                                                                         ItExpr.IsAny <HttpRequestMessage>(),
                                                                         ItExpr.IsAny <CancellationToken>()).Throws(new Exception());

            var activity1 = new ContainerFunctionExecutionActivity(DateTime.UtcNow, "func1", ExecutionStage.InProgress,
                                                                   "QueueTrigger", false);

            var activity2 = new ContainerFunctionExecutionActivity(DateTime.UtcNow, "func2", ExecutionStage.Finished,
                                                                   "QueueTrigger", true);

            var activities = new List <ContainerFunctionExecutionActivity> {
                activity1, activity2
            };

            await _meshServiceClient.PublishContainerActivity(activities);

            // total count = 3 (1 set of activities * 3 retries)
            _handlerMock.Protected().Verify <Task <HttpResponseMessage> >("SendAsync", Times.Exactly(3),
                                                                          ItExpr.Is <HttpRequestMessage>(r => IsPublishExecutionStatusRequest(r, activity1, activity2)),
                                                                          ItExpr.IsAny <CancellationToken>());
        }
 public Task PublishContainerFunctionExecutionActivity(ContainerFunctionExecutionActivity activity)
 {
     return(Task.CompletedTask);
 }
 public void PublishFunctionExecutionActivity(ContainerFunctionExecutionActivity activity)
 {
     //do nothing
 }
        public void Activity_Equals_Itself()
        {
            var activity = new ContainerFunctionExecutionActivity(DateTime.UtcNow, "func-1", ExecutionStage.InProgress, "QueueTrigger", false);

            Assert.Equal(activity, activity);
        }