Пример #1
0
        private static void ValidateFunctionExecutionEventArgumentsList(List <FunctionExecutionEventArguments> list, int noOfFuncExecutions)
        {
            FunctionExecutionEventArguments invalidElement = null;
            string errorMessage = null;

            Assert.True(
                ValidateFunctionExecutionEventArgumentsList(list, noOfFuncExecutions, out invalidElement, out errorMessage),
                string.Format("ErrorMessage:{0} InvalidElement:{1} List:{2}", errorMessage, invalidElement.ToString(), SerializeFunctionExecutionEventArguments(list)));
        }
Пример #2
0
        private static bool ValidateFunctionExecutionEventArgumentsList(List <FunctionExecutionEventArguments> list, int noOfFuncExecutions, out FunctionExecutionEventArguments invalidElement, out string errorMessage)
        {
            invalidElement = new FunctionExecutionEventArguments();
            errorMessage   = string.Empty;
            var functionValidationTrackerList = new List <FunctionEventValidationTracker <FunctionExecutionEventArguments> >();

            for (int currentIndex = 0; currentIndex < list.Count; currentIndex++)
            {
                functionValidationTrackerList.Add(new FunctionEventValidationTracker <FunctionExecutionEventArguments>(list[currentIndex]));
            }

            var hashes = new HashSet <string>();

            for (int currentIndex = 0; currentIndex < functionValidationTrackerList.Count; currentIndex++)
            {
                // The element has not already been processed
                if (!functionValidationTrackerList[currentIndex].HasBeenProcessed)
                {
                    var functionExecutionArgs = functionValidationTrackerList[currentIndex].EventArguments;

                    if (hashes.Contains(functionExecutionArgs.InvocationId))
                    {
                        invalidElement = functionExecutionArgs;
                        errorMessage   = "InvocationId has already been used";
                        return(false);
                    }

                    // If function execution was in progress then there should be a corresponding 'Finished' event
                    if (functionExecutionArgs.ExecutionStage == ExecutionStage.InProgress.ToString())
                    {
                        List <int> relatedEventIds = new List <int>();
                        relatedEventIds.Add(currentIndex);
                        for (int secondIndex = currentIndex + 1; secondIndex < functionValidationTrackerList.Count; secondIndex++)
                        {
                            // The element has not already been processed for another function execution and related to the current function invocation event
                            if (!functionValidationTrackerList[secondIndex].HasBeenProcessed &&
                                functionValidationTrackerList[secondIndex].EventArguments.FunctionName == functionExecutionArgs.FunctionName &&
                                functionValidationTrackerList[secondIndex].EventArguments.InvocationId == functionExecutionArgs.InvocationId)
                            {
                                relatedEventIds.Add(secondIndex);
                                if (functionValidationTrackerList[secondIndex].EventArguments.ExecutionStage == ExecutionStage.Finished.ToString())
                                {
                                    break;
                                }
                            }
                        }

                        if (relatedEventIds.Count < 2)
                        {
                            invalidElement = functionExecutionArgs;
                            errorMessage   = "There should be at least one related event";
                            return(false);
                        }

                        var lastEvent = list[relatedEventIds[relatedEventIds.Count - 1]];
                        if (lastEvent.ExecutionStage != ExecutionStage.Finished.ToString())
                        {
                            invalidElement = lastEvent;
                            errorMessage   = "Couldn't find Finished event for the current function invocation";
                            return(false);
                        }
                        else
                        {
                            hashes.Add(lastEvent.InvocationId);
                        }

                        var minEventsExpected = Math.Floor(lastEvent.ExecutionTimeSpan / (double)MinimumLongRunningDurationInMs) - 2;
                        var maxEventsExpected = Math.Ceiling(lastEvent.ExecutionTimeSpan / (double)MinimumLongRunningDurationInMs) + 2;

                        // We should see atleast one InProgress event if it takes more than 5 seconds
                        if (lastEvent.ExecutionTimeSpan >= MinimumLongRunningDurationInMs &&
                            (relatedEventIds.Count < minEventsExpected ||
                             relatedEventIds.Count > maxEventsExpected))
                        {
                            invalidElement = lastEvent;
                            errorMessage   = string.Format("Long running function doesn't contain expected number of Etw events. Minimum:{0} Maximum:{1} Actual:{2}", minEventsExpected, maxEventsExpected, relatedEventIds.Count);
                            return(false);
                        }

                        foreach (var relatedEventId in relatedEventIds)
                        {
                            // Mark all related events as processed
                            functionValidationTrackerList[relatedEventId].HasBeenProcessed = true;
                        }
                    }
                    else if (functionExecutionArgs.ExecutionStage == ExecutionStage.Finished.ToString())
                    {
                        functionValidationTrackerList[currentIndex].HasBeenProcessed = true;
                        hashes.Add(functionExecutionArgs.InvocationId);
                    }
                }
            }

            var unprocessedEvents = functionValidationTrackerList.Where(e => !e.HasBeenProcessed).ToList();

            if (unprocessedEvents.Count > 0)
            {
                invalidElement = unprocessedEvents.FirstOrDefault()?.EventArguments;
                errorMessage   = string.Format("There are unprocessed events: {0}", SerializeFunctionExecutionEventArguments(unprocessedEvents.Select(e => e.EventArguments).ToList()));
                return(false);
            }

            if (hashes.Count != noOfFuncExecutions)
            {
                invalidElement = unprocessedEvents.FirstOrDefault()?.EventArguments;
                errorMessage   = string.Format("No of finished events does not match with number of function executions: Expected:{0} Actual:{1}", noOfFuncExecutions, hashes.Count);
                return(false);
            }

            return(true);
        }