How to dispose AppHost and all loaded plugins (especially AuthFeature)

Hi,

I have base test class which prepares service stack’s AppHost and disposes it when tests are done.

I have two tests: A and B.
Test A loads AuthFeature plugin to AppHost, B does not).
When I run one test per session it works ok. The problem is when tests are executed in order: A, B.
Normally test B don’t have session (IRequest.GetSession() returns null - and it should be null).
When B is run after A however, GetSession returns new empty session.

AppHost is created this way:

    protected abstract void RegisterPlugins(AppSelfHost selfHost);

    [SetUp]
    public virtual void SetUp()
    {
        var host = TestLifetimeScope.Resolve<AppSelfHost>();
        RegisterPlugins(selfHost);
        host.UseAutofac(TestLifetimeScope);
        host.TestMode = true;
        AppSelfHost = host;
        AppSelfHost.Init().Start(BaseUri);
    }

    [TearDown]
    public virtual void TearDown()
    {
        AppSelfHost.Stop();
        AppSelfHost.Dispose();
        AppSelfHost = null;
    }

I guess I encounter this, because of some static initialization done by AuthFeature or SessionFeature, but I can’t found solution on my own.

Tomasz

There’s an integration testing example template in the [Testing docs][1], I can’t tell what TestLifetimeScope.Resolve<AppSelfHost>() does, but you should be creating a new AppHost instance, it looks suspicious resolving it from an IOC also I’d recommend only creating/disposing your AppHost per Test Fixture, e.g:

[TestFixtureSetUp]
public void TestFixtureSetUp()
{
    //Start your AppHost on TestFixtureSetUp
    appHost = new AppHost() 
        .Init()
        .Start(BaseUri);
}

[TestFixtureTearDown]
public void TestFixtureTearDown()
{
    //Dispose it on TearDown
    appHost.Dispose();     
}
```

I can't tell why your Session is leaking without a repro from here, but a quick solution should be to move conflicting tests into a new TestFixture.


  [1]: https://github.com/ServiceStack/ServiceStack/wiki/Testing#integration-testing

Sorry for late response, I was out of office since my last post :confused:

I’ve made sample project: https://bitbucket.org/tlaguz/ssauthleak/

Normally ServiceStack creates session (even when AuthFeature isn’t loaded) of type AuthUserSession.
I am configuring AuthFeature to use my own type. After AppHost disposal new AppHost still creates my custom type.

Tomasz

If the user hasn’t authenticated GetSession() or SessionAs<T> returns an empty Session, you need to check IsAuthenticated to see whether they have an Authenticated Session or not, e.g:

public object Any(DoIHaveSession dto)
{
    var session = SessionAs<AuthSession>();
    return new DoIHaveSessionResponse { Result = session.IsAuthenticated };
}

But preferably you should be protecting your Services using the [Authenticate] attribute, e.g:

[Authenticate]
public class TestingService : Service
{
    public object Any(DoIHaveSession dto)
    {
        var session = SessionAs<AuthSession>();
        return new DoIHaveSessionResponse { Result = session };
    }
}

Which will throw a 401 Unauthorized error if the user isn’t authenticated with any of the registered Auth providers.

Thank you Mythz :smile:

I have now this code for getting session:

var session = request.GetSession();
return session?.IsAuthenticated ?? false ? session as IEwidAuthUserSession : null;

and it works as expected.

I needed to create my own session resolver, because of our FakeSession mechanism. Some services are called by timers where request (and session) does not exist.

1 Like