Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

rootPathProvider.GetRootPath returns null in FaviconStartup.LocateIconOnFileSystem #624

Closed
dragan opened this Issue · 26 comments

5 participants

@dragan

I'm not sure if you get the same result under .NET, but under Mono when running a simple test: https://gist.github.com/2757624

A ArgumentNullException is being thrown. I did a little investigating and sure enough rootPathProvider.GetRootPath() is returning null. Let me know if there's anything else that is needed. Below is the exception information.

System.ArgumentNullException : Argument cannot be null.
Parameter name: path
Stack Trace:
at System.IO.Path.Validate (System.String path, System.String parameterName) [0x00000] in <filename unknown>:0 
at System.IO.Path.Validate (System.String path) [0x00000] in <filename unknown>:0 
at System.IO.Directory.EnumerateCheck (System.String path, System.String searchPattern, SearchOption searchOption) [0x00000] in <filename unknown>:0 
at System.IO.Directory.EnumerateFiles (System.String path, System.String searchPattern, SearchOption searchOption) [0x00000] in <filename unknown>:0 
at Nancy.Bootstrapper.FavIconStartup.<LocateIconOnFileSystem>m__D (System.String extension) [0x00000] in <filename unknown>:0 
at System.Linq.Enumerable+<CreateSelectManyIterator>c__Iterator29`2[System.String,System.String].MoveNext () [0x00000] in <filename unknown>:0 
at System.Collections.Generic.List`1[System.String].AddEnumerable (IEnumerable`1 enumerable) [0x00000] in <filename unknown>:0 
at System.Collections.Generic.List`1[System.String]..ctor (IEnumerable`1 collection) [0x00000] in <filename unknown>:0 
at System.Linq.Enumerable.ToArray[String] (IEnumerable`1 source) [0x00000] in <filename unknown>:0 
at Nancy.Bootstrapper.FavIconStartup.LocateIconOnFileSystem () [0x00000] in <filename unknown>:0 
at Nancy.Bootstrapper.FavIconStartup.ScanForFavIcon () [0x00000] in <filename unknown>:0 
at Nancy.Bootstrapper.FavIconStartup.get_FavIcon () [0x00000] in <filename unknown>:0 
at Nancy.Bootstrapper.NancyBootstrapperBase`1[TinyIoC.TinyIoCContainer].get_FavIcon () [0x00000] in <filename unknown>:0 
at Nancy.Bootstrapper.NancyBootstrapperBase`1[TinyIoC.TinyIoCContainer].Initialise () [0x00000] in <filename unknown>:0 
at Nancy.Testing.Browser..ctor (INancyBootstrapper bootstrapper) [0x00000] in <filename unknown>:0 
at NancySandbox.Tests.Modules.RootModuleTests+when_requesting_root.should_return_status_ok () [0x00000] in <filename unknown>:0 
at (wrapper managed-to-native) System.Reflection.MonoMethod:InternalInvoke (System.Reflection.MonoMethod,object,object[],System.Exception&)
at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0
@dragan

I was wondering if you have to provide a RootPathProvider when your tests are in another assembly than the modules when using the Browser object? My bootstrapper just inherits off of DefaultNancyBootstrapper and figured this was handled for me being the super-duper-happy-path after all? ;-)

@thecodejunkie

@dragan think you could perhaps try this on the latest build (0.12.1) ? Somehow this report slipped through the cracks and I would like to make sure it's still happening in the latest drop before digging into it :)

@dragan

@thecodejunkie Sure, give me a bit, pretty busy at the moment with the conference next week.

@thecodejunkie

@dragan sure thing! Good luck with MonkeySpace!

@alexy

This is a problem for me on mono and Nancy.Hosting.Self 0.12.1.

@thecodejunkie

@dragan @alexy could either of you download the Nancy solution and stick a breakpoint in there? Having issues with my VM that has Mono setup =/

@dragan

@thecodejunkie Just tried this with v0.13.0 and it's still happening.

@thecodejunkie

@dragan is that using the same test as you mention in your initial post? https://gist.github.com/2757624 also what does your Bootstrapper class look like that you create and use in the test? Does it happen is you use DefaultNancyBootstrapper or the ConfigurableBootstrapper ?

@dragan

@thecodejunkie Yes and I'm using the ConfigurableBootstrapper.

@MichaelAz

I've ran into this issue, running Nancy 0.15.3.0 (downloaded from NuGet) on top of ASP.NET on .NET 4.
Like @dragan speculated it does indeed happen when the module is in a different assembly.
I explicitly specified the RootPathProvider as per the recommendation above and it seems to work now:

var browser = new Browser(x => x.RootPathProvider(new DefaultRootPathProvider()));

One curious thing - I managed to get the test to run without the code above by inserting some breakpoints and waiting between them but this only worked once and seems unreproducible without breakpoints and with Thread.Sleep instead of waiting. Possible race conditions perhaps?

@grumpydev
Owner

Shouldn't be a race condition, we are completely sync and single threaded on startup.

@MichaelAz

I've reproduced the bug running with the Nancy solution forked from this repo, once again on top of ASP.NET on .NET 4 and the solution to manually provide a RootPathProvider still works.
I don't know if this affects other versions of .NET, Mono, non ASP.NET hosting etc but this bug seems pretty confirmed. Will try to push a fix to you guys in the near future.

@grumpydev
Owner

I'd love to know what provider.GetType(); is in that case .. I wonder if it's picking up a bad fake or something.

@MichaelAz

Nope, the code ends up in AspNetRootSourceProvider as expected of an ASP.net hosted app. It fails on GetRootPath:

    public class AspNetRootSourceProvider : IRootPathProvider
    {
        public string GetRootPath()
        {
            return HostingEnvironment.MapPath("~/");
        }
    }

HostingEnviroment seems to be uninitialized with everything being null or some other default value.

SO says it's because, when testing, we aren't actually running under IIS so HostingEnvirmonet is uninitialized.

Browser should probably initialize the RootPathProvider to DefaultPathProvider by default, allowing the bootstrapper to later change it if need be.

@grumpydev
Owner

Ah, that makes sense then - we have spoken in the past about making a more "intelligent" root path provider for testing, one that actually tries to search for the correct path, but given how test runners copy files all over the shop I'm not sure it will actually work.

@MichaelAz

@grumpydev Well, this is a bit above my league (I'm still getting the hang of the codebase) but in the meanwhile, I'll put a warning about this in the Wiki page on testing.

@MichaelAz MichaelAz referenced this issue from a commit in MichaelAz/Nancy
@MichaelAz MichaelAz This commit fixes issue #624
Encapsulates the "hotfix" for #624 as a bootstrapper for testing
purposes, "TestingBootstrapper"
218c4b6
@thecodejunkie
@MichaelAz

@thecodejunkie I've tested this bug with the latest version of master and this doesn't fix the bug.
#963 only returns DefaultRootPathProvider if providerType is null

var providerType = AppDomainAssemblyTypeScanner
    .TypesOf<IRootPathProvider>(ScanMode.ExcludeNancy)
    .SingleOrDefault();

if (providerType == null)
{
    providerType = typeof(DefaultRootPathProvider);
}

but in the scenario that triggers this bug providerType still hits AspNetRootSourceProvider. This is understandable, seeing as the testing assembly and the modules being tested are not in the same assembly but are in the same AppDomain.

I, personally, see two solutions:
1. Somehow tell the bootstrapper we're doing testing so it excludes assemblies like Nancy.Hosting.* for example.
2. Write a TestingBootstrapper that defaults to sensible values for stuff like GetRootPathProvider and SafeGetNancyEngineInstance

I'm personally in favor of option two.

@thecodejunkie
@MichaelAz

Right, it seems I was testing against the wrong bootstrapper (DefaultNancyBootstrapper insted of ConfigurableBootstrapper). I'll change the wiki page on testing to reflect the need to use ConfigurableBootstrapper.

@thecodejunkie

So if you switch to ConfigurableBootstrapper the problem is now gone? I.e you used to have it when using that bootstrapper, but the change has fixed it?

@MichaelAz

The testing was done against DefaultNancyBootstrapper as per the instructions on the wiki (which I've now changed to use ConfigurableBootstrapper). But yes, the problem is now gone.

@thecodejunkie

Na I think we should leave the docs as is + update the FavIcon scanner to be able to handle the error

@thecodejunkie

@michaelaz @dragan could you verify that my last commit fixed it when you use the DefaultNancyBootstrapper ?

@MichaelAz

@thecodejunkie seems to work now. Might be worth to check this on Mono, but it's resolved as far as I can see.

@grumpydev grumpydev closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.