File: RemoteTestAgent.cs

package info (click to toggle)
mono 4.6.2.7+dfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 778,148 kB
  • ctags: 914,052
  • sloc: cs: 5,779,509; xml: 2,773,713; ansic: 432,645; sh: 14,749; makefile: 12,361; perl: 2,488; python: 1,434; cpp: 849; asm: 531; sql: 95; sed: 16; php: 1
file content (133 lines) | stat: -rw-r--r-- 2,965 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
using System;
using System.Threading;
using System.Collections;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using NUnit.Core;

namespace NUnit.Util
{
	/// <summary>
	/// RemoteTestAgent represents a remote agent executing in another process
	/// and communicating with NUnit by TCP. Although it is similar to a
	/// TestServer, it does not publish a Uri at which clients may connect 
	/// to it. Rather, it reports back to the sponsoring TestAgency upon 
	/// startup so that the agency may in turn provide it to clients for use.
	/// </summary>
	public class RemoteTestAgent : MarshalByRefObject, IDisposable
	{
		#region Fields
		/// <summary>
		/// Url of the agency that controls this agent
		/// </summary>
		string agencyUrl;

		/// <summary>
		/// Reference to the TestAgency that controls this agent
		/// </summary>
		TestAgency agency;

		/// <summary>
		/// Channel used for communications with the agency
		/// and with clients
		/// </summary>
		private TcpChannel channel;

		/// <summary>
		/// Lock used to avoid thread contention
		/// </summary>
		private object theLock = new object();

		#endregion

		#region Constructor
		/// <summary>
		/// Construct a RemoteTestAgent given the Url of its agency
		/// </summary>
		/// <param name="agencyUrl"></param>
		public RemoteTestAgent( string agencyUrl )
		{
			this.agencyUrl = agencyUrl;
		}
		#endregion

		#region Properties
		public TestAgency Agency
		{
			get { return agency; }
		}

		public int ProcessId
		{
			get { return System.Diagnostics.Process.GetCurrentProcess().Id; }
		}
		#endregion

		#region Public Methods - Called By local Agent
		public TestRunner CreateRunner(int runnerID)
		{
			return new TestDomain( runnerID );
		}
		#endregion

		#region Public Methods
		public void Start()
		{
			NTrace.Info("Starting");
			this.channel = ServerUtilities.GetTcpChannel();
			NTrace.Debug("Acquired Tcp Channel");

			try
			{
				this.agency = (TestAgency)Activator.GetObject( typeof( TestAgency ), agencyUrl );
				NTrace.DebugFormat("Connected to TestAgency at {0}", agencyUrl);
			}
			catch( Exception ex )
			{
				NTrace.ErrorFormat( "Unable to connect to test agency at {0}", agencyUrl );
				NTrace.Error( ex.Message );
			}

			try
			{
				this.agency.Register( this, ProcessId );
				NTrace.Debug( "Registered with TestAgency" );
			}
			catch( Exception ex )
			{
				NTrace.Error( "Failed to register with TestAgency", ex );
			}
		}

		[System.Runtime.Remoting.Messaging.OneWay]
		public void Stop()
		{
			NTrace.Info( "Stopping" );
			lock( theLock )
			{
				if ( this.channel != null )
					ChannelServices.UnregisterChannel( this.channel );
				Monitor.PulseAll( theLock );
			}
		}

		public void WaitForStop()
		{
			lock( theLock )
			{
				Monitor.Wait( theLock );
			}
		}
		#endregion

		#region IDisposable Members

		public void Dispose()
		{
			this.Stop();
		}

		#endregion
	}
}