Exemple #1
0
        /// <summary>
        /// constructor
        /// </summary>
        /// <param name="pPage">the visio page</param>
        /// <param name="pMapping">the mapping to create the objects</param>
        public void Initialize(Page pPage, MappingList pMapping)
        {
            //var init
            this.PageName = pPage.Name;

            //generate and initialize objects
            this.ObjectList = GenerateObjects(this, pPage, pMapping);
            this.ObjectList.ForEach(t => t.Initialize());
            this.ObjectsInitialized = true;

            //set connections
            this.ObjectList.ForEach(t =>
            {
                var connection = t as Connection;
                if (connection != null)
                {
                    try
                    {
                        connection.SetConnections(ObjectList);
                    }
                    catch (ValidationFailedException ex)
                    {
                        ValidationFailedEvent?.Invoke(new ValidationFailedMessage(2, ex));
                    }
                }
            });
            this.ConnectionsInitialized = true;
        }
Exemple #2
0
        public static ChaosEvent FromNativeEvent(NativeTypes.FABRIC_CHAOS_EVENT nativeEvent)
        {
            switch (nativeEvent.Kind)
            {
            case NativeTypes.FABRIC_CHAOS_EVENT_KIND.FABRIC_CHAOS_EVENT_KIND_STARTED:
                return(StartedEvent.FromNative(nativeEvent.Value));

            case NativeTypes.FABRIC_CHAOS_EVENT_KIND.FABRIC_CHAOS_EVENT_KIND_EXECUTING_FAULTS:
                return(ExecutingFaultsEvent.FromNative(nativeEvent.Value));

            case NativeTypes.FABRIC_CHAOS_EVENT_KIND.FABRIC_CHAOS_EVENT_KIND_STOPPED:
                return(StoppedEvent.FromNative(nativeEvent.Value));

            case NativeTypes.FABRIC_CHAOS_EVENT_KIND.FABRIC_CHAOS_EVENT_KIND_TEST_ERROR:
                return(TestErrorEvent.FromNative(nativeEvent.Value));

            case NativeTypes.FABRIC_CHAOS_EVENT_KIND.FABRIC_CHAOS_EVENT_KIND_VALIDATION_FAILED:
                return(ValidationFailedEvent.FromNative(nativeEvent.Value));

            case NativeTypes.FABRIC_CHAOS_EVENT_KIND.FABRIC_CHAOS_EVENT_KIND_WAITING:
                return(WaitingEvent.FromNative(nativeEvent.Value));

            default:
                return(null);
            }
        }
Exemple #3
0
        public static ChaosEvent GetEventFromBytes(byte[] data)
        {
            ChaosEvent     e    = null;
            ChaosEventType type = (ChaosEventType)BitConverter.ToInt32(data, 0);

            switch (type)
            {
            case ChaosEventType.Started:
            {
                e = new StartedEvent();
            }

            break;

            case ChaosEventType.Stopped:
            {
                e = new StoppedEvent();
            }

            break;

            case ChaosEventType.ExecutingFaults:
            {
                e = new ExecutingFaultsEvent();
            }

            break;

            case ChaosEventType.ValidationFailed:
            {
                e = new ValidationFailedEvent();
            }

            break;

            case ChaosEventType.TestError:
            {
                e = new TestErrorEvent();
            }

            break;

            case ChaosEventType.Waiting:
            {
                e = new WaitingEvent();
            }

            break;
            }

            if (e != null)
            {
                byte[] eventData = new byte[data.Length - 4];
                Array.Copy(data, 4, eventData, 0, eventData.Length);
                e.FromBytes(eventData);
            }

            return(e);
        }
Exemple #4
0
        protected IActionResult FromFailedValidationResult(ValidationFailedEvent failedEvent)
        {
            if (failedEvent.ValidationResult.IsNotFoundResult())
            {
                return(NotFound());
            }

            failedEvent.ValidationResult.AddToModelState(ModelState, null);
            return(BadRequest(ModelState));
        }
        private void HandleTaskComplete(Task t, string actionId, string actionName)
        {
            TestabilityTrace.TraceSource.WriteInfo(TraceType, "Action '{0}' completed with status: '{1}'.", actionName, t.Status.ToString());
            if (t.Exception != null)
            {
                t.Exception.Handle(ex =>
                {
                    var exceptionToTrace = ex is AggregateException ? ex.InnerException : ex;

                    if (exceptionToTrace is FabricValidationException)
                    {
                        string reason             = string.Format("Failed while executing {0}, with the exception: {1}", actionName, exceptionToTrace);
                        var validationFailedEvent = new ValidationFailedEvent(DateTime.UtcNow, reason);

                        // record validation failed event
                        this.StateManager.RegisterChaosEventAndUpdateChaosStatusAsync(
                            validationFailedEvent,
                            ChaosStatus.Running,
                            this.partition,
                            this.cancellationToken,
                            () =>
                        {
                            FabricEvents.Events.ChaosValidationFailed(
                                Guid.NewGuid().ToString(),
                                validationFailedEvent.TimeStampUtc.Ticks,
                                validationFailedEvent.Reason);
                        }).GetAwaiter().GetResult();
                    }
                    else
                    {
                        TestabilityTrace.TraceSource.WriteInfo(
                            TraceType,
                            actionId,
                            "Action {0}. Failed with exception {1}.",
                            actionName,
                            exceptionToTrace);
                    }

                    // Exception will be propagated if total consecutive failures greater than MaxConsecutiveFailures
                    return(this.RecordError()); // throwing the exception if false
                });
            }
            else
            {
                this.RecordSuccess();
            }
        }
Exemple #6
0
        /// <summary>
        /// validates basic intra model spezifications. Can be overwritten and extended by calling base.Validate()
        /// </summary>
        public virtual void Verify()
        {
            //check if sheet is not empty
            if (ObjectList.Count < 1)
            {
                ValidationFailedEvent?.Invoke(new ValidationFailedMessage(1, $"model {this.PageName} is empty"));
                return;
            }

            //check if elements are allowed on model
            if (AllowedItems != null)
            {
                foreach (var element in ObjectList)
                {
                    if (AllowedItems.All(t => t != element.GetType()) && element.GetType() != typeof(NRO))
                    {
                        ValidationFailedEvent?.Invoke(new ValidationFailedMessage(1, "element not allowed", element));
                    }
                }
            }

            //check if elements exist double on any sheet
            List <BaseObject> objects = ObjectList.Where(t => t is Item && !String.IsNullOrEmpty(t.Text) && !((t as Item).CanHaveDuplicateText)).ToList();

            foreach (var obj in objects)
            {
                if (objects.Count(t => t.Text == obj.Text) > 1)
                {
                    ValidationFailedEvent?.Invoke(new ValidationFailedMessage(2, $"{this.PageName} contains elements with duplicate text", obj));
                }
            }

            //do checks on objects, if implemented
            ObjectList.ForEach(t =>
            {
                try
                {
                    t.Verify();
                }
                catch (ValidationFailedException ex)
                {
                    ValidationFailedEvent?.Invoke(new ValidationFailedMessage(2, ex));
                }
            });
        }
Exemple #7
0
        private List <BaseObject> GenerateObjects(Model pParentmodel, Page pPage, MappingList pMapping)
        {
            List <BaseObject> ObjectList = new List <BaseObject>();

            //transform all shapes into model objects
            foreach (Shape shape in pPage.Shapes)
            {
                BaseObject modelObject = ModelFactory.GetInstanceFromShape(pParentmodel, shape, pMapping);
                if (modelObject != null)
                {
                    ObjectList.Add(modelObject);
                }
                else
                {
                    //exception of no matching model object type is found
                    ValidationFailedEvent?.Invoke(new ValidationFailedMessage(1, $"could not match shape {shape.Name}", null));
                }
            }

            return(ObjectList);
        }
Exemple #8
0
        /// <summary>
        /// creates a n-tree based from a root node
        /// </summary>
        /// <param name="pRoot">the root node to start the tree from</param>
        private void ValidateAllNodesInValidPaths(BmscNode pRoot)
        {
            //http://stackoverflow.com/questions/5691926/traverse-every-unique-path-from-root-to-leaf-in-an-arbitrary-tree-structure
            //create list and traverse tree. only return paths with enditem as leaf
            List <List <BmscNode> > validpaths = new List <List <BmscNode> >();

            TraverseNodes(pRoot, new List <BmscNode>(), validpaths);

            //validpths should now contain all paths where .Last() == StartEndItem with !IsStart
            //take all items from valid paths and check if they are equal with all items in model
            //for bmsc: only instances are relevant as placeableobjects are not part of the tree
            var allitems = StartNode.Current.ParentModel.ObjectList.Where(t => t is Instance);

            var validpathitems = validpaths.SelectMany(t => t).Select(t => t.Current).Distinct();
            var missingitems   = allitems.Where(t => !validpathitems.Contains(t)).ToList();

            if (missingitems.Any())
            {
                missingitems.ForEach(t => ValidationFailedEvent?.Invoke(new ValidationFailedMessage(4, "Item has no valid path.", t)));
            }

            //check if all messages are traversed with valid paths
            var allmessages = StartNode.Current.ParentModel.ObjectList.Where(t => t is Message);
            var allnextvalidpathmessagesmessages = validpaths.SelectMany(t => t).SelectMany(t => t.NextMessages).ToList();
            //special case: specifically add found messages
            var allnextvalidpathincomingmessages = validpaths.SelectMany(t => t).Select(t => t.IncomingMessage);

            allnextvalidpathmessagesmessages.AddRange(allnextvalidpathincomingmessages);
            var validpathmessages = allnextvalidpathmessagesmessages.Distinct();

            var missingmessages = allmessages.Where(t => !validpathmessages.Contains(t)).ToList();

            if (missingmessages.Any())
            {
                missingmessages.ForEach(t => ValidationFailedEvent?.Invoke(new ValidationFailedMessage(4, $"Message({t.Text}) has no valid path.", t)));
            }
        }
        internal async Task ExecuteIterationsWithPauseAsync()
        {
            TestabilityTrace.TraceSource.WriteNoise("StartTrek", "Enter ExecuteIterationsWithPauseAsync, datetimeutc={0}", DateTime.UtcNow);

            this.stopwatch = new Stopwatch();
            this.stopwatch.Start();

            Exception capturedException = null;

            TimeSpan waitTime = this.ChaosParameters.WaitTimeBetweenIterations;

            while (!this.cancellationToken.IsCancellationRequested)
            {
                // If this is not the beginning of a fresh Chaos run, before starting a new iteration,
                // consult the NextIterationTimeStampRD to find out if there is some
                // residual wait time from the previous iteration, if there is then wait that amount
                var nextIterationTimeStampUtc = await this.StateManager.GetUtcTimeStampAsync(
                    FASConstants.NextItearationTimeStampRDName,
                    FASConstants.NextItearationTimeStampKey,
                    this.partition,
                    this.cancellationToken).ConfigureAwait(false);

                var residualWaitTime = nextIterationTimeStampUtc.Subtract(DateTime.UtcNow);

                if (residualWaitTime > TimeSpan.Zero)
                {
                    await this.StateManager.RegisterChaosEventAndUpdateChaosStatusAsync(
                        new WaitingEvent(DateTime.UtcNow, StringHelper.Format(StringResources.ChaosInfo_ResidualWaitingFromPreviousIteration, residualWaitTime)),
                        ChaosStatus.Running,
                        this.partition,
                        this.cancellationToken,
                        () =>
                    {
                        TestabilityTrace.TraceSource.WriteInfo(TraceType, "Registering WaitingEvent for waiting '{0}' left over from the previous iteration.", residualWaitTime);
                    }).ConfigureAwait(false);

                    await Task.Delay(residualWaitTime, this.cancellationToken).ConfigureAwait(false);
                }

                try
                {
                    if (await this.IsClusterReadyForFaultsAsync(this.cancellationToken).ConfigureAwait(false))
                    {
                        System.Fabric.Common.TimeoutHelper timer = new System.Fabric.Common.TimeoutHelper(this.ChaosParameters.MaxClusterStabilizationTimeout);

                        StringBuilder validationReport = new StringBuilder();

                        var clusterReport =
                            await
                            this.validationHelper.ValidateClusterHealthAsync(
                                timer.GetRemainingTime(),
                                this.cancellationToken).ConfigureAwait(false);

                        if (clusterReport.ValidationFailed)
                        {
                            // quadratic with an upper bound of DefaultMaximumBackoffForChaosIterations
                            waitTime += (waitTime >= FASConstants.DefaultMaximumBackoffForChaosIterations) ? TimeSpan.Zero : waitTime;

                            var serviceReport =
                                await
                                this.validationHelper.ValidateAllServicesAsync(
                                    timer.GetRemainingTime(),
                                    this.cancellationToken).ConfigureAwait(false);

                            if (serviceReport.ValidationFailed)
                            {
                                TestabilityTrace.TraceSource.WriteInfo(TraceType, "Even though some services are unhealthy or unstable, going to induce faults, because the cluster is healthy.");

                                TestabilityTrace.TraceSource.WriteInfo(TraceType, "Failure reason: \n'{0}'", serviceReport.FailureReason);

                                validationReport.Append(serviceReport.FailureReason);
                            }

                            StringBuilder reportBuilder = new StringBuilder();
                            reportBuilder.Append(StringHelper.Format(StringResources.ChaosInfo_WaitingNotice, waitTime));
                            reportBuilder.AppendLine();
                            reportBuilder.AppendLine(clusterReport.FailureReason);

                            validationReport.Insert(0, reportBuilder.ToString());

                            TestabilityTrace.TraceSource.WriteInfo(TraceType, "Cluster validation failed for '{0}'.", clusterReport.FailureReason);

                            var validationFailedEvent = new ValidationFailedEvent(DateTime.UtcNow, validationReport.ToString());

                            // record validation failed event
                            await this.StateManager.RegisterChaosEventAndUpdateChaosStatusAsync(
                                validationFailedEvent,
                                ChaosStatus.Running,
                                this.partition,
                                this.cancellationToken,
                                () =>
                            {
                                FabricEvents.Events.ChaosValidationFailed(
                                    Guid.NewGuid().ToString(),
                                    validationFailedEvent.TimeStampUtc.Ticks,
                                    validationFailedEvent.Reason);
                            }).ConfigureAwait(false);

                            TestabilityTrace.TraceSource.WriteInfo(TraceType, "Pausing for '{0}' before performing next check.", waitTime);
                        }
                        else
                        {
                            waitTime = this.ChaosParameters.WaitTimeBetweenIterations;

                            await this.StateManager.RegisterCurrentStatusAsync(
                                ChaosStatus.Running,
                                this.partition,
                                this.cancellationToken).ConfigureAwait(false);

                            var timestampOfNextIteration = DateTime.UtcNow.Add(waitTime);

                            await this.StateManager.SetUtcTimeStampAsync(
                                FASConstants.NextItearationTimeStampRDName,
                                FASConstants.NextItearationTimeStampKey,
                                timestampOfNextIteration,
                                this.partition,
                                this.cancellationToken).ConfigureAwait(false);

                            await this.ExecuteFaultIterationAsync(this.cancellationToken).ConfigureAwait(false);

                            TestabilityTrace.TraceSource.WriteInfo(TraceType, "Pausing for '{0}' before executing next iteration.", waitTime);
                        }
                    }
                }
                catch (Exception exception)
                {
                    capturedException = exception;

                    // quadratic with an upper bound of DefaultMaximumBackoffForChaosIterations
                    waitTime += (waitTime >= FASConstants.DefaultMaximumBackoffForChaosIterations) ? TimeSpan.Zero : waitTime;

                    var timestampOfNextIteration = DateTime.UtcNow.Add(waitTime);

                    await this.StateManager.SetUtcTimeStampAsync(
                        FASConstants.NextItearationTimeStampRDName,
                        FASConstants.NextItearationTimeStampKey,
                        timestampOfNextIteration,
                        this.partition,
                        this.cancellationToken).ConfigureAwait(false);

                    TestabilityTrace.TraceSource.WriteInfo(TraceType, "Exception occurred in the ChaosTestScenario loop: {0}, cancellationreq: {1}", capturedException, this.cancellationToken.IsCancellationRequested);
                }

                if (capturedException != null)
                {
                    var ae = capturedException as AggregateException;
                    if (ae != null)
                    {
                        capturedException = ae.Flatten().InnerException;
                    }

                    if (!ChaosUtil.IsExpectedException(capturedException))
                    {
                        string testErrorEventMessage = capturedException.Message;

                        if (capturedException is FabricChaosEngineException)
                        {
                            testErrorEventMessage = StringResources.ChaosError_UnexpectedInChaosEngine;
                        }

                        await this.StateManager.RegisterChaosEventAndUpdateChaosStatusAsync(
                            new TestErrorEvent(DateTime.UtcNow, testErrorEventMessage),
                            ChaosStatus.Running,
                            this.partition,
                            this.cancellationToken).ConfigureAwait(false);

                        TestabilityTrace.TraceSource.WriteInfo(TraceType, "Unexpected exception '{0}' was turned into TestErrorEvent.", capturedException);
                    }

                    // handled the exception, now clear it
                    capturedException = null;
                }

                if (this.testMode && (this.ChaosParameters.Context != null && this.ChaosParameters.Context.ContainsKey(ChaosConstants.FailoverAfterChaosFaultsKey)))
                {
                    this.partition.ReportFault(FaultType.Transient);
                }

                await this.StateManager.RegisterChaosEventAndUpdateChaosStatusAsync(
                    new WaitingEvent(DateTime.UtcNow, StringHelper.Format(StringResources.ChaosInfo_WaitingBetweenIterations, waitTime)),
                    ChaosStatus.Running,
                    this.partition,
                    this.cancellationToken,
                    () =>
                {
                    TestabilityTrace.TraceSource.WriteInfo(TraceType, "Registering WaitingEvent for waiting '{0}' between iterations.", waitTime);
                }).ConfigureAwait(false);

                await Task.Delay(waitTime, this.cancellationToken).ConfigureAwait(false);

                this.IterationsCompleted++;
            }

            TestabilityTrace.TraceSource.WriteInfo(TraceType, "Session has completed. \nTotal iterations: {0}. Total elapsed time: {1}", this.IterationsCompleted, this.GetElapsedTime());
        }
Exemple #10
0
 /// <summary>
 /// notifies when a validation error occured
 /// </summary>
 /// <param name="pArgs">validation failed message</param>
 public void NotifyValidationFailed(ValidationFailedMessage pArgs)
 {
     ValidationFailedEvent?.Invoke(pArgs);
 }