Thread.CurrentPrincipal.Identity.Name changes between tests, though thread ID is the same

188 views
Skip to first unread message

James B

unread,
Dec 28, 2009, 5:17:21 PM12/28/09
to NUnit-Discuss
Minor but curious issue running some of our tests, wondering if the
developers know why this might be.

Our test classes set up a GenericPrincipal object for impersonation in
the constructor before running tests against a web service, and assign
it to Thread.CurrentPrincipal (the called code will fail if the
'logged on' user does not have permissions).

If we run the tests individually, they all succeed. If we run them as
a group, the first will succeed, but the second one runs with an empty
GenericPrincipal; the one we created is seemingly thrown out.

I thought it was a thread issue, but stepping through the debugger
shows that both tests run under the same thread ID, and the
constructor is only being called once.

Our workaround is to create a GenericPrincipal object at the start of
each test; there aren't too many, so that's fine. But any ideas why
we'd see this behavior?

Charlie Poole

unread,
Dec 28, 2009, 6:11:43 PM12/28/09
to nunit-...@googlegroups.com
Hi James,

I'm going to assume you're running 2.5.3 - if not, it's a bit
more of a mystery, but you should try it under 2.5.3 anyway.

Under .NET 4.0, we saw some crashing errors in tests that set
the current principal but didn't restore it. For NUnit 2.5.3,
this was fixed by ensuring that the current principal was
saved for each test and restored afterward. That's why you
might expect to see what you are seeing.

Except...

A fixture is also a test and anything set at the fixture level
should stay the same during all the tests. That's the way all
the other things we save and restore work - e.g.: Culture,
UiCulture, current directory, etc.

My guess is that this is happening because you're setting it
in the constructor. Try moving this to TestFixtureSetUp or
SetUp and see how it's handled.

Generally, I advise people to do little or nothing of importance
in the constructor for a test fixture class. You don't know
(unless you read the code) when NUnit constructs your class,
or how many times. Even if you do read the code, there is no
guarantee that NUnit will use your constructor in a consistent
way in the next release. But there is a guarantee about how
SetUp, TearDown, TestFixtureSetUp and TestFixtureTearDown
are called.

That said, I'm a little mystified. From what I now of our
internals, I would have expected what you are doing to work,
at least for now. Let me know how setup does for you and
that may provide a clue.

Charlie
> --
>
> You received this message because you are subscribed to the
> Google Groups "NUnit-Discuss" group.
> To post to this group, send email to nunit-...@googlegroups.com.
> To unsubscribe from this group, send email to
> nunit-discus...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/nunit-discuss?hl=en.
>
>
>

Simone Busoli

unread,
Dec 28, 2009, 6:15:50 PM12/28/09
to nunit-...@googlegroups.com
Or just post a snippet of code ;)

James B

unread,
Dec 30, 2009, 10:57:36 AM12/30/09
to NUnit-Discuss
It would have to be more than just a snippet : )

That explains it, I will try TestFixtureSetUp, already running
2.5.3.

Thanks!!

James B

unread,
Dec 30, 2009, 11:41:38 AM12/30/09
to NUnit-Discuss
Actually, no dice... moving the code to a [TestFixtureSetUp] method
still results in the Thread's current principal being reset.

The smallest snippet I can make... hope the format comes out okay:

The TestFixtureSetUp:
[TestFixtureSetUp]
public void InitTest() {
Thread.CurrentPrincipal = new GenericPrincipal(
new GenericIdentity("username", "NTLM"),
new[] { "administrators" });
}

The Tests:
[Test]
public void TestStuff() {
MyObject obj = new MyObject();
Assert.IsTrue(obj.DoStuff(), "Nope");
}
[Test]
public void TestMoreStuff() {
MyObject obj = new MyObject();
Assert.IsTrue(obj.DoStuff(), "Nope");
}

The object being tested:
public class MyObject {
public bool DoStuff() {
// The name is populated for the first test, but is empty the
second
return !string.IsNullOrEmpy(Thread.CurrentPrincipal.Identity.Name);
}
}


Reply all
Reply to author
Forward
0 new messages