public void Evaluate_SingleVersionRange(string sdkVersion, bool allowed)
        {
            var config = new
            {
                identity    = "test-constraint-01",
                constraints = new
                {
                    specVersions = new
                    {
                        type = "sdk-version",
                        args = "(1.2.3-*, 4.5]"
                    }
                }
            };

            var configModel = SimpleConfigModel.FromJObject(JObject.FromObject(config));
            ISdkInfoProvider           sdkInfoProvider = new SdkInfoProviderMock(sdkVersion); //A.Fake<ISdkInfoProvider>();
            IEngineEnvironmentSettings settings        = A.Fake <IEngineEnvironmentSettings>();

            A.CallTo(() => settings.Components.OfType <ISdkInfoProvider>()).Returns(new[] { sdkInfoProvider });
            A.CallTo(() => settings.Components.OfType <ITemplateConstraintFactory>()).Returns(new[] { new SdkVersionConstraintFactory() });

            var constraintManager = new TemplateConstraintManager(settings);

            //Workaround needed
            //A.CallTo(() => sdkInfoProvider.GetVersionAsync(A<CancellationToken>._)).Returns(t);

            var evaluateResult = constraintManager.EvaluateConstraintAsync(configModel.Constraints.Single().Type, configModel.Constraints.Single().Args, default).Result;

            Assert.Equal(allowed ? TemplateConstraintResult.Status.Allowed : TemplateConstraintResult.Status.Restricted, evaluateResult.EvaluationStatus);
        }
예제 #2
0
        public async Task Evaluate_ArrayOfVersions(IReadOnlyList <string> workloads, bool allowed)
        {
            var config = new
            {
                identity    = "test-constraint-01",
                constraints = new
                {
                    specVersions = new
                    {
                        type = "workload",
                        args = new[] { "workloadA", "workloadB" }
                    }
                }
            };

            var configModel = SimpleConfigModel.FromJObject(JObject.FromObject(config));
            IWorkloadsInfoProvider     workloadInfoProvider = new WorkloadsInfoProviderMock(workloads); //A.Fake<IWorkloadsInfoProvider>();
            IEngineEnvironmentSettings settings             = A.Fake <IEngineEnvironmentSettings>();

            A.CallTo(() => settings.Components.OfType <IWorkloadsInfoProvider>()).Returns(new[] { workloadInfoProvider });
            A.CallTo(() => settings.Components.OfType <ITemplateConstraintFactory>()).Returns(new[] { new WorkloadConstraintFactory() });

            var constraintManager = new TemplateConstraintManager(settings);

            //A.CallTo(() => workloadInfoProvider
            //    .GetInstalledWorkloadsAsync(A<CancellationToken>._))
            //    .Returns(Task.FromResult(workloads.Select(s => new WorkloadInfo(s, $"D:{s}"))));

            var evaluateResult = await constraintManager.EvaluateConstraintAsync(configModel.Constraints.Single().Type, configModel.Constraints.Single().Args, default).ConfigureAwait(false);

            Assert.Equal(allowed ? TemplateConstraintResult.Status.Allowed : TemplateConstraintResult.Status.Restricted, evaluateResult.EvaluationStatus);
        }
        public async Task Evaluate_AlternativeInstalledVersions(string sdkVersion, IReadOnlyList <string> installedVersions, bool hasAlternativeInstalled)
        {
            var config = new
            {
                identity    = "test-constraint-01",
                constraints = new
                {
                    specVersions = new
                    {
                        type = "sdk-version",
                        args = new[] { "1.2.3-*", "4.5.*" }
                    }
                }
            };

            var configModel = SimpleConfigModel.FromJObject(JObject.FromObject(config));
            ISdkInfoProvider           sdkInfoProvider = new SdkInfoProviderMock(sdkVersion, installedVersions); //A.Fake<ISdkInfoProvider>();
            IEngineEnvironmentSettings settings        = A.Fake <IEngineEnvironmentSettings>();

            A.CallTo(() => settings.Components.OfType <ISdkInfoProvider>()).Returns(new[] { sdkInfoProvider });
            A.CallTo(() => settings.Components.OfType <ITemplateConstraintFactory>()).Returns(new[] { new SdkVersionConstraintFactory() });

            var constraintManager = new TemplateConstraintManager(settings);

            var evaluateResult = await constraintManager.EvaluateConstraintAsync(configModel.Constraints.Single().Type, configModel.Constraints.Single().Args, default).ConfigureAwait(false);

            Assert.Equal(TemplateConstraintResult.Status.Restricted, evaluateResult.EvaluationStatus);
            Assert.StartsWith(
                hasAlternativeInstalled
                    ? "Sample CTA with alternatives"
                    : "Sample CTA without alternatives",
                evaluateResult.CallToAction);
        }
예제 #4
0
        public async Task CanReadArrayConfiguration()
        {
            var config = new
            {
                identity    = "test",
                constraints = new
                {
                    winOnly = new
                    {
                        type = "os",
                        args = new[] { "Windows", "Linux" }
                    }
                }
            };

            var configModel       = SimpleConfigModel.FromJObject(JObject.FromObject(config));
            var constraintManager = new TemplateConstraintManager(_sharedSettings);
            var evaluateResult    = await constraintManager.EvaluateConstraintAsync(configModel.Constraints.Single().Type, configModel.Constraints.Single().Args, default).ConfigureAwait(false);

            var pass = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) || RuntimeInformation.IsOSPlatform(OSPlatform.Linux);

            Assert.Equal(pass, evaluateResult.EvaluationStatus == TemplateConstraintResult.Status.Allowed);

            if (!pass)
            {
                Assert.Equal($"Running template on {RuntimeInformation.OSDescription} is not supported, supported OS is/are: {OSPlatform.Windows}, {OSPlatform.Linux}.", evaluateResult.LocalizedErrorMessage);
            }
            else
            {
                Assert.Null(evaluateResult.LocalizedErrorMessage);
            }
            Assert.Null(evaluateResult.CallToAction);
        }
예제 #5
0
        public async Task CanEvaluateConstraint()
        {
            var engineEnvironmentSettings = _environmentSettingsHelper.CreateEnvironment(virtualize: true);

            engineEnvironmentSettings.Components.AddComponent(typeof(ITemplateConstraintFactory), new TestConstraintFactory("test-1"));
            engineEnvironmentSettings.Components.AddComponent(typeof(ITemplateConstraintFactory), new TestConstraintFactory("test-2"));

            var constraintManager = new TemplateConstraintManager(engineEnvironmentSettings);

            var success1 = await constraintManager.EvaluateConstraintAsync("test-1", "yes", default).ConfigureAwait(false);

            var failure1 = await constraintManager.EvaluateConstraintAsync("test-1", "no", default).ConfigureAwait(false);

            var notEvaluated1 = await constraintManager.EvaluateConstraintAsync("test-1", "not-valid", default).ConfigureAwait(false);

            var success2 = await constraintManager.EvaluateConstraintAsync("test-2", "yes", default).ConfigureAwait(false);

            Assert.Equal(TemplateConstraintResult.Status.Allowed, success1.EvaluationStatus);
            Assert.Null(success1.LocalizedErrorMessage);
            Assert.Null(success1.CallToAction);

            Assert.Equal(TemplateConstraintResult.Status.Restricted, failure1.EvaluationStatus);
            Assert.Equal("cannot run", failure1.LocalizedErrorMessage);
            Assert.Equal("do smth", failure1.CallToAction);

            Assert.Equal(TemplateConstraintResult.Status.NotEvaluated, notEvaluated1.EvaluationStatus);
            Assert.Equal("bad params", notEvaluated1.LocalizedErrorMessage);
            Assert.Null(notEvaluated1.CallToAction);

            Assert.Equal(TemplateConstraintResult.Status.Allowed, success2.EvaluationStatus);
            Assert.Null(success2.LocalizedErrorMessage);
            Assert.Null(success2.CallToAction);
        }
예제 #6
0
        public async Task CanGetConstraints_DoesNotWaitForNotNeededConstraints()
        {
            var engineEnvironmentSettings = _environmentSettingsHelper.CreateEnvironment(virtualize: true);

            engineEnvironmentSettings.Components.AddComponent(typeof(ITemplateConstraintFactory), new LongRunningTestConstraintFactory("test-1"));
            engineEnvironmentSettings.Components.AddComponent(typeof(ITemplateConstraintFactory), new TestConstraintFactory("test-2"));

            var templateInfo = A.Fake <ITemplateInfo>();

            A.CallTo(() => templateInfo.Constraints).Returns(new[]
            {
                new TemplateConstraintInfo("test-2", "yes")
            });

            IReadOnlyList <ITemplateConstraint>?constraints = null;
            var constraintsTask = Task.Run(async() =>
            {
                var constraintManager = new TemplateConstraintManager(engineEnvironmentSettings);
                constraints           = await constraintManager.GetConstraintsAsync(new[] { templateInfo }, default).ConfigureAwait(false);
            }
                                           );
            var completedTask = await Task.WhenAny(constraintsTask, Task.Delay(10000)).ConfigureAwait(false);

            Assert.Equal(completedTask, constraintsTask);
            Assert.Equal(1, constraints?.Count);
            Assert.Equal("test-2", constraints?.Single().Type);
        }
예제 #7
0
        public async Task FailsOnWrongConfiguration()
        {
            var config = new
            {
                identity    = "test",
                constraints = new
                {
                    host = new
                    {
                        type = "host",
                        args =
                            new
                        {
                            hostName = "host2",
                            version  = "1.0.0"
                        }
                    }
                }
            };

            var configModel = SimpleConfigModel.FromJObject(JObject.FromObject(config));

            IEngineEnvironmentSettings settings = A.Fake <IEngineEnvironmentSettings>();

            A.CallTo(() => settings.Host.HostIdentifier).Returns("host3");
            A.CallTo(() => settings.Host.Version).Returns("2.0.0");
            A.CallTo(() => settings.Components.OfType <ITemplateConstraintFactory>()).Returns(new[] { new HostConstraintFactory() });

            var constraintManager = new TemplateConstraintManager(settings);
            var evaluateResult    = await constraintManager.EvaluateConstraintAsync(configModel.Constraints.Single().Type, configModel.Constraints.Single().Args, default).ConfigureAwait(false);

            Assert.Equal(TemplateConstraintResult.Status.NotEvaluated, evaluateResult.EvaluationStatus);
            Assert.Equal("'{\"hostName\":\"host2\",\"version\":\"1.0.0\"}' is not a valid JSON array.", evaluateResult.LocalizedErrorMessage);
            Assert.Equal("Check the constraint configuration in template.json.", evaluateResult.CallToAction);
        }
예제 #8
0
 internal TemplatePackageCoordinator(
     ITelemetryLogger telemetryLogger,
     IEngineEnvironmentSettings environmentSettings,
     TemplatePackageManager templatePackageManager)
 {
     _telemetryLogger           = telemetryLogger ?? throw new ArgumentNullException(nameof(telemetryLogger));
     _engineEnvironmentSettings = environmentSettings ?? throw new ArgumentNullException(nameof(environmentSettings));
     _templatePackageManager    = templatePackageManager ?? throw new ArgumentNullException(nameof(templatePackageManager));
     _constraintsManager        = new TemplateConstraintManager(_engineEnvironmentSettings);
     _hostSpecificDataLoader    = new HostSpecificDataLoader(_engineEnvironmentSettings);
 }
예제 #9
0
        public async Task CanGetConstraints_WhenCreationFailed()
        {
            var engineEnvironmentSettings = _environmentSettingsHelper.CreateEnvironment(virtualize: true);

            engineEnvironmentSettings.Components.AddComponent(typeof(ITemplateConstraintFactory), new FailingTestConstraintFactory("test-1"));
            engineEnvironmentSettings.Components.AddComponent(typeof(ITemplateConstraintFactory), new TestConstraintFactory("test-2"));

            var constraintManager = new TemplateConstraintManager(engineEnvironmentSettings);
            var constraints       = await constraintManager.GetConstraintsAsync().ConfigureAwait(false);

            Assert.Equal(3, constraints.Count);
            Assert.Equal(new[] { "host", "os", "test-2" }, constraints.Select(c => c.Type).OrderBy(t => t));
        }
예제 #10
0
        internal TemplateListCoordinator(
            IEngineEnvironmentSettings engineEnvironmentSettings,
            TemplatePackageManager templatePackageManager,
            IHostSpecificDataLoader hostSpecificDataLoader,
            ITelemetryLogger telemetryLogger)

        {
            _engineEnvironmentSettings = engineEnvironmentSettings ?? throw new ArgumentNullException(nameof(engineEnvironmentSettings));
            _templatePackageManager    = templatePackageManager ?? throw new ArgumentNullException(nameof(templatePackageManager));
            _hostSpecificDataLoader    = hostSpecificDataLoader ?? throw new ArgumentNullException(nameof(hostSpecificDataLoader));
            _telemetryLogger           = telemetryLogger ?? throw new ArgumentNullException(nameof(telemetryLogger));
            _defaultLanguage           = engineEnvironmentSettings.GetDefaultLanguage();
            _constraintManager         = new TemplateConstraintManager(_engineEnvironmentSettings);
        }
예제 #11
0
        public async Task CannotEvaluateConstraint_WhenCreationFailed()
        {
            var engineEnvironmentSettings = _environmentSettingsHelper.CreateEnvironment(virtualize: true);

            engineEnvironmentSettings.Components.AddComponent(typeof(ITemplateConstraintFactory), new FailingTestConstraintFactory("test-1"));

            var constraintManager = new TemplateConstraintManager(engineEnvironmentSettings);

            var result = await constraintManager.EvaluateConstraintAsync("test-1", "yes", default);

            Assert.Equal(TemplateConstraintResult.Status.NotEvaluated, result.EvaluationStatus);
            Assert.Equal("The constraint 'test-1' failed to initialize: creation failed", result.LocalizedErrorMessage);
            Assert.Null(result.CallToAction);
        }
예제 #12
0
        public async Task CanEvaluateConstraint_WhenOtherCreationStillRuns()
        {
            var engineEnvironmentSettings = _environmentSettingsHelper.CreateEnvironment(virtualize: true);

            engineEnvironmentSettings.Components.AddComponent(typeof(ITemplateConstraintFactory), new LongRunningTestConstraintFactory("test-1"));
            engineEnvironmentSettings.Components.AddComponent(typeof(ITemplateConstraintFactory), new TestConstraintFactory("test-2"));

            var constraintManager = new TemplateConstraintManager(engineEnvironmentSettings);

            var success2 = await constraintManager.EvaluateConstraintAsync("test-2", "yes", default).ConfigureAwait(false);

            Assert.Equal(TemplateConstraintResult.Status.Allowed, success2.EvaluationStatus);
            Assert.Null(success2.LocalizedErrorMessage);
            Assert.Null(success2.CallToAction);
        }
예제 #13
0
        public async Task CanProcessDifferentHostNames(string hostName, string fallbackHostNames, string hostVersion, bool expectedResult)
        {
            var config = new
            {
                identity    = "test",
                constraints = new
                {
                    host = new
                    {
                        type = "host",
                        args = new[]
                        {
                            new
                            {
                                hostName = "host1",
                                version  = "[1.0, 2.0]"
                            },
                            new
                            {
                                hostName = "fallback",
                                version  = "[2.0, 3.0]"
                            },
                        }
                    }
                }
            };

            var configModel = SimpleConfigModel.FromJObject(JObject.FromObject(config));
            IEngineEnvironmentSettings settings = A.Fake <IEngineEnvironmentSettings>();

            A.CallTo(() => settings.Host.HostIdentifier).Returns(hostName);
            A.CallTo(() => settings.Host.Version).Returns(hostVersion);
            A.CallTo(() => settings.Host.FallbackHostTemplateConfigNames).Returns(fallbackHostNames.Split('|'));
            A.CallTo(() => settings.Components.OfType <ITemplateConstraintFactory>()).Returns(new[] { new HostConstraintFactory() });

            var constraintManager = new TemplateConstraintManager(settings);
            var evaluateResult    = await constraintManager.EvaluateConstraintAsync(configModel.Constraints.Single().Type, configModel.Constraints.Single().Args, default).ConfigureAwait(false);

            if (expectedResult)
            {
                Assert.Equal(TemplateConstraintResult.Status.Allowed, evaluateResult.EvaluationStatus);
            }
            else
            {
                Assert.Equal(TemplateConstraintResult.Status.Restricted, evaluateResult.EvaluationStatus);
            }
        }
예제 #14
0
        public async Task CanReadConfiguration_ExactVersion()
        {
            var config = new
            {
                identity    = "test",
                constraints = new
                {
                    host = new
                    {
                        type = "host",
                        args = new[]
                        {
                            new
                            {
                                hostName = "host1",
                                version  = ""
                            },
                            new
                            {
                                hostName = "host2",
                                version  = "1.0.0"
                            },
                            new
                            {
                                hostName = "host3",
                                version  = "[1.0.0-*]"
                            },
                        }
                    }
                }
            };

            var configModel = SimpleConfigModel.FromJObject(JObject.FromObject(config));
            IEngineEnvironmentSettings settings = A.Fake <IEngineEnvironmentSettings>();

            A.CallTo(() => settings.Host.HostIdentifier).Returns("host2");
            A.CallTo(() => settings.Host.Version).Returns("2.0.0");
            A.CallTo(() => settings.Components.OfType <ITemplateConstraintFactory>()).Returns(new[] { new HostConstraintFactory() });

            var constraintManager = new TemplateConstraintManager(settings);
            var evaluateResult    = await constraintManager.EvaluateConstraintAsync(configModel.Constraints.Single().Type, configModel.Constraints.Single().Args, default).ConfigureAwait(false);

            Assert.Equal(TemplateConstraintResult.Status.Restricted, evaluateResult.EvaluationStatus);
            Assert.Equal("Running template on host2 (version: 2.0.0) is not supported, supported hosts is/are: host1, host2(1.0.0), host3([1.0.0-*]).", evaluateResult.LocalizedErrorMessage);
            Assert.Null(evaluateResult.CallToAction);
        }
예제 #15
0
        public async Task CanReadConfiguration_VersionRange()
        {
            var config = new
            {
                identity    = "test",
                constraints = new
                {
                    host = new
                    {
                        type = "host",
                        args = new[]
                        {
                            new
                            {
                                hostName = "host1",
                                version  = ""
                            },
                            new
                            {
                                hostName = "host2",
                                version  = "1.0.0"
                            },
                            new
                            {
                                hostName = "host3",
                                version  = "[1.0.0-*]"
                            },
                        }
                    }
                }
            };

            var configModel = SimpleConfigModel.FromJObject(JObject.FromObject(config));

            IEngineEnvironmentSettings settings = A.Fake <IEngineEnvironmentSettings>();

            A.CallTo(() => settings.Host.HostIdentifier).Returns("host3");
            A.CallTo(() => settings.Host.Version).Returns("2.0.0");
            A.CallTo(() => settings.Components.OfType <ITemplateConstraintFactory>()).Returns(new[] { new HostConstraintFactory() });

            var constraintManager = new TemplateConstraintManager(settings);
            var evaluateResult    = await constraintManager.EvaluateConstraintAsync(configModel.Constraints.Single().Type, configModel.Constraints.Single().Args, default).ConfigureAwait(false);

            Assert.Equal(TemplateConstraintResult.Status.Allowed, evaluateResult.EvaluationStatus);
        }
예제 #16
0
        public async Task Evaluate_MultipleConflictingProviders()
        {
            var config = new
            {
                identity    = "test-constraint-01",
                constraints = new
                {
                    specVersions = new
                    {
                        type = "workload",
                        args = new[] { "workloadA", "workloadB" }
                    }
                }
            };

            var configModel = SimpleConfigModel.FromJObject(JObject.FromObject(config));
            IWorkloadsInfoProvider workloadInfoProviderA = A.Fake <IWorkloadsInfoProvider>();

            A.CallTo(() => workloadInfoProviderA
                     .GetInstalledWorkloadsAsync(A <CancellationToken> ._))
            .Returns(Task.FromResult(new[] { "workload", "workloadA" }.Select(s => new WorkloadInfo(s, $"D:{s}"))));

            IWorkloadsInfoProvider workloadInfoProviderB = A.Fake <IWorkloadsInfoProvider>();

            A.CallTo(() => workloadInfoProviderB
                     .GetInstalledWorkloadsAsync(A <CancellationToken> ._))
            .Returns(Task.FromResult(new[] { "workload", "workloadA", "workloadB" }.Select(s => new WorkloadInfo(s, $"D:{s}"))));

            IEngineEnvironmentSettings settings = A.Fake <IEngineEnvironmentSettings>();

            A.CallTo(() => settings.Components.OfType <IWorkloadsInfoProvider>()).Returns(new[] { workloadInfoProviderA, workloadInfoProviderB });
            A.CallTo(() => settings.Components.OfType <ITemplateConstraintFactory>()).Returns(new[] { new WorkloadConstraintFactory() });
            List <(LogLevel, string)> messagesCollection = new();
            ILogger logger = new InMemoryLoggerProvider(messagesCollection).CreateLogger("x");

            A.CallTo(() => settings.Host.Logger).Returns(logger);

            var constraintManager = new TemplateConstraintManager(settings);

            var evaluateResult = await constraintManager.EvaluateConstraintAsync(configModel.Constraints.Single().Type, configModel.Constraints.Single().Args, default).ConfigureAwait(false);

            Assert.Equal(TemplateConstraintResult.Status.NotEvaluated, evaluateResult.EvaluationStatus);
            Assert.Equal(0, messagesCollection.Count(t => t.Item1 >= LogLevel.Warning));
            Assert.StartsWith("The constraint 'workload' failed to initialize", evaluateResult.LocalizedErrorMessage);
        }
        internal static IEnumerable <CompletionItem> GetTemplateCompletions(
            InstantiateCommandArgs args,
            IEnumerable <TemplateGroup> templateGroups,
            IEngineEnvironmentSettings environmentSettings,
            TemplatePackageManager templatePackageManager,
            TextCompletionContext context)
        {
            HashSet <CompletionItem>  distinctCompletions = new HashSet <CompletionItem>();
            TemplateConstraintManager constraintManager   = new TemplateConstraintManager(environmentSettings);

            foreach (TemplateGroup templateGroup in templateGroups.Where(template => template.ShortNames.Contains(args.ShortName)))
            {
                foreach (IGrouping <int, CliTemplateInfo> templateGrouping in GetAllowedTemplates(constraintManager, templateGroup).GroupBy(g => g.Precedence).OrderByDescending(g => g.Key))
                {
                    foreach (CliTemplateInfo template in templateGrouping)
                    {
                        try
                        {
                            TemplateCommand command = new TemplateCommand(
                                args.Command,
                                environmentSettings,
                                templatePackageManager,
                                templateGroup,
                                template);

                            Parser parser = ParserFactory.CreateParser(command);

                            //it is important to pass raw text to get the completion
                            //completions for args passed as array are not supported
                            ParseResult parseResult = parser.Parse(context.CommandLineText);
                            foreach (CompletionItem completion in parseResult.GetCompletions(context.CursorPosition))
                            {
                                distinctCompletions.Add(completion);
                            }
                        }
                        catch (InvalidTemplateParametersException e)
                        {
                            Reporter.Error.WriteLine(string.Format(LocalizableStrings.GenericWarning, e.Message));
                        }
                    }
                }
            }
            return(distinctCompletions.OrderBy(c => c.Label, StringComparer.OrdinalIgnoreCase));
        }
예제 #18
0
        public async Task CanEvaluateConstraints_Success()
        {
            var engineEnvironmentSettings = _environmentSettingsHelper.CreateEnvironment(virtualize: true);

            engineEnvironmentSettings.Components.AddComponent(typeof(ITemplateConstraintFactory), new TestConstraintFactory("test-1"));
            engineEnvironmentSettings.Components.AddComponent(typeof(ITemplateConstraintFactory), new TestConstraintFactory("test-2"));

            var           constraintManager = new TemplateConstraintManager(engineEnvironmentSettings);
            ITemplateInfo template          = A.Fake <ITemplateInfo>();

            A.CallTo(() => template.Constraints).Returns(new[] { new TemplateConstraintInfo("test-1", "yes"), new TemplateConstraintInfo("test-2", "no") });

            var result = await constraintManager.EvaluateConstraintsAsync(new [] { template }, default).ConfigureAwait(false);

            Assert.Equal(2, result.Single().Result.Count);
            Assert.Equal(template, result.Single().Template);
            Assert.Equal(TemplateConstraintResult.Status.Allowed, result.Single().Result.Single(r => r.ConstraintType == "test-1").EvaluationStatus);
            Assert.Equal(TemplateConstraintResult.Status.Restricted, result.Single().Result.Single(r => r.ConstraintType == "test-2").EvaluationStatus);
        }
예제 #19
0
        public async Task CanGetConstraints_Filter()
        {
            var engineEnvironmentSettings = _environmentSettingsHelper.CreateEnvironment(virtualize: true);

            engineEnvironmentSettings.Components.AddComponent(typeof(ITemplateConstraintFactory), new TestConstraintFactory("test-1"));
            engineEnvironmentSettings.Components.AddComponent(typeof(ITemplateConstraintFactory), new TestConstraintFactory("test-2"));

            var constraintManager = new TemplateConstraintManager(engineEnvironmentSettings);

            var templateInfo = A.Fake <ITemplateInfo>();

            A.CallTo(() => templateInfo.Constraints).Returns(new[]
            {
                new TemplateConstraintInfo("test-1", "yes")
            });

            var constraints = await constraintManager.GetConstraintsAsync(new[] { templateInfo }, default).ConfigureAwait(false);

            Assert.Equal(1, constraints.Count);
            Assert.Equal("test-1", constraints.Single().Type);
        }
        internal static IEnumerable <CompletionItem> GetTemplateNameCompletions(string?tempalteName, IEnumerable <TemplateGroup> templateGroups, IEngineEnvironmentSettings environmentSettings)
        {
            TemplateConstraintManager constraintManager = new TemplateConstraintManager(environmentSettings);

            if (string.IsNullOrWhiteSpace(tempalteName))
            {
                return(GetAllowedTemplateGroups(constraintManager, templateGroups)
                       .SelectMany(g => g.ShortNames, (g, shortName) => new CompletionItem(shortName, documentation: g.Description))
                       .Distinct()
                       .OrderBy(c => c.Label, StringComparer.OrdinalIgnoreCase)
                       .ToArray());
            }

            var matchingTemplateGroups = templateGroups.Where(t => t.ShortNames.Any(sn => sn.StartsWith(tempalteName, StringComparison.OrdinalIgnoreCase)));

            return(GetAllowedTemplateGroups(constraintManager, matchingTemplateGroups)
                   .SelectMany(g => g.ShortNames, (g, shortName) => new CompletionItem(shortName, documentation: g.Description))
                   .Where(c => c.Label.StartsWith(tempalteName))
                   .Distinct()
                   .OrderBy(c => c.Label, StringComparer.OrdinalIgnoreCase)
                   .ToArray());
        }
예제 #21
0
 public ListTemplateResolver(TemplateConstraintManager constraintManager, TemplatePackageManager templatePackageManager, IHostSpecificDataLoader hostSpecificDataLoader)
     : base(templatePackageManager, hostSpecificDataLoader)
 {
     _constraintManager = constraintManager;
 }
예제 #22
0
        internal async Task <NewCommandStatus> InvokeAsync(ParseResult parseResult, ITelemetryLogger telemetryLogger, CancellationToken cancellationToken)
        {
            TemplateCommandArgs        args               = new TemplateCommandArgs(this, _instantiateCommand, parseResult);
            TemplateInvoker            invoker            = new TemplateInvoker(_environmentSettings, telemetryLogger, () => Console.ReadLine() ?? string.Empty, _instantiateCommand.Callbacks);
            TemplatePackageCoordinator packageCoordinator = new TemplatePackageCoordinator(telemetryLogger, _environmentSettings, _templatePackageManager);
            TemplateConstraintManager  constraintManager  = new TemplateConstraintManager(_environmentSettings);

            CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();

            cancellationTokenSource.CancelAfter(ConstraintEvaluationTimeout);

            Task <IReadOnlyList <TemplateConstraintResult> > constraintsEvaluation = ValidateConstraintsAsync(constraintManager, args.Template, args.IsForceFlagSpecified ? cancellationTokenSource.Token : cancellationToken);

            if (!args.IsForceFlagSpecified)
            {
                var constraintResults = await constraintsEvaluation.ConfigureAwait(false);

                if (constraintResults.Any())
                {
                    DisplayConstraintResults(constraintResults, args);
                    return(NewCommandStatus.CreateFailed);
                }
            }

            cancellationToken.ThrowIfCancellationRequested();

            Task <NewCommandStatus> instantiateTask = invoker.InvokeTemplateAsync(args, cancellationToken);
            Task <(string Id, string Version, string Provider)> builtInPackageCheck = packageCoordinator.ValidateBuiltInPackageAvailabilityAsync(args.Template, cancellationToken);
            Task <CheckUpdateResult?> checkForUpdateTask = packageCoordinator.CheckUpdateForTemplate(args, cancellationToken);

            Task[] tasksToWait = new Task[] { instantiateTask, builtInPackageCheck, checkForUpdateTask };

            await Task.WhenAll(tasksToWait).ConfigureAwait(false);

            Reporter.Output.WriteLine();

            cancellationToken.ThrowIfCancellationRequested();

            if (checkForUpdateTask.Result != null)
            {
                // print if there is update for the template package containing the template
                packageCoordinator.DisplayUpdateCheckResult(checkForUpdateTask.Result, args);
            }

            if (builtInPackageCheck.Result != default)
            {
                // print if there is same or newer built-in package
                packageCoordinator.DisplayBuiltInPackagesCheckResult(
                    builtInPackageCheck.Result.Id,
                    builtInPackageCheck.Result.Version,
                    builtInPackageCheck.Result.Provider,
                    args);
            }

            if (args.IsForceFlagSpecified)
            {
                // print warning about the constraints that were not met.
                try
                {
                    IReadOnlyList <TemplateConstraintResult> constraintResults = await constraintsEvaluation.WaitAsync(cancellationTokenSource.Token).ConfigureAwait(false);

                    if (constraintResults.Any())
                    {
                        DisplayConstraintResults(constraintResults, args);
                    }
                }
                catch (TaskCanceledException)
                {
                    // do nothing
                }
            }

            return(instantiateTask.Result);
        }
예제 #23
0
        /// <summary>
        /// Gets the list of allowed templates from <paramref name="templateGroup"/> as the result of constraints evaluation.
        /// </summary>
        internal static async Task <IEnumerable <CliTemplateInfo> > GetAllowedTemplatesAsync(this TemplateGroup templateGroup, TemplateConstraintManager constraintManager, CancellationToken cancellationToken)
        {
            IReadOnlyList <(ITemplateInfo Template, IReadOnlyList <TemplateConstraintResult> Result)> results =
                await constraintManager.EvaluateConstraintsAsync(templateGroup.Templates, cancellationToken).ConfigureAwait(false);

            cancellationToken.ThrowIfCancellationRequested();
            return(results.Where(r => r.Result.IsTemplateAllowed()).Select(r => r.Template).Cast <CliTemplateInfo>());
        }
예제 #24
0
        internal static async Task <IReadOnlyList <TemplateConstraintResult> > ValidateConstraintsAsync(TemplateConstraintManager constraintManager, ITemplateInfo template, CancellationToken cancellationToken)
        {
            if (!template.Constraints.Any())
            {
                return(Array.Empty <TemplateConstraintResult>());
            }

            IReadOnlyList <(ITemplateInfo Template, IReadOnlyList <TemplateConstraintResult> Result)> result = await constraintManager.EvaluateConstraintsAsync(new[] { template }, cancellationToken).ConfigureAwait(false);

            IReadOnlyList <TemplateConstraintResult> templateConstraints = result.Single().Result;

            if (templateConstraints.IsTemplateAllowed())
            {
                return(Array.Empty <TemplateConstraintResult>());
            }
            return(templateConstraints.Where(cr => cr.EvaluationStatus != TemplateConstraintResult.Status.Allowed).ToList());
        }