コード例 #1
0
 public InMemoryTrackingParticipant()
 {
     TestTraceManager.OptionalLogTrace("[InMemoryTrackingParticipant]New instance of InMemoryTrackingParticipant invoked...");
     this.TestTraceManager = TestTraceManager.Instance;
     //this.ProfileProvider = new CustomCodeProfileProvider();
     TestTraceManager.OptionalLogTrace("[InMemoryTrackingParticipant]InMemoryTrackingParticipant instantiated...");
 }
コード例 #2
0
        private bool TrackActivityStateRecord(ActivityStateRecord activityRecord, ActualTrace _trace)
        {
            TestTraceManager.OptionalLogTrace("[InMemoryTrackingParticipant]activityRecord.Name = {0}", activityRecord.Activity.Name);
            ActivityTrace activityTrace = new ActivityTrace(
                activityRecord.Activity.Name,
                (ActivityInstanceState)Enum.Parse(typeof(ActivityInstanceState), activityRecord.State), activityRecord);

            //to avoid the confusion b\w Executing & scheduling events, we always use scheduled
            if (activityTrace.ActivityStatus != ActivityInstanceState.Executing)
            {
                _trace.Add(activityTrace);
                return(true);
            }

            //for tracking test cases, it may be the scenario that the profile does not have a scheduled record.
            //in that scenario, we need to add that explicitly to the trace.
            if (TestTraceManager.IsDefaultTrackingConfiguration == false)//is a tracking test case
            {
                if (
                    (_trace.Steps.Count == 0) ||
                    (
                        (_trace.Steps.Count != 0) &&
                        (_trace.Steps[_trace.Steps.Count - 1].Equals(activityTrace) == false)
                    )
                    )
                {
                    _trace.Add(activityTrace);
                    return(true);
                }
            }

            return(false);
        }
コード例 #3
0
        private int ExecuteSqlStringScalarCount(string script, SqlConnection conn)
        {
            // temporary fix: reopen connection after it is closed, fail after 3 tries
            int iRet     = 0;
            int tryCount = 0;

            while (true)
            {
                try
                {
                    using (SqlCommand command = new SqlCommand("", conn))
                    {
                        command.CommandText = script;
                        // iRet = (int)PartialTrustSQLCommand.ExecuteScalar(command);
                    }
                    break;
                }
                catch (SqlException e) // jasonv - approved; specific, commented, rethrows after retries
                {
                    TestTraceManager.OptionalLogTrace(e.ToString());
                    //Log.TraceInternal(e.Message);
                    //Log.TraceInternal("[SqlInstance] After exception Connection state is " + conn.State);
                    if (tryCount++ < 3)
                    {
                        // PartialTrustSQLConnect.Open(conn);
                    }
                    else
                    {
                        throw;
                    }
                }
            }
            return(iRet);
        }
コード例 #4
0
        public static void ValidateTracking(ExpectedTrace expectedTrace, ActualTrace actualTrace, TrackingProfile profile, TestProfileType profileType, TrackingParticipantType participantType)
        {
            //1. Filter the expected trace against the workFlow profile
            ExpectedTrace filteredExpectedTrace = TrackingFilter.ApplyTrackingProfile(expectedTrace, profile);

            ////2. Delete not supported trace steps by testObjects.
            ActualTrace modifiedActualTrace = TrackingFilter.DeleteNotSupportedTraceSteps(actualTrace);

            TestTraceManager.OptionalLogTrace("[TestTrackingDataManager]*****ValidateTracking()");
            ////3. Validate the expected & the actual trace
            TestTraceManager.OptionalLogTrace("[TestTrackingDataManager]Profile = {0}", profile);
            TestTraceManager.OptionalLogTrace("[TestTrackingDataManager]Actual Trace = {0}", actualTrace);
            TestTraceManager.OptionalLogTrace("[TestTrackingDataManager]Expected Trace = {0}", expectedTrace);
            TestTraceManager.OptionalLogTrace("[TestTrackingDataManager]Filtered Expected Trace (after applying tracking profile) = {0}", filteredExpectedTrace);
            TestTraceManager.OptionalLogTrace("[TestTrackingDataManager]Modified ActualTrace Trace = {0}", modifiedActualTrace);
            TestTraceManager.OptionalLogTrace("[TestTrackingDataManager]Invoking internally the trace validation...");

            ////if (!(TestProfileProvider.IsAllOrNullProfile(profileType) &&
            if (((participantType != TrackingParticipantType.SqlTrackingParticipant) &&
                 (participantType != TrackingParticipantType.ETWTrackingParticipant)))
            {
                modifiedActualTrace.Validate(filteredExpectedTrace, TestTraceManager.IsDefaultTrackingConfiguration);
            }

            //Log.TraceInternal("[TestTrackingDataManager]*****Validate method Succeeded...");
        }
コード例 #5
0
 private void TrackActivityScheduledRecord(ActivityScheduledRecord activityScheduledRecord, ActualTrace _trace)
 {
     //the scheduling record simply states that i am scheduled blah. Currently we do not have any support in TO for this.
     //Hence, turning it off for now. we will have the tracking tests cover the validation.
     TestTraceManager.OptionalLogTrace("[InMemoryTrackingParticipant]activityScheduledRecord.TargetName = {0}", activityScheduledRecord.Child.Name);
     _trace.Add(new ActivityTrace(activityScheduledRecord.Child.Name,
                                  ActivityInstanceState.Executing, activityScheduledRecord));
 }
コード例 #6
0
        private void TrackBookmarkResumptionRecord(BookmarkResumptionRecord bookmarkResumptionRecord, ActualTrace _trace)
        {
            TestTraceManager.OptionalLogTrace("[InMemoryTrackingParticipant]BookmarkName = {0}, bookmarkResumptionRecord = {1} ", bookmarkResumptionRecord.BookmarkName, bookmarkResumptionRecord.ToString());
            _trace.Add(new BookmarkResumptionTrace(
                           bookmarkResumptionRecord.BookmarkName,
                           bookmarkResumptionRecord.BookmarkScope,
                           bookmarkResumptionRecord.Owner.Name));

            //_trace.Add(new ActivityTrace(bookmarkResumptionRecord.ToString(),
            //    ActivityInstanceState.Executing));
        }
コード例 #7
0
        private void TrackCancelRequestedRecord(CancelRequestedRecord cancelRecord, ActualTrace _trace)
        {
            TestTraceManager.OptionalLogTrace("[InMemoryTrackingParticipant]cancelRequestedRecord.TargetName = {0}", cancelRecord.Child.Name);

            //this gets propogated twice by the product: ActivityStates.Fault information.
            {
                // WFCore - AT LEAST the DoWhile test cases that Cancel were failing because of these "extra"
                // Activity Canceled records in the trace. It's not clear if this is the right thing to do.
                //_trace.Add(new ActivityTrace(
                //    cancelRecord.Child.Name,
                //    (ActivityInstanceState)Enum.Parse(typeof(ActivityInstanceState), ActivityStates.Canceled)));
            }
        }
コード例 #8
0
        public static TextWriter CreateClientTraceWriter(string testName)
        {
            if (TestTraceManager.IsEnabled)
            {
                var logBasePath     = Path.Combine(Directory.GetCurrentDirectory(), "..");
                var clientTracePath = TestTraceManager.GetTraceFilePath($"{testName}.client.trace.log");
                var writer          = new StreamWriter(clientTracePath);
                writer.AutoFlush = true;
                return(writer);
            }

            return(TextWriter.Null);
        }
コード例 #9
0
        private void TrackFaultPropagationRecord(FaultPropagationRecord faultRecord, ActualTrace _trace)
        {
            string faultName = (faultRecord.FaultHandler == null) ? "<Unknown>" : faultRecord.FaultHandler.Name;

            TestTraceManager.OptionalLogTrace("[InMemoryTrackingParticipant]faultPropatationRecord.TargetName = {0}", faultName);
            //string status = "Faulted";

            // There is no Property called State in FaultPropagationRecord. Need to understand Fault propagation here
            //this gets propogated twice by the product: ActivityStates.Fault information.
            //if (faultRecord.State == ActivityStates.Schedule)
            //{
            //    _trace.Add(new ActivityTrace(
            //        faultName,
            //        (ActivityInstanceState)Enum.Parse(typeof(ActivityInstanceState), status)));
            //}
        }
コード例 #10
0
        protected override void Track(TrackingRecord record, TimeSpan timeout)
        {
            try
            {
                TestTraceManager.OptionalLogTrace("[InMemoryTrackingParticipant]Track()::InMemory tracking participant = {0} ; Tracking record type = {1} ; Record Details = {2}", this.Name, record.GetType(), record.ToString());
                TestTraceManager.OptionalLogTrace("[InMemoryTrackingParticipant]TestTraceManager.IsDefaultTrackingConfiguration = {0}", TestTraceManager.IsDefaultTrackingConfiguration.ToString());
                bool IsPushDataToTraceManager = true;

                ActualTrace _trace = this.GetActualTrackingData(record.InstanceId);

                if (record is WorkflowInstanceRecord)
                {
                    TrackWorkflowInstanceRecord(record as WorkflowInstanceRecord, _trace);
                }
                else if (record is ActivityStateRecord)
                {
                    IsPushDataToTraceManager = TrackActivityStateRecord(record as ActivityStateRecord, _trace);
                }
                else if (record is ActivityScheduledRecord)
                {
                    TrackActivityScheduledRecord(record as ActivityScheduledRecord, _trace);
                }
                else if (record is BookmarkResumptionRecord)
                {
                    TrackBookmarkResumptionRecord(record as BookmarkResumptionRecord, _trace);
                }
                else if (record is CancelRequestedRecord)
                {
                    TrackCancelRequestedRecord(record as CancelRequestedRecord, _trace);
                }
                else if (record is FaultPropagationRecord)
                {
                    TrackFaultPropagationRecord(record as FaultPropagationRecord, _trace);
                }
                if (IsPushDataToTraceManager)
                {
                    PushDataToTraceManager(record);
                }
            }
            //This exception will be eaten by the product tracking code and not available for review
            //So the only chance we have to see it is if we log it.
            catch (Exception e)
            {
                //Log.WarnInternal("Exception thrown in Track() method\n" + e.ToString());
                throw;
            }
        }
コード例 #11
0
 public static TestTrackingDataManager GetInstance(Guid workflowId)
 {
     TestTraceManager.OptionalLogTrace("[TestTrackingDataManager]TestTrackingDataManager::GetInstance() " + workflowId.ToString());
     lock (TestTrackingDataManager.s_testTrackingDataManagers)
     {
         if (!TestTrackingDataManager.s_testTrackingDataManagers.ContainsKey(workflowId))
         {
             if (TestTrackingDataManager.s_eventTrackingDataManager != null)
             {
                 TestTrackingDataManager.s_eventTrackingDataManager._workflowId = workflowId;
                 TestTrackingDataManager.s_testTrackingDataManagers.Add(workflowId, TestTrackingDataManager.s_eventTrackingDataManager);
                 TestTrackingDataManager.s_eventTrackingDataManager = null;
             }
             else
             {
                 TestTrackingDataManager.s_testTrackingDataManagers.Add(workflowId, new TestTrackingDataManager(workflowId));
             }
         }
     }
     return(TestTrackingDataManager.s_testTrackingDataManagers[workflowId]);
 }
コード例 #12
0
        /// <summary>
        /// Constructor
        /// </summary>
        public static void Validate(ActualTrace actualTrace, ExpectedTrace expectedTrace, bool traceTracking)
        {
            TraceValidator.s_actualTrace   = actualTrace;
            TraceValidator.s_expectedTrace = expectedTrace;

            TraceValidator.s_errorList  = new List <string>();
            TraceValidator.s_stepCounts = new Dictionary <string, StepCount>();

            TestTraceManager.OptionalLogTrace("[TraceValidator]Unfiltered expected trace:\n{0}", expectedTrace.ToString());
            TestTraceManager.OptionalLogTrace("[TraceValidator]Unfiltered actual trace:\n{0}", actualTrace.ToString());

            TraceValidator.NormalizeExpectedTrace(expectedTrace.Trace);
            TraceValidator.RemoveIgnorableSteps(expectedTrace.Trace);
            TraceValidator.PrepareExpectedTrace(expectedTrace.Trace, false, null, -1);

            TraceValidator.PrepareActualTrace();

            if (traceTracking)
            {
                //Log.TraceInternal("[TraceValidator]Filtered expected trace:\n{0}", expectedTrace.ToString());
                //Log.TraceInternal("[TraceValidator]Filtered actual trace:\n{0}", actualTrace.ToString());
                //Log.TraceInternal("[TraceValidator]Doing count validation...");
            }

            TraceValidator.CheckStepCounts();
            TraceValidator.CheckErrors();

            if (traceTracking)
            {
                //Log.TraceInternal("[TraceValidator]Validating...");
            }
            TraceValidator.ValidateFirst(expectedTrace.Trace, 0);
            TraceValidator.CheckErrors();

            if (traceTracking)
            {
                //Log.TraceInternal("[TraceValidator]ExpectedTrace: Validation complete.");
            }
        }
コード例 #13
0
        public void InstantiateTrackingParticipants(IEnumerable <TrackingConfiguration> config)
        {
            _trackingParticipants = new Dictionary <string, TrackingParticipant>();
            bool isTrackingParticipantSelected = false;
            int  numberOfTrackingParticipants  = config.Count();

            foreach (TrackingConfiguration trackingConfig in config)
            {
                TestTraceManager.OptionalLogTrace("[TestTrackingDataManager]Adding tracking participant TrackingParticipantType = {0}, ProfileManagerType = {1}, TestProfileType = {2}",
                                                  trackingConfig.TrackingParticipantType,
                                                  trackingConfig.ProfileManagerType,
                                                  trackingConfig.TestProfileType);
                switch (trackingConfig.TrackingParticipantType)
                {
                //case TrackingParticipantType.SqlTrackingParticipant:
                //    //Sql works against the product & only for the default config profile provider
                //    SqlTrackingParticipant sqlTrackingParticipant = (SqlTrackingParticipant)TestTrackingParticipantBase.GetInstance(trackingConfig.TrackingParticipantType, ParticipantAssociation.WorkflowExtention);
                //    SqlTrackingConfiguration sqlTrackingConfig = trackingConfig as SqlTrackingConfiguration;
                //    //sqlTrackingParticipant.TrackingProfile = TestProfileProvider.GetTrackingProfile(sqlTrackingConfig.ProfileName);
                //    //Log.TraceInternal("[TestTrackingDataManager]sqlTrackingParticipant.TrackingProfile =" + sqlTrackingParticipant.TrackingProfile);

                //    sqlTrackingParticipant.ParticipateInProcessTransaction = sqlTrackingConfig.IsTransactional;
                //    sqlTrackingParticipant.ConnectionString = sqlTrackingConfig.ConnectionString;
                //    this.trackingParticipants.Add(trackingConfig.TrackingParticipantName, sqlTrackingParticipant);
                //    if (!isTrackingParticipantSelected)
                //    {
                //        //Log.TraceInternal("[TestTrackingDataManager]Test profile type = {0}, TestProfileProvider.IsAllOrNullProfile(trackingConfig.TestProfileType) = {1}", trackingConfig.TestProfileType, TestProfileProvider.IsAllOrNullProfile(trackingConfig.TestProfileType));
                //        //if (TestProfileProvider.IsAllOrNullProfile(trackingConfig.TestProfileType) || (numberOfTrackingParticipants == 1))
                //        //{
                //        //    isTrackingParticipantSelected = true;
                //        //    sqlTrackingConfig.PushToTrackingDataManager = true;
                //        //}
                //    }
                //    //Log.TraceInternal("[TestTrackingDataManager]Added PRODUCT SqlTrackingParticipant with: ProfileName={0}, isTransactional={1}, ConnectionString={2}",
                //    //    sqlTrackingParticipant.TrackingProfile.Name,
                //    //    sqlTrackingParticipant.ParticipateInProcessTransaction.ToString(),
                //    //    sqlTrackingParticipant.ConnectionString);
                //    break;
                case TrackingParticipantType.InMemoryTrackingParticipant:
                    InMemoryTrackingParticipant memoryTrackingParticipant = (InMemoryTrackingParticipant)TestTrackingParticipantBase.GetInstance(trackingConfig.TrackingParticipantType, ParticipantAssociation.WorkflowExtention);
                    memoryTrackingParticipant.PushToTrackingDataManager = true;
                    _trackingParticipants.Add(trackingConfig.TrackingParticipantName, memoryTrackingParticipant);
                    break;

                default:
                    TestTrackingParticipantBase trackingParticipant = (TestTrackingParticipantBase)TestTrackingParticipantBase.GetInstance(trackingConfig.TrackingParticipantType, ParticipantAssociation.TestVerification);
                    //trackingParticipant.ProfileProvider = TestProfileProvider.GetInstance(trackingConfig);
                    trackingParticipant.ProfileProvider.ActiveTrackingProfile = trackingConfig.TestProfileType;
                    trackingParticipant.Name = trackingConfig.TrackingParticipantName;
                    _trackingParticipants.Add(trackingConfig.TrackingParticipantName, trackingParticipant);
                    if (!isTrackingParticipantSelected)
                    {
                        //if (TestProfileProvider.IsAllOrNullProfile(trackingConfig.TestProfileType) || (numberOfTrackingParticipants == 1))
                        //{
                        //    isTrackingParticipantSelected = true;
                        //    trackingParticipant.PushToTrackingDataManager = true;
                        //}
                    }
                    break;
                }
                TestTraceManager.OptionalLogTrace("[TestTrackingDataManager]Successfully added tracking participant");
            }
            TestTraceManager.OptionalLogTrace("[TestTrackingDataManager]Successfully added all tracking participants...");
        }
コード例 #14
0
 protected IDisposable EnableTracing()
 {
     return(TestTraceManager.CreateTraceListener($"{GetTestName()}.{Interlocked.Increment(ref _id)}"));
 }
コード例 #15
0
        internal void ValidateTracking(ExpectedTrace expectedTrace)
        {
            // Sort before
            if (expectedTrace.SortBeforeVerification)
            {
                //Log.TraceInternal("[TestTracingWatcher] Sort before verification is enabled, tracking will go into an infinite loop, so skipping.");
                return;
            }

            ActualTrace actualTrace;

            //TestTrackingDataManager.ValidateTracking(expectedTrace, actualTrace, profile, trackingConfig.TestProfileType, trackingConfig.TrackingParticipantType);

            //expected trace needs to be validated with each of the trackign services that are currently enabled.
            //Initial Design: Moved the common validation to the base method to avoid redundant code. Validation still
            //in the tracking service so as to take into account the scneario for profile versioning when
            //the validation is tricky due to multipel profiles & the particular service may need finer control
            //for that particular workflow id.
            //Final Design: Moved it from the TrackingParticipant since we need validation to work fine even if say
            //for Partial trust.
            foreach (TrackingConfiguration trackingConfig in _remoteworkflowRuntime.TrackingConfigurations)
            {
                TestTraceManager.OptionalLogTrace("[TestTracingWatcher]******Tracking validation for {0}", trackingConfig.TrackingParticipantName);

                //1. get the profile for the workFlow
                //note profiles are not seralizable. Hence you need ot get it from a local instance. (in account for the web-hosted scenario)
                TestTrackingParticipantBase trackingParticipant = TestTrackingParticipantBase.GetInstanceForVerification(trackingConfig.TrackingParticipantType);
                TrackingProfile             profile             = TestProfileProvider.GetTrackingProfile(trackingParticipant, trackingConfig);

                // Assign tracking participant name to new profile name because this will be used to find out
                // the current tracking configuration in TrackingFilter.
                if (profile != null)
                {
                    profile.Name = trackingConfig.TrackingParticipantName;
                }

                switch (trackingConfig.TrackingParticipantType)
                {
                case TrackingParticipantType.SqlTrackingParticipant:
                    SqlTrackingConfiguration sqlTrackingConfiguration = trackingConfig as SqlTrackingConfiguration;
                    if (sqlTrackingConfiguration != null)
                    {
                        trackingParticipant.PushToTrackingDataManager = sqlTrackingConfiguration.PushToTrackingDataManager;
                    }
                    actualTrace = trackingParticipant.GetActualTrackingData(_workflowInstanceId);

                    for (int i = profile.Queries.Count - 1; i >= 0; i--)
                    {
                        Type queryType = profile.Queries[i].GetType();
                        if (queryType == typeof(ActivityScheduledQuery))
                        {
                            profile.Queries.RemoveAt(i);
                        }
                    }
                    break;

                default:
                    actualTrace = _remoteworkflowRuntime.ActualTrackingData(trackingConfig.TrackingParticipantName);
                    break;
                }

                //3. validate
                TestTrackingDataManager.ValidateTracking(expectedTrace, actualTrace, profile, trackingConfig.TestProfileType, trackingConfig.TrackingParticipantType);
            }
        }
コード例 #16
0
        public static ExpectedTrace ApplyTrackingProfile(ExpectedTrace expectedTrace, TrackingProfile profile)
        {
            ExpectedTrace modifiedTrace = TrackingFilter.RemovePlaceholderTrace(expectedTrace);

            modifiedTrace = TrackingFilter.RemoveUserTrace(modifiedTrace);
            TestTraceManager.OptionalLogTrace("[TrackingFilter]After Remove UserTrace, modifiedTrace = {0}", modifiedTrace);
            modifiedTrace = TrackingFilter.NormalizeTrace(modifiedTrace);
            TestTraceManager.OptionalLogTrace("[TrackingFilter]After NormalizeTrace, modifiedTrace = {0}", modifiedTrace);
            //vc temp only till we figure out the user record story for M2.
            if (profile == null)//all events to be returned
            {
                return(modifiedTrace);
            }

            int count = modifiedTrace.Trace.Steps.Count;

            for (int i = 0; i < count; i++)
            {
                WorkflowTraceStep workflowTraceStep = modifiedTrace.Trace.Steps[i];

                // Check if this is a faulted state.
                // When we have a faulted state the preceding executing state should be deleted.

                TrackingConfiguration currentTrackingConfiguration = GetCurrentTP(profile.Name);
                bool isExecutingRecExpectedOnFaultedState          = true;
                if (!isExecutingRecExpectedOnFaultedState)
                {
                    ActivityTrace activityTrace = (ActivityTrace)workflowTraceStep;
                    if ((i > 0) && (activityTrace.ActivityStatus == ActivityInstanceState.Faulted))
                    {
                        ActivityTrace precedingActivityTrace = (ActivityTrace)modifiedTrace.Trace.Steps[i - 1];
                        if (precedingActivityTrace.ActivityStatus == ActivityInstanceState.Executing)
                        {
                            bool trackScheduledQuery = false;

                            foreach (ActivityScheduledQuery activityScheduledQuery in profile.Queries.OfType <ActivityScheduledQuery>())
                            {
                                if (IsActivityScheduledTracked(activityScheduledQuery, precedingActivityTrace.ActivityName))
                                {
                                    trackScheduledQuery = true;
                                }
                            }

                            // If we don't track the scheduled records delete the preceding executing state record.
                            // The preceding executing state is from scheduled record.
                            if (!trackScheduledQuery)
                            {
                                modifiedTrace.Trace.Steps.RemoveAt(i - 1);
                                i--;
                                count = modifiedTrace.Trace.Steps.Count;
                                //Log.TraceInternal("[TrackingFilter]Preceding executing activity trace deleted because the current expected trace state is Faulted.");
                            }
                        }
                    }
                }

                if (!profile.ShouldTrackStep(workflowTraceStep))
                {
                    modifiedTrace.Trace.Steps.RemoveAt(i);
                    count = modifiedTrace.Trace.Steps.Count;
                    //continue at the same step
                    i--;
                    //Log.TraceInternal("[TrackingFilter]Removed event = {0}=", workflowTraceStep);
                }
            }

            return(modifiedTrace);
        }
コード例 #17
0
        public static ITestHost CreateHost(HostType hostType, TransportType transportType, string testName, string url = null)
        {
            ITestHost host = null;

            var traceDisposable = TestTraceManager.CreateTraceListener(testName + ".test.trace.log");

            switch (hostType)
            {
            case HostType.IISExpress:
                throw new NotSupportedException("IIS Express testing is disabled.");

            case HostType.External:
                host = new ExternalTestHost(url);
                host.TransportFactory = () => CreateTransport(transportType);
                host.Transport        = host.TransportFactory();
                break;

            case HostType.Memory:
            default:
                var mh = new MemoryHost();
                host = new MemoryTestHost(mh, TestTraceManager.GetTraceFilePath(testName));
                host.TransportFactory = () => CreateTransport(transportType, mh);
                host.Transport        = host.TransportFactory();
                break;

            case HostType.HttpListener:
                host = new OwinTestHost(TestTraceManager.GetTraceFilePath(testName));
                host.TransportFactory = () => CreateTransport(transportType);
                host.Transport        = host.TransportFactory();
                Trace.TraceInformation("HttpListener url: {0}", host.Url);
                break;
            }

            host.Disposables.Add(traceDisposable);

            host.ClientTraceOutput = CreateClientTraceWriter(testName);

            if (hostType != HostType.Memory && hostType != HostType.External && TestTraceManager.IsEnabled)
            {
                host.Disposables.Add(SystemNetLogging.Enable(TestTraceManager.GetTraceFilePath($"{testName}.client.network.log")));
                var httpSysTracing = StartHttpSysTracing(TestTraceManager.GetTraceFilePath($"{testName}.httpSys"));

                // If tracing is enabled then turn it off on host dispose
                if (httpSysTracing != null)
                {
                    host.Disposables.Add(httpSysTracing);
                }
            }

            EventHandler <UnobservedTaskExceptionEventArgs> handler = (sender, args) =>
            {
                Trace.TraceError("Unobserved task exception: " + args.Exception.GetBaseException());

                args.SetObserved();
            };

            TaskScheduler.UnobservedTaskException += handler;
            host.Disposables.Add(new DisposableAction(() =>
            {
                TaskScheduler.UnobservedTaskException -= handler;
            }));

            return(host);
        }