Exemple #1
0
        private bool RewriteSyntax(Workspace workspace, Uri entryUri, Func <SemanticModel, SyntaxRewriteVisitor> rewriteVisitorBuilder)
        {
            var hasChanges         = false;
            var dispatcher         = new ModuleDispatcher(this.registryProvider);
            var configuration      = configurationManager.GetBuiltInConfiguration(disableAnalyzers: true);
            var linterAnalyzer     = new LinterAnalyzer(configuration);
            var sourceFileGrouping = SourceFileGroupingBuilder.Build(fileResolver, dispatcher, workspace, entryUri, configuration);
            var compilation        = new Compilation(this.features, namespaceProvider, sourceFileGrouping, configuration, linterAnalyzer);

            // force enumeration here with .ToImmutableArray() as we're going to be modifying the sourceFileGrouping collection as we iterate
            var fileUris = sourceFileGrouping.SourceFiles.Select(x => x.FileUri).ToImmutableArray();

            foreach (var fileUri in fileUris)
            {
                if (sourceFileGrouping.SourceFiles.FirstOrDefault(x => x.FileUri == fileUri) is not BicepFile bicepFile)
                {
                    throw new InvalidOperationException($"Failed to find a bicep source file for URI {fileUri}.");
                }

                var newProgramSyntax = rewriteVisitorBuilder(compilation.GetSemanticModel(bicepFile)).Rewrite(bicepFile.ProgramSyntax);

                if (!object.ReferenceEquals(bicepFile.ProgramSyntax, newProgramSyntax))
                {
                    hasChanges = true;
                    var newFile = SourceFileFactory.CreateBicepFile(fileUri, newProgramSyntax.ToText());
                    workspace.UpsertSourceFile(newFile);

                    sourceFileGrouping = SourceFileGroupingBuilder.Build(fileResolver, dispatcher, workspace, entryUri, configuration);
                    compilation        = new Compilation(this.features, namespaceProvider, sourceFileGrouping, configuration, linterAnalyzer);
                }
            }

            return(hasChanges);
        }
Exemple #2
0
        private static bool RewriteSyntax(IResourceTypeProvider resourceTypeProvider, Workspace workspace, Uri entryUri, Func <SemanticModel, SyntaxRewriteVisitor> rewriteVisitorBuilder)
        {
            var hasChanges         = false;
            var fileResolver       = new FileResolver();
            var dispatcher         = new ModuleDispatcher(new DefaultModuleRegistryProvider(fileResolver));
            var sourceFileGrouping = SourceFileGroupingBuilder.Build(fileResolver, dispatcher, workspace, entryUri);
            var compilation        = new Compilation(resourceTypeProvider, sourceFileGrouping);

            foreach (var(fileUri, sourceFile) in workspace.GetActiveSourceFilesByUri())
            {
                if (sourceFile is not BicepFile bicepFile)
                {
                    throw new InvalidOperationException("Expected a bicep source file.");
                }

                var newProgramSyntax = rewriteVisitorBuilder(compilation.GetSemanticModel(bicepFile)).Rewrite(bicepFile.ProgramSyntax);

                if (!object.ReferenceEquals(bicepFile.ProgramSyntax, newProgramSyntax))
                {
                    hasChanges = true;
                    var newFile = new BicepFile(fileUri, ImmutableArray <int> .Empty, newProgramSyntax);
                    workspace.UpsertSourceFile(newFile);

                    sourceFileGrouping = SourceFileGroupingBuilder.Build(fileResolver, dispatcher, workspace, entryUri);
                    compilation        = new Compilation(resourceTypeProvider, sourceFileGrouping);
                }
            }

            return(hasChanges);
        }
        public void ValidBicepTextWriter_TemplateEmiterShouldProduceExpectedTemplate(DataSet dataSet)
        {
            var          outputDirectory = dataSet.SaveFilesToTestDirectory(TestContext);
            var          bicepFilePath   = Path.Combine(outputDirectory, DataSet.TestFileMain);
            MemoryStream memoryStream    = new MemoryStream();

            // emitting the template should be successful
            FileResolver fileResolver = BicepTestConstants.FileResolver;
            var          dispatcher   = new ModuleDispatcher(new DefaultModuleRegistryProvider(BicepTestConstants.FileResolver));
            var          result       = this.EmitTemplate(SourceFileGroupingBuilder.Build(fileResolver, dispatcher, new Workspace(), PathHelper.FilePathToFileUrl(bicepFilePath)), memoryStream, BicepTestConstants.DevAssemblyFileVersion);

            result.Diagnostics.Should().NotHaveErrors();
            result.Status.Should().Be(EmitStatus.Succeeded);

            // normalizing the formatting in case there are differences in indentation
            // this way the diff between actual and expected will be clean
            var actual           = JToken.ReadFrom(new JsonTextReader(new StreamReader(new MemoryStream(memoryStream.ToArray()))));
            var compiledFilePath = FileHelper.SaveResultFile(this.TestContext, Path.Combine(dataSet.Name, DataSet.TestFileMainCompiled), actual.ToString(Formatting.Indented));

            actual.Should().EqualWithJsonDiffOutput(
                TestContext,
                JToken.Parse(dataSet.Compiled !),
                expectedLocation: DataSet.GetBaselineUpdatePath(dataSet, DataSet.TestFileMainCompiled),
                actualLocation: compiledFilePath);
        }
Exemple #4
0
        public static Compilation CopyFilesAndCreateCompilation(this DataSet dataSet, TestContext testContext, out string outputDirectory, out Uri fileUri)
        {
            outputDirectory = dataSet.SaveFilesToTestDirectory(testContext);
            fileUri         = PathHelper.FilePathToFileUrl(Path.Combine(outputDirectory, DataSet.TestFileMain));
            var dispatcher         = new ModuleDispatcher(new DefaultModuleRegistryProvider(BicepTestConstants.FileResolver));
            var sourceFileGrouping = SourceFileGroupingBuilder.Build(BicepTestConstants.FileResolver, dispatcher, new Workspace(), fileUri);

            return(new Compilation(AzResourceTypeProvider.CreateWithAzTypes(), sourceFileGrouping));
        }
Exemple #5
0
        public void Reset_WhenCameraIdDoesNotExist_ShouldThrowException()
        {
            // GIVEN
            var moduleDispatcher = new ModuleDispatcher();
            var module           = new CamerasModule(moduleDispatcher);
            var cameraFileName   = _WriteCameraResourceToFile();

            // WHEN-THEN
            Exception actualException = Assert.Catch(typeof(ArgumentException), delegate { CamResetDelegate(module, cameraFileName); });

            Assert.AreEqual("Specified camera identifier does not exist: 0\nParameter name: entryId", actualException.Message);
        }
Exemple #6
0
        public async Task ForceModuleRestoreShouldRestoreAllModules(IEnumerable <ExternalModuleInfo> moduleInfos, int moduleCount)
        {
            var dataSet = DataSets.Registry_LF;

            var outputDirectory = dataSet.SaveFilesToTestDirectory(TestContext);
            var clientFactory   = dataSet.CreateMockRegistryClients(TestContext);
            var templateSpecRepositoryFactory = dataSet.CreateMockTemplateSpecRepositoryFactory(TestContext);
            await dataSet.PublishModulesToRegistryAsync(clientFactory, TestContext);

            var cacheDirectory = FileHelper.GetCacheRootPath(TestContext);

            Directory.CreateDirectory(cacheDirectory);

            var features = StrictMock.Of <IFeatureProvider>();

            features.Setup(m => m.RegistryEnabled).Returns(true);
            features.Setup(m => m.CacheRootDirectory).Returns(cacheDirectory);

            FileResolver fileResolver = new FileResolver();
            var          dispatcher   = new ModuleDispatcher(new DefaultModuleRegistryProvider(fileResolver, clientFactory, templateSpecRepositoryFactory, features.Object));

            var configuration    = BicepTestConstants.BuiltInConfigurationWithAnalyzersDisabled;
            var moduleReferences = moduleInfos
                                   .OrderBy(m => m.Metadata.Target)
                                   .Select(m => dispatcher.TryGetModuleReference(m.Metadata.Target, configuration, out _) ?? throw new AssertFailedException($"Invalid module target '{m.Metadata.Target}'."))
                                   .ToImmutableList();

            moduleReferences.Should().HaveCount(moduleCount);

            // initially the cache should be empty
            foreach (var moduleReference in moduleReferences)
            {
                dispatcher.GetModuleRestoreStatus(moduleReference, configuration, out _).Should().Be(ModuleRestoreStatus.Unknown);
            }

            var moduleFileUri = dispatcher.TryGetLocalModuleEntryPointUri(new Uri("file://main.bicep"), moduleReferences[0], configuration, out _) !;

            moduleFileUri.Should().NotBeNull();

            var moduleFilePath  = moduleFileUri.LocalPath;
            var moduleDirectory = Path.GetDirectoryName(moduleFilePath) !;

            Directory.CreateDirectory(moduleDirectory);

            (await dispatcher.RestoreModules(BicepTestConstants.BuiltInConfiguration, moduleReferences, forceModulesRestore: true)).Should().BeTrue();

            // all other modules should have succeeded
            foreach (var moduleReference in moduleReferences)
            {
                dispatcher.GetModuleRestoreStatus(moduleReference, configuration, out _).Should().Be(ModuleRestoreStatus.Succeeded);
            }
        }
Exemple #7
0
        public async Task ModuleRestoreContentionShouldProduceConsistentState()
        {
            var dataSet = DataSets.Registry_LF;

            var outputDirectory = dataSet.SaveFilesToTestDirectory(TestContext);
            var clientFactory   = dataSet.CreateMockRegistryClients(TestContext);
            var templateSpecRepositoryFactory = dataSet.CreateMockTemplateSpecRepositoryFactory(TestContext);
            await dataSet.PublishModulesToRegistryAsync(clientFactory, TestContext);

            var cacheDirectory = FileHelper.GetCacheRootPath(TestContext);

            Directory.CreateDirectory(cacheDirectory);

            var features = StrictMock.Of <IFeatureProvider>();

            features.Setup(m => m.RegistryEnabled).Returns(true);
            features.Setup(m => m.CacheRootDirectory).Returns(cacheDirectory);

            var dispatcher = new ModuleDispatcher(new DefaultModuleRegistryProvider(new FileResolver(), clientFactory, templateSpecRepositoryFactory, features.Object));

            var configuration    = BicepTestConstants.BuiltInConfigurationWithAnalyzersDisabled;
            var moduleReferences = dataSet.RegistryModules.Values
                                   .OrderBy(m => m.Metadata.Target)
                                   .Select(m => dispatcher.TryGetModuleReference(m.Metadata.Target, configuration, out _) ?? throw new AssertFailedException($"Invalid module target '{m.Metadata.Target}'."))
                                   .ToImmutableList();

            moduleReferences.Should().HaveCount(7);

            // initially the cache should be empty
            foreach (var moduleReference in moduleReferences)
            {
                dispatcher.GetModuleRestoreStatus(moduleReference, configuration, out _).Should().Be(ModuleRestoreStatus.Unknown);
            }

            const int ConcurrentTasks = 50;
            var       tasks           = new List <Task <bool> >();

            for (int i = 0; i < ConcurrentTasks; i++)
            {
                tasks.Add(Task.Run(() => dispatcher.RestoreModules(BicepTestConstants.BuiltInConfiguration, moduleReferences)));
            }

            var result = await Task.WhenAll(tasks);

            result.Should().HaveCount(ConcurrentTasks);

            // modules should now be in the cache
            foreach (var moduleReference in moduleReferences)
            {
                dispatcher.GetModuleRestoreStatus(moduleReference, configuration, out _).Should().Be(ModuleRestoreStatus.Succeeded);
            }
        }
Exemple #8
0
        private static Compilation GetCompilation(string fileContents)
        {
            var fileUri    = new Uri("inmemory:///main.bicep");
            var workspace  = new Workspace();
            var sourceFile = SourceFileFactory.CreateSourceFile(fileUri, fileContents);

            workspace.UpsertSourceFile(sourceFile);

            var fileResolver       = new FileResolver();
            var dispatcher         = new ModuleDispatcher(new EmptyModuleRegistryProvider());
            var sourceFileGrouping = SourceFileGroupingBuilder.Build(fileResolver, dispatcher, workspace, fileUri);

            return(new Compilation(resourceTypeProvider, sourceFileGrouping));
        }
        public void InvalidBicep_TemplateEmiterShouldNotProduceAnyTemplate(DataSet dataSet)
        {
            var    outputDirectory = dataSet.SaveFilesToTestDirectory(TestContext);
            var    bicepFilePath   = Path.Combine(outputDirectory, DataSet.TestFileMain);
            string filePath        = FileHelper.GetResultFilePath(this.TestContext, $"{dataSet.Name}_Compiled_Original.json");

            // emitting the template should fail
            var dispatcher    = new ModuleDispatcher(BicepTestConstants.RegistryProvider);
            var configuration = BicepTestConstants.BuiltInConfigurationWithAnalyzersDisabled;
            var result        = this.EmitTemplate(SourceFileGroupingBuilder.Build(BicepTestConstants.FileResolver, dispatcher, new Workspace(), PathHelper.FilePathToFileUrl(bicepFilePath), configuration), BicepTestConstants.EmitterSettings, filePath);

            result.Diagnostics.Should().NotBeEmpty();
            result.Status.Should().Be(EmitStatus.Failed);
        }
Exemple #10
0
        public void List_WhenCameraIdExists_AndNewCameraIdentifier_ShouldReturnDetails()
        {
            // GIVEN
            var moduleDispatcher = new ModuleDispatcher();
            var module           = new CamerasModule(moduleDispatcher);
            var cameraFileName   = _WriteCameraResourceToFile();

            // WHEN
            module.List(new string[] { cameraFileName, "315" });

            // THEN
            var expectedOutput = _ReadTextFromResourceFile("Djey.TduModdingTools.CLI.Resources.ListCameraOutput-Default.json");

            Assert.AreEqual(expectedOutput, moduleDispatcher.ModuleOutput);
        }
Exemple #11
0
        private static Compilation GetCompilation(string fileContents)
        {
            var fileUri    = new Uri("inmemory:///main.bicep");
            var workspace  = new Workspace();
            var sourceFile = SourceFileFactory.CreateSourceFile(fileUri, fileContents);

            workspace.UpsertSourceFile(sourceFile);

            var fileResolver         = new FileResolver();
            var dispatcher           = new ModuleDispatcher(new EmptyModuleRegistryProvider());
            var configurationManager = new ConfigurationManager(new IOFileSystem());
            var configuration        = configurationManager.GetBuiltInConfiguration();
            var sourceFileGrouping   = SourceFileGroupingBuilder.Build(fileResolver, dispatcher, workspace, fileUri, configuration);

            return(new Compilation(namespaceProvider, sourceFileGrouping, configuration));
        }
Exemple #12
0
        public void Create_ShouldReturnValidCompilation()
        {
            var fileUri      = DocumentUri.Parse($"/{DataSets.Parameters_LF.Name}.bicep");
            var fileResolver = CreateFileResolver(fileUri.ToUri(), DataSets.Parameters_LF.Bicep);
            var dispatcher   = new ModuleDispatcher(new DefaultModuleRegistryProvider(fileResolver));

            var provider = new BicepCompilationProvider(TestTypeHelper.CreateEmptyProvider(), fileResolver, dispatcher);

            var sourceFile = SourceFileFactory.CreateSourceFile(fileUri.ToUri(), DataSets.Parameters_LF.Bicep);
            var workspace  = new Workspace();

            workspace.UpsertSourceFile(sourceFile);
            var context = provider.Create(workspace, fileUri, ImmutableDictionary <ISourceFile, ISemanticModel> .Empty);

            context.Compilation.Should().NotBeNull();
            // TODO: remove Where when the support of modifiers is dropped.
            context.Compilation.GetEntrypointSemanticModel().GetAllDiagnostics(new ConfigHelper().GetDisabledLinterConfig()).Should().BeEmpty();
            context.LineStarts.Should().NotBeEmpty();
            context.LineStarts[0].Should().Be(0);
        }
Exemple #13
0
        protected static IEnumerable <string> GetAllDiagnostics(string bicepFilePath)
        {
            var dispatcher         = new ModuleDispatcher(new DefaultModuleRegistryProvider(BicepTestConstants.FileResolver));
            var sourceFileGrouping = SourceFileGroupingBuilder.Build(BicepTestConstants.FileResolver, dispatcher, new Workspace(), PathHelper.FilePathToFileUrl(bicepFilePath));
            var compilation        = new Compilation(TestTypeHelper.CreateEmptyProvider(), sourceFileGrouping);

            var output = new List <string>();

            foreach (var(bicepFile, diagnostics) in compilation.GetAllDiagnosticsByBicepFile())
            {
                foreach (var diagnostic in diagnostics)
                {
                    var(line, character) = TextCoordinateConverter.GetPosition(bicepFile.LineStarts, diagnostic.Span.Position);
                    var codeDescription = diagnostic.Uri == null ? string.Empty : $" [{diagnostic.Uri.AbsoluteUri}]";
                    output.Add($"{bicepFile.FileUri.LocalPath}({line + 1},{character + 1}) : {diagnostic.Level} {diagnostic.Code}: {diagnostic.Message}{codeDescription}");
                }
            }

            return(output);
        }
Exemple #14
0
        public void ValidBicep_TemplateEmiterShouldProduceExpectedTemplate(DataSet dataSet)
        {
            var outputDirectory  = dataSet.SaveFilesToTestDirectory(TestContext);
            var bicepFilePath    = Path.Combine(outputDirectory, DataSet.TestFileMain);
            var compiledFilePath = FileHelper.GetResultFilePath(this.TestContext, Path.Combine(dataSet.Name, DataSet.TestFileMainCompiled));

            // emitting the template should be successful
            var dispatcher = new ModuleDispatcher(new DefaultModuleRegistryProvider(BicepTestConstants.FileResolver));
            var result     = this.EmitTemplate(SourceFileGroupingBuilder.Build(BicepTestConstants.FileResolver, dispatcher, new Workspace(), PathHelper.FilePathToFileUrl(bicepFilePath)), compiledFilePath, BicepTestConstants.DevAssemblyFileVersion);

            result.Diagnostics.Should().NotHaveErrors();
            result.Status.Should().Be(EmitStatus.Succeeded);

            var actual = JToken.Parse(File.ReadAllText(compiledFilePath));

            actual.Should().EqualWithJsonDiffOutput(
                TestContext,
                JToken.Parse(dataSet.Compiled !),
                expectedLocation: DataSet.GetBaselineUpdatePath(dataSet, DataSet.TestFileMainCompiled),
                actualLocation: compiledFilePath);
        }
Exemple #15
0
        /// <summary>
        /// Unique entry point for command line application.
        /// </summary>
        /// <param name="args"></param>
        internal static int Main(string[] args)
        {
            try {
                ValidateCommandLineArguments(args);
            } catch (ArgumentException ae) {
                Console.Error.WriteLine(ae);
                return(1);
            }

            var dispatcher = new ModuleDispatcher();

            try {
                dispatcher.Dispatch(args [0], ArgsToCommandArgs(args));
            } catch (Exception e) {
                Console.Error.WriteLine(e);
                return(1);
            }

            Console.WriteLine(dispatcher.ModuleOutput);
            return(0);
        }
Exemple #16
0
        public void Create_ShouldReturnValidCompilation()
        {
            var fileUri      = DocumentUri.Parse($"/{DataSets.Parameters_LF.Name}.bicep");
            var fileResolver = CreateFileResolver(fileUri.ToUri(), DataSets.Parameters_LF.Bicep);
            var dispatcher   = new ModuleDispatcher(new DefaultModuleRegistryProvider(fileResolver, BicepTestConstants.ClientFactory, BicepTestConstants.TemplateSpecRepositoryFactory, BicepTestConstants.Features));

            var provider = new BicepCompilationProvider(BicepTestConstants.Features, TestTypeHelper.CreateWithAzTypes(), fileResolver, dispatcher);

            var sourceFile = SourceFileFactory.CreateSourceFile(fileUri.ToUri(), DataSets.Parameters_LF.Bicep);
            var workspace  = new Workspace();

            workspace.UpsertSourceFile(sourceFile);
            var configuration = BicepTestConstants.BuiltInConfigurationWithAnalyzersDisabled;
            var context       = provider.Create(workspace, fileUri, ImmutableDictionary <ISourceFile, ISemanticModel> .Empty, configuration, new LinterAnalyzer(configuration));

            context.Compilation.Should().NotBeNull();
            // TODO: remove Where when the support of modifiers is dropped.
            context.Compilation.GetEntrypointSemanticModel().GetAllDiagnostics().Should().BeEmpty();
            context.LineStarts.Should().NotBeEmpty();
            context.LineStarts[0].Should().Be(0);
        }
        public static async Task <(Compilation compilation, string outputDirectory, Uri fileUri)> SetupPrerequisitesAndCreateCompilation(this DataSet dataSet, TestContext testContext)
        {
            var features        = BicepTestConstants.CreateFeaturesProvider(testContext, registryEnabled: dataSet.HasExternalModules);
            var outputDirectory = dataSet.SaveFilesToTestDirectory(testContext);
            var clientFactory   = dataSet.CreateMockRegistryClients(testContext);
            await dataSet.PublishModulesToRegistryAsync(clientFactory, testContext);

            var templateSpecRepositoryFactory = dataSet.CreateMockTemplateSpecRepositoryFactory(testContext);
            var fileUri            = PathHelper.FilePathToFileUrl(Path.Combine(outputDirectory, DataSet.TestFileMain));
            var dispatcher         = new ModuleDispatcher(new DefaultModuleRegistryProvider(BicepTestConstants.FileResolver, clientFactory, templateSpecRepositoryFactory, features));
            var workspace          = new Workspace();
            var namespaceProvider  = new DefaultNamespaceProvider(new AzResourceTypeLoader(), features);
            var configuration      = BicepTestConstants.ConfigurationManager.GetConfiguration(fileUri);
            var sourceFileGrouping = SourceFileGroupingBuilder.Build(BicepTestConstants.FileResolver, dispatcher, workspace, fileUri, configuration);

            if (await dispatcher.RestoreModules(configuration, dispatcher.GetValidModuleReferences(sourceFileGrouping.ModulesToRestore, configuration)))
            {
                sourceFileGrouping = SourceFileGroupingBuilder.Rebuild(dispatcher, workspace, sourceFileGrouping, configuration);
            }

            return(new Compilation(namespaceProvider, sourceFileGrouping, configuration, new LinterAnalyzer(configuration)), outputDirectory, fileUri);
        }
Exemple #18
0
        public async Task ValidBicep_EmitTemplate_should_produce_expected_symbolicname_template(DataSet dataSet)
        {
            var outputDirectory = dataSet.SaveFilesToTestDirectory(TestContext);
            var clientFactory   = dataSet.CreateMockRegistryClients(TestContext);
            var templateSpecRepositoryFactory = dataSet.CreateMockTemplateSpecRepositoryFactory(TestContext);
            await dataSet.PublishModulesToRegistryAsync(clientFactory, TestContext);

            var bicepFilePath    = Path.Combine(outputDirectory, DataSet.TestFileMain);
            var bicepFileUri     = PathHelper.FilePathToFileUrl(bicepFilePath);
            var compiledFilePath = FileHelper.GetResultFilePath(this.TestContext, Path.Combine(dataSet.Name, DataSet.TestFileMainCompiledWithSymbolicNames));
            var configuration    = BicepTestConstants.ConfigurationManager.GetConfiguration(bicepFileUri);

            // emitting the template should be successful
            var       dispatcher         = new ModuleDispatcher(new DefaultModuleRegistryProvider(BicepTestConstants.FileResolver, clientFactory, templateSpecRepositoryFactory, BicepTestConstants.CreateFeaturesProvider(TestContext, registryEnabled: dataSet.HasRegistryModules)));
            Workspace workspace          = new();
            var       sourceFileGrouping = SourceFileGroupingBuilder.Build(BicepTestConstants.FileResolver, dispatcher, workspace, bicepFileUri, configuration);

            if (await dispatcher.RestoreModules(configuration, dispatcher.GetValidModuleReferences(sourceFileGrouping.ModulesToRestore, configuration)))
            {
                sourceFileGrouping = SourceFileGroupingBuilder.Rebuild(dispatcher, workspace, sourceFileGrouping, configuration);
            }

            var result = this.EmitTemplate(sourceFileGrouping, BicepTestConstants.EmitterSettingsWithSymbolicNames, compiledFilePath);

            result.Diagnostics.Should().NotHaveErrors();
            result.Status.Should().Be(EmitStatus.Succeeded);

            var outputFile = File.ReadAllText(compiledFilePath);
            var actual     = JToken.Parse(outputFile);

            actual.Should().EqualWithJsonDiffOutput(
                TestContext,
                JToken.Parse(dataSet.CompiledWithSymbolicNames !),
                expectedLocation: DataSet.GetBaselineUpdatePath(dataSet, DataSet.TestFileMainCompiledWithSymbolicNames),
                actualLocation: compiledFilePath);

            // validate that the template is parseable by the deployment engine
            TemplateHelper.TemplateShouldBeValid(outputFile);
        }
Exemple #19
0
        public async Task ValidBicepTextWriter_TemplateEmiterShouldProduceExpectedTemplate(DataSet dataSet)
        {
            var outputDirectory = dataSet.SaveFilesToTestDirectory(TestContext);
            var clientFactory   = dataSet.CreateMockRegistryClients(TestContext);
            var templateSpecRepositoryFactory = dataSet.CreateMockTemplateSpecRepositoryFactory(TestContext);
            await dataSet.PublishModulesToRegistryAsync(clientFactory, TestContext);

            var          bicepFilePath = Path.Combine(outputDirectory, DataSet.TestFileMain);
            var          bicepFileUri  = PathHelper.FilePathToFileUrl(bicepFilePath);
            MemoryStream memoryStream  = new MemoryStream();

            // emitting the template should be successful
            var dispatcher         = new ModuleDispatcher(new DefaultModuleRegistryProvider(BicepTestConstants.FileResolver, clientFactory, templateSpecRepositoryFactory, BicepTestConstants.CreateFeaturesProvider(TestContext, registryEnabled: dataSet.HasExternalModules)));
            var workspace          = new Workspace();
            var configuration      = BicepTestConstants.ConfigurationManager.GetConfiguration(bicepFileUri);
            var sourceFileGrouping = SourceFileGroupingBuilder.Build(BicepTestConstants.FileResolver, dispatcher, workspace, PathHelper.FilePathToFileUrl(bicepFilePath), configuration);

            if (await dispatcher.RestoreModules(configuration, dispatcher.GetValidModuleReferences(sourceFileGrouping.ModulesToRestore, configuration)))
            {
                sourceFileGrouping = SourceFileGroupingBuilder.Rebuild(dispatcher, workspace, sourceFileGrouping, configuration);
            }

            var result = this.EmitTemplate(sourceFileGrouping, BicepTestConstants.EmitterSettings, memoryStream);

            result.Diagnostics.Should().NotHaveErrors();
            result.Status.Should().Be(EmitStatus.Succeeded);

            // normalizing the formatting in case there are differences in indentation
            // this way the diff between actual and expected will be clean
            var actual           = JToken.ReadFrom(new JsonTextReader(new StreamReader(new MemoryStream(memoryStream.ToArray()))));
            var compiledFilePath = FileHelper.SaveResultFile(this.TestContext, Path.Combine(dataSet.Name, DataSet.TestFileMainCompiled), actual.ToString(Formatting.Indented));

            actual.Should().EqualWithJsonDiffOutput(
                TestContext,
                JToken.Parse(dataSet.Compiled !),
                expectedLocation: DataSet.GetBaselineUpdatePath(dataSet, DataSet.TestFileMainCompiled),
                actualLocation: compiledFilePath);
        }
Exemple #20
0
 public BanksModule(ModuleDispatcher moduleDispatcher)
 {
     _moduleDispatcher = moduleDispatcher;
 }
Exemple #21
0
        public async Task ModuleRestoreWithStuckFileLockShouldFailAfterTimeout(IEnumerable <ExternalModuleInfo> moduleInfos, int moduleCount)
        {
            var dataSet = DataSets.Registry_LF;

            var outputDirectory = dataSet.SaveFilesToTestDirectory(TestContext);
            var clientFactory   = dataSet.CreateMockRegistryClients(TestContext);
            var templateSpecRepositoryFactory = dataSet.CreateMockTemplateSpecRepositoryFactory(TestContext);
            await dataSet.PublishModulesToRegistryAsync(clientFactory, TestContext);

            var cacheDirectory = FileHelper.GetCacheRootPath(TestContext);

            Directory.CreateDirectory(cacheDirectory);

            var features = StrictMock.Of <IFeatureProvider>();

            features.Setup(m => m.RegistryEnabled).Returns(true);
            features.Setup(m => m.CacheRootDirectory).Returns(cacheDirectory);

            FileResolver fileResolver = new FileResolver();
            var          dispatcher   = new ModuleDispatcher(new DefaultModuleRegistryProvider(fileResolver, clientFactory, templateSpecRepositoryFactory, features.Object));

            var configuration    = BicepTestConstants.BuiltInConfigurationWithAnalyzersDisabled;
            var moduleReferences = moduleInfos
                                   .OrderBy(m => m.Metadata.Target)
                                   .Select(m => dispatcher.TryGetModuleReference(m.Metadata.Target, configuration, out _) ?? throw new AssertFailedException($"Invalid module target '{m.Metadata.Target}'."))
                                   .ToImmutableList();

            moduleReferences.Should().HaveCount(moduleCount);

            // initially the cache should be empty
            foreach (var moduleReference in moduleReferences)
            {
                dispatcher.GetModuleRestoreStatus(moduleReference, configuration, out _).Should().Be(ModuleRestoreStatus.Unknown);
            }

            var moduleFileUri = dispatcher.TryGetLocalModuleEntryPointUri(new Uri("file://main.bicep"), moduleReferences[0], configuration, out _) !;

            moduleFileUri.Should().NotBeNull();

            var moduleFilePath  = moduleFileUri.LocalPath;
            var moduleDirectory = Path.GetDirectoryName(moduleFilePath) !;

            Directory.CreateDirectory(moduleDirectory);

            var lockFileName = Path.Combine(moduleDirectory, "lock");
            var lockFileUri  = new Uri(lockFileName);

            var @lock = fileResolver.TryAcquireFileLock(lockFileUri);

            @lock.Should().NotBeNull();

            // let's try to restore a module while holding a lock
            using (@lock)
            {
                (await dispatcher.RestoreModules(BicepTestConstants.BuiltInConfiguration, moduleReferences)).Should().BeTrue();
            }

            // the first module should have failed due to a timeout
            dispatcher.GetModuleRestoreStatus(moduleReferences[0], configuration, out var failureBuilder).Should().Be(ModuleRestoreStatus.Failed);
            using (new AssertionScope())
            {
                failureBuilder !.Should().HaveCode("BCP192");
                failureBuilder !.Should().HaveMessageStartWith($"Unable to restore the module with reference \"{moduleReferences[0].FullyQualifiedReference}\": Exceeded the timeout of \"00:00:05\" to acquire the lock on file \"");
            }

            // all other modules should have succeeded
            foreach (var moduleReference in moduleReferences.Skip(1))
            {
                dispatcher.GetModuleRestoreStatus(moduleReference, configuration, out _).Should().Be(ModuleRestoreStatus.Succeeded);
            }
        }
Exemple #22
0
        public async Task InvalidRootCachePathShouldProduceReasonableErrors()
        {
            var dataSet = DataSets.Registry_LF;

            var outputDirectory = dataSet.SaveFilesToTestDirectory(TestContext);
            var clientFactory   = dataSet.CreateMockRegistryClients(TestContext);
            var templateSpecRepositoryFactory = dataSet.CreateMockTemplateSpecRepositoryFactory(TestContext);
            await dataSet.PublishModulesToRegistryAsync(clientFactory, TestContext);

            var fileUri = PathHelper.FilePathToFileUrl(Path.Combine(outputDirectory, DataSet.TestFileMain));

            var badCacheDirectory = FileHelper.GetCacheRootPath(TestContext);

            Directory.CreateDirectory(badCacheDirectory);

            var badCachePath = Path.Combine(badCacheDirectory, "file.txt");

            File.Create(badCachePath);
            File.Exists(badCachePath).Should().BeTrue();

            // cache root points to a file
            var features = new Mock <IFeatureProvider>(MockBehavior.Strict);

            features.Setup(m => m.RegistryEnabled).Returns(true);
            features.SetupGet(m => m.CacheRootDirectory).Returns(badCachePath);

            var dispatcher = new ModuleDispatcher(new DefaultModuleRegistryProvider(BicepTestConstants.FileResolver, clientFactory, templateSpecRepositoryFactory, features.Object));

            var workspace          = new Workspace();
            var configuration      = BicepTestConstants.ConfigurationManager.GetConfiguration(fileUri);
            var sourceFileGrouping = SourceFileGroupingBuilder.Build(BicepTestConstants.FileResolver, dispatcher, workspace, fileUri, configuration);

            if (await dispatcher.RestoreModules(configuration, dispatcher.GetValidModuleReferences(sourceFileGrouping.ModulesToRestore, configuration)))
            {
                sourceFileGrouping = SourceFileGroupingBuilder.Rebuild(dispatcher, workspace, sourceFileGrouping, configuration);
            }

            var compilation = new Compilation(BicepTestConstants.Features, BicepTestConstants.NamespaceProvider, sourceFileGrouping, configuration, BicepTestConstants.LinterAnalyzer);
            var diagnostics = compilation.GetAllDiagnosticsByBicepFile();

            diagnostics.Should().HaveCount(1);

            diagnostics.Single().Value.ExcludingLinterDiagnostics().Should().SatisfyRespectively(
                x =>
            {
                x.Level.Should().Be(DiagnosticLevel.Error);
                x.Code.Should().Be("BCP192");
                x.Message.Should().StartWith("Unable to restore the module with reference \"br:mock-registry-one.invalid/demo/plan:v2\": Unable to create the local module directory \"");
            },
                x =>
            {
                x.Level.Should().Be(DiagnosticLevel.Error);
                x.Code.Should().Be("BCP192");
                x.Message.Should().StartWith("Unable to restore the module with reference \"br:mock-registry-one.invalid/demo/plan:v2\": Unable to create the local module directory \"");
            },
                x =>
            {
                x.Level.Should().Be(DiagnosticLevel.Error);
                x.Code.Should().Be("BCP192");
                x.Message.Should().StartWith("Unable to restore the module with reference \"br:mock-registry-two.invalid/demo/site:v3\": Unable to create the local module directory \"");
            },
                x =>
            {
                x.Level.Should().Be(DiagnosticLevel.Error);
                x.Code.Should().Be("BCP192");
                x.Message.Should().StartWith("Unable to restore the module with reference \"br:mock-registry-two.invalid/demo/site:v3\": Unable to create the local module directory \"");
            },
                x =>
            {
                x.Level.Should().Be(DiagnosticLevel.Error);
                x.Code.Should().Be("BCP192");
                x.Message.Should().StartWith("Unable to restore the module with reference \"ts:00000000-0000-0000-0000-000000000000/test-rg/storage-spec:1.0\": Unable to create the local module directory \"");
            },
                x =>
            {
                x.Level.Should().Be(DiagnosticLevel.Error);
                x.Code.Should().Be("BCP192");
                x.Message.Should().StartWith("Unable to restore the module with reference \"ts:00000000-0000-0000-0000-000000000000/test-rg/storage-spec:1.0\": Unable to create the local module directory \"");
            },
                x =>
            {
                x.Level.Should().Be(DiagnosticLevel.Error);
                x.Code.Should().Be("BCP192");
                x.Message.Should().StartWith("Unable to restore the module with reference \"ts:11111111-1111-1111-1111-111111111111/prod-rg/vnet-spec:v2\": Unable to create the local module directory \"");
            },
                x =>
            {
                x.Level.Should().Be(DiagnosticLevel.Error);
                x.Code.Should().Be("BCP062");
                x.Message.Should().Be("The referenced declaration with name \"siteDeploy\" is not valid.");
            },
                x =>
            {
                x.Level.Should().Be(DiagnosticLevel.Error);
                x.Code.Should().Be("BCP192");
                x.Message.Should().StartWith("Unable to restore the module with reference \"br:localhost:5000/passthrough/port:v1\": Unable to create the local module directory \"");
            },
                x =>
            {
                x.Level.Should().Be(DiagnosticLevel.Error);
                x.Code.Should().Be("BCP192");
                x.Message.Should().StartWith("Unable to restore the module with reference \"br:127.0.0.1/passthrough/ipv4:v1\": Unable to create the local module directory \"");
            },
                x =>
            {
                x.Level.Should().Be(DiagnosticLevel.Error);
                x.Code.Should().Be("BCP192");
                x.Message.Should().StartWith("Unable to restore the module with reference \"br:127.0.0.1:5000/passthrough/ipv4port:v1\": Unable to create the local module directory \"");
            },
                x =>
            {
                x.Level.Should().Be(DiagnosticLevel.Error);
                x.Code.Should().Be("BCP192");
                x.Message.Should().StartWith("Unable to restore the module with reference \"br:[::1]/passthrough/ipv6:v1\": Unable to create the local module directory \"");
            },
                x =>
            {
                x.Level.Should().Be(DiagnosticLevel.Error);
                x.Code.Should().Be("BCP192");
                x.Message.Should().StartWith("Unable to restore the module with reference \"br:[::1]:5000/passthrough/ipv6port:v1\": Unable to create the local module directory \"");
            });
        }
Exemple #23
0
 public CamerasModule(ModuleDispatcher moduleDispatcher)
 {
     _moduleDispatcher = moduleDispatcher;
 }