diff --git a/src/Bicep.Core.IntegrationTests/Files/RegistryProviderTests/HttpProvider/types/index.json b/src/Bicep.Core.IntegrationTests/Files/RegistryProviderTests/HttpProvider/types/index.json new file mode 100644 index 00000000000..65460fac59c --- /dev/null +++ b/src/Bicep.Core.IntegrationTests/Files/RegistryProviderTests/HttpProvider/types/index.json @@ -0,0 +1 @@ +{"Resources":{"request@v1":{"RelativePath":"v1/types.json","Index":12}},"Functions":{}} \ No newline at end of file diff --git a/src/Bicep.Core.IntegrationTests/Files/RegistryProviderTests/HttpProvider/types/v1/types.json b/src/Bicep.Core.IntegrationTests/Files/RegistryProviderTests/HttpProvider/types/v1/types.json new file mode 100644 index 00000000000..49d1d686c4d --- /dev/null +++ b/src/Bicep.Core.IntegrationTests/Files/RegistryProviderTests/HttpProvider/types/v1/types.json @@ -0,0 +1 @@ +[{"1":{"Kind":1}},{"1":{"Kind":2}},{"1":{"Kind":3}},{"1":{"Kind":4}},{"1":{"Kind":5}},{"1":{"Kind":6}},{"1":{"Kind":7}},{"1":{"Kind":8}},{"6":{"Value":"raw"}},{"6":{"Value":"json"}},{"5":{"Elements":[8,9]}},{"2":{"Name":"request@v1","Properties":{"uri":{"Type":4,"Flags":1,"Description":"The HTTP request URI to submit a GET request to."},"format":{"Type":10,"Flags":0,"Description":"How to deserialize the response body."},"method":{"Type":4,"Flags":0,"Description":"The HTTP method to submit request to the given URI."},"statusCode":{"Type":3,"Flags":2,"Description":"The status code of the HTTP request."},"body":{"Type":0,"Flags":2,"Description":"The parsed request bodyz."}}}},{"4":{"Name":"request@v1","ScopeType":0,"Body":11,"Flags":0}}] \ No newline at end of file diff --git a/src/Bicep.Core.IntegrationTests/RegistryProviderTests.cs b/src/Bicep.Core.IntegrationTests/RegistryProviderTests.cs new file mode 100644 index 00000000000..a32b91635ba --- /dev/null +++ b/src/Bicep.Core.IntegrationTests/RegistryProviderTests.cs @@ -0,0 +1,61 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using System; +using System.IO; +using System.Threading.Tasks; +using System.Web.Services.Description; +using Bicep.Core.Registry; +using Bicep.Core.Samples; +using Bicep.Core.UnitTests; +using Bicep.Core.UnitTests.Assertions; +using Bicep.Core.UnitTests.Utils; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using IOFileSystem = System.IO.Abstractions.FileSystem; + +namespace Bicep.Core.IntegrationTests; + +[TestClass] +public class RegistryProviderTests : TestBase +{ + private static ServiceBuilder GetServiceBuilder(IContainerRegistryClientFactory clientFactory) + => new ServiceBuilder() + .WithFeatureOverrides(new(ExtensibilityEnabled: true)) + .WithContainerRegistryClientFactory(clientFactory); + + [TestMethod] + [Ignore("In true TDD fashion, the functionality to fix this test is yet to be implemented")] + public async Task Providers_published_to_a_registry_can_be_compiled() + { + var registry = "example.azurecr.io"; + var registryUri = new Uri($"https://{registry}"); + var repository = $"test/provider/http"; + + // types taken from https://github.com/Azure/bicep-registry-providers/tree/21aadf24cd6e8c9c5da2db0d1438df9def548b09/providers/http + var outputDirectory = FileHelper.SaveEmbeddedResourcesWithPathPrefix( + TestContext, + typeof(RegistryProviderTests).Assembly, + "Files/RegistryProviderTests/HttpProvider"); + + var indexJson = Path.Combine(outputDirectory, "types/index.json"); + + var (clientFactory, _) = DataSetsExtensions.CreateMockRegistryClients(false, (registryUri, repository)); + await DataSetsExtensions.PublishProviderToRegistryAsync(new IOFileSystem(), clientFactory, indexJson, $"br:{registry}/{repository}:1.2.3"); + + var result = CompilationHelper.Compile(GetServiceBuilder(clientFactory), """ +provider 'br:example.azurecr.io/test/provider/http@1.2.3' + +resource dadJoke 'request@v1' = { + uri: 'https://icanhazdadjoke.com' + method: 'GET' + format: 'json' +} + +output joke string = dadJoke.body.joke +"""); + + // TODO fix the below and assert that the template contents are correctly formatted + result.Should().NotHaveAnyDiagnostics(); + result.Template.Should().NotBeNull(); + } +} \ No newline at end of file diff --git a/src/Bicep.Core.Samples/DataSetsExtensions.cs b/src/Bicep.Core.Samples/DataSetsExtensions.cs index 684ea8ec39c..3d06aaeb3db 100644 --- a/src/Bicep.Core.Samples/DataSetsExtensions.cs +++ b/src/Bicep.Core.Samples/DataSetsExtensions.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Collections.Immutable; using System.IO; +using System.IO.Abstractions; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -13,6 +14,7 @@ using Bicep.Core.Modules; using Bicep.Core.Registry; using Bicep.Core.Registry.Oci; +using Bicep.Core.Registry.Providers; using Bicep.Core.Semantics; using Bicep.Core.SourceCode; using Bicep.Core.UnitTests; @@ -180,6 +182,22 @@ public static async Task PublishModuleToRegistryAsync(IContainerRegistryClientFa await dispatcher.PublishModule(targetReference, stream, sourcesStream, documentationUri); } + public static async Task PublishProviderToRegistryAsync(IFileSystem fileSystem, IContainerRegistryClientFactory clientFactory, string pathToIndexJson, string target) + { + var dispatcher = ServiceBuilder.Create(s => s.WithDisabledAnalyzersConfiguration() + .AddSingleton(clientFactory) + .AddSingleton(BicepTestConstants.TemplateSpecRepositoryFactory) + .AddSingleton(BicepTestConstants.FeatureProviderFactory) + ).Construct(); + + var targetReference = dispatcher.TryGetArtifactReference(ArtifactType.Provider, target, PathHelper.FilePathToFileUrl(pathToIndexJson)).IsSuccess(out var @ref) ? @ref + : throw new InvalidOperationException($"Invalid target reference '{target}'. Specify a reference to an OCI artifact."); + + var tgzStream = await TypesV1Archive.GenerateProviderTarStream(fileSystem, pathToIndexJson); + + await dispatcher.PublishProvider(targetReference, tgzStream); + } + private static Uri RandomFileUri() => PathHelper.FilePathToFileUrl(Path.GetTempFileName()); } }