How to know when a WF service instance has finished

Feb 1, 2011 at 2:29 PM

Hello,

We are using WorkflowServiceTestHost for our tests with good results but a few problems. 

 

The schema for executing a secuencial WF is the following:

     

using (var testHost = WorkflowServiceTestHost.Open(@"*.xamlx", _serviceAddress.Uri))
            {
                // Use the generated proxy with named pipes  
                var channelFactoryService = new ChannelFactory<IService>(new NetNamedPipeBinding() { SendTimeout = new TimeSpan(0, 20, 0) }, _serviceAddress);
 
                try
                {
                    var client = channelFactoryService.CreateChannel();
 
                    client.CallToWF();
		WorkflowServiceTestHost.WaitForInstanceUnloaded(30000);
                    WorkflowServiceTestHost.WaitForInstanceDeleted(30000);
 
 
                }
                catch (Exception)
                {
                    channelFactoryPopulateReads.Abort();
                    
                    throw;
                }
                finally
                {
                    testHost.Tracking.Trace();
 
                    channelFactoryPopulateReads.Close();
testHost.Close();
	Assert.IsTrue(WorkflowServiceTestHost.WaitForHostClosed());
                }
 
            }

 

Is this correct?

  • Sometimes we have an exception in the close method (some strange timeout of 10 seconds). 
  • In don't know why do I have to insert workflowinstanceunloaded, but sometimes the wait until deleted goes away before the WF is finished!! :(

Thanks in advance.

Coordinator
Feb 8, 2011 at 9:14 PM

Which Close method has the exception?

The hardest part of testing workflow services is to detect when they are really finished.  There could be issues there that we need to improve.

If you can help me by providing a repro of problems that you find I might be able to help you more with this.

Feb 9, 2011 at 7:20 AM

Oh! sorry! I didn't notice I wrote two close methods, the WCF client one and the host one.

I am refering to the second one --> testHost.Close();

When I have time I will try to create a project just to reproduce the issue, but as we see it, it is random and difficult to reproduce.

Thanks

Coordinator
Feb 10, 2011 at 11:48 PM

Sometimes you don't have to wait for the instance to complete when asserting things.  However if the workflow instance is doing work after sending the response you might have to wait until the tracking shows that it has done what you were looking for.

Apr 14, 2011 at 7:30 AM
Edited Apr 14, 2011 at 7:30 AM

I haven't looked that much at the code, but I think there's a problem with the static methods on the service test host, and running multiple workflows in a test, etc...  I'll find cases where a test will work when run alone, but oddly won't if run with other tests in certain orders and combinations.  So I think there's a weird state problem.

Maybe there's an easier way, but this is what I cooked up.  It's along the lines of Ron's comment - it just waits for a particular known event in the workflow tracking via (another) custom tracking participant.

We have a wrapper around the WorkflowServiceTestHost that adds this to the workflow extensions and does some other utility operations like setup Xaml injection, some other stuff.   Here's the part related to waiting for events.

 

        public class TestWorkflowRunner : TrackingParticipant
	{
		...utility stuff... 
		public List<T> WaitFor<T>(Func<T, bool> condition, int timeout)
		{
			return WaitFor<T>((f, s) => condition(f), timeout);
		}
		public List<T> WaitFor<T>(Func<T, List<TrackingRecord>, bool> condition, int timeout)
		{
			DateTime end = DateTime.Now.AddMilliseconds(timeout);
			while (DateTime.Now < end)
			{
				if (!_trackingEvent.WaitOne(end - DateTime.Now))
					break;
				lock (_trackingSync)
				{
					var r = _trackingQueue.OfType<T>().Where(i => condition(i, _trackingRecords)).ToList();
					_trackingQueue.Clear();
					if (r.Count > 0)
						return r;
				}
			}
			return new List<T>();
		}


		protected override void Track(TrackingRecord record, TimeSpan timeout)
		{
			lock (_trackingSync)
			{
				_trackingRecords.Add(record);
				_trackingQueue.Enqueue(record);
				_trackingEvent.Set();
			}
		}
	}

 

Coordinator
Jul 25, 2011 at 8:31 PM
Edited Jul 25, 2011 at 8:33 PM

Found the problem - see WorkflowServiceHost level events cannot be static because it causes test failures when multiple tests are running.This will be fixed in Microsoft.Activities.UnitTesting v1.8.6