public async Task Scheduled_commands_in_initial_events_are_not_executed_if_they_become_due_before_Prepare_is_called()
        {
            var aggregateId = Any.Guid();

            using (VirtualClock.Start())
            {
                var scenario = CreateScenarioBuilder()
                               .AddEvents(new CommandScheduled <Order>
                {
                    AggregateId = aggregateId,
                    Command     = new Cancel(),
                    DueTime     = Clock.Now().AddDays(2)
                })
                               .AdvanceClockBy(TimeSpan.FromDays(3))
                               .Prepare();

                (await scenario.GetLatestAsync <Order>(aggregateId))
                .EventHistory
                .Last()
                .Should()
                .BeOfType <CommandScheduled <Order> >();
            }
        }
Esempio n. 2
0
        public async Task When_a_command_fails_and_is_scheduled_for_retry_then_advancing_the_virtual_clock_triggers_redelivery()
        {
            VirtualClock.Start();

            var target = new NonEventSourcedCommandTarget(Any.CamelCaseName())
            {
                IsValid = false
            };
            var retries = 0;

            var configuration = Configuration.Current;

            await configuration.Store <NonEventSourcedCommandTarget>().Put(target);

            configuration.UseCommandHandler <NonEventSourcedCommandTarget, TestCommand>(
                enactCommand: async(_, __) => { },
                handleScheduledCommandException: async(_, command) =>
            {
                if (command.NumberOfPreviousAttempts >= 12)
                {
                    command.Cancel();
                    return;
                }
                retries++;
                command.Retry(1.Hours());
            });

            var scheduler = configuration.CommandScheduler <NonEventSourcedCommandTarget>();

            await scheduler.Schedule(target.Id,
                                     new TestCommand(),
                                     dueTime : Clock.Now().AddHours(1));

            VirtualClock.Current.AdvanceBy(1.Days());

            retries.Should().Be(12);
        }
Esempio n. 3
0
        public async Task Advancing_the_clock_blocks_until_triggered_commands_on_the_SqllCommandScheduler_are_completed()
        {
            var configuration = new Configuration()
                                .UseInMemoryEventStore()
                                .UseSqlCommandScheduling()
                                .TriggerSqlCommandSchedulerWithVirtualClock();

            VirtualClock.Start();

            configuration.SqlCommandScheduler()
            .GetClockName = e => Any.CamelCaseName();

            using (ConfigurationContext.Establish(configuration))
            {
                var scheduler  = configuration.CommandScheduler <Order>();
                var repository = configuration.Repository <Order>();

                var aggregateId = Any.Guid();

                await scheduler.Schedule(new CommandScheduled <Order>
                {
                    Command = new CreateOrder(Any.FullName())
                    {
                        AggregateId = aggregateId
                    },
                    DueTime     = Clock.Now().AddHours(1),
                    AggregateId = aggregateId
                });

                VirtualClock.Current.AdvanceBy(TimeSpan.FromDays(1));

                var order = await repository.GetLatest(aggregateId);

                order.Should().NotBeNull();
            }
        }
        public async Task Advancing_the_clock_blocks_until_triggered_commands_on_the_command_scheduler_are_completed()
        {
            VirtualClock.Start();

            var scheduler  = Configuration.Current.CommandScheduler <Order>();
            var repository = Configuration.Current.Repository <Order>();

            var aggregateId = Any.Guid();
            await scheduler.Schedule(new CommandScheduled <Order>
            {
                Command = new CreateOrder(Any.FullName())
                {
                    AggregateId = aggregateId
                },
                DueTime     = Clock.Now().AddHours(1),
                AggregateId = aggregateId
            });

            VirtualClock.Current.AdvanceBy(TimeSpan.FromDays(1));

            var order = await repository.GetLatest(aggregateId);

            order.Should().NotBeNull();
        }
Esempio n. 5
0
        public void CommandDelivery_properties_are_initialized_properly_from_a_received_Message()
        {
            using (VirtualClock.Start())
            {
                var message = new CommandDelivery <string>(
                    "hi",
                    dueTime: Clock.Now()).ToMessage();

                SimulateMessageHavingBeenReceived(
                    message,
                    enqueuedTimeUtc: Clock.Now().UtcDateTime);

                var deserialized = message.ToCommandDelivery <string>();

                deserialized
                .DueTime
                .Value
                .UtcDateTime
                .ShouldBeEquivalentTo(
                    message.SystemProperties
                    .EnqueuedTimeUtc);
                deserialized
                .OriginalDueTime
                .Should()
                .Be(
                    message.SystemProperties
                    .EnqueuedTimeUtc);
                deserialized
                .NumberOfPreviousAttempts
                .Should()
                .Be(
                    message
                    .SystemProperties
                    .DeliveryCount - 1);
            }
        }
Esempio n. 6
0
        public static Parser Create(
            IServiceCollection services,
            StartServer startServer = null,
            Demo demo           = null,
            TryGitHub tryGithub = null,
            Pack pack           = null,
            Install install     = null,
            Verify verify       = null,
            Jupyter jupyter     = null,
            StartKernelServer startKernelServer = null,
            ITelemetry telemetry = null,
            IFirstTimeUseNoticeSentinel firstTimeUseNoticeSentinel = null)
        {
            if (services == null)
            {
                throw new ArgumentNullException(nameof(services));
            }

            startServer = startServer ??
                          ((startupOptions, invocationContext) =>
                           Program.ConstructWebHost(startupOptions).Run());

            jupyter = jupyter ??
                      ((startupOptions, console, server, context) =>
                       JupyterCommand.Do(startupOptions, console, server, context));

            demo = demo ??
                   DemoCommand.Do;

            tryGithub = tryGithub ??
                        ((repo, console) =>
                         GitHubHandler.Handler(repo,
                                               console,
                                               new GitHubRepoLocator()));

            verify = verify ??
                     ((options, console, startupOptions) =>
                      VerifyCommand.Do(options,
                                       console,
                                       startupOptions));

            pack = pack ??
                   PackCommand.Do;

            install = install ??
                      InstallCommand.Do;

            startKernelServer = startKernelServer ??
                                ((startupOptions, kernel, console) =>
                                 KernelServerCommand.Do(startupOptions, kernel, console));

            // Setup first time use notice sentinel.
            firstTimeUseNoticeSentinel = firstTimeUseNoticeSentinel ?? new FirstTimeUseNoticeSentinel();

            // Setup telemetry.
            telemetry = telemetry ?? new Telemetry.Telemetry(firstTimeUseNoticeSentinel);
            var filter = new TelemetryFilter(Sha256Hasher.HashWithNormalizedCasing);
            Action <ParseResult> track = o => telemetry.SendFiltered(filter, o);

            var dirArgument = new Argument <FileSystemDirectoryAccessor>(() => new FileSystemDirectoryAccessor(Directory.GetCurrentDirectory()))
            {
                Name        = nameof(StartupOptions.RootDirectory),
                Arity       = ArgumentArity.ZeroOrOne,
                Description = "Specify the path to the root directory for your documentation",
            };

            dirArgument.AddValidator(symbolResult =>
            {
                var directory = symbolResult.Tokens
                                .Select(t => t.Value)
                                .FirstOrDefault();

                if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory))
                {
                    return($"Directory does not exist: {directory}");
                }

                return(null);
            });

            var rootCommand = StartInTryMode();

            rootCommand.AddCommand(StartInHostedMode());
            rootCommand.AddCommand(Demo());
            rootCommand.AddCommand(GitHub());
            rootCommand.AddCommand(Pack());
            rootCommand.AddCommand(Install());
            rootCommand.AddCommand(Verify());
            rootCommand.AddCommand(Jupyter());
            rootCommand.AddCommand(KernelServer());

            return(new CommandLineBuilder(rootCommand)
                   .UseDefaults()
                   .UseMiddleware(async(context, next) =>
            {
                // If sentinel does not exist, print the welcome message showing the telemetry notification.
                if (!firstTimeUseNoticeSentinel.Exists() && !Telemetry.Telemetry.SkipFirstTimeExperience)
                {
                    context.Console.Out.WriteLine();
                    context.Console.Out.WriteLine(Telemetry.Telemetry.WelcomeMessage);

                    firstTimeUseNoticeSentinel.CreateIfNotExists();
                }

                if (context.ParseResult.Directives.Contains("debug") &&
                    !(Clock.Current is VirtualClock))
                {
                    VirtualClock.Start();
                }

                await next(context);
            })
                   .Build());

            RootCommand StartInTryMode()
            {
                var command = new RootCommand
                {
                    Name        = "dotnet-try",
                    Description = "Interactive documentation in your browser"
                };

                command.AddArgument(dirArgument);

                command.AddOption(new Option(
                                      "--add-package-source",
                                      "Specify an additional NuGet package source")
                {
                    Argument = new Argument <PackageSource>(() => new PackageSource(Directory.GetCurrentDirectory()))
                    {
                        Name = "NuGet source"
                    }
                });

                command.AddOption(new Option(
                                      "--package",
                                      "Specify a Try .NET package or path to a .csproj to run code samples with")
                {
                    Argument = new Argument <string>
                    {
                        Name = "name or .csproj"
                    }
                });

                command.AddOption(new Option(
                                      "--package-version",
                                      "Specify a Try .NET package version to use with the --package option")
                {
                    Argument = new Argument <string>
                    {
                        Name = "version"
                    }
                });

                command.AddOption(new Option(
                                      "--uri",
                                      "Specify a URL or a relative path to a Markdown file")
                {
                    Argument = new Argument <Uri>()
                });

                command.AddOption(new Option(
                                      "--enable-preview-features",
                                      "Enable preview features")
                {
                    Argument = new Argument <bool>()
                });

                command.AddOption(new Option(
                                      "--log-path",
                                      "Enable file logging to the specified directory")
                {
                    Argument = new Argument <DirectoryInfo>
                    {
                        Name = "dir"
                    }
                });

                command.AddOption(new Option(
                                      "--verbose",
                                      "Enable verbose logging to the console")
                {
                    Argument = new Argument <bool>()
                });

                var portArgument = new Argument <ushort>();

                portArgument.AddValidator(symbolResult =>
                {
                    if (symbolResult.Tokens
                        .Select(t => t.Value)
                        .Count(value => !ushort.TryParse(value, out _)) > 0)
                    {
                        return("Invalid argument for --port option");
                    }

                    return(null);
                });

                command.AddOption(new Option(
                                      "--port",
                                      "Specify the port for dotnet try to listen on")
                {
                    Argument = portArgument
                });

                command.Handler = CommandHandler.Create <InvocationContext, StartupOptions>((context, options) =>
                {
                    services.AddSingleton(_ => PackageRegistry.CreateForTryMode(
                                              options.RootDirectory,
                                              options.AddPackageSource));

                    startServer(options, context);
                });

                return(command);
            }

            Command StartInHostedMode()
            {
                var command = new Command("hosted")
                {
                    new Option(
                        "--id",
                        "A unique id for the agent instance (e.g. its development environment id).")
                    {
                        Argument = new Argument <string>(defaultValue: () => Environment.MachineName)
                    },
                    new Option(
                        "--production",
                        "Specifies whether the agent is being run using production resources")
                    {
                        Argument = new Argument <bool>()
                    },
                    new Option(
                        "--language-service",
                        "Specifies whether the agent is being run in language service-only mode")
                    {
                        Argument = new Argument <bool>()
                    },
                    new Option(
                        new[]
                    {
                        "-k",
                        "--key"
                    },
                        "The encryption key")
                    {
                        Argument = new Argument <string>()
                    },
                    new Option(
                        new[]
                    {
                        "--ai-key",
                        "--application-insights-key"
                    },
                        "Application Insights key.")
                    {
                        Argument = new Argument <string>()
                    },
                    new Option(
                        "--region-id",
                        "A unique id for the agent region")
                    {
                        Argument = new Argument <string>()
                    },
                    new Option(
                        "--log-to-file",
                        "Writes a log file")
                    {
                        Argument = new Argument <bool>()
                    }
                };

                command.Description = "Starts the Try .NET agent";

                command.IsHidden = true;

                command.Handler = CommandHandler.Create <InvocationContext, StartupOptions>((context, options) =>
                {
                    services.AddSingleton(_ => PackageRegistry.CreateForHostedMode());
                    services.AddSingleton(c => new MarkdownProject(c.GetRequiredService <PackageRegistry>()));
                    services.AddSingleton <IHostedService, Warmup>();

                    startServer(options, context);
                });

                return(command);
            }

            Command Demo()
            {
                var demoCommand = new Command(
                    "demo",
                    "Learn how to create Try .NET content with an interactive demo")
                {
                    new Option("--output", "Where should the demo project be written to?")
                    {
                        Argument = new Argument <DirectoryInfo>(
                            defaultValue: () => new DirectoryInfo(Directory.GetCurrentDirectory()))
                    }
                };

                demoCommand.Handler = CommandHandler.Create <DemoOptions, InvocationContext>((options, context) =>
                {
                    demo(options, context.Console, startServer, context);
                });

                return(demoCommand);
            }

            Command GitHub()
            {
                var argument = new Argument <string>
                {
                    // System.CommandLine parameter binding does lookup by name,
                    // so name the argument after the github command's string param
                    Name = nameof(TryGitHubOptions.Repo)
                };

                var github = new Command("github", "Try a GitHub repo")
                {
                    argument
                };

                github.IsHidden = true;

                github.Handler = CommandHandler.Create <TryGitHubOptions, IConsole>((repo, console) => tryGithub(repo, console));

                return(github);
            }

            Command Jupyter()
            {
                var jupyterCommand      = new Command("jupyter", "Starts dotnet try as a Jupyter kernel");
                var defaultKernelOption = new Option("--default-kernel", "The default .NET kernel language for the notebook.")
                {
                    Argument = new Argument <string>(defaultValue: () => "csharp")
                };

                jupyterCommand.AddOption(defaultKernelOption);
                var connectionFileArgument = new Argument <FileInfo>
                {
                    Name  = "ConnectionFile",
                    Arity = ArgumentArity.ZeroOrOne //should be removed once the commandlineapi allows subcommands to not have arguments from the main command
                }.ExistingOnly();

                jupyterCommand.AddArgument(connectionFileArgument);

                jupyterCommand.Handler = CommandHandler.Create <StartupOptions, JupyterOptions, IConsole, InvocationContext>((startupOptions, options, console, context) =>
                {
                    track(context.ParseResult);

                    services
                    .AddSingleton(c => ConnectionInformation.Load(options.ConnectionFile))
                    .AddSingleton(
                        c =>
                    {
                        return(CommandScheduler
                               .Create <JupyterRequestContext>(delivery => c.GetRequiredService <ICommandHandler <JupyterRequestContext> >()
                                                               .Trace()
                                                               .Handle(delivery)));
                    })
                    .AddSingleton(c => CreateKernel(options.DefaultKernel))
                    .AddSingleton(c => new JupyterRequestContextHandler(c.GetRequiredService <IKernel>())
                                  .Trace())
                    .AddSingleton <IHostedService, Shell>()
                    .AddSingleton <IHostedService, Heartbeat>();

                    return(jupyter(startupOptions, console, startServer, context));
                });

                var installCommand = new Command("install", "Install the .NET kernel for Jupyter");

                installCommand.Handler = CommandHandler.Create <IConsole, InvocationContext>((console, context) =>
                {
                    track(context.ParseResult);
                    return(new JupyterCommandLine(console, new FileSystemJupyterKernelSpec()).InvokeAsync());
                });

                jupyterCommand.AddCommand(installCommand);

                return(jupyterCommand);
            }

            Command KernelServer()
            {
                var startKernelServerCommand = new Command("kernel-server", "Starts dotnet-try with kernel functionality exposed over standard I/O");
                var defaultKernelOption      = new Option("--default-kernel", "The default .NET kernel language for the notebook.")
                {
                    Argument = new Argument <string>(defaultValue: () => "csharp")
                };

                startKernelServerCommand.AddOption(defaultKernelOption);

                startKernelServerCommand.Handler = CommandHandler.Create <StartupOptions, KernelServerOptions, IConsole, InvocationContext>(
                    (startupOptions, options, console, context) =>
                {
                    track(context.ParseResult);
                    return(startKernelServer(startupOptions, CreateKernel(options.DefaultKernel), console));
                });

                return(startKernelServerCommand);
            }

            Command Pack()
            {
                var packCommand = new Command("pack", "Create a Try .NET package")
                {
                    new Argument <DirectoryInfo>
                    {
                        Name = nameof(PackOptions.PackTarget)
                    },
                    new Option("--version", "The version of the Try .NET package")
                    {
                        Argument = new Argument <string>()
                    },
                    new Option("--enable-wasm", "Enables web assembly code execution")
                };

                packCommand.IsHidden = true;

                packCommand.Handler = CommandHandler.Create <PackOptions, IConsole>(
                    (options, console) =>
                {
                    return(pack(options, console));
                });

                return(packCommand);
            }

            Command Install()
            {
                var installCommand = new Command("install", "Install a Try .NET package")
                {
                    new Argument <string>
                    {
                        Name  = nameof(InstallOptions.PackageName),
                        Arity = ArgumentArity.ExactlyOne
                    },
                    new Option("--add-source")
                    {
                        Argument = new Argument <PackageSource>()
                    }
                };

                installCommand.IsHidden = true;

                installCommand.Handler = CommandHandler.Create <InstallOptions, IConsole>((options, console) => install(options, console));

                return(installCommand);
            }

            Command Verify()
            {
                var verifyCommand = new Command("verify", "Verify Markdown files in the target directory and its children.")
                {
                    dirArgument
                };

                verifyCommand.Handler = CommandHandler.Create <VerifyOptions, IConsole, StartupOptions>(
                    (options, console, startupOptions) =>
                {
                    return(verify(options, console, startupOptions));
                });

                return(verifyCommand);
            }
        }
Esempio n. 7
0
 public WorkspaceServerRegistryTests(ITestOutputHelper output)
 {
     _disposables.Add(output.SubscribeToPocketLogger());
     _disposables.Add(VirtualClock.Start());
 }
Esempio n. 8
0
        public static Parser Create(
            IServiceCollection services,
            StartServer startServer = null,
            Demo demo           = null,
            TryGitHub tryGithub = null,
            Pack pack           = null,
            Install install     = null,
            Verify verify       = null,
            Jupyter jupyter     = null)
        {
            if (services == null)
            {
                throw new ArgumentNullException(nameof(services));
            }

            startServer = startServer ??
                          ((options, invocationContext) =>
                           Program.ConstructWebHost(options).Run());

            jupyter = jupyter ??
                      JupyterCommand.Do;

            demo = demo ??
                   DemoCommand.Do;

            tryGithub = tryGithub ??
                        ((repo, console) =>
                         GitHubHandler.Handler(repo,
                                               console,
                                               new GitHubRepoLocator()));

            verify = verify ??
                     ((verifyOptions, console, startupOptions) =>
                      VerifyCommand.Do(verifyOptions,
                                       console,
                                       () => new FileSystemDirectoryAccessor(verifyOptions.Dir),
                                       PackageRegistry.CreateForTryMode(verifyOptions.Dir),
                                       startupOptions));

            pack = pack ??
                   PackCommand.Do;

            install = install ??
                      InstallCommand.Do;


            var dirArgument = new Argument <DirectoryInfo>
            {
                Arity       = ArgumentArity.ZeroOrOne,
                Name        = nameof(StartupOptions.Dir).ToLower(),
                Description = "Specify the path to the root directory for your documentation"
            }.ExistingOnly();

            var rootCommand = StartInTryMode();

            rootCommand.AddCommand(StartInHostedMode());
            rootCommand.AddCommand(Demo());
            rootCommand.AddCommand(GitHub());
            rootCommand.AddCommand(Pack());
            rootCommand.AddCommand(Install());
            rootCommand.AddCommand(Verify());
            rootCommand.AddCommand(Jupyter());

            return(new CommandLineBuilder(rootCommand)
                   .UseDefaults()
                   .UseMiddleware(async(context, next) =>
            {
                if (context.ParseResult.Directives.Contains("debug") &&
                    !(Clock.Current is VirtualClock))
                {
                    VirtualClock.Start();
                }

                await next(context);
            })
                   .Build());

            RootCommand StartInTryMode()
            {
                var command = new RootCommand
                {
                    Name        = "dotnet-try",
                    Description = "Interactive documentation in your browser"
                };

                command.AddArgument(dirArgument);

                command.AddOption(new Option(
                                      "--add-package-source",
                                      "Specify an additional NuGet package source")
                {
                    Argument = new Argument <PackageSource>(() => new PackageSource(Directory.GetCurrentDirectory()))
                    {
                        Name = "NuGet source"
                    }
                });

                command.AddOption(new Option(
                                      "--package",
                                      "Specify a Try .NET package or path to a .csproj to run code samples with")
                {
                    Argument = new Argument <string>
                    {
                        Name = "name or .csproj"
                    }
                });

                command.AddOption(new Option(
                                      "--package-version",
                                      "Specify a Try .NET package version to use with the --package option")
                {
                    Argument = new Argument <string>
                    {
                        Name = "version"
                    }
                });

                command.AddOption(new Option(
                                      "--uri",
                                      "Specify a URL or a relative path to a Markdown file")
                {
                    Argument = new Argument <Uri>()
                });

                command.AddOption(new Option(
                                      "--enable-preview-features",
                                      "Enable preview features")
                {
                    Argument = new Argument <bool>()
                });

                command.AddOption(new Option(
                                      "--log-path",
                                      "Enable file logging to the specified directory")
                {
                    Argument = new Argument <DirectoryInfo>
                    {
                        Name = "dir"
                    }
                });

                command.AddOption(new Option(
                                      "--verbose",
                                      "Enable verbose logging to the console")
                {
                    Argument = new Argument <bool>()
                });

                var portArgument = new Argument <ushort>();

                portArgument.AddValidator(symbolResult =>
                {
                    if (symbolResult.Tokens
                        .Select(t => t.Value)
                        .Count(value => !ushort.TryParse(value, out _)) > 0)
                    {
                        return("Invalid argument for --port option");
                    }

                    return(null);
                });

                command.AddOption(new Option(
                                      "--port",
                                      "Specify the port for dotnet try to listen on")
                {
                    Argument = portArgument
                });

                command.Handler = CommandHandler.Create <InvocationContext, StartupOptions>((context, options) =>
                {
                    services.AddSingleton(_ => PackageRegistry.CreateForTryMode(
                                              options.Dir,
                                              options.AddPackageSource));

                    startServer(options, context);
                });

                return(command);
            }

            Command StartInHostedMode()
            {
                var command = new Command("hosted")
                {
                    new Option(
                        "--id",
                        "A unique id for the agent instance (e.g. its development environment id).")
                    {
                        Argument = new Argument <string>(defaultValue: () => Environment.MachineName)
                    },
                    new Option(
                        "--production",
                        "Specifies whether the agent is being run using production resources")
                    {
                        Argument = new Argument <bool>()
                    },
                    new Option(
                        "--language-service",
                        "Specifies whether the agent is being run in language service-only mode")
                    {
                        Argument = new Argument <bool>()
                    },
                    new Option(
                        new[]
                    {
                        "-k",
                        "--key"
                    },
                        "The encryption key")
                    {
                        Argument = new Argument <string>()
                    },
                    new Option(
                        new[]
                    {
                        "--ai-key",
                        "--application-insights-key"
                    },
                        "Application Insights key.")
                    {
                        Argument = new Argument <string>()
                    },
                    new Option(
                        "--region-id",
                        "A unique id for the agent region")
                    {
                        Argument = new Argument <string>()
                    },
                    new Option(
                        "--log-to-file",
                        "Writes a log file")
                    {
                        Argument = new Argument <bool>()
                    }
                };

                command.Description = "Starts the Try .NET agent";

                command.IsHidden = true;

                command.Handler = CommandHandler.Create <InvocationContext, StartupOptions>((context, options) =>
                {
                    services.AddSingleton(_ => PackageRegistry.CreateForHostedMode());
                    services.AddSingleton(c => new MarkdownProject(c.GetRequiredService <PackageRegistry>()));
                    services.AddSingleton <IHostedService, Warmup>();

                    startServer(options, context);
                });

                return(command);
            }

            Command Demo()
            {
                var demoCommand = new Command(
                    "demo",
                    "Learn how to create Try .NET content with an interactive demo")
                {
                    new Option("--output", "Where should the demo project be written to?")
                    {
                        Argument = new Argument <DirectoryInfo>(
                            defaultValue: () => new DirectoryInfo(Directory.GetCurrentDirectory()))
                    }
                };

                demoCommand.Handler = CommandHandler.Create <DemoOptions, InvocationContext>((options, context) =>
                {
                    demo(options, context.Console, startServer, context);
                });

                return(demoCommand);
            }

            Command GitHub()
            {
                var argument = new Argument <string>
                {
                    // System.CommandLine parameter binding does lookup by name,
                    // so name the argument after the github command's string param
                    Name = nameof(TryGitHubOptions.Repo)
                };

                var github = new Command("github", "Try a GitHub repo")
                {
                    argument
                };

                github.IsHidden = true;

                github.Handler = CommandHandler.Create <TryGitHubOptions, IConsole>((repo, console) => tryGithub(repo, console));

                return(github);
            }

            Command Jupyter()
            {
                var jupyterCommand = new Command("jupyter", "Starts dotnet try as a Jupyter kernel")
                {
                    IsHidden = true
                };
                var connectionFileArgument = new Argument <FileInfo>
                {
                    Name = "ConnectionFile"
                }.ExistingOnly();

                jupyterCommand.AddArgument(connectionFileArgument);

                jupyterCommand.Handler = CommandHandler.Create <JupyterOptions, IConsole, InvocationContext>((options, console, context) =>
                {
                    services
                    .AddSingleton(c => ConnectionInformation.Load(options.ConnectionFile))
                    .AddSingleton(
                        c =>
                    {
                        return(CommandScheduler
                               .Create <JupyterRequestContext>(delivery => c.GetRequiredService <ICommandHandler <JupyterRequestContext> >()
                                                               .Trace()
                                                               .Handle(delivery)));
                    })
                    .AddTransient <IKernel>(c => new CompositeKernel
                    {
                        new CSharpKernel().UseNugetDirective()
                    })
                    .AddSingleton(c => new JupyterRequestContextHandler(
                                      c.GetRequiredService <PackageRegistry>(),
                                      c.GetRequiredService <IKernel>())
                                  .Trace())
                    .AddSingleton <IHostedService, Shell>()
                    .AddSingleton <IHostedService, Heartbeat>();

                    return(jupyter(options, console, startServer, context));
                });

                return(jupyterCommand);
            }

            Command Pack()
            {
                var packCommand = new Command("pack", "Create a Try .NET package")
                {
                    new Argument <DirectoryInfo>
                    {
                        Name = nameof(PackOptions.PackTarget)
                    },
                    new Option("--version", "The version of the Try .NET package")
                    {
                        Argument = new Argument <string>()
                    },
                    new Option("--enable-wasm", "Enables web assembly code execution")
                };

                packCommand.IsHidden = true;

                packCommand.Handler = CommandHandler.Create <PackOptions, IConsole>(
                    (options, console) =>
                {
                    return(pack(options, console));
                });

                return(packCommand);
            }

            Command Install()
            {
                var installCommand = new Command("install", "Install a Try .NET package")
                {
                    new Argument <string>
                    {
                        Name = nameof(InstallOptions.PackageName)
                    },
                    new Option("--add-source")
                    {
                        Argument = new Argument <PackageSource>()
                    }
                };

                installCommand.IsHidden = true;

                installCommand.Handler = CommandHandler.Create <InstallOptions, IConsole>((options, console) => install(options, console));

                return(installCommand);
            }

            Command Verify()
            {
                var verifyCommand = new Command("verify", "Verify Markdown files in the target directory and its children.")
                {
                    dirArgument
                };

                verifyCommand.Handler = CommandHandler.Create <VerifyOptions, IConsole, StartupOptions>(
                    (options, console, startupOptions) =>
                {
                    return(verify(options, console, startupOptions));
                });

                return(verifyCommand);
            }
        }
            public TestableJobRunner(TimeSpan pollInterval, bool skipDispatch = false)
                : base(pollInterval)
            {
                // Arrange
                Queue = (MockQueue = new Mock<InvocationQueue>()).Object;
                Dispatcher = (MockDispatcher = new Mock<JobDispatcher>()).Object;
                Clock = VirtualClock = new VirtualClock();

                _skipDispatch = skipDispatch;
                DispatchTCS = new TaskCompletionSource<object>();

                // Set up things so that async methods don't return null Tasks
                MockQueue
                    .Setup(q => q.UpdateStatus(It.IsAny<InvocationState>(), It.IsAny<InvocationStatus>(), It.IsAny<ExecutionResult>()))
                    .Completes(true);
                MockQueue
                    .Setup(q => q.Complete(It.IsAny<InvocationState>(), It.IsAny<ExecutionResult>(), It.IsAny<string>(), It.IsAny<string>()))
                    .Completes(true);
                MockQueue
                    .Setup(q => q.Enqueue(It.IsAny<string>(), It.IsAny<string>()))
                    .Completes((InvocationState)null);
                MockQueue
                    .Setup(q => q.Enqueue(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<Dictionary<string, string>>(), It.IsAny<TimeSpan>(), null))
                    .Completes((InvocationState)null);
                MockQueue
                    .Setup(q => q.Suspend(It.IsAny<InvocationState>(), It.IsAny<Dictionary<string, string>>(), It.IsAny<TimeSpan>(), It.IsAny<string>()))
                    .Completes(true);
            }
Esempio n. 10
0
        public static Parser Create(
            IServiceCollection services,
            StartServer startServer = null,
            Install install         = null,
            Demo demo            = null,
            TryGitHub tryGithub  = null,
            Pack pack            = null,
            Verify verify        = null,
            Publish publish      = null,
            ITelemetry telemetry = null,
            IFirstTimeUseNoticeSentinel firstTimeUseNoticeSentinel = null)
        {
            if (services == null)
            {
                throw new ArgumentNullException(nameof(services));
            }

            startServer ??= (startupOptions, invocationContext) =>
            Program.ConstructWebHost(startupOptions).Run();

            demo ??= DemoCommand.Do;

            tryGithub ??= (repo, console) =>
            GitHubHandler.Handler(repo,
                                  console,
                                  new GitHubRepoLocator());

            verify ??= VerifyCommand.Do;

            publish ??= (options, console, startupOptions) =>
            PublishCommand.Do(options,
                              console,
                              startupOptions);

            pack ??= PackCommand.Do;

            // Setup first time use notice sentinel.
            firstTimeUseNoticeSentinel ??=
            new FirstTimeUseNoticeSentinel(VersionSensor.Version().AssemblyInformationalVersion);

            // Setup telemetry.
            telemetry ??= new Telemetry(
                VersionSensor.Version().AssemblyInformationalVersion,
                firstTimeUseNoticeSentinel);
            var filter = new TelemetryFilter(Sha256Hasher.HashWithNormalizedCasing);
            Action <ParseResult> track = o => telemetry.SendFiltered(filter, o);

            var dirArgument = new Argument <FileSystemDirectoryAccessor>(result =>
            {
                var directory = result.Tokens
                                .Select(t => t.Value)
                                .FirstOrDefault();

                if (!string.IsNullOrEmpty(directory) &&
                    !Directory.Exists(directory))
                {
                    result.ErrorMessage = $"Directory does not exist: {directory}";
                    return(null);
                }

                return(new FileSystemDirectoryAccessor(
                           directory ??
                           Directory.GetCurrentDirectory()));
            }, isDefault: true)
            {
                Name        = "root-directory",
                Arity       = ArgumentArity.ZeroOrOne,
                Description = "The root directory for your documentation"
            };

            var rootCommand = StartInTryMode();

            rootCommand.AddCommand(StartInHostedMode());
            rootCommand.AddCommand(Demo());
            rootCommand.AddCommand(GitHub());
            rootCommand.AddCommand(Install());
            rootCommand.AddCommand(Pack());
            rootCommand.AddCommand(Verify());
            rootCommand.AddCommand(Publish());

            return(new CommandLineBuilder(rootCommand)
                   .UseDefaults()
                   .UseMiddleware(async(context, next) =>
            {
                if (context.ParseResult.Errors.Count == 0)
                {
                    telemetry.SendFiltered(filter, context.ParseResult);
                }

                // If sentinel does not exist, print the welcome message showing the telemetry notification.
                if (!firstTimeUseNoticeSentinel.Exists() && !Telemetry.SkipFirstTimeExperience)
                {
                    context.Console.Out.WriteLine();
                    context.Console.Out.WriteLine(Telemetry.WelcomeMessage);

                    firstTimeUseNoticeSentinel.CreateIfNotExists();
                }

                if (context.ParseResult.Directives.Contains("debug") &&
                    !(Clock.Current is VirtualClock))
                {
                    VirtualClock.Start();
                }

                await next(context);
            })
                   .Build());

            RootCommand StartInTryMode()
            {
                var command = new RootCommand
                {
                    Name        = "dotnet-try",
                    Description = "Interactive documentation in your browser"
                };

                command.AddArgument(dirArgument);

                command.AddOption(new Option(
                                      "--add-package-source",
                                      "Specify an additional NuGet package source")
                {
                    Argument = new Argument <PackageSource>(() => new PackageSource(Directory.GetCurrentDirectory()))
                    {
                        Name = "NuGet source"
                    }
                });

                command.AddOption(new Option(
                                      "--package",
                                      "Specify a Try .NET package or path to a .csproj to run code samples with")
                {
                    Argument = new Argument <string>
                    {
                        Name = "name or .csproj"
                    }
                });

                command.AddOption(new Option(
                                      "--package-version",
                                      "Specify a Try .NET package version to use with the --package option")
                {
                    Argument = new Argument <string>
                    {
                        Name = "version"
                    }
                });

                command.AddOption(new Option <Uri>(
                                      "--uri",
                                      "Specify a URL or a relative path to a Markdown file"));

                command.AddOption(new Option <bool>(
                                      "--enable-preview-features",
                                      "Enable preview features"));

                command.AddOption(new Option(
                                      "--log-path",
                                      "Enable file logging to the specified directory")
                {
                    Argument = new Argument <DirectoryInfo>
                    {
                        Name = "dir"
                    }
                });

                command.AddOption(new Option <bool>(
                                      "--verbose",
                                      "Enable verbose logging to the console"));

                var portArgument = new Argument <ushort>();

                portArgument.AddValidator(symbolResult =>
                {
                    if (symbolResult.Tokens
                        .Select(t => t.Value)
                        .Count(value => !ushort.TryParse(value, out _)) > 0)
                    {
                        return("Invalid argument for --port option");
                    }

                    return(null);
                });

                command.AddOption(new Option(
                                      "--port",
                                      "Specify the port for dotnet try to listen on")
                {
                    Argument = portArgument
                });

                command.Handler = CommandHandler.Create <InvocationContext, StartupOptions>((context, options) =>
                {
                    services.AddSingleton(_ => PackageRegistry.CreateForTryMode(
                                              options.RootDirectory,
                                              options.AddPackageSource));

                    startServer(options, context);
                });

                return(command);
            }

            Command StartInHostedMode()
            {
                var command = new Command("hosted")
                {
                    new Option <string>(
                        "--id",
                        description: "A unique id for the agent instance (e.g. its development environment id).",
                        getDefaultValue: () => Environment.MachineName),
                    new Option <bool>(
                        "--production",
                        "Specifies whether the agent is being run using production resources"),
                    new Option <bool>(
                        "--language-service",
                        "Specifies whether the agent is being run in language service-only mode"),
                    new Option <string>(
                        new[]
                    {
                        "-k",
                        "--key"
                    },
                        "The encryption key"),
                    new Option <string>(
                        new[]
                    {
                        "--ai-key",
                        "--application-insights-key"
                    },
                        "Application Insights key."),
                    new Option <string>(
                        "--region-id",
                        "A unique id for the agent region"),
                    new Option <bool>(
                        "--log-to-file",
                        "Writes a log file")
                };

                command.Description = "Starts the Try .NET agent";

                command.IsHidden = true;

                command.Handler = CommandHandler.Create <InvocationContext, StartupOptions>((context, options) =>
                {
                    services.AddSingleton(_ => PackageRegistry.CreateForHostedMode());
                    services.AddSingleton(c => new MarkdownProject(c.GetRequiredService <PackageRegistry>()));
                    startServer(options, context);
                });

                return(command);
            }

            Command Demo()
            {
                var demoCommand = new Command(
                    "demo",
                    "Learn how to create Try .NET content with an interactive demo")
                {
                    new Option <DirectoryInfo>(
                        "--output",
                        description: "Where should the demo project be written to?",
                        getDefaultValue: () => new DirectoryInfo(Directory.GetCurrentDirectory()))
                };

                demoCommand.Handler = CommandHandler.Create <DemoOptions, InvocationContext>((options, context) => { demo(options, context.Console, startServer, context); });

                return(demoCommand);
            }

            Command GitHub()
            {
                var argument = new Argument <string>
                {
                    // System.CommandLine parameter binding does lookup by name,
                    // so name the argument after the github command's string param
                    Name = nameof(TryGitHubOptions.Repo)
                };

                var github = new Command("github", "Try a GitHub repo")
                {
                    argument
                };

                github.IsHidden = true;

                github.Handler = CommandHandler.Create <TryGitHubOptions, IConsole>((repo, console) => tryGithub(repo, console));

                return(github);
            }

            Command Install()
            {
                var installCommand = new Command("install", "Install a Try .NET package")
                {
                    new Argument <string>
                    {
                        Name  = nameof(InstallOptions.PackageName),
                        Arity = ArgumentArity.ExactlyOne
                    },
                    new Option <PackageSource>("--add-source")
                };

                installCommand.IsHidden = true;

                installCommand.Handler = CommandHandler.Create <InstallOptions, IConsole>((options, console) => install(options, console));

                return(installCommand);
            }

            Command Pack()
            {
                var packCommand = new Command("pack", "Create a Try .NET package")
                {
                    new Argument <DirectoryInfo>
                    {
                        Name = nameof(PackOptions.PackTarget)
                    },
                    new Option <string>("--version", "The version of the Try .NET package"),
                    new Option <bool>("--enable-wasm", "Enables web assembly code execution")
                };

                packCommand.IsHidden = true;

                packCommand.Handler = CommandHandler.Create <PackOptions, IConsole>(
                    (options, console) =>
                {
                    return(pack(options, console));
                });

                return(packCommand);
            }

            Command Verify()
            {
                var verifyCommand = new Command("verify", "Verify Markdown files found under the root directory.")
                {
                    dirArgument
                };

                verifyCommand.Handler = CommandHandler.Create <VerifyOptions, IConsole, StartupOptions>(
                    (options, console, startupOptions) =>
                {
                    return(verify(options, console, startupOptions));
                });

                return(verifyCommand);
            }

            Command Publish()
            {
                var publishCommand = new Command("publish", "Publish code from sample projects found under the root directory into Markdown files in the target directory")
                {
                    new Option <PublishFormat>(
                        "--format",
                        description: "Format of the files to publish",
                        getDefaultValue: () => PublishFormat.Markdown),
                    new Option <IDirectoryAccessor>(
                        "--target-directory",
                        description: "The path where the output files should go. This can be the same as the root directory, which will overwrite files in place.",
                        parseArgument: result =>
                    {
                        var directory = result.Tokens
                                        .Select(t => t.Value)
                                        .Single();

                        return(new FileSystemDirectoryAccessor(directory));
                    }
                        ),
                    dirArgument
                };

                publishCommand.Handler = CommandHandler.Create <PublishOptions, IConsole, StartupOptions>(
                    (options, console, startupOptions) => publish(options, console, startupOptions));

                return(publishCommand);
            }
        }
Esempio n. 11
0
 public RebuildablePackageTests(ITestOutputHelper output)
 {
     disposables.Add(output.SubscribeToPocketLogger());
     disposables.Add(VirtualClock.Start());
 }
Esempio n. 12
0
 public void Init()
 {
     VirtualClock.Start();
 }
 public void SetUp()
 {
     _clock = new VirtualClock();
     _rtc   = new RealTimeClock(_clock);
 }
Esempio n. 14
0
 public UnitTestingPackageTests(ITestOutputHelper output)
 {
     _disposables.Add(output.SubscribeToPocketLogger());
     _disposables.Add(VirtualClock.Start());
 }
Esempio n. 15
0
 protected ApiViaHttpTestsBase(ITestOutputHelper output)
 {
     _disposables.Add(output.SubscribeToPocketLogger());
     _disposables.Add(VirtualClock.Start());
     EnsureConsoleWorkspaceCreated();
 }
Esempio n. 16
0
 public RealTimeClockTests()
 {
     clock = new VirtualClock();
     rtc   = new RealTimeClock(clock);
 }
Esempio n. 17
0
 public AspNetWorkspaceTests(ITestOutputHelper output)
 {
     _disposables.Add(output.SubscribeToPocketLogger());
     _disposables.Add(VirtualClock.Start());
 }
Esempio n. 18
0
 public VirtualClockBudgetExtensionsTests(ITestOutputHelper output) :
     base(VirtualClock.Start(), output)
 {
 }
 protected ApiViaHttpTestsBase(ITestOutputHelper output)
 {
     _disposables.Add(output.SubscribeToPocketLogger());
     _disposables.Add(VirtualClock.Start());
 }
Esempio n. 20
0
        public async Task Recursive_scheduling_is_supported_when_the_virtual_clock_is_advanced()
        {
            // arrange
            using (VirtualClock.Start(DateTimeOffset.Parse("2014-10-08 06:52:10 AM -07:00")))
            {
                var scenario = CreateScenarioBuilder()
                               .AddEvents(new CustomerAccount.EmailAddressChanged
                {
                    NewEmailAddress = Any.Email()
                })
                               .Prepare();

                // act
                var account = (await scenario.GetLatestAsync <CustomerAccount>())
                              .Apply(new RequestSpam())
                              .Apply(new SendMarketingEmail());
                await scenario.SaveAsync(account);

                VirtualClock.Current.AdvanceBy(TimeSpan.FromDays((7 * 4) + 2));

                await scenario.CommandSchedulerDone();

                account = await scenario.GetLatestAsync <CustomerAccount>();

                // assert
                account.Events()
                .OfType <CommandScheduled <CustomerAccount> >()
                .Select(e => e.Timestamp.Date)
                .Should()
                .BeEquivalentTo(new[]
                {
                    DateTime.Parse("2014-10-08"),
                    DateTime.Parse("2014-10-15"),
                    DateTime.Parse("2014-10-22"),
                    DateTime.Parse("2014-10-29"),
                    DateTime.Parse("2014-11-05")
                });
                account.Events()
                .OfType <CustomerAccount.MarketingEmailSent>()
                .Select(e => e.Timestamp.Date)
                .Should()
                .BeEquivalentTo(new[]
                {
                    DateTime.Parse("2014-10-08"),
                    DateTime.Parse("2014-10-15"),
                    DateTime.Parse("2014-10-22"),
                    DateTime.Parse("2014-10-29"),
                    DateTime.Parse("2014-11-05")
                });
                account.Events()
                .Last()
                .Should()
                .BeOfType <CommandScheduled <CustomerAccount> >();

                if (this is ScenarioBuilderWithSqlEventStoreTests)
                {
                    using (var db = new CommandSchedulerDbContext())
                    {
                        var scheduledCommands = db.ScheduledCommands
                                                .Where(c => c.AggregateId == account.Id)
                                                .ToArray();

                        // all but the last command (which didn't come due yet) should have been marked as applied
                        scheduledCommands
                        .Reverse()
                        .Skip(1)
                        .Should()
                        .OnlyContain(c => c.AppliedTime != null);
                    }
                }
            }
        }
Esempio n. 21
0
 protected void StartClock(DateTimeOffset?now = null) => VirtualClock.Start(now);