예제 #1
0
        public async Task Should_allow_to_use_configuration_during_configuration_setup()
        {
            application = new Application();

            host = new VostokHost(new TestHostSettings(application,
                                                       builder =>
            {
                builder.SetupApplicationIdentity(
                    id => id
                    .SetProject("infra")
                    .SetSubproject("vostok")
                    .SetApplication("app")
                    .SetInstance("1"));

                builder.SetupApplicationIdentity((id, ctx) => id.SetEnvironment("env"));

                builder.SetupConfiguration(
                    config =>
                {
                    config.AddSource(new ObjectSource(new
                    {
                        A = "hello"
                    }));
                });

                builder.SetupConfiguration(
                    config =>
                    config.GetIntermediateConfiguration <ApplicationSettings>().A.Should().Be("hello"));
            }));

            var result = await host.RunAsync();

            result.State.Should().Be(VostokApplicationState.Exited);
        }
예제 #2
0
        public async Task Should_combine_secret_sources_in_order()
        {
            application = new Application(
                env =>
            {
                env.ConfigurationProvider.Get <int[]>(env.SecretConfigurationSource.ScopeTo("Array"))
                .Should().BeEquivalentTo(new[] { 1, 2, 3 }, options => options.WithStrictOrdering());
                env.ConfigurationProvider.Get <int[]>(env.ConfigurationSource.ScopeTo("Array"))
                .Should().BeEmpty();
            });

            host = new VostokHost(new TestHostSettings(application, setup =>
            {
                SetupEnvironment(setup);

                setup.SetupConfiguration(c => c.AddSecretSource(new ObjectSource(new { Array = new[] { 1 } })));
                setup.SetupConfiguration(c => c.AddSecretSource(new ObjectSource(new { Array = new[] { 2 } })));
                setup.SetupConfiguration(c => c.CustomizeSecretConfigurationSource(s => s.CombineWith(new ObjectSource(new { Array = new[] { 3 } }), new SettingsMergeOptions {
                    ArrayMergeStyle = ArrayMergeStyle.Concat
                })));

                setup.SetupConfiguration(c => c.CustomizeSecretSettingsMerging(s => s.ArrayMergeStyle = ArrayMergeStyle.Concat));

                setup.SetupConfiguration(c => c.GetIntermediateSecretConfiguration <int[]>("Array")
                                         .Should().BeEquivalentTo(new[] { 1, 2, 3 }, options => options.WithStrictOrdering()));

                setup.SetupConfiguration(c => c.CustomizeConfigurationContext(env =>
                                                                              env.ConfigurationProvider.Get <int[]>(env.SecretConfigurationSource.ScopeTo("Array"))
                                                                              .Should().BeEquivalentTo(new[] { 1, 2, 3 }, options => options.WithStrictOrdering())));
            }));

            var result = await host.RunAsync();

            result.State.Should().Be(VostokApplicationState.Exited);
        }
예제 #3
0
        public async Task Should_allow_to_use_datacenters_during_clusterconfig_setup()
        {
            application = new Application();

            host = new VostokHost(new TestHostSettings(application,
                                                       builder =>
            {
                builder.SetupApplicationIdentity(
                    id => id
                    .SetProject("infra")
                    .SetSubproject("vostok")
                    .SetApplication("app")
                    .SetInstance("1"));

                builder.SetupApplicationIdentity((id, ctx) => id.SetEnvironment("env"));

                builder.SetupLog(b => b.SetupConsoleLog());

                builder.SetupConfiguration(
                    (config, context) => { context.Datacenters.GetLocalDatacenter().Should().BeNull(); });
            }));

            var result = await host.RunAsync();

            result.State.Should().Be(VostokApplicationState.Exited);
        }
예제 #4
0
        public void Start_should_check_that_beacon_has_started()
        {
            var zkClient = Substitute.For <IZooKeeperClient>();

            zkClient.CreateAsync(Arg.Any <CreateRequest>()).Returns(Task.FromResult(CreateResult.Unsuccessful(ZooKeeperStatus.AuthFailed, "", null)));

            application = new PortRequiresApplication();
            host        = new VostokHost(
                new TestHostSettings(
                    application,
                    s =>
            {
                SetupEnvironment(s);
                s.SetupZooKeeperClient(zkSetup => zkSetup.UseInstance(zkClient));
                s.SetupServiceBeacon(
                    beaconSetup => beaconSetup.SetupReplicaInfo(
                        replicaInfoSetup => { replicaInfoSetup.SetApplication("auth-test"); }));
            })
            {
                BeaconRegistrationWaitEnabled = true,
                BeaconRegistrationTimeout     = 2.Seconds()
            });

            Action checkStart = () => host.Start();

            checkStart.Should().Throw <Exception>().Where(e => e.Message.Contains("beacon hasn't registered"));

            host.ApplicationState.Should().Be(VostokApplicationState.CrashedDuringInitialization);
        }
예제 #5
0
 public static async Task Main(string[] args)
 {
     var application  = new WebApplication();
     var setupBuilder = new EnvironmentSetupBuilder("antiplagiarism-web", args);
     var hostSettings = new VostokHostSettings(application, setupBuilder.EnvironmentSetup);
     var host         = new VostokHost(hostSettings);
     await host.WithConsoleCancellation().RunAsync();
 }
예제 #6
0
 public static async Task Main(string[] args)
 {
     var application  = new XQueueWatcherApplication();
     var setupBuilder = new EnvironmentSetupBuilder("xqueuewatcher", args);
     var hostSettings = new VostokHostSettings(application, setupBuilder.EnvironmentSetup);
     var host         = new VostokHost(hostSettings);
     await host.WithConsoleCancellation().RunAsync();
 }
예제 #7
0
 public static async Task Main(string[] args)
 {
     var isOneTimeSend = args.Length > 0 && args[0] == "send";
     var application   = new NotificationsApplication(isOneTimeSend);
     var setupBuilder  = new EnvironmentSetupBuilder("notifications", args);
     var hostSettings  = new VostokHostSettings(application, setupBuilder.EnvironmentSetup);
     var host          = new VostokHost(hostSettings);
     await host.WithConsoleCancellation().RunAsync();
 }
예제 #8
0
        private async Task <VostokHost> StartHost(int port)
        {
            var app          = new TestVostokAspNetCoreApplication(SetupGlobal);
            var hostSettings = new VostokHostSettings(app, b => SetupEnvironment(b, port));
            var host         = new VostokHost(hostSettings);

            await host.StartAsync();

            return(host);
        }
예제 #9
0
        public async Task OneTimeSetup()
        {
            Log = new SynchronousConsoleLog();

            var serverPort = FreeTcpPortFinder.GetFreePort();

            Client = CreateClusterClient(serverPort);

            testHost = await StartHost(serverPort);
        }
예제 #10
0
        public void Should_dispose_of_the_application()
        {
            var app = new DisposableApplication();

            var host = new VostokHost(new TestHostSettings(app, SetupEnvironment));

            host.Run().State.Should().Be(VostokApplicationState.Exited);

            app.Disposed.Should().BeTrue();
        }
예제 #11
0
        public void Start_should_wait_until_given_state_occurs(VostokApplicationState stateToAwait)
        {
            application = new Application();
            host        = new VostokHost(new TestHostSettings(application, SetupEnvironment));

            host.Start(stateToAwait);
            host.ApplicationState.Should().Match <VostokApplicationState>(state => state >= stateToAwait);

            host.Stop();
            host.ApplicationState.IsTerminal().Should().BeTrue();
        }
예제 #12
0
        public void Should_not_crash_on_dispose_errors()
        {
            var app = new DisposableApplication
            {
                DisposeError = new Exception("crash")
            };

            var host = new VostokHost(new TestHostSettings(app, SetupEnvironment));

            host.Run().State.Should().Be(VostokApplicationState.Exited);

            app.Disposed.Should().BeTrue();
        }
예제 #13
0
        public void Start_should_not_throw_on_run_fail()
        {
            application = new BadApplication(false);
            host        = new VostokHost(new TestHostSettings(application, SetupEnvironment));

            Action checkStart = () => host.Start(VostokApplicationState.Initialized);

            checkStart.Should().NotThrow();

            Action checkStop = () => host.Stop();

            checkStop.Should().Throw <Exception>().WithMessage("run");
        }
예제 #14
0
        public async Task Should_allow_to_setup_sources_in_an_idempotent_way()
        {
            application = new Application(
                env =>
            {
                env.ConfigurationProvider.SetupSourceFor <ApplicationSettings>(env.ConfigurationSource);
                env.SecretConfigurationProvider.SetupSourceFor <ApplicationSecretSettings>(env.SecretConfigurationSource);
            });

            host = new VostokHost(new TestHostSettings(application, SetupEnvironment));

            var result = await host.RunAsync();

            result.State.Should().Be(VostokApplicationState.Exited);
        }
예제 #15
0
        public void Should_not_block_on_dispose_longer_than_shutdown_timeout_allows()
        {
            var app = new DisposableApplication
            {
                DisposeDelay = 10.Seconds()
            };

            var host = new VostokHost(new TestHostSettings(app, SetupEnvironment));

            var watch = Stopwatch.StartNew();

            host.Run().State.Should().Be(VostokApplicationState.Exited);

            watch.Elapsed.Should().BeLessThan(5.Seconds());
        }
예제 #16
0
        private static (WeakReference, WeakReference) RunApp()
        {
            var app  = new DisposableApplication();
            var host = new VostokHost(new TestHostSettings(app, SetupEnvironment)
            {
                ConfigureStaticProviders = false
            });

            var appWeak  = new WeakReference(app);
            var hostWeak = new WeakReference(host);

            host.Run().State.Should().Be(VostokApplicationState.Exited);

            return(appWeak, hostWeak);
        }
예제 #17
0
        public void Should_not_crash_on_components_dispose_errors()
        {
            var check      = "";
            var app        = new DisposableApplication();
            var component1 = new ActionDisposable(() => throw new Exception("crash"));
            var component2 = new ActionDisposable(() => check += "2");

            var host = new VostokHost(new TestHostSettings(app,
                                                           setup =>
            {
                SetupEnvironment(setup);
                setup.SetupHostExtensions(e => e.AddDisposable("2", component2));
                setup.SetupHostExtensions(e => e.AddDisposable("1", component1));
            }));

            host.Run().State.Should().Be(VostokApplicationState.Exited);

            check.Should().Be("2");
        }
예제 #18
0
        public void Should_dispose_components_with_reverse_order()
        {
            var check      = "";
            var app        = new DisposableApplication();
            var component1 = new ActionDisposable(() => check += "1");
            var component2 = new ActionDisposable(() => check += "2");

            var host = new VostokHost(new TestHostSettings(app,
                                                           setup =>
            {
                SetupEnvironment(setup);
                setup.SetupHostExtensions(e => e.AddDisposable("2", component2));
                setup.SetupHostExtensions(e => e.AddDisposable("1", component1));
            }));

            host.Run().State.Should().Be(VostokApplicationState.Exited);

            app.Disposed.Should().BeTrue();
            check.Should().Be("12");
        }
예제 #19
0
        public async Task Should_allow_to_use_statically_configured_app_identity_properties_during_configuration_setup()
        {
            application = new Application();

            host = new VostokHost(new TestHostSettings(application,
                                                       builder =>
            {
                builder.SetupApplicationIdentity(
                    id => id
                    .SetProject("infra")
                    .SetSubproject("vostok")
                    .SetApplication("app")
                    .SetInstance("1"));

                builder.SetupApplicationIdentity((id, ctx) => id.SetEnvironment("env"));

                builder.SetupLog(log => log.SetupConsoleLog());

                builder.SetupConfiguration(
                    (config, ctx) =>
                {
                    ctx.Log.Info(ctx.ApplicationIdentity.ToString());

                    ctx.ApplicationIdentity.Project.Should().Be("infra");
                    ctx.ApplicationIdentity.Subproject.Should().Be("vostok");
                    ctx.ApplicationIdentity.Application.Should().Be("app");
                    ctx.ApplicationIdentity.Instance.Should().Be("1");

                    // ReSharper disable once ReturnValueOfPureMethodIsNotUsed
                    Action action = () => ctx.ApplicationIdentity.Environment.GetHashCode();

                    var exception = action.Should().Throw <InvalidOperationException>().Which;

                    Console.Out.WriteLine(exception);
                });
            }));

            var result = await host.RunAsync();

            result.State.Should().Be(VostokApplicationState.Exited);
        }
예제 #20
0
        public void Should_not_block_on_components_dispose_longer_than_dispose_timeout_allows()
        {
            var app       = new DisposableApplication();
            var component = new ActionDisposable(() => Thread.Sleep(10.Seconds()));

            var host = new VostokHost(new TestHostSettings(app,
                                                           setup =>
            {
                SetupEnvironment(setup);
                setup.SetupHostExtensions(e => e.AddDisposable(component));
                setup.SetupShutdownTimeout(1.Minutes());
            })
            {
                DisposeComponentTimeout = 1.Seconds()
            });

            var watch = Stopwatch.StartNew();

            host.Run().State.Should().Be(VostokApplicationState.Exited);

            watch.Elapsed.Should().BeLessThan(5.Seconds());
        }
예제 #21
0
        public async Task Should_allow_to_use_configuration_during_logging_setup(LogLevel logLevel)
        {
            application = new Application();

            host = new VostokHost(new TestHostSettings(application,
                                                       builder =>
            {
                builder.SetupApplicationIdentity(
                    id => id
                    .SetProject("infra")
                    .SetSubproject("vostok")
                    .SetApplication("app")
                    .SetInstance("1"));

                builder.SetupApplicationIdentity((id, ctx) => id.SetEnvironment("env"));

                builder.SetupLog((b, ctx) =>
                {
                    b.SetupConsoleLog(
                        c => c.SetupMinimumLevelProvider(
                            () => ctx.ConfigurationProvider.Get <ApplicationSettings>().LogLevel));
                });

                builder.SetupConfiguration(
                    config =>
                {
                    config.AddSource(new ObjectSource(new
                    {
                        LogLevel = logLevel
                    }));
                });
            }));

            var result = await host.RunAsync();

            result.State.Should().Be(VostokApplicationState.Exited);
        }
예제 #22
0
        private Task <VostokApplicationRunResult> CreateAndRunAsync(
            [NotNull] SimpleApplicationSettings settings,
            [CanBeNull] Action <IVostokHostingEnvironmentBuilder> additionalEnvSetup = null,
            [CanBeNull] Action <VostokHostSettings> additionalHostSetup = null)
        {
            observer = new TestObserver <VostokApplicationState>();

            settings.CrashError = crashError;
            application         = new SimpleApplication(settings);

            void EnvironmentSetup(IVostokHostingEnvironmentBuilder builder)
            {
                builder.SetupApplicationIdentity(
                    (applicationIdentitySetup, setupContext) => applicationIdentitySetup.SetProject("Infrastructure")
                    .SetSubproject("vostok")
                    .SetEnvironment("dev")
                    .SetApplication("simple-application")
                    .SetInstance("1"))
                .SetupLog(logSetup => logSetup.SetupConsoleLog(consoleLogSetup => consoleLogSetup.UseSynchronous()));

                additionalEnvSetup?.Invoke(builder);
            }

            var hostSettings = new TestHostSettings(application, EnvironmentSetup)
            {
                ShutdownTimeout = shutdownTimeout
            };

            additionalHostSetup?.Invoke(hostSettings);

            host = new VostokHost(hostSettings);

            host.OnApplicationStateChanged.Subscribe(observer);

            return(host.RunAsync());
        }
예제 #23
0
        public async Task Should_support_well_known_substitutions()
        {
            application = new Application(
                env =>
            {
                Action assertion = () =>
                {
                    var settings = env.ConfigurationProvider.Get <ApplicationSettings>();
                    var secrets  = env.SecretConfigurationProvider.Get <ApplicationSecretSettings>();

                    settings.A.Should().Be("infra");
                    settings.B.Should().Be("vostok");
                    settings.C.Should().Be("app");
                    settings.D.Should().Be("dev");
                    settings.E.Should().Be("1");

                    secrets.F.Should().Be("sd-app");
                    secrets.G.Should().Be("sd-env");
                };

                assertion.ShouldPassIn(10.Seconds(), 100.Milliseconds());
            });

            host = new VostokHost(new TestHostSettings(application,
                                                       builder =>
            {
                builder.SetupApplicationIdentity(
                    id => id
                    .SetProject("infra")
                    .SetSubproject("vostok")
                    .SetEnvironment("dev")
                    .SetApplication("app")
                    .SetInstance("1"));

                builder.SetupLog(log => log.SetupConsoleLog());

                builder.SetBeaconApplication("sd-app");
                builder.SetBeaconEnvironment("sd-env");

                builder.SetupConfiguration(
                    config =>
                {
                    config.AddSource(new ObjectSource(new
                    {
                        A = $"#{{{VostokConfigurationPlaceholders.IdentityProject}}}",
                        B = $"#{{{VostokConfigurationPlaceholders.IdentitySubproject}}}",
                        C = $"#{{{VostokConfigurationPlaceholders.IdentityApplication}}}",
                        D = $"#{{{VostokConfigurationPlaceholders.IdentityEnvironment}}}",
                        E = $"#{{{VostokConfigurationPlaceholders.IdentityInstance}}}"
                    }));

                    config.AddSecretSource(new ObjectSource(new
                    {
                        F = $"#{{{VostokConfigurationPlaceholders.ServiceDiscoveryApplication}}}",
                        G = $"#{{{VostokConfigurationPlaceholders.ServiceDiscoveryEnvironment}}}",
                    }));
                });

                builder.SetupHerculesSink(
                    (sink, context) =>
                {
                    context.ConfigurationProvider.Get <ApplicationSettings>();
                    context.SecretConfigurationProvider.Get <ApplicationSecretSettings>();
                });
            }));

            var result = await host.RunAsync();

            result.State.Should().Be(VostokApplicationState.Exited);
        }