diff --git a/README.md b/README.md index e5fa44a..718334a 100644 --- a/README.md +++ b/README.md @@ -42,4 +42,4 @@ dotnet new function-csharp -n TheFunction -o c:\repos\func | upbound.io | [Link](https://www.nuget.org/packages/KubernetesCRDModelGen.Models.upbound.io/) | | vault.upbound.io | [Link](https://www.nuget.org/packages/KubernetesCRDModelGen.Models.vault.upbound.io/) | -- Supports Crossplane v1.17 or greater +- Supports Crossplane v2 or greater diff --git a/src/Function.SDK.CSharp.SourceGenerator/SourceGenerator.cs b/src/Function.SDK.CSharp.SourceGenerator/SourceGenerator.cs index 8e54520..ec282f6 100644 --- a/src/Function.SDK.CSharp.SourceGenerator/SourceGenerator.cs +++ b/src/Function.SDK.CSharp.SourceGenerator/SourceGenerator.cs @@ -14,11 +14,18 @@ namespace Function.SDK.CSharp.SourceGenerator; +/// +/// Source generator for Function.SDK.CSharp. It reads a Kubernetes Custom Resource Definition (CRD) from an additional text file named "xrd.yaml", processes it, and generates C# code based on the OpenAPI schema defined in the CRD. The generated code is added to the compilation during the build process. The generator also logs diagnostic messages for debugging and error handling purposes. +/// [Generator] public class SourceGenerator : IIncrementalGenerator { private static CodeGenerator codeGenerator; + /// + /// Initializes the source generator. This method is called by the compiler to set up the generator's pipeline. + /// + /// The context for the incremental generator. public void Initialize(IncrementalGeneratorInitializationContext context) { #if DEBUG diff --git a/src/Function.SDK.CSharp/Extensions/RequestExtensions.cs b/src/Function.SDK.CSharp/Extensions/RequestExtensions.cs index b44a9a7..b352c3d 100644 --- a/src/Function.SDK.CSharp/Extensions/RequestExtensions.cs +++ b/src/Function.SDK.CSharp/Extensions/RequestExtensions.cs @@ -1,7 +1,5 @@ using Apiextensions.Fn.Proto.V1; -using Google.Protobuf; using Google.Protobuf.WellKnownTypes; -using k8s; namespace Function.SDK.CSharp; @@ -48,42 +46,35 @@ public static RunFunctionResponse To(this RunFunctionRequest request, Duration t return resp; } - public static T GetKubeResource(this Resource resource) - { - var json = JsonFormatter.Default.Format(resource.Resource_); - - return KubernetesJson.Deserialize(json); - } - /// /// Get Observed Composite Resource from the supplied request. /// - /// - /// - /// + /// The type of the Kubernetes object. + /// The RunFunctionRequest. + /// The Kubernetes object of the specified type. public static T? GetObservedCompositeResource(this RunFunctionRequest request) { return request.Observed.Composite.GetKubeResource(); } /// - /// Get Observed Composed Resources from the supplied request. + /// Get Observed Resources from the supplied request. /// /// The RunFunctionRequest. - /// A dictionary mapping resource names to ObservedComposed objects. + /// A dictionary mapping resource names to Observed objects. /// Throws if conversion using Resource.AsObject fails. - public static IDictionary GetObservedComposedResources(this RunFunctionRequest request) + public static IDictionary GetObservedResources(this RunFunctionRequest request) { return request.Observed.Resources.ToDictionary(); } /// - /// Get Desired Composed Resources from the supplied request. + /// Get Desired Resources from the supplied request. /// /// The RunFunctionRequest. - /// A dictionary mapping resource names to ObservedComposed objects. + /// A dictionary mapping resource names to Desired objects. /// Throws if conversion using Resource.AsObject fails. - public static IDictionary GetDesiredComposedResources(this RunFunctionRequest request) + public static IDictionary GetDesiredResources(this RunFunctionRequest request) { return request.Desired.Resources.ToDictionary(); } @@ -91,10 +82,10 @@ public static IDictionary GetDesiredComposedResources(this Run /// /// Get Desired Resource from the supplied request. /// - /// - /// - /// - /// + /// The type of the Kubernetes object. + /// The RunFunctionRequest. + /// The key of the resource. + /// The Kubernetes object of the specified type, or null if not found. public static T? GetDesiredResource(this RunFunctionRequest request, string key) { if (request.Desired.Resources.TryGetValue(key, out var resource)) @@ -108,9 +99,10 @@ public static IDictionary GetDesiredComposedResources(this Run /// /// Get Observed Resource from the supplied request. /// - /// - /// - /// + /// The type of the Kubernetes object. + /// The RunFunctionRequest. + /// The key of the resource. + /// The Kubernetes object of the specified type, or null if not found. public static T? GetObservedResource(this RunFunctionRequest request, string key) { if (request.Observed.Resources.TryGetValue(key, out var resource)) diff --git a/src/Function.SDK.CSharp/Extensions/ResourceExtensions.cs b/src/Function.SDK.CSharp/Extensions/ResourceExtensions.cs index 1d55ff4..9833cfc 100644 --- a/src/Function.SDK.CSharp/Extensions/ResourceExtensions.cs +++ b/src/Function.SDK.CSharp/Extensions/ResourceExtensions.cs @@ -1,16 +1,34 @@ using Apiextensions.Fn.Proto.V1; +using Google.Protobuf; using Google.Protobuf.WellKnownTypes; +using k8s; namespace Function.SDK.CSharp; +/// +/// Resource extensions contains utilities for working with Resources. +/// public static class ResourceExtensions { + /// + /// Converts the Resource to a Kubernetes object of the specified type. + /// + /// The Resource to convert. + /// The type of the Kubernetes object. + /// The Kubernetes object of the specified type. + public static T GetKubeResource(this Resource resource) + { + var json = JsonFormatter.Default.Format(resource.Resource_); + + return KubernetesJson.Deserialize(json); + } + /// /// Gets the Resource condition by name /// - /// - /// - /// + /// The Resource to get the condition from. + /// The type of the condition to get. + /// The condition as a Struct, or null if not found. public static Struct? GetCondition(this Resource resource, string conditionType) { if (resource.Resource_.Fields.TryGetValue("status", out Value? status)) diff --git a/src/Function.SDK.CSharp/Extensions/ResponseExtensions.cs b/src/Function.SDK.CSharp/Extensions/ResponseExtensions.cs index 077b031..86c2791 100644 --- a/src/Function.SDK.CSharp/Extensions/ResponseExtensions.cs +++ b/src/Function.SDK.CSharp/Extensions/ResponseExtensions.cs @@ -146,9 +146,16 @@ public static void RequireResources( rsp.Requirements.Resources[name] = selector; } + /// + /// UpdateDesiredReadyStatus iterates through the desired resources in the response and updates their Ready status based on the observed resources in the request. + /// + /// The RunFunctionResponse containing the desired resources. + /// The RunFunctionRequest containing the observed resources. + /// The logger to use for logging information. + /// An optional array of resource identifiers to ignore if they have no Ready condition. public static void UpdateDesiredReadyStatus(this RunFunctionResponse response, RunFunctionRequest request, ILogger _logger, string[]? ignoreNoReadyCondition = null) { - var observed = request.GetObservedComposedResources(); + var observed = request.GetObservedResources(); foreach (var dr in response.Desired.Resources.ToDictionary()) { diff --git a/src/Function.SDK.CSharp/Extensions/StateExtensions.cs b/src/Function.SDK.CSharp/Extensions/StateExtensions.cs index d3ae504..7bf3901 100644 --- a/src/Function.SDK.CSharp/Extensions/StateExtensions.cs +++ b/src/Function.SDK.CSharp/Extensions/StateExtensions.cs @@ -4,16 +4,25 @@ namespace Function.SDK.CSharp; +/// +/// State extensions contains utilities for working with State objects. +/// public static class StateExtensions { /// - /// Adds Resource or merges with an exiting one + /// Adds Resource or merges with an existing one. Sets the ApiVersion and Kind if not set on the object. + /// If the resource with the same key already exists, the existing resource will be merged with the new one using protobuf merge semantics. /// - /// - /// - /// + /// The state to update. + /// The key of the resource. + /// The Kubernetes object to add or update. public static void AddOrUpdate(this State state, string key, IKubernetesObject obj) { + if (string.IsNullOrEmpty(obj.ApiVersion) || string.IsNullOrEmpty(obj.Kind)) + { + obj.Initialize(); + } + var kubeObj = Struct.Parser.ParseJson(KubernetesJson.Serialize(obj)); if (state.Resources.TryGetValue(key, out Resource? value)) diff --git a/src/Function.SDK.CSharp/Models/V1ConversionReview.cs b/src/Function.SDK.CSharp/Models/V1ConversionReview.cs index 8276007..2604292 100644 --- a/src/Function.SDK.CSharp/Models/V1ConversionReview.cs +++ b/src/Function.SDK.CSharp/Models/V1ConversionReview.cs @@ -1,94 +1,94 @@ -using System.Runtime.Serialization; -using System.Text.Json; -using System.Text.Json.Serialization; - -namespace Function.SDK.CSharp.Models; - -public sealed class V1ConversionReview -{ - public const string KubeApiVersion = "v1"; - public const string KubeKind = "ConversionReview"; - public const string KubeGroup = "apiextensions.k8s.io"; - - [JsonPropertyName("apiVersion")] - public string ApiVersion { get; set; } = KubeGroup + "/" + KubeApiVersion; - - [JsonPropertyName("kind")] - public string Kind { get; set; } = KubeKind; - - [JsonPropertyName("request")] - public V1ConversionReviewRequest Request { get; set; } - - [JsonPropertyName("response")] - public V1ConversionReviewResponse Response { get; set; } = new(); -} - -public sealed class V1ConversionReviewRequest -{ - /// - /// Random uid uniquely identifying this conversion call - /// - [JsonPropertyName("uid")] - public string Uid { get; set; } = default!; - - /// - /// The API group and version the objects should be converted to - /// - [JsonPropertyName("desiredAPIVersion")] - public string DesiredApiVersion { get; set; } = default!; - - /// - /// # The list of objects to convert. May contain one or more objects, in one or more versions. - /// - [JsonPropertyName("objects")] - public JsonElement[] Objects { get; set; } = default!; -} - -public sealed class V1ConversionReviewResponse -{ - /// - /// Must match <request.uid> - /// - [JsonPropertyName("uid")] - public string Uid { get; set; } = ""; - - /// - /// Objects must match the order of request.objects, and have apiVersion set to <request.desiredAPIVersion>. - /// kind, metadata.uid, metadata.name, and metadata.namespace fields must not be changed by the webhook. - /// metadata.labels and metadata.annotations fields may be changed by the webhook. - /// All other changes to metadata fields by the webhook are ignored. - /// - [JsonPropertyName("convertedObjects")] - public List ConvertedObjects { get; set; } = []; - - [JsonPropertyName("result")] - public V1ConversionReviewResponseStatus Result { get; set; } = new(); -} - -/// -/// Webhook Response Status -/// -public enum V1ConversionReviewResponseStatusEnum -{ - ///Success - [EnumMember(Value = "Success"), JsonStringEnumMemberName("Success")] - Success, - ///Failure - [EnumMember(Value = "Failure"), JsonStringEnumMemberName("Failure")] - Failure, -} - -public sealed class V1ConversionReviewResponseStatus -{ - [JsonPropertyName("status")] - public V1ConversionReviewResponseStatusEnum Status { get; set; } - - [JsonPropertyName("message")] - public string? Message { get; set; } - - [JsonPropertyName("reason")] - public string? Reason { get; set; } - - [JsonPropertyName("code")] - public int Code { get; set; } = 200; +using System.Runtime.Serialization; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace Function.SDK.CSharp.Models; + +public sealed class V1ConversionReview +{ + public const string KubeApiVersion = "v1"; + public const string KubeKind = "ConversionReview"; + public const string KubeGroup = "apiextensions.k8s.io"; + + [JsonPropertyName("apiVersion")] + public string ApiVersion { get; set; } = KubeGroup + "/" + KubeApiVersion; + + [JsonPropertyName("kind")] + public string Kind { get; set; } = KubeKind; + + [JsonPropertyName("request")] + public V1ConversionReviewRequest Request { get; set; } + + [JsonPropertyName("response")] + public V1ConversionReviewResponse Response { get; set; } = new(); +} + +public sealed class V1ConversionReviewRequest +{ + /// + /// Random uid uniquely identifying this conversion call + /// + [JsonPropertyName("uid")] + public string Uid { get; set; } = default!; + + /// + /// The API group and version the objects should be converted to + /// + [JsonPropertyName("desiredAPIVersion")] + public string DesiredApiVersion { get; set; } = default!; + + /// + /// # The list of objects to convert. May contain one or more objects, in one or more versions. + /// + [JsonPropertyName("objects")] + public JsonElement[] Objects { get; set; } = default!; +} + +public sealed class V1ConversionReviewResponse +{ + /// + /// Must match <request.uid> + /// + [JsonPropertyName("uid")] + public string Uid { get; set; } = ""; + + /// + /// Objects must match the order of request.objects, and have apiVersion set to <request.desiredAPIVersion>. + /// kind, metadata.uid, metadata.name, and metadata.namespace fields must not be changed by the webhook. + /// metadata.labels and metadata.annotations fields may be changed by the webhook. + /// All other changes to metadata fields by the webhook are ignored. + /// + [JsonPropertyName("convertedObjects")] + public List ConvertedObjects { get; set; } = []; + + [JsonPropertyName("result")] + public V1ConversionReviewResponseStatus Result { get; set; } = new(); +} + +/// +/// Webhook Response Status +/// +public enum V1ConversionReviewResponseStatusEnum +{ + ///Success + [EnumMember(Value = "Success"), JsonStringEnumMemberName("Success")] + Success, + ///Failure + [EnumMember(Value = "Failure"), JsonStringEnumMemberName("Failure")] + Failure, +} + +public sealed class V1ConversionReviewResponseStatus +{ + [JsonPropertyName("status")] + public V1ConversionReviewResponseStatusEnum Status { get; set; } + + [JsonPropertyName("message")] + public string? Message { get; set; } + + [JsonPropertyName("reason")] + public string? Reason { get; set; } + + [JsonPropertyName("code")] + public int Code { get; set; } = 200; } diff --git a/src/Function.SDK.CSharp/Properties/launchSettings.json b/src/Function.SDK.CSharp/Properties/launchSettings.json index 122dfbd..de99f69 100644 --- a/src/Function.SDK.CSharp/Properties/launchSettings.json +++ b/src/Function.SDK.CSharp/Properties/launchSettings.json @@ -1,12 +1,12 @@ -{ - "profiles": { - "Function.SDK.CSharp": { - "commandName": "Project", - "launchBrowser": true, - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - }, - "applicationUrl": "https://localhost:61263;http://localhost:61264" - } - } +{ + "profiles": { + "Function.SDK.CSharp": { + "commandName": "Project", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "applicationUrl": "https://localhost:51428;http://localhost:51429" + } + } } \ No newline at end of file diff --git a/tests/Function.SDK.CSharp.Example.Tests/ConversionWebhookTests.cs b/tests/Function.SDK.CSharp.Example.Tests/ConversionWebhookTests.cs deleted file mode 100644 index 01c6201..0000000 --- a/tests/Function.SDK.CSharp.Example.Tests/ConversionWebhookTests.cs +++ /dev/null @@ -1,57 +0,0 @@ -using System.Text.Json; -using Function.SDK.CSharp.Models; -using Function.SDK.CSharp.SourceGenerator.Models.platform.example.com; -using k8s; -using Shouldly; - -namespace Function.SDK.CSharp.Example.Tests; - -public class ConversionWebhookTests -{ - [Fact] - public void V2toV1ConversionTest() - { - var input = new V1ConversionReview() - { - Request = new() - { - Uid = Guid.NewGuid().ToString(), - DesiredApiVersion = V1alpha1XStorageBucket.KubeApiVersion, - Objects = [ - new V1alpha2XStorageBucket() - { - Spec = new() - { - Parameters = new() - { - Acl = V1alpha2XStorageBucketSpecParametersAclEnum.Private, - Location = V1alpha2XStorageBucketSpecParametersLocationEnum.Asia, - Versioning = true - } - } - }.ToJsonElement() - ] - } - }; - - var output = ConversionWebhook.Convert(input); - - var response = output.Response; - - response.ShouldNotBeNull(); - - response.Uid.ShouldBe(input.Request.Uid); - - response.Result.Code.ShouldBe(200); - - response.ConvertedObjects[0].GetProperty("apiVersion").GetString().ShouldBe(V1alpha1XStorageBucket.KubeApiVersion); - } -} - -public static class Extensions -{ - public static JsonElement ToJsonElement(this IKubernetesObject obj) - { - return JsonDocument.Parse(KubernetesJson.Serialize(obj)).RootElement.Clone(); - } -} diff --git a/tests/Function.SDK.CSharp.Example.Tests/Function.SDK.CSharp.Example.Tests.csproj b/tests/Function.SDK.CSharp.Example.Tests/Function.SDK.CSharp.Example.Tests.csproj deleted file mode 100644 index cff694a..0000000 --- a/tests/Function.SDK.CSharp.Example.Tests/Function.SDK.CSharp.Example.Tests.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - net10.0 - Exe - enable - enable - - false - true - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tests/Function.SDK.CSharp.Example.Tests/TestExtensions.cs b/tests/Function.SDK.CSharp.Example.Tests/TestExtensions.cs deleted file mode 100644 index 2cafd8c..0000000 --- a/tests/Function.SDK.CSharp.Example.Tests/TestExtensions.cs +++ /dev/null @@ -1,51 +0,0 @@ -using Apiextensions.Fn.Proto.V1; -using Google.Protobuf; -using Google.Protobuf.WellKnownTypes; -using Grpc.Core; -using Grpc.Core.Testing; -using Grpc.Core.Utils; -using k8s; -using Microsoft.Extensions.Logging; - -namespace Function.SDK.CSharp.Example.Tests; - -public static class TestExtensions -{ - public static RunFunctionRequest GetFunctionRequest() - { - var request = new RunFunctionRequest - { - Observed = new() - { - Composite = new() - }, - Desired = new(), - Context = new(), - }; - - return request; - } - - public static RunFunctionResponse GetTestResponse(this RunFunctionRequest request) - { - var svc = new RunFunctionService(new LoggerFactory().CreateLogger()); - var fakeServerCallContext = TestServerCallContext.Create("/apiextensions.fn.proto.v1.FunctionRunnerService/RunFunction", null, DateTime.UtcNow.AddHours(1), [], CancellationToken.None, "127.0.0.1", null, null, (metadata) => TaskUtils.CompletedTask, () => new WriteOptions(), (writeOptions) => { }); - - return svc.RunFunction(request, fakeServerCallContext) - .GetAwaiter() - .GetResult(); - } - - public static void SetCompositeResource(this RunFunctionRequest request, IKubernetesObject obj) - { - var kubeObj = Struct.Parser.ParseJson(KubernetesJson.Serialize(obj)); - request.Observed.Composite.Resource_ = kubeObj; - } - - public static T GetResource(this State state, string key) - { - var json = JsonFormatter.Default.Format(state.Resources[key].Resource_); - - return KubernetesJson.Deserialize(json); - } -} diff --git a/tests/Function.SDK.CSharp.Example.Tests/UnitTest1.cs b/tests/Function.SDK.CSharp.Example.Tests/UnitTest1.cs deleted file mode 100644 index 17e1172..0000000 --- a/tests/Function.SDK.CSharp.Example.Tests/UnitTest1.cs +++ /dev/null @@ -1,275 +0,0 @@ -using Apiextensions.Fn.Proto.V1; -using EnumsNET; -using Function.SDK.CSharp.SourceGenerator.Models.platform.example.com; -using KubernetesCRDModelGen.Models.azure.m.upbound.io; -using Shouldly; - -namespace Function.SDK.CSharp.Example.Tests; - -public class UnitTest1 -{ - [Fact] - public void TestMerge() - { - var xr = new V1alpha1XStorageBucket() - { - Metadata = new() - { - Name = "test", - NamespaceProperty = "default" - }, - Spec = new() - { - Parameters = new() - { - Location = V1alpha1XStorageBucketSpecParametersLocationEnum.Eastus, - Versioning = true, - Acl = V1alpha1XStorageBucketSpecParametersAclEnum.Private, - } - } - }; - - var request = TestExtensions.GetFunctionRequest(); - request.SetCompositeResource(xr); - - var response1 = request.GetTestResponse(); - - var desiredResource = new V1beta1ResourceGroup() - { - Spec = new() - { - ForProvider = new() - { - Location = xr.Spec.Parameters.Location.AsString(EnumFormat.EnumMemberValue) - } - } - }; - - response1.Desired.GetResource("rg").ShouldBeEquivalentTo(desiredResource); - - // Update Desired Resource Status and rerun function - - var desiredResource2 = new V1beta1ResourceGroup() - { - Spec = new() - { - ForProvider = new() - { - Location = xr.Spec.Parameters.Location.AsString(EnumFormat.EnumMemberValue) - } - }, - Status = new() - { - Conditions = - [ - new() - { - Status = "Ready", - LastTransitionTime = "01/01/2025", - Reason = "test", - Type = "testType" - } - ] - } - }; - - var request2 = TestExtensions.GetFunctionRequest(); - request2.SetCompositeResource(xr); - - request2.Desired.AddOrUpdate("rg", desiredResource2); - - var response2 = request2.GetTestResponse(); - - response2.Desired.GetResource("rg").ShouldBeEquivalentTo(desiredResource2); - } - - [Fact] - public void TestReadyFalse() - { - var xr = new V1alpha1XStorageBucket() - { - Metadata = new() - { - Name = "test", - NamespaceProperty = "default" - }, - Spec = new() - { - Parameters = new() - { - Location = V1alpha1XStorageBucketSpecParametersLocationEnum.Eastus, - Versioning = true, - Acl = V1alpha1XStorageBucketSpecParametersAclEnum.Private, - } - } - }; - - var desiredResource = new V1beta1ResourceGroup() - { - Spec = new() - { - ForProvider = new() - { - Location = xr.Spec.Parameters.Location.AsString(EnumFormat.EnumMemberValue) - } - } - }; - - var observedResource = new V1beta1ResourceGroup() - { - Spec = new() - { - ForProvider = new() - { - Location = xr.Spec.Parameters.Location.AsString(EnumFormat.EnumMemberValue) - } - }, - Status = new() - { - Conditions = - [ - new() - { - Status = "Ready", - LastTransitionTime = "01/01/2025", - Reason = "test", - Type = "testType" - } - ] - } - }; - - var request = TestExtensions.GetFunctionRequest(); - request.SetCompositeResource(xr); - request.Desired.AddOrUpdate("rg", desiredResource); - request.Observed.AddOrUpdate("rg", observedResource); - - var response1 = request.GetTestResponse(); - - var desiredResourceResponse = response1.Desired.Resources["rg"]; - desiredResourceResponse.Ready.ShouldBe(Ready.False); - } - - [Fact] - public void TestReadyTrue() - { - var xr = new V1alpha1XStorageBucket() - { - Metadata = new() - { - Name = "test", - NamespaceProperty = "default" - }, - Spec = new() - { - Parameters = new() - { - Location = V1alpha1XStorageBucketSpecParametersLocationEnum.Eastus, - Versioning = true, - Acl = V1alpha1XStorageBucketSpecParametersAclEnum.Private, - } - } - }; - - var desiredResource = new V1beta1ResourceGroup() - { - Spec = new() - { - ForProvider = new() - { - Location = xr.Spec.Parameters.Location.AsString(EnumFormat.EnumMemberValue) - } - } - }; - - var observedResource = new V1beta1ResourceGroup() - { - Spec = new() - { - ForProvider = new() - { - Location = xr.Spec.Parameters.Location.AsString(EnumFormat.EnumMemberValue) - } - }, - Status = new() - { - Conditions = - [ - new() - { - LastTransitionTime = "01/01/2025", - Reason = "test", - Status = "True", - Type = "Ready", - } - ] - } - }; - - var request = TestExtensions.GetFunctionRequest(); - request.SetCompositeResource(xr); - request.Desired.AddOrUpdate("rg", desiredResource); - request.Observed.AddOrUpdate("rg", observedResource); - - var response1 = request.GetTestResponse(); - var desiredResourceResponse = response1.Desired.Resources["rg"]; - desiredResourceResponse.Ready.ShouldBe(Ready.True); - } - - [Fact] - public void TestReadyIgnore() - { - var xr = new V1alpha1XStorageBucket() - { - Metadata = new() - { - Name = "test", - NamespaceProperty = "default" - }, - Spec = new() - { - Parameters = new() - { - Location = V1alpha1XStorageBucketSpecParametersLocationEnum.Eastus, - Versioning = true, - Acl = V1alpha1XStorageBucketSpecParametersAclEnum.Private, - } - } - }; - - var desiredResource = new V1beta1ProviderConfig() - { - Spec = new() - { - Credentials = new() - { - Source = new() - { - } - } - } - }; - - var observedResource = new V1beta1ProviderConfig() - { - Spec = new() - { - Credentials = new() - { - Source = new() - { - } - } - } - }; - - var request = TestExtensions.GetFunctionRequest(); - request.SetCompositeResource(xr); - request.Desired.AddOrUpdate("resource", desiredResource); - request.Observed.AddOrUpdate("resource", observedResource); - - var response1 = request.GetTestResponse(); - var desiredResourceResponse = response1.Desired.Resources["resource"]; - desiredResourceResponse.Ready.ShouldBe(Ready.True); - } -} diff --git a/tests/Function.SDK.CSharp.Example.Tests/xunit.runner.json b/tests/Function.SDK.CSharp.Example.Tests/xunit.runner.json deleted file mode 100644 index 86c7ea0..0000000 --- a/tests/Function.SDK.CSharp.Example.Tests/xunit.runner.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "$schema": "https://xunit.net/schema/current/xunit.runner.schema.json" -} diff --git a/tests/Function.SDK.CSharp.Tests/V1alpha1XStorageBucket.cs b/tests/Function.SDK.CSharp.Tests/V1alpha1XStorageBucket.cs index 26a84c2..eb25331 100644 --- a/tests/Function.SDK.CSharp.Tests/V1alpha1XStorageBucket.cs +++ b/tests/Function.SDK.CSharp.Tests/V1alpha1XStorageBucket.cs @@ -1,12 +1,8 @@ #nullable enable -using k8s; -using k8s.Models; -using System; -using System.Collections.Generic; using System.Runtime.Serialization; -using System.Text.Json; -using System.Text.Json.Nodes; using System.Text.Json.Serialization; +using k8s; +using k8s.Models; namespace Function.SDK.CSharp.SourceGenerator.Models.platform.example.com; /// StorageBucket is the Schema for the StorageBucket API.