public async Task Restore_ShouldSucceed(DataSet dataSet) { var clientFactory = dataSet.CreateMockRegistryClients(TestContext); var templateSpecRepositoryFactory = dataSet.CreateMockTemplateSpecRepositoryFactory(TestContext); var outputDirectory = dataSet.SaveFilesToTestDirectory(TestContext); await dataSet.PublishModulesToRegistryAsync(clientFactory, TestContext); var bicepFilePath = Path.Combine(outputDirectory, DataSet.TestFileMain); var settings = new InvocationSettings(BicepTestConstants.CreateFeaturesProvider(TestContext, registryEnabled: dataSet.HasExternalModules), clientFactory, templateSpecRepositoryFactory); TestContext.WriteLine($"Cache root = {settings.Features.CacheRootDirectory}"); var(output, error, result) = await Bicep(settings, "restore", bicepFilePath); using (new AssertionScope()) { result.Should().Be(0); output.Should().BeEmpty(); error.Should().BeEmpty(); } if (dataSet.HasExternalModules) { // ensure something got restored settings.Features.Should().HaveValidModules(); } }
public async Task Publish_AggregateExceptionWithInnerRequestFailedExceptions_ShouldFail() { var dataSet = DataSets.Empty; var outputDirectory = dataSet.SaveFilesToTestDirectory(TestContext); var compiledFilePath = Path.Combine(outputDirectory, DataSet.TestFileMainCompiled); var client = StrictMock.Of <ContainerRegistryBlobClient>(); client .Setup(m => m.UploadBlobAsync(It.IsAny <Stream>(), It.IsAny <CancellationToken>())) .ThrowsAsync(new AggregateException(new RequestFailedException("Mock registry request failure 1."), new RequestFailedException("Mock registry request failure 2."))); var clientFactory = StrictMock.Of <IContainerRegistryClientFactory>(); clientFactory .Setup(m => m.CreateAuthenticatedBlobClient(It.IsAny <RootConfiguration>(), new Uri("https://fake"), "fake")) .Returns(client.Object); var templateSpecRepositoryFactory = StrictMock.Of <ITemplateSpecRepositoryFactory>(); var settings = new InvocationSettings(BicepTestConstants.CreateFeaturesProvider(TestContext, registryEnabled: true), clientFactory.Object, templateSpecRepositoryFactory.Object); var(output, error, result) = await Bicep(settings, "publish", compiledFilePath, "--target", "br:fake/fake:v1"); using (new AssertionScope()) { error.Should().StartWith("Unable to publish module \"br:fake/fake:v1\": One or more errors occurred. (Mock registry request failure 1.) (Mock registry request failure 2.)"); output.Should().BeEmpty(); result.Should().Be(1); } }
public async Task Restore_ByDigest_ShouldSucceed() { var registry = "example.com"; var registryUri = new Uri("https://" + registry); var repository = "hello/there"; var client = new MockRegistryBlobClient(); var clientFactory = StrictMock.Of <IContainerRegistryClientFactory>(); clientFactory.Setup(m => m.CreateAuthenticatedBlobClient(It.IsAny <RootConfiguration>(), registryUri, repository)).Returns(client); var templateSpecRepositoryFactory = BicepTestConstants.TemplateSpecRepositoryFactory; var settings = new InvocationSettings(BicepTestConstants.CreateFeaturesProvider(TestContext, registryEnabled: true), clientFactory.Object, BicepTestConstants.TemplateSpecRepositoryFactory); var tempDirectory = FileHelper.GetUniqueTestOutputPath(TestContext); Directory.CreateDirectory(tempDirectory); var publishedBicepFilePath = Path.Combine(tempDirectory, "published.bicep"); File.WriteAllText(publishedBicepFilePath, string.Empty); var(publishOutput, publishError, publishResult) = await Bicep(settings, "publish", publishedBicepFilePath, "--target", $"br:{registry}/{repository}:v1"); using (new AssertionScope()) { publishResult.Should().Be(0); publishOutput.Should().BeEmpty(); publishError.Should().BeEmpty(); } client.Blobs.Should().HaveCount(2); client.Manifests.Should().HaveCount(1); client.ManifestTags.Should().HaveCount(1); string digest = client.Manifests.Single().Key; var bicep = $@" module empty 'br:{registry}/{repository}@{digest}' = {{ name: 'empty' }} "; var restoreBicepFilePath = Path.Combine(tempDirectory, "restored.bicep"); File.WriteAllText(restoreBicepFilePath, bicep); var(output, error, result) = await Bicep(settings, "restore", restoreBicepFilePath); using (new AssertionScope()) { result.Should().Be(0); output.Should().BeEmpty(); error.Should().BeEmpty(); } }
public async Task Publish_OciDigestTarget_ShouldProduceExpectedError() { var settings = new InvocationSettings(BicepTestConstants.CreateFeaturesProvider(TestContext, registryEnabled: true), BicepTestConstants.ClientFactory, BicepTestConstants.TemplateSpecRepositoryFactory); var(output, error, result) = await Bicep(settings, "publish", "WrongFile.bicep", "--target", "br:example.com/test@sha256:80f63ced0b80b63874c808a321f472755a3c9e93987d1fa0a51e13c65e4a52b9"); result.Should().Be(1); output.Should().BeEmpty(); error.Should().Contain("The specified module target \"br:example.com/test@sha256:80f63ced0b80b63874c808a321f472755a3c9e93987d1fa0a51e13c65e4a52b9\" is not supported."); }
public async Task Publish_InvalidInputFile_ShouldProduceExpectedError() { var settings = new InvocationSettings(BicepTestConstants.CreateFeaturesProvider(TestContext, registryEnabled: true), BicepTestConstants.ClientFactory, BicepTestConstants.TemplateSpecRepositoryFactory); var(output, error, result) = await Bicep(settings, "publish", "WrongFile.bicep", "--target", "br:example.azurecr.io/hello/there:v1"); result.Should().Be(1); output.Should().BeEmpty(); error.Should().MatchRegex(@"An error occurred reading file\. Could not find file '.+WrongFile.bicep'\."); }
public async Task Build_Valid_SingleFile_After_Restore_Should_Succeed(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 settings = new InvocationSettings(BicepTestConstants.CreateFeaturesProvider(TestContext, registryEnabled: dataSet.HasExternalModules), clientFactory, templateSpecRepositoryFactory); var(restoreOutput, restoreError, restoreResult) = await Bicep(settings, "restore", bicepFilePath); using (new AssertionScope()) { restoreResult.Should().Be(0); restoreOutput.Should().BeEmpty(); restoreError.Should().BeEmpty(); } // run restore with the same feature settings, so it will use the mock local module cache // but break the client to ensure no outgoing calls are made var settingsWithBrokenClient = settings with { ClientFactory = Repository.Create <IContainerRegistryClientFactory>().Object }; var(output, error, result) = await Bicep(settingsWithBrokenClient, "build", "--stdout", "--no-restore", bicepFilePath); using (new AssertionScope()) { result.Should().Be(0); output.Should().NotBeEmpty(); AssertNoErrors(error); } var compiledFilePath = Path.Combine(outputDirectory, DataSet.TestFileMainCompiled); File.Exists(compiledFilePath).Should().BeTrue(); var actual = JToken.Parse(output); actual.Should().EqualWithJsonDiffOutput( TestContext, JToken.Parse(dataSet.Compiled !), expectedLocation: Path.Combine("src", "Bicep.Core.Samples", "Files", dataSet.Name, DataSet.TestFileMainCompiled), actualLocation: compiledFilePath); }
public async Task Publish_InvalidFile_ShouldFail_WithExpectedErrorMessage(DataSet dataSet) { var outputDirectory = dataSet.SaveFilesToTestDirectory(TestContext); var bicepFilePath = Path.Combine(outputDirectory, DataSet.TestFileMain); // publish won't actually happen, so broken client factory is fine var settings = new InvocationSettings(BicepTestConstants.CreateFeaturesProvider(TestContext, registryEnabled: true), BicepTestConstants.ClientFactory, BicepTestConstants.TemplateSpecRepositoryFactory); var diagnostics = GetAllDiagnostics(bicepFilePath, settings.ClientFactory, settings.TemplateSpecRepositoryFactory); var(output, error, result) = await Bicep(settings, "publish", bicepFilePath, "--target", $"br:example.com/fail/{dataSet.Name.ToLowerInvariant()}:v1"); using (new AssertionScope()) { result.Should().Be(1); output.Should().BeEmpty(); error.Should().ContainAll(diagnostics); } }
public async Task Publish_ValidFile_ShouldSucceed(DataSet dataSet) { var outputDirectory = dataSet.SaveFilesToTestDirectory(TestContext); var registryStr = "example.com"; var registryUri = new Uri($"https://{registryStr}"); var repository = $"test/{dataSet.Name}".ToLowerInvariant(); var clientFactory = dataSet.CreateMockRegistryClients(TestContext, (registryUri, repository)); var templateSpecRepositoryFactory = dataSet.CreateMockTemplateSpecRepositoryFactory(TestContext); await dataSet.PublishModulesToRegistryAsync(clientFactory, TestContext); var bicepFilePath = Path.Combine(outputDirectory, DataSet.TestFileMain); var compiledFilePath = Path.Combine(outputDirectory, DataSet.TestFileMainCompiled); // mock client factory caches the clients var testClient = (MockRegistryBlobClient)clientFactory.CreateAuthenticatedBlobClient(BicepTestConstants.BuiltInConfiguration, registryUri, repository); var settings = new InvocationSettings(BicepTestConstants.CreateFeaturesProvider(TestContext, registryEnabled: true), clientFactory, templateSpecRepositoryFactory); var(output, error, result) = await Bicep(settings, "publish", bicepFilePath, "--target", $"br:{registryStr}/{repository}:v1"); result.Should().Be(0); output.Should().BeEmpty(); AssertNoErrors(error); using var expectedCompiledStream = new FileStream(compiledFilePath, FileMode.Open, FileAccess.Read); // verify the module was published testClient.Should().OnlyHaveModule("v1", expectedCompiledStream); // publish the same content again var(output2, error2, result2) = await Bicep(settings, "publish", bicepFilePath, "--target", $"br:{registryStr}/{repository}:v1"); result2.Should().Be(0); output2.Should().BeEmpty(); AssertNoErrors(error2); // we should still only have 1 module expectedCompiledStream.Position = 0; testClient.Should().OnlyHaveModule("v1", expectedCompiledStream); }
public async Task Restore_NonExistentModules_ShouldFail(DataSet dataSet) { var clientFactory = dataSet.CreateMockRegistryClients(TestContext); var templateSpecRepositoryFactory = dataSet.CreateMockTemplateSpecRepositoryFactory(TestContext); var outputDirectory = dataSet.SaveFilesToTestDirectory(TestContext); // do not publish modules to the registry var bicepFilePath = Path.Combine(outputDirectory, DataSet.TestFileMain); var settings = new InvocationSettings(BicepTestConstants.CreateFeaturesProvider(TestContext, registryEnabled: dataSet.HasExternalModules), clientFactory, templateSpecRepositoryFactory); TestContext.WriteLine($"Cache root = {settings.Features.CacheRootDirectory}"); var(output, error, result) = await Bicep(settings, "restore", bicepFilePath); using (new AssertionScope()) { result.Should().Be(1); output.Should().BeEmpty(); error.Should().ContainAll(": Error BCP192: Unable to restore the module with reference ", "The module does not exist in the registry."); } }
public async Task Build_Valid_SingleFile_ShouldSucceed(DataSet dataSet) { var clientFactory = dataSet.CreateMockRegistryClients(TestContext); var templateSpecRepositoryFactory = dataSet.CreateMockTemplateSpecRepositoryFactory(TestContext); var outputDirectory = dataSet.SaveFilesToTestDirectory(TestContext); await dataSet.PublishModulesToRegistryAsync(clientFactory, TestContext); var bicepFilePath = Path.Combine(outputDirectory, DataSet.TestFileMain); var settings = new InvocationSettings(BicepTestConstants.CreateFeaturesProvider(TestContext, registryEnabled: dataSet.HasExternalModules), clientFactory, templateSpecRepositoryFactory); var(output, error, result) = await Bicep(settings, "build", bicepFilePath); using (new AssertionScope()) { result.Should().Be(0); output.Should().BeEmpty(); AssertNoErrors(error); } if (dataSet.HasExternalModules) { // ensure something got restored Directory.Exists(settings.Features.CacheRootDirectory).Should().BeTrue(); Directory.EnumerateFiles(settings.Features.CacheRootDirectory, "*.json", SearchOption.AllDirectories).Should().NotBeEmpty(); } var compiledFilePath = Path.Combine(outputDirectory, DataSet.TestFileMainCompiled); File.Exists(compiledFilePath).Should().BeTrue(); var actual = JToken.Parse(File.ReadAllText(compiledFilePath)); actual.Should().EqualWithJsonDiffOutput( TestContext, JToken.Parse(dataSet.Compiled !), expectedLocation: Path.Combine("src", "Bicep.Core.Samples", "Files", dataSet.Name, DataSet.TestFileMainCompiled), actualLocation: compiledFilePath); }
public async Task Restore_RequestFailedException_ShouldFail() { var dataSet = DataSets.Registry_LF; var outputDirectory = FileHelper.GetUniqueTestOutputPath(TestContext); Directory.CreateDirectory(outputDirectory); var compiledFilePath = Path.Combine(outputDirectory, "main.bicep"); File.WriteAllText(compiledFilePath, @"module foo 'br:fake/fake:v1'"); var client = StrictMock.Of <ContainerRegistryBlobClient>(); client .Setup(m => m.DownloadManifestAsync(It.IsAny <DownloadManifestOptions>(), It.IsAny <CancellationToken>())) .ThrowsAsync(new RequestFailedException("Mock registry request failure.")); var clientFactory = StrictMock.Of <IContainerRegistryClientFactory>(); clientFactory .Setup(m => m.CreateAuthenticatedBlobClient(It.IsAny <RootConfiguration>(), new Uri("https://fake"), "fake")) .Returns(client.Object); var templateSpecRepositoryFactory = StrictMock.Of <ITemplateSpecRepositoryFactory>(); var settings = new InvocationSettings(BicepTestConstants.CreateFeaturesProvider(TestContext, registryEnabled: true), clientFactory.Object, templateSpecRepositoryFactory.Object); var(output, error, result) = await Bicep(settings, "restore", compiledFilePath); using (new AssertionScope()) { result.Should().Be(1); output.Should().BeEmpty(); error.Should().Contain("main.bicep(1,12) : Error BCP192: Unable to restore the module with reference \"br:fake/fake:v1\": Mock registry request failure."); } }