1
//-----------------------------------------------------------------------
2 // <copyright file="CoordinatorBase.cs" company="Andrew Arnott">
3 // Copyright (c) Andrew Arnott. All rights reserved.
5 //-----------------------------------------------------------------------
7 namespace DotNetOpenAuth
.Test
{
9 using System
.Threading
;
10 using DotNetOpenAuth
.Messaging
;
11 using DotNetOpenAuth
.OpenId
.RelyingParty
;
12 using DotNetOpenAuth
.Test
.Mocks
;
13 using Microsoft
.VisualStudio
.TestTools
.UnitTesting
;
15 internal abstract class CoordinatorBase
<T1
, T2
> {
16 private Action
<T1
> party1Action
;
17 private Action
<T2
> party2Action
;
19 protected CoordinatorBase(Action
<T1
> party1Action
, Action
<T2
> party2Action
) {
20 ErrorUtilities
.VerifyArgumentNotNull(party1Action
, "party1Action");
21 ErrorUtilities
.VerifyArgumentNotNull(party2Action
, "party2Action");
23 this.party1Action
= party1Action
;
24 this.party2Action
= party2Action
;
27 protected internal Action
<IProtocolMessage
> IncomingMessageFilter { get; set; }
29 protected internal Action
<IProtocolMessage
> OutgoingMessageFilter { get; set; }
31 internal abstract void Run();
33 protected void RunCore(T1 party1Object
, T2 party2Object
) {
34 Thread party1Thread
= null, party2Thread
= null;
35 Exception failingException
= null;
37 // Each thread we create needs a surrounding exception catcher so that we can
38 // terminate the other thread and inform the test host that the test failed.
39 Action
<Action
> safeWrapper
= (action
) => {
42 } catch (Exception ex
) {
43 // We may be the second thread in an ThreadAbortException, so check the "flag"
45 if (failingException
== null || (failingException
is ThreadAbortException
&& !(ex
is ThreadAbortException
))) {
46 failingException
= ex
;
47 if (Thread
.CurrentThread
== party1Thread
) {
57 // Run the threads, and wait for them to complete.
58 // If this main thread is aborted (test run aborted), go ahead and abort the other two threads.
59 party1Thread
= new Thread(() => { safeWrapper(() => { this.party1Action(party1Object); }
); });
60 party2Thread
= new Thread(() => { safeWrapper(() => { this.party2Action(party2Object); }
); });
66 } catch (ThreadAbortException
) {
72 // Use the failing reason of a failing sub-thread as our reason, if anything failed.
73 if (failingException
!= null) {
74 throw new AssertFailedException("Coordinator thread threw unhandled exception: " + failingException
, failingException
);