AppMetrics / InfluxDB

App Metrics Extensions for InfluxDB reporting
https://www.app-metrics.io/reporting/reporters/influx-data/
Apache License 2.0
17 stars 13 forks source link

can't work with TestServer when UseMetricsReporting(lifetime) #4

Closed vinh84 closed 7 years ago

vinh84 commented 7 years ago
public class UnitTest1
    {
        private readonly TestServer _server;
        public readonly HttpClient _client;

        public UnitTest1()
        {
            _server = new TestServer(new WebHostBuilder()
                                .UseStartup<Startup>());
            _client = _server.CreateClient();
        }
        [Fact]
        public void Test1()
        {
        }
    }

I use your sample Api.InfluxDB.Sample Add XUnitTest project Try unit test above can't work

Try comment this //app.UseMetricsReporting(lifetime); => Work

Thank for you lib, it very usefull

alhardy commented 7 years ago

@vinhhrv Glad you find it useful.

I'm not sure but I'd say it's probably something to do with the IApplicationLifetime, where are you getting that instance from? Maybe you can mock that?

If you're using the Startup class from the client application, you could probably create a TestStartup and use that with a mocked IApplicationLifetime

vinh84 commented 7 years ago

@alhardy Your sample

image

My UnitTest, IApplicationLifetime not null

image

bug.zip

alhardy commented 7 years ago

OK I found the problem, when running in a unit test, when is the ApplicationLifetime.ApplicationStopping token expected to be cancelled? In my test the token is never cancelled so the reporter continues to run.

For your tests are you able to just use a test startup to run your TestServer? e..g https://github.com/alhardy/AppMetrics/blob/dev/test/App.Metrics.Extensions.Middleware.Integration.Facts/Startup/DefaultTestStartup.cs Alternatively, have the cancellation token on the IApplicationLifetime cancelled after your test run.

vinh84 commented 7 years ago

@alhardy

When i use UseMetricsReporting

IApplicationLifetime

appLifetime.ApplicationStarted.Register(() => { });

Not Work, issue is criticle, please fix

alhardy commented 7 years ago

@vinhhrv can you provide some more details please? If possible a sample or unit test, otherwise what exactly isn't working and what are you trying to achieve.

vinh84 commented 7 years ago

Unit Test For Can't Start with Test Server

XUnitTest_AppMetric.zip

When run in real env, application can start, but ApplicationLifetime problem

appLifetime.ApplicationStarted.Register(() => { // not fire });

alhardy commented 7 years ago

@vinhhrv The UseMetricsReporting extension method is registering a delegate on the IApplicationLIfetime and therefore will override the delegate you are registering. UseMetricsReporting is simply a helper method to simplify running a reporter in a web context.

If you require more than just registering a reporter you can implement the same thing yourself, e.g. change your code sample's Startup_with_reporting Configure method to the following:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IApplicationLifetime appLifetime)
        {
            var reportFactory = app.ApplicationServices.GetRequiredService<IReportFactory>();
            var metrics = app.ApplicationServices.GetRequiredService<IMetrics>();
            var reporter = reportFactory.CreateReporter();

            appLifetime.ApplicationStarted.Register(
                () =>
                {
                    IsStarted = true;
                    reporter.RunReports(metrics, appLifetime.ApplicationStopping);
                });

            app.UseMetrics();
        }
vinh84 commented 7 years ago
appLifetime.ApplicationStarted.Register(
                () =>
                {
                    IsStarted = true;
                    reporter.RunReports(metrics, appLifetime.ApplicationStopping);
                    Console.Write("event one never run");
                });

appLifetime.ApplicationStarted.Register(
                () =>
                {
                    Console.Write("event two never run tow");
                });

this is problem, the code run blocked here. reporter.RunReports(metrics, appLifetime.ApplicationStopping); this function shoult start your scheduler service and return.

if u remove this line, two event is run

FluentScheduler, u can try this for task scheduler

alhardy commented 7 years ago

@vinhhrv I see, for now you can just run reporter.RunReports in a new Task. Task.Run(() => ... )

I'm familiar with FluentScheduler, I don't want to take any other dependencies when they can be avoided, plus that's a bit overkill for my needs.

alhardy commented 7 years ago

@vinhhrv https://github.com/alhardy/AppMetrics/issues/129