diff --git a/.gitignore b/.gitignore index f400df3..9a4719a 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ obj/ /packages/ riderModule.iml /_ReSharper.Caches/ -.idea/ \ No newline at end of file +.idea/ +*.DotSettings.user \ No newline at end of file diff --git a/CDK.Framework.sln b/CDK.Framework.sln index 9736ca1..94bb075 100644 --- a/CDK.Framework.sln +++ b/CDK.Framework.sln @@ -35,6 +35,18 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "2. CDK Modules", "2. CDK Mo EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{F2C4D978-97A6-4451-AAD2-16EDCA158D97}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sagittaras.CDK.Tests.Route53", "Sagittaras.CDK.Tests.Route53\Sagittaras.CDK.Tests.Route53.csproj", "{64D45D92-6955-42FC-87CD-E1419FB1EA17}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sagittaras.CDK.Tests", "Sagittaras.CDK.Tests\Sagittaras.CDK.Tests.csproj", "{E42AD3AD-DBF2-4A25-98CF-E8DA76B356AF}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "3. Testing", "3. Testing", "{3A01C380-5151-4039-A00C-A33687E00861}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sagittaras.CDK.Testing", "Sagittaras.CDK.Testing\Sagittaras.CDK.Testing.csproj", "{D753C559-6F75-4493-A5A3-00CD0727A2DC}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sagittaras.CDK.Testing.Route53", "Sagittaras.CDK.Testing.Route53\Sagittaras.CDK.Testing.Route53.csproj", "{2C4B4454-A145-405E-85BC-F54B56EAC39B}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sagittaras.CDK.Testing.KMS", "Sagittaras.CDK.Testing.KMS\Sagittaras.CDK.Testing.KMS.csproj", "{FF8FB1E8-9071-470E-A4F3-6C0CD27716F4}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -51,6 +63,12 @@ Global {61F8F5CD-30FF-4019-AE9D-E1AD0DA55029} = {506BD5FC-1E9D-47D4-A609-F977EDF69184} {272BA799-3674-4104-8E01-511E9EDA0198} = {506BD5FC-1E9D-47D4-A609-F977EDF69184} {C8F37959-BCB7-43DC-9812-A5623E420923} = {506BD5FC-1E9D-47D4-A609-F977EDF69184} + {64D45D92-6955-42FC-87CD-E1419FB1EA17} = {F2C4D978-97A6-4451-AAD2-16EDCA158D97} + {E42AD3AD-DBF2-4A25-98CF-E8DA76B356AF} = {F2C4D978-97A6-4451-AAD2-16EDCA158D97} + {3A01C380-5151-4039-A00C-A33687E00861} = {AEF441A3-E5F9-46D2-82B9-8EE105CC3274} + {D753C559-6F75-4493-A5A3-00CD0727A2DC} = {3A01C380-5151-4039-A00C-A33687E00861} + {2C4B4454-A145-405E-85BC-F54B56EAC39B} = {3A01C380-5151-4039-A00C-A33687E00861} + {FF8FB1E8-9071-470E-A4F3-6C0CD27716F4} = {3A01C380-5151-4039-A00C-A33687E00861} EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {940EEEA3-A068-4793-A44A-D2FCE1143E49}.Debug|Any CPU.ActiveCfg = Debug|Any CPU @@ -81,5 +99,25 @@ Global {C8F37959-BCB7-43DC-9812-A5623E420923}.Debug|Any CPU.Build.0 = Debug|Any CPU {C8F37959-BCB7-43DC-9812-A5623E420923}.Release|Any CPU.ActiveCfg = Release|Any CPU {C8F37959-BCB7-43DC-9812-A5623E420923}.Release|Any CPU.Build.0 = Release|Any CPU + {64D45D92-6955-42FC-87CD-E1419FB1EA17}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {64D45D92-6955-42FC-87CD-E1419FB1EA17}.Debug|Any CPU.Build.0 = Debug|Any CPU + {64D45D92-6955-42FC-87CD-E1419FB1EA17}.Release|Any CPU.ActiveCfg = Release|Any CPU + {64D45D92-6955-42FC-87CD-E1419FB1EA17}.Release|Any CPU.Build.0 = Release|Any CPU + {E42AD3AD-DBF2-4A25-98CF-E8DA76B356AF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E42AD3AD-DBF2-4A25-98CF-E8DA76B356AF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E42AD3AD-DBF2-4A25-98CF-E8DA76B356AF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E42AD3AD-DBF2-4A25-98CF-E8DA76B356AF}.Release|Any CPU.Build.0 = Release|Any CPU + {D753C559-6F75-4493-A5A3-00CD0727A2DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D753C559-6F75-4493-A5A3-00CD0727A2DC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D753C559-6F75-4493-A5A3-00CD0727A2DC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D753C559-6F75-4493-A5A3-00CD0727A2DC}.Release|Any CPU.Build.0 = Release|Any CPU + {2C4B4454-A145-405E-85BC-F54B56EAC39B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2C4B4454-A145-405E-85BC-F54B56EAC39B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2C4B4454-A145-405E-85BC-F54B56EAC39B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2C4B4454-A145-405E-85BC-F54B56EAC39B}.Release|Any CPU.Build.0 = Release|Any CPU + {FF8FB1E8-9071-470E-A4F3-6C0CD27716F4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FF8FB1E8-9071-470E-A4F3-6C0CD27716F4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FF8FB1E8-9071-470E-A4F3-6C0CD27716F4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FF8FB1E8-9071-470E-A4F3-6C0CD27716F4}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal diff --git a/Sagittaras.CDK.Testing.KMS/AliasAssertion.cs b/Sagittaras.CDK.Testing.KMS/AliasAssertion.cs new file mode 100644 index 0000000..f72810c --- /dev/null +++ b/Sagittaras.CDK.Testing.KMS/AliasAssertion.cs @@ -0,0 +1,11 @@ +using Sagittaras.CDK.Testing.Resources; + +namespace Sagittaras.CDK.Testing.KMS; + +/// +/// Assertion for AWS::KMS::Alias. +/// +public class AliasAssertion : ResourceAssertion +{ + public override string Type => "AWS::KMS::Alias"; +} \ No newline at end of file diff --git a/Sagittaras.CDK.Testing.KMS/AliasProperties.cs b/Sagittaras.CDK.Testing.KMS/AliasProperties.cs new file mode 100644 index 0000000..89a3825 --- /dev/null +++ b/Sagittaras.CDK.Testing.KMS/AliasProperties.cs @@ -0,0 +1,14 @@ +using Sagittaras.CDK.Testing.Resources; + +namespace Sagittaras.CDK.Testing.KMS; + +/// +/// Properties for AWS::KMS::Alias. +/// +public class AliasProperties : ResourceProperties +{ + /// + /// Name of the key alias. + /// + public string? AliasName { get; set; } +} \ No newline at end of file diff --git a/Sagittaras.CDK.Testing.KMS/KeyAssertion.cs b/Sagittaras.CDK.Testing.KMS/KeyAssertion.cs new file mode 100644 index 0000000..0022139 --- /dev/null +++ b/Sagittaras.CDK.Testing.KMS/KeyAssertion.cs @@ -0,0 +1,11 @@ +using Sagittaras.CDK.Testing.Resources; + +namespace Sagittaras.CDK.Testing.KMS; + +/// +/// Assertion for AWS::KMS::Key. +/// +public class KeyAssertion : ResourceAssertion +{ + public override string Type => "AWS::KMS::Key"; +} \ No newline at end of file diff --git a/Sagittaras.CDK.Testing.KMS/KeyProperties.cs b/Sagittaras.CDK.Testing.KMS/KeyProperties.cs new file mode 100644 index 0000000..79e049f --- /dev/null +++ b/Sagittaras.CDK.Testing.KMS/KeyProperties.cs @@ -0,0 +1,11 @@ +using Sagittaras.CDK.Testing.Resources; + +namespace Sagittaras.CDK.Testing.KMS; + +/// +/// Properties for AWS::KMS::Key. +/// +public class KeyProperties : ResourceProperties +{ + +} \ No newline at end of file diff --git a/Sagittaras.CDK.Testing.KMS/Sagittaras.CDK.Testing.KMS.csproj b/Sagittaras.CDK.Testing.KMS/Sagittaras.CDK.Testing.KMS.csproj new file mode 100644 index 0000000..07ffb8a --- /dev/null +++ b/Sagittaras.CDK.Testing.KMS/Sagittaras.CDK.Testing.KMS.csproj @@ -0,0 +1,20 @@ + + + + net6.0 + enable + enable + true + 1.0.0-preview-01 + CDK KMS testing library + Sagittaras Games + https://github.com/sagittaras/cdk.framework + https://github.com/sagittaras/cdk.framework/blob/main/LICENSE + https://github.com/sagittaras/cdk.framework + + + + + + + diff --git a/Sagittaras.CDK.Testing.Route53/DnsSecAssertion.cs b/Sagittaras.CDK.Testing.Route53/DnsSecAssertion.cs new file mode 100644 index 0000000..adb271a --- /dev/null +++ b/Sagittaras.CDK.Testing.Route53/DnsSecAssertion.cs @@ -0,0 +1,12 @@ +using Sagittaras.CDK.Testing.Resources; + +namespace Sagittaras.CDK.Testing.Route53; + +/// +/// Assertion for Aws::Route53::DNSSEC. +/// +public class DnsSecAssertion : ResourceAssertion +{ + /// + public override string Type => "AWS::Route53::DNSSEC"; +} \ No newline at end of file diff --git a/Sagittaras.CDK.Testing.Route53/DnsSecDependency.cs b/Sagittaras.CDK.Testing.Route53/DnsSecDependency.cs new file mode 100644 index 0000000..438f91d --- /dev/null +++ b/Sagittaras.CDK.Testing.Route53/DnsSecDependency.cs @@ -0,0 +1,24 @@ +using Sagittaras.CDK.Testing.Resources; + +namespace Sagittaras.CDK.Testing.Route53; + +/// +/// Class defining DNS SEC dependency on Key Signing Key. +/// +public class DnsSecDependency : ResourceDependency +{ + /// + /// + /// + /// Identification of KSK by its name. + public DnsSecDependency(string kskName) + { + With(new KeySigningKeyAssertion + { + Properties = new KeySigningKeyProperties + { + Name = kskName + } + }); + } +} \ No newline at end of file diff --git a/Sagittaras.CDK.Testing.Route53/DnsSecProperties.cs b/Sagittaras.CDK.Testing.Route53/DnsSecProperties.cs new file mode 100644 index 0000000..e05e45a --- /dev/null +++ b/Sagittaras.CDK.Testing.Route53/DnsSecProperties.cs @@ -0,0 +1,11 @@ +using Sagittaras.CDK.Testing.Resources; + +namespace Sagittaras.CDK.Testing.Route53; + +/// +/// Properties for AWS::Route53::DNSSEC. +/// +public class DnsSecProperties : ResourceProperties +{ + +} \ No newline at end of file diff --git a/Sagittaras.CDK.Testing.Route53/HostedZoneAssertion.cs b/Sagittaras.CDK.Testing.Route53/HostedZoneAssertion.cs new file mode 100644 index 0000000..5a56941 --- /dev/null +++ b/Sagittaras.CDK.Testing.Route53/HostedZoneAssertion.cs @@ -0,0 +1,12 @@ +using Sagittaras.CDK.Testing.Resources; + +namespace Sagittaras.CDK.Testing.Route53; + +/// +/// Assertion for AWS::Route53::HostedZone. +/// +public class HostedZoneAssertion : ResourceAssertion +{ + /// + public override string Type => "AWS::Route53::HostedZone"; +} \ No newline at end of file diff --git a/Sagittaras.CDK.Testing.Route53/HostedZoneProperties.cs b/Sagittaras.CDK.Testing.Route53/HostedZoneProperties.cs new file mode 100644 index 0000000..b76ae79 --- /dev/null +++ b/Sagittaras.CDK.Testing.Route53/HostedZoneProperties.cs @@ -0,0 +1,23 @@ +using Sagittaras.CDK.Testing.Resources; + +namespace Sagittaras.CDK.Testing.Route53; + +/// +/// Properties describing the Hosted Zone in the CloudFormation template. +/// +public class HostedZoneProperties : ResourceProperties +{ + private string? _name; + + /// + /// Name of the hosted zone. + /// + /// + /// Automatically appends the trailing dot that is generated for CloudFormation template. + /// + public string? Name + { + get => _name; + set => _name = value?.TrimEnd('.') + "."; + } +} \ No newline at end of file diff --git a/Sagittaras.CDK.Testing.Route53/KeySigningKeyAssertion.cs b/Sagittaras.CDK.Testing.Route53/KeySigningKeyAssertion.cs new file mode 100644 index 0000000..e025e25 --- /dev/null +++ b/Sagittaras.CDK.Testing.Route53/KeySigningKeyAssertion.cs @@ -0,0 +1,12 @@ +using Sagittaras.CDK.Testing.Resources; + +namespace Sagittaras.CDK.Testing.Route53; + +/// +/// Assertion for AWS::Route53::KeySigningKey. +/// +public class KeySigningKeyAssertion : ResourceAssertion +{ + /// + public override string Type => "AWS::Route53::KeySigningKey"; +} \ No newline at end of file diff --git a/Sagittaras.CDK.Testing.Route53/KeySigningKeyProperties.cs b/Sagittaras.CDK.Testing.Route53/KeySigningKeyProperties.cs new file mode 100644 index 0000000..9026501 --- /dev/null +++ b/Sagittaras.CDK.Testing.Route53/KeySigningKeyProperties.cs @@ -0,0 +1,19 @@ +using Sagittaras.CDK.Testing.Resources; + +namespace Sagittaras.CDK.Testing.Route53; + +/// +/// Properties for AWS::Route53::KeySigningKey. +/// +public class KeySigningKeyProperties : ResourceProperties +{ + /// + /// Current status of the KSK. + /// + public string? Status { get; set; } + + /// + /// Name of the KSK. + /// + public string? Name { get; set; } +} \ No newline at end of file diff --git a/Sagittaras.CDK.Testing.Route53/RecordSetAssertion.cs b/Sagittaras.CDK.Testing.Route53/RecordSetAssertion.cs new file mode 100644 index 0000000..d44d3f2 --- /dev/null +++ b/Sagittaras.CDK.Testing.Route53/RecordSetAssertion.cs @@ -0,0 +1,12 @@ +using Sagittaras.CDK.Testing.Resources; + +namespace Sagittaras.CDK.Testing.Route53; + +/// +/// Assertion for AWS::Route53::RecordSet. +/// +public class RecordSetAssertion : ResourceAssertion +{ + /// + public override string Type => "AWS::Route53::RecordSet"; +} \ No newline at end of file diff --git a/Sagittaras.CDK.Testing.Route53/RecordSetProperties.cs b/Sagittaras.CDK.Testing.Route53/RecordSetProperties.cs new file mode 100644 index 0000000..018f4d5 --- /dev/null +++ b/Sagittaras.CDK.Testing.Route53/RecordSetProperties.cs @@ -0,0 +1,11 @@ +using Sagittaras.CDK.Testing.Resources; + +namespace Sagittaras.CDK.Testing.Route53; + +/// +/// Properties for AWS::Route53::RecordSet. +/// +public class RecordSetProperties : ResourceProperties +{ + +} \ No newline at end of file diff --git a/Sagittaras.CDK.Testing.Route53/Sagittaras.CDK.Testing.Route53.csproj b/Sagittaras.CDK.Testing.Route53/Sagittaras.CDK.Testing.Route53.csproj new file mode 100644 index 0000000..1c1cdca --- /dev/null +++ b/Sagittaras.CDK.Testing.Route53/Sagittaras.CDK.Testing.Route53.csproj @@ -0,0 +1,20 @@ + + + + net6.0 + enable + enable + true + 1.0.0-preview-01 + CDK Route53 test library + Sagittaras Games + https://github.com/sagittaras/cdk.framework + https://github.com/sagittaras/cdk.framework/blob/main/LICENSE + https://github.com/sagittaras/cdk.framework + + + + + + + diff --git a/Sagittaras.CDK.Testing/Extensions/TemplateAssertionExtension.cs b/Sagittaras.CDK.Testing/Extensions/TemplateAssertionExtension.cs new file mode 100644 index 0000000..62af3f9 --- /dev/null +++ b/Sagittaras.CDK.Testing/Extensions/TemplateAssertionExtension.cs @@ -0,0 +1,34 @@ +using Amazon.CDK.Assertions; +using Sagittaras.CDK.Testing.Resources; + +namespace Sagittaras.CDK.Testing.Extensions; + +/// +/// Extends the assertion template from the CDK by custom assertion methods. +/// +public static class TemplateAssertionExtension +{ + /// + /// Asserts that the template has a resource with the given description. + /// + /// + /// + /// + public static void Assert(this Template template, TResourceAssertion assertion) + where TResourceAssertion : IResourceAssertion + { + template.HasResource(assertion.Type, assertion.GetResourceDescription(template)); + } + + /// + /// Asserts that the template has a given number of resources of the given type. + /// + /// + /// + /// + public static void AssertCount(this Template template, int count) + where TResourceAssertion : IResourceAssertion, new() + { + template.ResourceCountIs(new TResourceAssertion().Type, count); + } +} \ No newline at end of file diff --git a/Sagittaras.CDK.Testing/Resources/IResourceAssertion.cs b/Sagittaras.CDK.Testing/Resources/IResourceAssertion.cs new file mode 100644 index 0000000..19e3582 --- /dev/null +++ b/Sagittaras.CDK.Testing/Resources/IResourceAssertion.cs @@ -0,0 +1,38 @@ +using Amazon.CDK.Assertions; + +namespace Sagittaras.CDK.Testing.Resources; + +/// +/// Basic interface describing the assertion for AWS resource. +/// +public interface IResourceAssertion +{ + /// + /// AWS Resource type. + /// + string Type { get; } + + /// + /// Maps on which resources the current resource depends on. + /// + IResourceDependency? DependsOn { get; set; } + + /// + /// Converts the resource description to a dictionary suitable for template assertion. + /// + /// + IDictionary GetResourceDescription(Template template); +} + +/// +/// Extends the basic resource assertion with properties. +/// +/// Type of the properties used for the resource. +public interface IResourceAssertion : IResourceAssertion + where TProperties : IResourceProperties, new() +{ + /// + /// Properties that helps to identify the resource. + /// + TProperties? Properties { get; set; } +} \ No newline at end of file diff --git a/Sagittaras.CDK.Testing/Resources/IResourceDependency.cs b/Sagittaras.CDK.Testing/Resources/IResourceDependency.cs new file mode 100644 index 0000000..e1ed116 --- /dev/null +++ b/Sagittaras.CDK.Testing/Resources/IResourceDependency.cs @@ -0,0 +1,25 @@ +using Amazon.CDK.Assertions; + +namespace Sagittaras.CDK.Testing.Resources; + +/// +/// Helps to describe and resolve dependencies between resources. +/// +public interface IResourceDependency +{ + /// + /// Assigns the given assertion to the dependency. + /// + /// + /// + /// + IResourceDependency With(TResourceAssertion assertion) + where TResourceAssertion : IResourceAssertion; + + /// + /// Resolves the dependencies from the given template. + /// + /// + /// + IEnumerable Resolve(Template template); +} \ No newline at end of file diff --git a/Sagittaras.CDK.Testing/Resources/IResourceProperties.cs b/Sagittaras.CDK.Testing/Resources/IResourceProperties.cs new file mode 100644 index 0000000..2fad86c --- /dev/null +++ b/Sagittaras.CDK.Testing/Resources/IResourceProperties.cs @@ -0,0 +1,13 @@ +namespace Sagittaras.CDK.Testing.Resources; + +/// +/// Describes the properties of a resource. +/// +public interface IResourceProperties +{ + /// + /// Converts the properties to a dictionary suitable for template assertion. + /// + /// + IDictionary ToDictionary(); +} \ No newline at end of file diff --git a/Sagittaras.CDK.Testing/Resources/ResourceAssertion.cs b/Sagittaras.CDK.Testing/Resources/ResourceAssertion.cs new file mode 100644 index 0000000..57a04ca --- /dev/null +++ b/Sagittaras.CDK.Testing/Resources/ResourceAssertion.cs @@ -0,0 +1,50 @@ +using System.Reflection; +using Amazon.CDK.Assertions; + +namespace Sagittaras.CDK.Testing.Resources; + +/// +/// Abstract implementation of . +/// +public abstract class ResourceAssertion : IResourceAssertion + where TProperties : IResourceProperties, new() +{ + /// + public abstract string Type { get; } + + /// + public IResourceDependency? DependsOn { get; set; } + + /// + public TProperties? Properties { get; set; } + + /// + /// Gets the property members of the derived class. + /// + private IEnumerable PropertyMembers => GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public); + + /// + public IDictionary GetResourceDescription(Template template) + { + Dictionary description = new(); + foreach (PropertyInfo member in PropertyMembers) + { + object? value = member.GetValue(this); + switch (value) + { + case null: + continue; + case IResourceProperties properties: + value = properties.ToDictionary(); + break; + case IResourceDependency dependency: + value = dependency.Resolve(template); + break; + } + + description.Add(member.Name, value); + } + + return description; + } +} \ No newline at end of file diff --git a/Sagittaras.CDK.Testing/Resources/ResourceDependency.cs b/Sagittaras.CDK.Testing/Resources/ResourceDependency.cs new file mode 100644 index 0000000..aabe506 --- /dev/null +++ b/Sagittaras.CDK.Testing/Resources/ResourceDependency.cs @@ -0,0 +1,36 @@ +using Amazon.CDK.Assertions; + +namespace Sagittaras.CDK.Testing.Resources; + +/// +/// Base implementation of the resource dependency. +/// +public class ResourceDependency : IResourceDependency +{ + /// + /// List of assertions that needs to be resolved as dependencies. + /// + private readonly List _dependencies = new(); + + /// + public IResourceDependency With(TResourceAssertion assertion) where TResourceAssertion : IResourceAssertion + { + _dependencies.Add(assertion); + return this; + } + + /// + public IEnumerable Resolve(Template template) + { + List resolved = new(); + foreach (IResourceAssertion assertion in _dependencies) + { + IEnumerable resolvedIds = template.FindResources(assertion.Type, assertion.GetResourceDescription(template)) + .Select(x => x.Key); + + resolved.AddRange(resolvedIds); + } + + return resolved.ToArray(); + } +} \ No newline at end of file diff --git a/Sagittaras.CDK.Testing/Resources/ResourceProperties.cs b/Sagittaras.CDK.Testing/Resources/ResourceProperties.cs new file mode 100644 index 0000000..e5bd247 --- /dev/null +++ b/Sagittaras.CDK.Testing/Resources/ResourceProperties.cs @@ -0,0 +1,35 @@ +using System.Reflection; + +namespace Sagittaras.CDK.Testing.Resources; + +/// +/// Abstract implementation of that provides a default implementation of . +/// +/// +/// The resource properties should be nullable types to exclude them from the dictionary. +/// +public abstract class ResourceProperties : IResourceProperties +{ + /// + /// Gets all properties members of the class. + /// + private IEnumerable Properties => GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance); + + /// + public IDictionary ToDictionary() + { + Dictionary dict = new(); + foreach (PropertyInfo property in Properties) + { + object? value = property.GetValue(this); + if (value is null) + { + continue; + } + + dict[property.Name] = value; + } + + return dict; + } +} \ No newline at end of file diff --git a/Sagittaras.CDK.Testing/Sagittaras.CDK.Testing.csproj b/Sagittaras.CDK.Testing/Sagittaras.CDK.Testing.csproj new file mode 100644 index 0000000..2fc8a91 --- /dev/null +++ b/Sagittaras.CDK.Testing/Sagittaras.CDK.Testing.csproj @@ -0,0 +1,20 @@ + + + + net6.0 + enable + enable + true + 1.0.0-preview-01 + Core test library for AWS CDK + Sagittaras Games + https://github.com/sagittaras/cdk.framework + https://github.com/sagittaras/cdk.framework/blob/main/LICENSE + https://github.com/sagittaras/cdk.framework + + + + + + + diff --git a/Sagittaras.CDK.Tests.Route53/PublicHostedZoneTest.cs b/Sagittaras.CDK.Tests.Route53/PublicHostedZoneTest.cs new file mode 100644 index 0000000..518284e --- /dev/null +++ b/Sagittaras.CDK.Tests.Route53/PublicHostedZoneTest.cs @@ -0,0 +1,72 @@ +using Amazon.CDK; +using Amazon.CDK.Assertions; +using Sagittaras.CDK.Framework.Route53; +using Sagittaras.CDK.Testing.Extensions; +using Sagittaras.CDK.Testing.KMS; +using Sagittaras.CDK.Testing.Resources; +using Sagittaras.CDK.Testing.Route53; +using Xunit; + +namespace Sagittaras.CDK.Tests.Route53; + +/// +/// Test creation of Public Hosted zone. +/// +public class PublicHostedZoneTest : ConstructTest +{ + private const string Domain = "example.com"; + private const string Comment = ""; + + /// + /// Tests basic usage of the factory for Hosted Zone. + /// + [Fact] + public void Test_BaseFactoryUsage() + { + new PublicHostedZoneFactory(Stack, Domain, Comment) + .Construct(); + + Template template = StackTemplate; + template.Assert(new HostedZoneAssertion + { + Properties = new HostedZoneProperties + { + Name = Domain + } + }); + template.AssertCount(1); + template.AssertCount(0); + } + + /// + /// Tests the creation of Hosted Zone with DNSSEC enabled. + /// + [Fact] + public void Test_DNSSEC() + { + new PublicHostedZoneFactory(Stack, Domain, Comment) + .WithDnsSec() + .Construct(); + + Template template = StackTemplate; + template.AssertCount(1); + template.Assert(new AliasAssertion + { + Properties = new AliasProperties + { + AliasName = "alias/examplecom-key" + } + }); + template.Assert(new KeySigningKeyAssertion + { + Properties = new KeySigningKeyProperties + { + Status = "ACTIVE" + } + }); + template.Assert(new DnsSecAssertion + { + DependsOn = new DnsSecDependency("examplecom") + }); + } +} \ No newline at end of file diff --git a/Sagittaras.CDK.Tests.Route53/Sagittaras.CDK.Tests.Route53.csproj b/Sagittaras.CDK.Tests.Route53/Sagittaras.CDK.Tests.Route53.csproj new file mode 100644 index 0000000..37f999a --- /dev/null +++ b/Sagittaras.CDK.Tests.Route53/Sagittaras.CDK.Tests.Route53.csproj @@ -0,0 +1,32 @@ + + + + net6.0 + enable + enable + + false + true + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + + + + diff --git a/Sagittaras.CDK.Tests/ConstructTest.cs b/Sagittaras.CDK.Tests/ConstructTest.cs new file mode 100644 index 0000000..2147478 --- /dev/null +++ b/Sagittaras.CDK.Tests/ConstructTest.cs @@ -0,0 +1,31 @@ +using Amazon.CDK; +using Amazon.CDK.Assertions; + +namespace Sagittaras.CDK.Tests; + +/// +/// Base class for easier writing of tests for constructs. +/// +public abstract class ConstructTest +{ + protected ConstructTest() + { + App = new App(); + Stack = new Stack(App); + } + + /// + /// Instance of App under which the stack is defined. + /// + protected App App { get; } + + /// + /// Instance of stack to which the constructs within the test can be assigned. + /// + protected Stack Stack { get; } + + /// + /// Creates a new instance of Assertion Template from current stack state. + /// + protected Template StackTemplate => Template.FromStack(Stack); +} \ No newline at end of file diff --git a/Sagittaras.CDK.Tests/Sagittaras.CDK.Tests.csproj b/Sagittaras.CDK.Tests/Sagittaras.CDK.Tests.csproj new file mode 100644 index 0000000..e0d3630 --- /dev/null +++ b/Sagittaras.CDK.Tests/Sagittaras.CDK.Tests.csproj @@ -0,0 +1,13 @@ + + + + net6.0 + enable + enable + + + + + + +