From 50a9e63da8a53a9ec31abf11d96f9223ddce05c8 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Tue, 11 Jun 2024 14:43:05 -0700 Subject: [PATCH 01/17] Split redis tests into separate test assembly --- Aspire.sln | 90 +++++++++++-------- .../Aspire.Hosting.Redis.csproj | 1 + src/Aspire.Hosting/Aspire.Hosting.csproj | 1 + .../Aspire.Hosting.Redis.Tests.csproj | 36 ++++++++ .../Directory.Build.props | 8 ++ .../Directory.Build.targets | 8 ++ .../Redis/AddRedisTests.cs | 2 +- .../XunitAttributes.cs | 6 ++ .../ContainerResourceBuilderTests.cs | 7 +- .../ManifestGenerationTests.cs | 4 +- 10 files changed, 118 insertions(+), 45 deletions(-) create mode 100644 tests/Aspire.Hosting.Redis.Tests/Aspire.Hosting.Redis.Tests.csproj create mode 100644 tests/Aspire.Hosting.Redis.Tests/Directory.Build.props create mode 100644 tests/Aspire.Hosting.Redis.Tests/Directory.Build.targets rename tests/{Aspire.Hosting.Tests => Aspire.Hosting.Redis.Tests}/Redis/AddRedisTests.cs (99%) create mode 100644 tests/Aspire.Hosting.Redis.Tests/XunitAttributes.cs diff --git a/Aspire.sln b/Aspire.sln index d215ac3336a..6b76002409f 100644 --- a/Aspire.sln +++ b/Aspire.sln @@ -1,4 +1,5 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 + +Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.0.31903.59 MinimumVisualStudioVersion = 10.0.40219.1 @@ -487,7 +488,13 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aspire.Milvus.Client.Tests" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aspire.Hosting.Azure.WebPubSub", "src\Aspire.Hosting.Azure.WebPubSub\Aspire.Hosting.Azure.WebPubSub.csproj", "{DF00FDA3-D3EC-4E07-B4EC-0EBB57A813A4}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aspire.Hosting.Valkey", "src\Aspire.Hosting.Valkey\Aspire.Hosting.Valkey.csproj", "{5CB63205-24F4-4388-A41B-BAF3BEA59866}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aspire.Hosting.Valkey", "src\Aspire.Hosting.Valkey\Aspire.Hosting.Valkey.csproj", "{5CB63205-24F4-4388-A41B-BAF3BEA59866}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Components", "Components", "{826BCF3D-5C1C-48BA-8758-205A9216A63D}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Hosting", "Hosting", "{B3391011-A6A7-4551-97FD-E9CF116A1334}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aspire.Hosting.Redis.Tests", "tests\Aspire.Hosting.Redis.Tests\Aspire.Hosting.Redis.Tests.csproj", "{E7F994F7-E94E-4713-9E26-0710E6613A06}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -495,10 +502,6 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {5CB63205-24F4-4388-A41B-BAF3BEA59866}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {5CB63205-24F4-4388-A41B-BAF3BEA59866}.Debug|Any CPU.Build.0 = Debug|Any CPU - {5CB63205-24F4-4388-A41B-BAF3BEA59866}.Release|Any CPU.ActiveCfg = Release|Any CPU - {5CB63205-24F4-4388-A41B-BAF3BEA59866}.Release|Any CPU.Build.0 = Release|Any CPU {B52DCF1A-465D-4E92-A68A-0EE1A9ED49DF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {B52DCF1A-465D-4E92-A68A-0EE1A9ED49DF}.Debug|Any CPU.Build.0 = Debug|Any CPU {B52DCF1A-465D-4E92-A68A-0EE1A9ED49DF}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -1287,12 +1290,19 @@ Global {DF00FDA3-D3EC-4E07-B4EC-0EBB57A813A4}.Debug|Any CPU.Build.0 = Debug|Any CPU {DF00FDA3-D3EC-4E07-B4EC-0EBB57A813A4}.Release|Any CPU.ActiveCfg = Release|Any CPU {DF00FDA3-D3EC-4E07-B4EC-0EBB57A813A4}.Release|Any CPU.Build.0 = Release|Any CPU + {5CB63205-24F4-4388-A41B-BAF3BEA59866}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5CB63205-24F4-4388-A41B-BAF3BEA59866}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5CB63205-24F4-4388-A41B-BAF3BEA59866}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5CB63205-24F4-4388-A41B-BAF3BEA59866}.Release|Any CPU.Build.0 = Release|Any CPU + {E7F994F7-E94E-4713-9E26-0710E6613A06}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E7F994F7-E94E-4713-9E26-0710E6613A06}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E7F994F7-E94E-4713-9E26-0710E6613A06}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E7F994F7-E94E-4713-9E26-0710E6613A06}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution - {5CB63205-24F4-4388-A41B-BAF3BEA59866} = {B80354C7-BE58-43F6-8928-9F3A74AB7F47} {B52DCF1A-465D-4E92-A68A-0EE1A9ED49DF} = {B80354C7-BE58-43F6-8928-9F3A74AB7F47} {E958BE04-81C2-434C-9E6C-CA145A2B8218} = {A68BA1A5-1604-433D-9778-DC0199831C2A} {C1D595AD-FFFD-4E52-AAF6-8DD8C4BD67F1} = {A68BA1A5-1604-433D-9778-DC0199831C2A} @@ -1305,17 +1315,17 @@ Global {7570F683-EB48-467F-B1B1-70FF0153F52B} = {63BB22D3-0FAC-4E87-BF9D-9FA2441684C9} {327CB76F-3BB8-4955-A01D-CD8553AD36CC} = {63BB22D3-0FAC-4E87-BF9D-9FA2441684C9} {B38EBDC8-9255-4AC2-A10E-5C908D4BE862} = {77CFE74A-32EE-400C-8930-5025E8555256} - {5A7D4F1C-98CB-45D5-955E-A601CFA70884} = {4981B3A5-4AFD-4191-BF7D-8692D9783D60} + {5A7D4F1C-98CB-45D5-955E-A601CFA70884} = {826BCF3D-5C1C-48BA-8758-205A9216A63D} {CC9CD371-9909-4101-83F1-22C7C2617DE4} = {27381127-6C45-4B4C-8F18-41FF48DFE4B2} {955EDC6D-11A3-4408-9C00-7BFE140AD597} = {A68BA1A5-1604-433D-9778-DC0199831C2A} {0F505BE9-42FE-49EC-93CC-57584C4C9671} = {27381127-6C45-4B4C-8F18-41FF48DFE4B2} {47714F18-6CEC-4F61-92BC-BAE60C619F61} = {27381127-6C45-4B4C-8F18-41FF48DFE4B2} {39AD3DBA-6B79-44FC-9637-232544D0CA46} = {27381127-6C45-4B4C-8F18-41FF48DFE4B2} {0C97F423-DAAE-4B63-B1B1-CB85E2840B98} = {27381127-6C45-4B4C-8F18-41FF48DFE4B2} - {23075FC1-D893-434D-9A20-02870B96ABA7} = {4981B3A5-4AFD-4191-BF7D-8692D9783D60} - {F371C3EE-8AB3-4261-A5F2-9A1FF77ADC19} = {4981B3A5-4AFD-4191-BF7D-8692D9783D60} - {6E7B2D62-A1A4-4232-8FA9-DB01A454B9C1} = {4981B3A5-4AFD-4191-BF7D-8692D9783D60} - {26E8EA4C-D3A6-4C6A-900D-2AA2C80D0AAF} = {4981B3A5-4AFD-4191-BF7D-8692D9783D60} + {23075FC1-D893-434D-9A20-02870B96ABA7} = {826BCF3D-5C1C-48BA-8758-205A9216A63D} + {F371C3EE-8AB3-4261-A5F2-9A1FF77ADC19} = {826BCF3D-5C1C-48BA-8758-205A9216A63D} + {6E7B2D62-A1A4-4232-8FA9-DB01A454B9C1} = {826BCF3D-5C1C-48BA-8758-205A9216A63D} + {26E8EA4C-D3A6-4C6A-900D-2AA2C80D0AAF} = {826BCF3D-5C1C-48BA-8758-205A9216A63D} {7C4F0F84-BAEC-469D-A3BC-28209B2C11AC} = {4981B3A5-4AFD-4191-BF7D-8692D9783D60} {CD7BF1EC-ABF9-48DE-8683-353216DB4958} = {7C4F0F84-BAEC-469D-A3BC-28209B2C11AC} {845B39FE-A982-44EB-A4DB-CCCD93CBF261} = {7C4F0F84-BAEC-469D-A3BC-28209B2C11AC} @@ -1323,17 +1333,17 @@ Global {AC5970BF-7A71-4CFE-BC21-8E597ECD347C} = {27381127-6C45-4B4C-8F18-41FF48DFE4B2} {D403DB4A-ABFC-4B13-A920-C6AC9B3EEE0B} = {B80354C7-BE58-43F6-8928-9F3A74AB7F47} {88A89C15-11DF-4F32-AA61-6896AF09F470} = {27381127-6C45-4B4C-8F18-41FF48DFE4B2} - {06D5A9E7-8CAA-4F0F-A41E-8C97D2FF8542} = {4981B3A5-4AFD-4191-BF7D-8692D9783D60} + {06D5A9E7-8CAA-4F0F-A41E-8C97D2FF8542} = {826BCF3D-5C1C-48BA-8758-205A9216A63D} {2E1E217C-A836-49E3-B655-6E42AD3E7943} = {27381127-6C45-4B4C-8F18-41FF48DFE4B2} - {59B8C4DE-FB94-4670-9DDE-B04F461219CB} = {4981B3A5-4AFD-4191-BF7D-8692D9783D60} + {59B8C4DE-FB94-4670-9DDE-B04F461219CB} = {826BCF3D-5C1C-48BA-8758-205A9216A63D} {FFFD251E-F555-4008-A759-5727784B0C98} = {27381127-6C45-4B4C-8F18-41FF48DFE4B2} - {E0E0D5C0-E8D1-458E-9C3A-F0B858BBAD3B} = {4981B3A5-4AFD-4191-BF7D-8692D9783D60} + {E0E0D5C0-E8D1-458E-9C3A-F0B858BBAD3B} = {826BCF3D-5C1C-48BA-8758-205A9216A63D} {EEED6AD9-6FC3-4483-B44E-691FF2DECFAF} = {63BB22D3-0FAC-4E87-BF9D-9FA2441684C9} {A3262B32-E4F6-4F95-9BB9-D522F798C0D3} = {27381127-6C45-4B4C-8F18-41FF48DFE4B2} - {B130B8E2-BF6E-4541-856F-F51558F8050A} = {4981B3A5-4AFD-4191-BF7D-8692D9783D60} + {B130B8E2-BF6E-4541-856F-F51558F8050A} = {826BCF3D-5C1C-48BA-8758-205A9216A63D} {1CB79745-8A58-4AE7-B6C8-2362DCDB1CA6} = {27381127-6C45-4B4C-8F18-41FF48DFE4B2} - {56D1697B-8CF9-4994-A484-060878821F9D} = {4981B3A5-4AFD-4191-BF7D-8692D9783D60} - {D3B3AFFF-211A-4450-AE5E-055BD1323D2E} = {4981B3A5-4AFD-4191-BF7D-8692D9783D60} + {56D1697B-8CF9-4994-A484-060878821F9D} = {826BCF3D-5C1C-48BA-8758-205A9216A63D} + {D3B3AFFF-211A-4450-AE5E-055BD1323D2E} = {B3391011-A6A7-4551-97FD-E9CF116A1334} {C3BA722D-B03F-465B-BC47-421CA97B97E0} = {975F6F41-B455-451D-A312-098DE4A167B6} {975F6F41-B455-451D-A312-098DE4A167B6} = {4981B3A5-4AFD-4191-BF7D-8692D9783D60} {31F5E4F3-AC4E-4538-BC7D-85BCF9CA686A} = {975F6F41-B455-451D-A312-098DE4A167B6} @@ -1342,9 +1352,9 @@ Global {1ABCD945-5CAA-4F30-A741-7A9DA919254A} = {4981B3A5-4AFD-4191-BF7D-8692D9783D60} {8C6877C0-3CB2-4B99-B8BD-1B7D0CADB543} = {F534D4F8-5E3A-42FC-BCD7-4C2D6060F9C8} {E20280B8-8BE0-4967-AFC2-65FFCD6EC5E4} = {F534D4F8-5E3A-42FC-BCD7-4C2D6060F9C8} - {6EAA089D-7ADD-4C74-B040-FD3D75DB5C75} = {4981B3A5-4AFD-4191-BF7D-8692D9783D60} - {9D9C360B-9DF1-4076-8416-66964427C8F3} = {4981B3A5-4AFD-4191-BF7D-8692D9783D60} - {67B9A8E4-7F51-4419-85BC-4BB0C2E67E71} = {4981B3A5-4AFD-4191-BF7D-8692D9783D60} + {6EAA089D-7ADD-4C74-B040-FD3D75DB5C75} = {826BCF3D-5C1C-48BA-8758-205A9216A63D} + {9D9C360B-9DF1-4076-8416-66964427C8F3} = {826BCF3D-5C1C-48BA-8758-205A9216A63D} + {67B9A8E4-7F51-4419-85BC-4BB0C2E67E71} = {826BCF3D-5C1C-48BA-8758-205A9216A63D} {57A42144-739E-49A7-BADB-BB8F5F20FA17} = {D173887B-AF42-4576-B9C1-96B9E9B3D9C0} {185BCD98-BD26-4535-BE6E-44AAA4F7C145} = {57A42144-739E-49A7-BADB-BB8F5F20FA17} {B1D88C56-46EB-4171-A997-56E67875CF80} = {57A42144-739E-49A7-BADB-BB8F5F20FA17} @@ -1353,14 +1363,14 @@ Global {A68BA1A5-1604-433D-9778-DC0199831C2A} = {D173887B-AF42-4576-B9C1-96B9E9B3D9C0} {23298562-C1D4-41CD-83FE-426C94FEE35F} = {27381127-6C45-4B4C-8F18-41FF48DFE4B2} {00C9BA50-2AFB-4D9C-A2D6-8154BCCD0A63} = {27381127-6C45-4B4C-8F18-41FF48DFE4B2} - {A5836BC1-6A45-4BB6-9D22-A7F750890AB8} = {4981B3A5-4AFD-4191-BF7D-8692D9783D60} - {FDA02617-9C49-4DA8-A43A-A34DBA9B8596} = {4981B3A5-4AFD-4191-BF7D-8692D9783D60} + {A5836BC1-6A45-4BB6-9D22-A7F750890AB8} = {826BCF3D-5C1C-48BA-8758-205A9216A63D} + {FDA02617-9C49-4DA8-A43A-A34DBA9B8596} = {826BCF3D-5C1C-48BA-8758-205A9216A63D} {A84C4EE3-2601-4804-BCDC-E9948E164A22} = {A68BA1A5-1604-433D-9778-DC0199831C2A} {4D8A92AB-4E77-4965-AD8E-8E206DCE66A4} = {27381127-6C45-4B4C-8F18-41FF48DFE4B2} - {165411FE-755E-4869-A756-F87F455860AC} = {4981B3A5-4AFD-4191-BF7D-8692D9783D60} + {165411FE-755E-4869-A756-F87F455860AC} = {826BCF3D-5C1C-48BA-8758-205A9216A63D} {6472D59F-7C04-43DE-AD33-9F20BE3804BF} = {975F6F41-B455-451D-A312-098DE4A167B6} {CA283D7F-EB95-4353-B196-C409965D2B42} = {27381127-6C45-4B4C-8F18-41FF48DFE4B2} - {C8079F06-304F-49B1-A0C1-45AA3782A923} = {4981B3A5-4AFD-4191-BF7D-8692D9783D60} + {C8079F06-304F-49B1-A0C1-45AA3782A923} = {826BCF3D-5C1C-48BA-8758-205A9216A63D} {DCF2D47A-921A-4900-B5B2-CF97B3531CE8} = {975F6F41-B455-451D-A312-098DE4A167B6} {91F22EEA-EB23-425A-9B32-9438A0809F4B} = {D173887B-AF42-4576-B9C1-96B9E9B3D9C0} {74F89D52-645B-4283-98AF-D04DA794EE37} = {91F22EEA-EB23-425A-9B32-9438A0809F4B} @@ -1373,25 +1383,25 @@ Global {3112D63C-A9E3-44F8-92A5-8F3052627312} = {B80354C7-BE58-43F6-8928-9F3A74AB7F47} {20A5A907-A135-4735-B4BF-E13514F360E3} = {27381127-6C45-4B4C-8F18-41FF48DFE4B2} {39FA2A64-012F-4EB9-A14F-E8AC54C975F6} = {2136E31D-2CBB-41BB-8618-716FF8E46E9E} - {E592E447-BA3C-44FA-86C1-EBEDC864A644} = {4981B3A5-4AFD-4191-BF7D-8692D9783D60} + {E592E447-BA3C-44FA-86C1-EBEDC864A644} = {826BCF3D-5C1C-48BA-8758-205A9216A63D} {00FEA181-84C9-42A7-AC81-29A9F176A1A0} = {4981B3A5-4AFD-4191-BF7D-8692D9783D60} {1828FA88-6BFB-437E-A163-A98AE2B948F1} = {27381127-6C45-4B4C-8F18-41FF48DFE4B2} - {52CF3584-4861-4769-AD20-F7173F2D8F75} = {4981B3A5-4AFD-4191-BF7D-8692D9783D60} + {52CF3584-4861-4769-AD20-F7173F2D8F75} = {826BCF3D-5C1C-48BA-8758-205A9216A63D} {A778F29A-6C40-4C53-A793-F23F20679ADE} = {27381127-6C45-4B4C-8F18-41FF48DFE4B2} - {A331C123-35A5-4E81-9999-354159821374} = {4981B3A5-4AFD-4191-BF7D-8692D9783D60} + {A331C123-35A5-4E81-9999-354159821374} = {826BCF3D-5C1C-48BA-8758-205A9216A63D} {11EF253D-086B-4358-9A50-2695913BD7E1} = {B80354C7-BE58-43F6-8928-9F3A74AB7F47} {8BAF2119-8370-4E9E-A887-D92506F8C727} = {D173887B-AF42-4576-B9C1-96B9E9B3D9C0} {04B03D1C-45C5-44D4-AEE5-BC315F3D9D26} = {8BAF2119-8370-4E9E-A887-D92506F8C727} {20758E81-7316-49AC-8E1B-A5461397530A} = {8BAF2119-8370-4E9E-A887-D92506F8C727} {F7D9FA54-1F64-4A36-961A-0087F8E88D07} = {8BAF2119-8370-4E9E-A887-D92506F8C727} {174E0507-3BB0-4CDC-829E-9CA75DA66473} = {27381127-6C45-4B4C-8F18-41FF48DFE4B2} - {A8CB331A-1247-41D9-8118-538E5A2CC9DF} = {4981B3A5-4AFD-4191-BF7D-8692D9783D60} + {A8CB331A-1247-41D9-8118-538E5A2CC9DF} = {826BCF3D-5C1C-48BA-8758-205A9216A63D} {DBEDDF76-1C33-4943-8CCB-337A7D48AFF5} = {D173887B-AF42-4576-B9C1-96B9E9B3D9C0} {51DDD6BC-1D6C-466A-B509-FC49E3BD72E4} = {DBEDDF76-1C33-4943-8CCB-337A7D48AFF5} {EABB20A8-CDA2-4AFE-A5B1-FB631200CD64} = {DBEDDF76-1C33-4943-8CCB-337A7D48AFF5} {25208C6F-0A9D-4D60-9EDD-256C9891B1CD} = {D173887B-AF42-4576-B9C1-96B9E9B3D9C0} {C565532A-0754-44FE-A0C7-78D5338DDBCA} = {27381127-6C45-4B4C-8F18-41FF48DFE4B2} - {BFAF55A8-A737-4EC1-BBA2-76001A8F16E0} = {4981B3A5-4AFD-4191-BF7D-8692D9783D60} + {BFAF55A8-A737-4EC1-BBA2-76001A8F16E0} = {826BCF3D-5C1C-48BA-8758-205A9216A63D} {2CA6AB88-21EF-4488-BB1B-3A5BAD5FE2AD} = {D173887B-AF42-4576-B9C1-96B9E9B3D9C0} {7616FD70-6BEC-439D-B39E-A838F939C0F9} = {2CA6AB88-21EF-4488-BB1B-3A5BAD5FE2AD} {78ABCF96-507B-4E5F-9265-CACC3EFD4C53} = {2CA6AB88-21EF-4488-BB1B-3A5BAD5FE2AD} @@ -1400,7 +1410,7 @@ Global {40EC38A2-69DB-4759-81C8-13F31090FEA6} = {C544D8A6-977E-40EA-8B1A-1FB2146A2108} {83267206-9438-42CD-860C-C92E7DBAA4C3} = {A68BA1A5-1604-433D-9778-DC0199831C2A} {0921F457-16A7-40C8-86B4-7FB02D52244F} = {27381127-6C45-4B4C-8F18-41FF48DFE4B2} - {3DE1697E-BB8C-4EBA-8DCA-0A6A94804689} = {4981B3A5-4AFD-4191-BF7D-8692D9783D60} + {3DE1697E-BB8C-4EBA-8DCA-0A6A94804689} = {826BCF3D-5C1C-48BA-8758-205A9216A63D} {C1483B79-4FE9-47FF-B544-EB5DBB7A0A3E} = {4981B3A5-4AFD-4191-BF7D-8692D9783D60} {F1387494-34DE-4B31-B587-699B2E9A20CA} = {D173887B-AF42-4576-B9C1-96B9E9B3D9C0} {54B66163-016D-4122-9364-409AB61BC36B} = {F1387494-34DE-4B31-B587-699B2E9A20CA} @@ -1423,12 +1433,12 @@ Global {8AA07A14-A4A7-45EC-B0F6-4690B516B16D} = {D173887B-AF42-4576-B9C1-96B9E9B3D9C0} {157A434E-E3CA-4080-96CF-903CC3DF66E9} = {8AA07A14-A4A7-45EC-B0F6-4690B516B16D} {921CB408-5E37-4354-B4CF-EAE517F633DC} = {8AA07A14-A4A7-45EC-B0F6-4690B516B16D} - {C774BE00-EE93-4148-B866-8F0F2BA1E473} = {4981B3A5-4AFD-4191-BF7D-8692D9783D60} + {C774BE00-EE93-4148-B866-8F0F2BA1E473} = {826BCF3D-5C1C-48BA-8758-205A9216A63D} {0870A667-FB0C-4758-AEAF-9E5F092AD7C1} = {4981B3A5-4AFD-4191-BF7D-8692D9783D60} {C4833DEC-0A4F-4504-B8D0-06C60B84119C} = {91F22EEA-EB23-425A-9B32-9438A0809F4B} {9CA94707-E801-444F-A582-D5BD0104CF9B} = {91F22EEA-EB23-425A-9B32-9438A0809F4B} {3216CF59-84B0-46FF-8572-D0AFB0155423} = {A7C6452C-FEDB-4883-9AE7-29892D260AA3} - {BE46B5B3-DFD4-4565-A2CD-7D95C623B03D} = {4981B3A5-4AFD-4191-BF7D-8692D9783D60} + {BE46B5B3-DFD4-4565-A2CD-7D95C623B03D} = {B3391011-A6A7-4551-97FD-E9CF116A1334} {8B1802BC-6CB0-4027-850C-2AED42A82C9E} = {D173887B-AF42-4576-B9C1-96B9E9B3D9C0} {7CC9BADD-B444-49E0-B6F0-BE2CD3A4669E} = {8B1802BC-6CB0-4027-850C-2AED42A82C9E} {E5C93F8B-D31B-4268-89EB-830EDC5524D0} = {8B1802BC-6CB0-4027-850C-2AED42A82C9E} @@ -1446,7 +1456,7 @@ Global {51654CD7-2E05-4664-B2EB-95308A300609} = {9C30FFD6-2262-45E7-B010-24B30E0433C2} {0244203D-7491-4414-9C88-10BFED9C5B2D} = {9C30FFD6-2262-45E7-B010-24B30E0433C2} {7C07AF64-1E53-4640-A7EF-6EE23D2F0BDA} = {27381127-6C45-4B4C-8F18-41FF48DFE4B2} - {D13F77BA-1FD1-4CEA-AEBB-9A28B033B2D3} = {4981B3A5-4AFD-4191-BF7D-8692D9783D60} + {D13F77BA-1FD1-4CEA-AEBB-9A28B033B2D3} = {826BCF3D-5C1C-48BA-8758-205A9216A63D} {90A70EFA-F26A-49E0-A375-DB461E4E0E25} = {D173887B-AF42-4576-B9C1-96B9E9B3D9C0} {36B782B3-9515-4AF0-BDB1-52062CECF6FD} = {90A70EFA-F26A-49E0-A375-DB461E4E0E25} {B1EB813D-1CAA-406F-9786-756939B7232C} = {90A70EFA-F26A-49E0-A375-DB461E4E0E25} @@ -1503,12 +1513,12 @@ Global {74644A4D-8F61-4314-B6E8-5CE3802CD6C2} = {4981B3A5-4AFD-4191-BF7D-8692D9783D60} {427F4D7C-8969-4015-AD1A-5EFFE921A184} = {77CFE74A-32EE-400C-8930-5025E8555256} {E0E1B557-D3CF-4446-B993-E5CE719234FB} = {27381127-6C45-4B4C-8F18-41FF48DFE4B2} - {A9CFA376-0C90-4231-9152-FBF14065195A} = {4981B3A5-4AFD-4191-BF7D-8692D9783D60} - {8191109E-130C-47F3-B84E-82070A6CD269} = {4981B3A5-4AFD-4191-BF7D-8692D9783D60} + {A9CFA376-0C90-4231-9152-FBF14065195A} = {826BCF3D-5C1C-48BA-8758-205A9216A63D} + {8191109E-130C-47F3-B84E-82070A6CD269} = {826BCF3D-5C1C-48BA-8758-205A9216A63D} {906B5687-31AD-4364-AD9F-B4B26113462D} = {8BAF2119-8370-4E9E-A887-D92506F8C727} {75760E8A-7025-4F6A-B152-6622688D0E7D} = {8BAF2119-8370-4E9E-A887-D92506F8C727} {3ECB176E-3CC8-4BEE-AF48-F439F9742C8B} = {4981B3A5-4AFD-4191-BF7D-8692D9783D60} - {0505F739-6F85-4502-A554-77E0D7325F26} = {4981B3A5-4AFD-4191-BF7D-8692D9783D60} + {0505F739-6F85-4502-A554-77E0D7325F26} = {826BCF3D-5C1C-48BA-8758-205A9216A63D} {B5D637F3-7E44-4C7D-AE4B-D56D400671CD} = {7C4F0F84-BAEC-469D-A3BC-28209B2C11AC} {920BB263-E68F-4FA2-93FC-2E385EEA405B} = {D173887B-AF42-4576-B9C1-96B9E9B3D9C0} {A39389A0-E780-4B97-808B-DC95CF59B35C} = {920BB263-E68F-4FA2-93FC-2E385EEA405B} @@ -1519,8 +1529,12 @@ Global {13219E70-5647-4B71-95DC-2C8AFA2A4C5D} = {BD2CD8FB-18EC-4930-8228-C49D89622022} {1A3A4865-69F2-4251-9A95-2D57C6A46870} = {B80354C7-BE58-43F6-8928-9F3A74AB7F47} {1BFE3C02-3B81-4596-99A2-4DCDD9129C9A} = {27381127-6C45-4B4C-8F18-41FF48DFE4B2} - {9FAE1602-2C69-4D24-8655-A164489441E8} = {4981B3A5-4AFD-4191-BF7D-8692D9783D60} + {9FAE1602-2C69-4D24-8655-A164489441E8} = {826BCF3D-5C1C-48BA-8758-205A9216A63D} {DF00FDA3-D3EC-4E07-B4EC-0EBB57A813A4} = {77CFE74A-32EE-400C-8930-5025E8555256} + {5CB63205-24F4-4388-A41B-BAF3BEA59866} = {B80354C7-BE58-43F6-8928-9F3A74AB7F47} + {826BCF3D-5C1C-48BA-8758-205A9216A63D} = {4981B3A5-4AFD-4191-BF7D-8692D9783D60} + {B3391011-A6A7-4551-97FD-E9CF116A1334} = {4981B3A5-4AFD-4191-BF7D-8692D9783D60} + {E7F994F7-E94E-4713-9E26-0710E6613A06} = {B3391011-A6A7-4551-97FD-E9CF116A1334} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {6DCEDFEC-988E-4CB3-B45B-191EB5086E0C} diff --git a/src/Aspire.Hosting.Redis/Aspire.Hosting.Redis.csproj b/src/Aspire.Hosting.Redis/Aspire.Hosting.Redis.csproj index 9cd1332fcf7..8b54b395bee 100644 --- a/src/Aspire.Hosting.Redis/Aspire.Hosting.Redis.csproj +++ b/src/Aspire.Hosting.Redis/Aspire.Hosting.Redis.csproj @@ -18,6 +18,7 @@ + diff --git a/src/Aspire.Hosting/Aspire.Hosting.csproj b/src/Aspire.Hosting/Aspire.Hosting.csproj index 111c972b3ba..229cda36323 100644 --- a/src/Aspire.Hosting/Aspire.Hosting.csproj +++ b/src/Aspire.Hosting/Aspire.Hosting.csproj @@ -62,6 +62,7 @@ + diff --git a/tests/Aspire.Hosting.Redis.Tests/Aspire.Hosting.Redis.Tests.csproj b/tests/Aspire.Hosting.Redis.Tests/Aspire.Hosting.Redis.Tests.csproj new file mode 100644 index 00000000000..ecfffea6be9 --- /dev/null +++ b/tests/Aspire.Hosting.Redis.Tests/Aspire.Hosting.Redis.Tests.csproj @@ -0,0 +1,36 @@ + + + + $(NetCurrent) + true + + $(NoWarn);CS8002 + + + + + + + + + + + + + + + + + + + Always + + + + + + + + diff --git a/tests/Aspire.Hosting.Redis.Tests/Directory.Build.props b/tests/Aspire.Hosting.Redis.Tests/Directory.Build.props new file mode 100644 index 00000000000..6386f3ec197 --- /dev/null +++ b/tests/Aspire.Hosting.Redis.Tests/Directory.Build.props @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/tests/Aspire.Hosting.Redis.Tests/Directory.Build.targets b/tests/Aspire.Hosting.Redis.Tests/Directory.Build.targets new file mode 100644 index 00000000000..be739139f72 --- /dev/null +++ b/tests/Aspire.Hosting.Redis.Tests/Directory.Build.targets @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/tests/Aspire.Hosting.Tests/Redis/AddRedisTests.cs b/tests/Aspire.Hosting.Redis.Tests/Redis/AddRedisTests.cs similarity index 99% rename from tests/Aspire.Hosting.Tests/Redis/AddRedisTests.cs rename to tests/Aspire.Hosting.Redis.Tests/Redis/AddRedisTests.cs index e6cfb50a9a1..accbebfa9c8 100644 --- a/tests/Aspire.Hosting.Tests/Redis/AddRedisTests.cs +++ b/tests/Aspire.Hosting.Redis.Tests/Redis/AddRedisTests.cs @@ -218,7 +218,7 @@ public void WithDataVolumeAddsVolumeAnnotation(bool? isReadOnly) var volumeAnnotation = redis.Resource.Annotations.OfType().Single(); - Assert.Equal("Aspire.Hosting.Tests-myRedis-data", volumeAnnotation.Source); + Assert.Equal("Aspire.Hosting.Redis.Tests-myRedis-data", volumeAnnotation.Source); Assert.Equal("/data", volumeAnnotation.Target); Assert.Equal(ContainerMountType.Volume, volumeAnnotation.Type); Assert.Equal(isReadOnly ?? false, volumeAnnotation.IsReadOnly); diff --git a/tests/Aspire.Hosting.Redis.Tests/XunitAttributes.cs b/tests/Aspire.Hosting.Redis.Tests/XunitAttributes.cs new file mode 100644 index 00000000000..92234b21820 --- /dev/null +++ b/tests/Aspire.Hosting.Redis.Tests/XunitAttributes.cs @@ -0,0 +1,6 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Xunit; + +[assembly: CollectionBehavior(DisableTestParallelization = true)] diff --git a/tests/Aspire.Hosting.Tests/Containers/ContainerResourceBuilderTests.cs b/tests/Aspire.Hosting.Tests/Containers/ContainerResourceBuilderTests.cs index 73497d5e63e..744c37e06f8 100644 --- a/tests/Aspire.Hosting.Tests/Containers/ContainerResourceBuilderTests.cs +++ b/tests/Aspire.Hosting.Tests/Containers/ContainerResourceBuilderTests.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Aspire.Hosting.Redis; using Aspire.Hosting.Utils; using Xunit; @@ -54,8 +53,8 @@ public void WithImageMutatesImageNameOfLastAnnotation() public void WithImageTagMutatesImageTag() { using var builder = TestDistributedApplicationBuilder.Create(); - var redis = builder.AddRedis("redis").WithImageTag(RedisContainerImageTags.Tag); - Assert.Equal(RedisContainerImageTags.Tag, redis.Resource.Annotations.OfType().Single().Tag); + var redis = builder.AddRedis("redis").WithImageTag("7.1"); + Assert.Equal("7.1", redis.Resource.Annotations.OfType().Single().Tag); } [Fact] @@ -80,7 +79,7 @@ public void WithImageTagThrowsIfNoImageAnnotation() using var builder = TestDistributedApplicationBuilder.Create(); var container = builder.AddResource(new TestContainerResource("testcontainer")); - var exception = Assert.Throws(() => container.WithImageTag(RedisContainerImageTags.Tag)); + var exception = Assert.Throws(() => container.WithImageTag("7.1")); Assert.Equal("The resource 'testcontainer' does not have a container image specified. Use WithImage to specify the container image and tag.", exception.Message); } diff --git a/tests/Aspire.Hosting.Tests/ManifestGenerationTests.cs b/tests/Aspire.Hosting.Tests/ManifestGenerationTests.cs index 8c28c2e330a..5f5b13b2dd6 100644 --- a/tests/Aspire.Hosting.Tests/ManifestGenerationTests.cs +++ b/tests/Aspire.Hosting.Tests/ManifestGenerationTests.cs @@ -97,7 +97,7 @@ public async Task WithContainerRegistryUpdatesContainerImageAnnotationsDuringPub ContainerRegistryOverride = "myprivateregistry.company.com" }); - var redis = builder.AddRedis("redis"); + var redis = builder.AddContainer("redis", "redis"); builder.Build().Run(); var redisManifest = await ManifestUtils.GetManifest(redis.Resource); @@ -105,7 +105,7 @@ public async Task WithContainerRegistryUpdatesContainerImageAnnotationsDuringPub { "type": "container.v0", "connectionString": "{redis.bindings.tcp.host}:{redis.bindings.tcp.port}", - "image": "myprivateregistry.company.com/{{RedisContainerImageTags.Image}}:{{RedisContainerImageTags.Tag}}", + "image": "myprivateregistry.company.com/redis:latest", "bindings": { "tcp": { "scheme": "tcp", From 8d36ff8a9fc6e77de04cc2f2547be5c91eeb5834 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Tue, 11 Jun 2024 15:20:10 -0700 Subject: [PATCH 02/17] Made some fixes --- .../{Redis => }/AddRedisTests.cs | 9 +++++---- .../Aspire.Hosting.Redis.Tests.csproj | 1 + tests/Aspire.Hosting.Redis.Tests/XunitAttributes.cs | 6 ------ tests/Aspire.Hosting.Tests/ManifestGenerationTests.cs | 11 +---------- 4 files changed, 7 insertions(+), 20 deletions(-) rename tests/Aspire.Hosting.Redis.Tests/{Redis => }/AddRedisTests.cs (98%) delete mode 100644 tests/Aspire.Hosting.Redis.Tests/XunitAttributes.cs diff --git a/tests/Aspire.Hosting.Redis.Tests/Redis/AddRedisTests.cs b/tests/Aspire.Hosting.Redis.Tests/AddRedisTests.cs similarity index 98% rename from tests/Aspire.Hosting.Redis.Tests/Redis/AddRedisTests.cs rename to tests/Aspire.Hosting.Redis.Tests/AddRedisTests.cs index accbebfa9c8..61d57c12a9e 100644 --- a/tests/Aspire.Hosting.Redis.Tests/Redis/AddRedisTests.cs +++ b/tests/Aspire.Hosting.Redis.Tests/AddRedisTests.cs @@ -2,13 +2,12 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Net.Sockets; -using Aspire.Hosting.Redis; using Aspire.Hosting.Tests.Utils; using Aspire.Hosting.Utils; using Microsoft.Extensions.DependencyInjection; using Xunit; -namespace Aspire.Hosting.Tests.Redis; +namespace Aspire.Hosting.Redis.Tests; public class AddRedisTests { @@ -125,7 +124,8 @@ public void WithRedisCommanderAddsRedisCommanderResource() public void WithRedisCommanderSupportsChangingContainerImageValues() { var builder = DistributedApplication.CreateBuilder(); - builder.AddRedis("myredis").WithRedisCommander(c => { + builder.AddRedis("myredis").WithRedisCommander(c => + { c.WithImageRegistry("example.mycompany.com"); c.WithImage("customrediscommander"); c.WithImageTag("someothertag"); @@ -142,7 +142,8 @@ public void WithRedisCommanderSupportsChangingContainerImageValues() public void WithRedisCommanderSupportsChangingHostPort() { var builder = DistributedApplication.CreateBuilder(); - builder.AddRedis("myredis").WithRedisCommander(c => { + builder.AddRedis("myredis").WithRedisCommander(c => + { c.WithHostPort(1000); }); diff --git a/tests/Aspire.Hosting.Redis.Tests/Aspire.Hosting.Redis.Tests.csproj b/tests/Aspire.Hosting.Redis.Tests/Aspire.Hosting.Redis.Tests.csproj index ecfffea6be9..a9285f4b93e 100644 --- a/tests/Aspire.Hosting.Redis.Tests/Aspire.Hosting.Redis.Tests.csproj +++ b/tests/Aspire.Hosting.Redis.Tests/Aspire.Hosting.Redis.Tests.csproj @@ -23,6 +23,7 @@ + Always diff --git a/tests/Aspire.Hosting.Redis.Tests/XunitAttributes.cs b/tests/Aspire.Hosting.Redis.Tests/XunitAttributes.cs deleted file mode 100644 index 92234b21820..00000000000 --- a/tests/Aspire.Hosting.Redis.Tests/XunitAttributes.cs +++ /dev/null @@ -1,6 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Xunit; - -[assembly: CollectionBehavior(DisableTestParallelization = true)] diff --git a/tests/Aspire.Hosting.Tests/ManifestGenerationTests.cs b/tests/Aspire.Hosting.Tests/ManifestGenerationTests.cs index 5f5b13b2dd6..e744004a333 100644 --- a/tests/Aspire.Hosting.Tests/ManifestGenerationTests.cs +++ b/tests/Aspire.Hosting.Tests/ManifestGenerationTests.cs @@ -104,16 +104,7 @@ public async Task WithContainerRegistryUpdatesContainerImageAnnotationsDuringPub var expectedManifest = $$""" { "type": "container.v0", - "connectionString": "{redis.bindings.tcp.host}:{redis.bindings.tcp.port}", - "image": "myprivateregistry.company.com/redis:latest", - "bindings": { - "tcp": { - "scheme": "tcp", - "protocol": "tcp", - "transport": "tcp", - "targetPort": 6379 - } - } + "image": "myprivateregistry.company.com/redis:latest" } """; Assert.Equal(expectedManifest, redisManifest.ToString()); From c6a165575c13c9a387afb910c10345dac0ce7c4c Mon Sep 17 00:00:00 2001 From: David Fowler Date: Wed, 12 Jun 2024 06:10:20 -0700 Subject: [PATCH 03/17] Added functional test --- .../Aspire.Hosting.Redis.Tests.csproj | 1 + .../RedisFunctionalTests.cs | 49 +++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 tests/Aspire.Hosting.Redis.Tests/RedisFunctionalTests.cs diff --git a/tests/Aspire.Hosting.Redis.Tests/Aspire.Hosting.Redis.Tests.csproj b/tests/Aspire.Hosting.Redis.Tests/Aspire.Hosting.Redis.Tests.csproj index a9285f4b93e..b340c1e9c64 100644 --- a/tests/Aspire.Hosting.Redis.Tests/Aspire.Hosting.Redis.Tests.csproj +++ b/tests/Aspire.Hosting.Redis.Tests/Aspire.Hosting.Redis.Tests.csproj @@ -12,6 +12,7 @@ + diff --git a/tests/Aspire.Hosting.Redis.Tests/RedisFunctionalTests.cs b/tests/Aspire.Hosting.Redis.Tests/RedisFunctionalTests.cs new file mode 100644 index 00000000000..011aed73ce9 --- /dev/null +++ b/tests/Aspire.Hosting.Redis.Tests/RedisFunctionalTests.cs @@ -0,0 +1,49 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Aspire.Hosting.Utils; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using StackExchange.Redis; +using Xunit; + +namespace Aspire.Hosting.Redis.Tests; + +public class RedisFunctionalTests +{ + [Fact] + public async Task VerifyRedisResource() + { + var builder = TestDistributedApplicationBuilder.Create(); + + var redis = builder.AddRedis("redis"); + + using var app = builder.Build(); + + await app.StartAsync(); + + var hb = Host.CreateApplicationBuilder(); + + hb.Configuration.AddInMemoryCollection(new Dictionary + { + ["ConnectionStrings:redis"] = await redis.Resource.GetConnectionStringAsync() + }); + + hb.AddRedisClient("redis"); + + using var host = hb.Build(); + + await host.StartAsync(); + + var redisClient = host.Services.GetRequiredService(); + + var db = redisClient.GetDatabase(); + + await db.StringSetAsync("key", "value"); + + var value = await db.StringGetAsync("key"); + + Assert.Equal("value", value); + } +} From fbda63295638b19de90f74d01535e0127f320249 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Wed, 12 Jun 2024 06:54:26 -0700 Subject: [PATCH 04/17] Use the resource name --- tests/Aspire.Hosting.Redis.Tests/RedisFunctionalTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Aspire.Hosting.Redis.Tests/RedisFunctionalTests.cs b/tests/Aspire.Hosting.Redis.Tests/RedisFunctionalTests.cs index 011aed73ce9..d40b11ec63b 100644 --- a/tests/Aspire.Hosting.Redis.Tests/RedisFunctionalTests.cs +++ b/tests/Aspire.Hosting.Redis.Tests/RedisFunctionalTests.cs @@ -27,10 +27,10 @@ public async Task VerifyRedisResource() hb.Configuration.AddInMemoryCollection(new Dictionary { - ["ConnectionStrings:redis"] = await redis.Resource.GetConnectionStringAsync() + [$"ConnectionStrings:{redis.Resource.Name}"] = await redis.Resource.GetConnectionStringAsync() }); - hb.AddRedisClient("redis"); + hb.AddRedisClient(redis.Resource.Name); using var host = hb.Build(); From 98d2f86ba5d99c92c326a7d8e6416564a07058fa Mon Sep 17 00:00:00 2001 From: Sebastien Ros Date: Mon, 1 Jul 2024 02:39:53 -0700 Subject: [PATCH 05/17] PR feedback --- .../AddRedisTests.cs | 3 ++- .../Aspire.Hosting.Redis.Tests.csproj | 23 +------------------ .../Directory.Build.props | 8 ------- .../Directory.Build.targets | 8 ------- 4 files changed, 3 insertions(+), 39 deletions(-) delete mode 100644 tests/Aspire.Hosting.Redis.Tests/Directory.Build.props delete mode 100644 tests/Aspire.Hosting.Redis.Tests/Directory.Build.targets diff --git a/tests/Aspire.Hosting.Redis.Tests/AddRedisTests.cs b/tests/Aspire.Hosting.Redis.Tests/AddRedisTests.cs index 61d57c12a9e..19dbba66831 100644 --- a/tests/Aspire.Hosting.Redis.Tests/AddRedisTests.cs +++ b/tests/Aspire.Hosting.Redis.Tests/AddRedisTests.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Net.Sockets; +using Aspire.Hosting.ApplicationModel; using Aspire.Hosting.Tests.Utils; using Aspire.Hosting.Utils; using Microsoft.Extensions.DependencyInjection; @@ -219,7 +220,7 @@ public void WithDataVolumeAddsVolumeAnnotation(bool? isReadOnly) var volumeAnnotation = redis.Resource.Annotations.OfType().Single(); - Assert.Equal("Aspire.Hosting.Redis.Tests-myRedis-data", volumeAnnotation.Source); + Assert.Equal("Aspire.Hosting.Tests-myRedis-data", volumeAnnotation.Source); Assert.Equal("/data", volumeAnnotation.Target); Assert.Equal(ContainerMountType.Volume, volumeAnnotation.Type); Assert.Equal(isReadOnly ?? false, volumeAnnotation.IsReadOnly); diff --git a/tests/Aspire.Hosting.Redis.Tests/Aspire.Hosting.Redis.Tests.csproj b/tests/Aspire.Hosting.Redis.Tests/Aspire.Hosting.Redis.Tests.csproj index 1fe8cbf4fe2..6c2033a67fb 100644 --- a/tests/Aspire.Hosting.Redis.Tests/Aspire.Hosting.Redis.Tests.csproj +++ b/tests/Aspire.Hosting.Redis.Tests/Aspire.Hosting.Redis.Tests.csproj @@ -2,36 +2,15 @@ $(NetCurrent) - true - - $(NoWarn);CS8002 + - - - - - - - - - - - - Always - - - - - diff --git a/tests/Aspire.Hosting.Redis.Tests/Directory.Build.props b/tests/Aspire.Hosting.Redis.Tests/Directory.Build.props deleted file mode 100644 index 6386f3ec197..00000000000 --- a/tests/Aspire.Hosting.Redis.Tests/Directory.Build.props +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/tests/Aspire.Hosting.Redis.Tests/Directory.Build.targets b/tests/Aspire.Hosting.Redis.Tests/Directory.Build.targets deleted file mode 100644 index be739139f72..00000000000 --- a/tests/Aspire.Hosting.Redis.Tests/Directory.Build.targets +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - From 7e9eef03d718aa18c94345d9ce78b999b524521a Mon Sep 17 00:00:00 2001 From: Sebastien Ros Date: Mon, 1 Jul 2024 07:39:25 -0700 Subject: [PATCH 06/17] Fix documentation --- src/Aspire.Hosting.Redis/RedisBuilderExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Aspire.Hosting.Redis/RedisBuilderExtensions.cs b/src/Aspire.Hosting.Redis/RedisBuilderExtensions.cs index 9374bfe8ab9..c521cfc7063 100644 --- a/src/Aspire.Hosting.Redis/RedisBuilderExtensions.cs +++ b/src/Aspire.Hosting.Redis/RedisBuilderExtensions.cs @@ -115,7 +115,7 @@ public static IResourceBuilder WithDataVolume(this IResourceBuild /// Use to adjust Redis persistence configuration, e.g.: /// /// var cache = builder.AddRedis("cache") - /// .WithDataBindMount() + /// .WithDataBindMount("myredisdata") /// .WithPersistence(TimeSpan.FromSeconds(10), 5); /// /// From c8be7b32f4ac4f4739fe119595659cdc72633709 Mon Sep 17 00:00:00 2001 From: Sebastien Ros Date: Mon, 1 Jul 2024 07:40:05 -0700 Subject: [PATCH 07/17] Mark functional test with RequiresDocker Otherwise would try to run it on Windows in CI where Docker is not available --- tests/Aspire.Hosting.Redis.Tests/RedisFunctionalTests.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/Aspire.Hosting.Redis.Tests/RedisFunctionalTests.cs b/tests/Aspire.Hosting.Redis.Tests/RedisFunctionalTests.cs index d40b11ec63b..522780282e0 100644 --- a/tests/Aspire.Hosting.Redis.Tests/RedisFunctionalTests.cs +++ b/tests/Aspire.Hosting.Redis.Tests/RedisFunctionalTests.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Aspire.Components.Common.Tests; using Aspire.Hosting.Utils; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; @@ -13,6 +14,7 @@ namespace Aspire.Hosting.Redis.Tests; public class RedisFunctionalTests { [Fact] + [RequiresDocker] public async Task VerifyRedisResource() { var builder = TestDistributedApplicationBuilder.Create(); From 64623584db2fb285b48efe7aa9b1be40fb3350f9 Mon Sep 17 00:00:00 2001 From: Sebastien Ros Date: Mon, 1 Jul 2024 08:48:27 -0700 Subject: [PATCH 08/17] Create AddDataVolume tests for Redis --- .../RedisFunctionalTests.cs | 149 ++++++++++++++++++ 1 file changed, 149 insertions(+) diff --git a/tests/Aspire.Hosting.Redis.Tests/RedisFunctionalTests.cs b/tests/Aspire.Hosting.Redis.Tests/RedisFunctionalTests.cs index 522780282e0..fa869824e95 100644 --- a/tests/Aspire.Hosting.Redis.Tests/RedisFunctionalTests.cs +++ b/tests/Aspire.Hosting.Redis.Tests/RedisFunctionalTests.cs @@ -48,4 +48,153 @@ public async Task VerifyRedisResource() Assert.Equal("value", value); } + + [Fact] + [RequiresDocker] + public async Task AddDataVolumeShouldPersistStateBetweenUsages() + { + var volumeName = "myvolume"; + + // Use a volume to do a snapshot save + + var builder1 = TestDistributedApplicationBuilder.Create(); + var redis1 = builder1.AddRedis("redis").WithDataVolume(volumeName); + + using (var app = builder1.Build()) + { + await app.StartAsync(); + + var hb = Host.CreateApplicationBuilder(); + + // BGSAVE is only available in admin mode, enable it for this instance + hb.Configuration.AddInMemoryCollection(new Dictionary + { + [$"ConnectionStrings:{redis1.Resource.Name}"] = $"{await redis1.Resource.GetConnectionStringAsync()},allowAdmin=true" + }); + + hb.AddRedisClient(redis1.Resource.Name); + + using (var host = hb.Build()) + { + await host.StartAsync(); + + var redisClient = host.Services.GetRequiredService(); + + var db = redisClient.GetDatabase(); + + await db.StringSetAsync("key", "value"); + + // Force Redis to save the keys (snapshotting) + // c.f. https://redis.io/docs/latest/operate/oss_and_stack/management/persistence/ + + await redisClient.GetServers().First().SaveAsync(SaveType.BackgroundSave); + } + } + + // Start a new instance with the same existing volume + + var builder2 = TestDistributedApplicationBuilder.Create(); + var redis2 = builder2.AddRedis("redis").WithDataVolume(volumeName); + + using (var app = builder2.Build()) + { + await app.StartAsync(); + + var hb = Host.CreateApplicationBuilder(); + + hb.Configuration.AddInMemoryCollection(new Dictionary + { + [$"ConnectionStrings:{redis2.Resource.Name}"] = await redis2.Resource.GetConnectionStringAsync() + }); + + hb.AddRedisClient(redis2.Resource.Name); + + using (var host = hb.Build()) + { + await host.StartAsync(); + + var redisClient = host.Services.GetRequiredService(); + + var db = redisClient.GetDatabase(); + + var value = await db.StringGetAsync("key"); + + Assert.Equal("value", value); + } + } + } + + [Fact] + [RequiresDocker] + public async Task AddDataVolumeWithCustomPersistenceInterval() + { + var volumeName = "myvolume"; + var interval = TimeSpan.FromSeconds(1); + + // Use a volume to do a snapshot save + + var builder1 = TestDistributedApplicationBuilder.Create(); + var redis1 = builder1.AddRedis("redis").WithDataVolume(volumeName).WithPersistence(interval); + + using (var app = builder1.Build()) + { + await app.StartAsync(); + + var hb = Host.CreateApplicationBuilder(); + + hb.Configuration.AddInMemoryCollection(new Dictionary + { + [$"ConnectionStrings:{redis1.Resource.Name}"] = await redis1.Resource.GetConnectionStringAsync() + }); + + hb.AddRedisClient(redis1.Resource.Name); + + using (var host = hb.Build()) + { + await host.StartAsync(); + + var redisClient = host.Services.GetRequiredService(); + + var db = redisClient.GetDatabase(); + + await db.StringSetAsync("key", "value"); + + // Wait 1 second more than the interval + await Task.Delay(interval + TimeSpan.FromSeconds(1)); + } + } + + // Start a new instance with the same existing volume + + var builder2 = TestDistributedApplicationBuilder.Create(); + var redis2 = builder2.AddRedis("redis").WithDataVolume(volumeName); + + using (var app = builder2.Build()) + { + await app.StartAsync(); + + var hb = Host.CreateApplicationBuilder(); + + hb.Configuration.AddInMemoryCollection(new Dictionary + { + [$"ConnectionStrings:{redis2.Resource.Name}"] = await redis2.Resource.GetConnectionStringAsync() + }); + + hb.AddRedisClient(redis2.Resource.Name); + + using (var host = hb.Build()) + { + await host.StartAsync(); + + var redisClient = host.Services.GetRequiredService(); + + var db = redisClient.GetDatabase(); + + var value = await db.StringGetAsync("key"); + + Assert.Equal("value", value); + } + } + } + } From 1394ee858b057b6a3df7ba7226abb4ff404bd389 Mon Sep 17 00:00:00 2001 From: Sebastien Ros Date: Tue, 2 Jul 2024 02:54:34 -0700 Subject: [PATCH 09/17] Add BindMount tests --- .../RedisFunctionalTests.cs | 138 ++++++++++-------- 1 file changed, 75 insertions(+), 63 deletions(-) diff --git a/tests/Aspire.Hosting.Redis.Tests/RedisFunctionalTests.cs b/tests/Aspire.Hosting.Redis.Tests/RedisFunctionalTests.cs index fa869824e95..114faf664ac 100644 --- a/tests/Aspire.Hosting.Redis.Tests/RedisFunctionalTests.cs +++ b/tests/Aspire.Hosting.Redis.Tests/RedisFunctionalTests.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using Aspire.Components.Common.Tests; +using Aspire.Hosting.ApplicationModel; using Aspire.Hosting.Utils; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; @@ -57,84 +58,93 @@ public async Task AddDataVolumeShouldPersistStateBetweenUsages() // Use a volume to do a snapshot save - var builder1 = TestDistributedApplicationBuilder.Create(); - var redis1 = builder1.AddRedis("redis").WithDataVolume(volumeName); - - using (var app = builder1.Build()) - { - await app.StartAsync(); - - var hb = Host.CreateApplicationBuilder(); - - // BGSAVE is only available in admin mode, enable it for this instance - hb.Configuration.AddInMemoryCollection(new Dictionary - { - [$"ConnectionStrings:{redis1.Resource.Name}"] = $"{await redis1.Resource.GetConnectionStringAsync()},allowAdmin=true" - }); - - hb.AddRedisClient(redis1.Resource.Name); - - using (var host = hb.Build()) - { - await host.StartAsync(); + await VerifyDataPersistence( + options => options.WithDataVolume(volumeName), + async redisClient => await redisClient.GetServers().First().SaveAsync(SaveType.BackgroundSave) + ); + } - var redisClient = host.Services.GetRequiredService(); + [Fact] + [RequiresDocker] + public async Task AddDataVolumeWithCustomPersistenceInterval() + { + var volumeName = "myvolume"; + var snapshotInterval = TimeSpan.FromSeconds(1); - var db = redisClient.GetDatabase(); + // Use a volume to do a snapshot save with a custom interval - await db.StringSetAsync("key", "value"); + await VerifyDataPersistence( + options => options.WithDataVolume(volumeName).WithPersistence(snapshotInterval), + async redisClient => await Task.Delay(snapshotInterval + TimeSpan.FromSeconds(1)) + ); + } - // Force Redis to save the keys (snapshotting) - // c.f. https://redis.io/docs/latest/operate/oss_and_stack/management/persistence/ + [Fact] + [RequiresDocker] + public async Task AddBindMountShouldPersistStateBetweenUsages() + { + var bindMountPath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); - await redisClient.GetServers().First().SaveAsync(SaveType.BackgroundSave); - } + if (!Directory.Exists(bindMountPath)) + { + Directory.CreateDirectory(bindMountPath); } - // Start a new instance with the same existing volume + // Use a bind mount to do a snapshot save - var builder2 = TestDistributedApplicationBuilder.Create(); - var redis2 = builder2.AddRedis("redis").WithDataVolume(volumeName); + await VerifyDataPersistence( + options => options.WithDataBindMount(bindMountPath), + async redisClient => await redisClient.GetServers().First().SaveAsync(SaveType.BackgroundSave) + ); - using (var app = builder2.Build()) + try { - await app.StartAsync(); - - var hb = Host.CreateApplicationBuilder(); - - hb.Configuration.AddInMemoryCollection(new Dictionary - { - [$"ConnectionStrings:{redis2.Resource.Name}"] = await redis2.Resource.GetConnectionStringAsync() - }); + File.Delete(bindMountPath); + } + catch + { + // Don't fail test if we can't clean the temporary folder + } + } - hb.AddRedisClient(redis2.Resource.Name); + [Fact] + [RequiresDocker] + public async Task AddBindMountWithCustomPersistenceInterval() + { + var bindMountPath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); - using (var host = hb.Build()) - { - await host.StartAsync(); + if (!Directory.Exists(bindMountPath)) + { + Directory.CreateDirectory(bindMountPath); + } - var redisClient = host.Services.GetRequiredService(); + var snapshotInterval = TimeSpan.FromSeconds(1); - var db = redisClient.GetDatabase(); + // Use a bind mount to do a snapshot save with a custom interval - var value = await db.StringGetAsync("key"); + await VerifyDataPersistence( + options => options.WithDataBindMount(bindMountPath).WithPersistence(snapshotInterval), + async redisClient => await Task.Delay(snapshotInterval + TimeSpan.FromSeconds(1)) + ); - Assert.Equal("value", value); - } + try + { + File.Delete(bindMountPath); + } + catch + { + // Don't fail test if we can't clean the temporary folder } } - [Fact] - [RequiresDocker] - public async Task AddDataVolumeWithCustomPersistenceInterval() + private static async Task VerifyDataPersistence( + Action> configureResource, + Func configureClient) { - var volumeName = "myvolume"; - var interval = TimeSpan.FromSeconds(1); - - // Use a volume to do a snapshot save - var builder1 = TestDistributedApplicationBuilder.Create(); - var redis1 = builder1.AddRedis("redis").WithDataVolume(volumeName).WithPersistence(interval); + var redis1 = builder1.AddRedis("redis"); + + configureResource?.Invoke(redis1); using (var app = builder1.Build()) { @@ -142,9 +152,10 @@ public async Task AddDataVolumeWithCustomPersistenceInterval() var hb = Host.CreateApplicationBuilder(); + // BGSAVE is only available in admin mode, enable it for this instance hb.Configuration.AddInMemoryCollection(new Dictionary { - [$"ConnectionStrings:{redis1.Resource.Name}"] = await redis1.Resource.GetConnectionStringAsync() + [$"ConnectionStrings:{redis1.Resource.Name}"] = $"{await redis1.Resource.GetConnectionStringAsync()},allowAdmin=true" }); hb.AddRedisClient(redis1.Resource.Name); @@ -159,15 +170,16 @@ public async Task AddDataVolumeWithCustomPersistenceInterval() await db.StringSetAsync("key", "value"); - // Wait 1 second more than the interval - await Task.Delay(interval + TimeSpan.FromSeconds(1)); + // Force Redis to save the keys (snapshotting) + // c.f. https://redis.io/docs/latest/operate/oss_and_stack/management/persistence/ + + await configureClient.Invoke(redisClient); } } - // Start a new instance with the same existing volume - var builder2 = TestDistributedApplicationBuilder.Create(); - var redis2 = builder2.AddRedis("redis").WithDataVolume(volumeName); + var redis2 = builder2.AddRedis("redis"); + configureResource?.Invoke(redis2); using (var app = builder2.Build()) { From 7268fe3673a4a5d7bcc44c80f4b2ec6ffa6c4d1c Mon Sep 17 00:00:00 2001 From: Sebastien Ros Date: Tue, 2 Jul 2024 03:57:24 -0700 Subject: [PATCH 10/17] Add false positive check --- .../RedisFunctionalTests.cs | 27 ++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/tests/Aspire.Hosting.Redis.Tests/RedisFunctionalTests.cs b/tests/Aspire.Hosting.Redis.Tests/RedisFunctionalTests.cs index 114faf664ac..2468ddc8311 100644 --- a/tests/Aspire.Hosting.Redis.Tests/RedisFunctionalTests.cs +++ b/tests/Aspire.Hosting.Redis.Tests/RedisFunctionalTests.cs @@ -9,6 +9,7 @@ using Microsoft.Extensions.Hosting; using StackExchange.Redis; using Xunit; +using Xunit.Sdk; namespace Aspire.Hosting.Redis.Tests; @@ -52,9 +53,9 @@ public async Task VerifyRedisResource() [Fact] [RequiresDocker] - public async Task AddDataVolumeShouldPersistStateBetweenUsages() + public async Task WithDataVolumeShouldPersistStateBetweenUsages() { - var volumeName = "myvolume"; + var volumeName = "myvolume1"; // Use a volume to do a snapshot save @@ -66,9 +67,9 @@ await VerifyDataPersistence( [Fact] [RequiresDocker] - public async Task AddDataVolumeWithCustomPersistenceInterval() + public async Task WithDataVolumeWithCustomPersistenceInterval() { - var volumeName = "myvolume"; + var volumeName = "myvolume2"; var snapshotInterval = TimeSpan.FromSeconds(1); // Use a volume to do a snapshot save with a custom interval @@ -81,7 +82,7 @@ await VerifyDataPersistence( [Fact] [RequiresDocker] - public async Task AddBindMountShouldPersistStateBetweenUsages() + public async Task WithDataBindMountShouldPersistStateBetweenUsages() { var bindMountPath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); @@ -109,7 +110,7 @@ await VerifyDataPersistence( [Fact] [RequiresDocker] - public async Task AddBindMountWithCustomPersistenceInterval() + public async Task WithDataBindMountWithCustomPersistenceInterval() { var bindMountPath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); @@ -137,6 +138,20 @@ await VerifyDataPersistence( } } + [Fact] + [RequiresDocker] + public async Task PersistenceIsDisabledByDefault() + { + // Checks that without enabling Redis Persistence the tests fail + + await Assert.ThrowsAsync(async () => + await VerifyDataPersistence( + options => { }, + redisClient => Task.CompletedTask + ) + ); + } + private static async Task VerifyDataPersistence( Action> configureResource, Func configureClient) From 03e54d3e9b25fb3ee379033809e52f0b5bed5544 Mon Sep 17 00:00:00 2001 From: Sebastien Ros Date: Tue, 2 Jul 2024 22:50:55 -0700 Subject: [PATCH 11/17] Import TestServiceProvider --- tests/Aspire.Hosting.Tests/Aspire.Hosting.Tests.csproj | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/Aspire.Hosting.Tests/Aspire.Hosting.Tests.csproj b/tests/Aspire.Hosting.Tests/Aspire.Hosting.Tests.csproj index e42422c60a9..3a599f4f687 100644 --- a/tests/Aspire.Hosting.Tests/Aspire.Hosting.Tests.csproj +++ b/tests/Aspire.Hosting.Tests/Aspire.Hosting.Tests.csproj @@ -74,4 +74,8 @@ + + + + From 153f97b9db8bca446ee965c6feb9a0649cb533b8 Mon Sep 17 00:00:00 2001 From: Sebastien Ros Date: Tue, 2 Jul 2024 23:11:04 -0700 Subject: [PATCH 12/17] Debugging functional tests Nothing works anymore, checking the simplest one for conflicts --- .../Aspire.Hosting.Redis.Tests/RedisFunctionalTests.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/Aspire.Hosting.Redis.Tests/RedisFunctionalTests.cs b/tests/Aspire.Hosting.Redis.Tests/RedisFunctionalTests.cs index 2468ddc8311..c959dd2903c 100644 --- a/tests/Aspire.Hosting.Redis.Tests/RedisFunctionalTests.cs +++ b/tests/Aspire.Hosting.Redis.Tests/RedisFunctionalTests.cs @@ -51,7 +51,7 @@ public async Task VerifyRedisResource() Assert.Equal("value", value); } - [Fact] + [Fact(Skip = "Debugging")] [RequiresDocker] public async Task WithDataVolumeShouldPersistStateBetweenUsages() { @@ -65,7 +65,7 @@ await VerifyDataPersistence( ); } - [Fact] + [Fact(Skip = "Debugging")] [RequiresDocker] public async Task WithDataVolumeWithCustomPersistenceInterval() { @@ -80,7 +80,7 @@ await VerifyDataPersistence( ); } - [Fact] + [Fact(Skip = "Debugging")] [RequiresDocker] public async Task WithDataBindMountShouldPersistStateBetweenUsages() { @@ -108,7 +108,7 @@ await VerifyDataPersistence( } } - [Fact] + [Fact(Skip = "Debugging")] [RequiresDocker] public async Task WithDataBindMountWithCustomPersistenceInterval() { @@ -138,7 +138,7 @@ await VerifyDataPersistence( } } - [Fact] + [Fact(Skip = "Debugging")] [RequiresDocker] public async Task PersistenceIsDisabledByDefault() { From 0859fb644deae0807b994cd01d0b91be9d762348 Mon Sep 17 00:00:00 2001 From: Sebastien Ros Date: Tue, 9 Jul 2024 00:45:24 -0700 Subject: [PATCH 13/17] Apply PR feedback --- src/Aspire.Hosting/Aspire.Hosting.csproj | 1 - .../ContainerResourceBuilderTests.cs | 2 +- tests/Aspire.Hosting.Redis.Tests/AddRedisTests.cs | 10 ++++++++-- .../Aspire.Hosting.Redis.Tests.csproj | 4 ++-- .../Aspire.Hosting.Redis.Tests/RedisFunctionalTests.cs | 2 +- tests/Aspire.Hosting.Tests/Aspire.Hosting.Tests.csproj | 4 ---- .../Aspire.Hosting.Tests/Utils/TestServiceProvider.cs | 2 +- 7 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/Aspire.Hosting/Aspire.Hosting.csproj b/src/Aspire.Hosting/Aspire.Hosting.csproj index 4cf48ccd38d..8208c241d15 100644 --- a/src/Aspire.Hosting/Aspire.Hosting.csproj +++ b/src/Aspire.Hosting/Aspire.Hosting.csproj @@ -68,7 +68,6 @@ - diff --git a/tests/Aspire.Hosting.Containers.Tests/ContainerResourceBuilderTests.cs b/tests/Aspire.Hosting.Containers.Tests/ContainerResourceBuilderTests.cs index 244f1332777..f10ad96e1e9 100644 --- a/tests/Aspire.Hosting.Containers.Tests/ContainerResourceBuilderTests.cs +++ b/tests/Aspire.Hosting.Containers.Tests/ContainerResourceBuilderTests.cs @@ -54,7 +54,7 @@ public void WithImageMutatesImageNameOfLastAnnotation() public void WithImageTagMutatesImageTag() { using var builder = TestDistributedApplicationBuilder.Create(); - var redis = builder.AddRedis("redis").WithImageTag("7.1"); + var redis = builder.AddContainer("redis", "redis").WithImageTag("7.1"); Assert.Equal("7.1", redis.Resource.Annotations.OfType().Single().Tag); } diff --git a/tests/Aspire.Hosting.Redis.Tests/AddRedisTests.cs b/tests/Aspire.Hosting.Redis.Tests/AddRedisTests.cs index 263e8e5275c..e6ba493f4fe 100644 --- a/tests/Aspire.Hosting.Redis.Tests/AddRedisTests.cs +++ b/tests/Aspire.Hosting.Redis.Tests/AddRedisTests.cs @@ -171,7 +171,10 @@ public async Task SingleRedisInstanceProducesCorrectRedisHostsVariable(string co var commander = builder.Resources.Single(r => r.Name.EndsWith("-commander")); - var config = await EnvironmentVariableEvaluator.GetEnvironmentVariablesAsync(commander, DistributedApplicationOperation.Run, TestServiceProvider.Instance); + var config = await EnvironmentVariableEvaluator.GetEnvironmentVariablesAsync( + commander, + DistributedApplicationOperation.Run, + TestServiceProvider.Instance); Assert.Equal($"myredis1:{containerHost}:5001:0", config["REDIS_HOSTS"]); } @@ -196,7 +199,10 @@ public async Task MultipleRedisInstanceProducesCorrectRedisHostsVariable(string var commander = builder.Resources.Single(r => r.Name.EndsWith("-commander")); - var config = await EnvironmentVariableEvaluator.GetEnvironmentVariablesAsync(commander, DistributedApplicationOperation.Run, TestServiceProvider.Instance); + var config = await EnvironmentVariableEvaluator.GetEnvironmentVariablesAsync( + commander, + DistributedApplicationOperation.Run, + TestServiceProvider.Instance); Assert.Equal($"myredis1:{containerHost}:5001:0,myredis2:host2:5002:0", config["REDIS_HOSTS"]); } diff --git a/tests/Aspire.Hosting.Redis.Tests/Aspire.Hosting.Redis.Tests.csproj b/tests/Aspire.Hosting.Redis.Tests/Aspire.Hosting.Redis.Tests.csproj index 6c2033a67fb..0bc1257c568 100644 --- a/tests/Aspire.Hosting.Redis.Tests/Aspire.Hosting.Redis.Tests.csproj +++ b/tests/Aspire.Hosting.Redis.Tests/Aspire.Hosting.Redis.Tests.csproj @@ -5,8 +5,8 @@ - - + + diff --git a/tests/Aspire.Hosting.Redis.Tests/RedisFunctionalTests.cs b/tests/Aspire.Hosting.Redis.Tests/RedisFunctionalTests.cs index c959dd2903c..fffbcac5118 100644 --- a/tests/Aspire.Hosting.Redis.Tests/RedisFunctionalTests.cs +++ b/tests/Aspire.Hosting.Redis.Tests/RedisFunctionalTests.cs @@ -80,7 +80,7 @@ await VerifyDataPersistence( ); } - [Fact(Skip = "Debugging")] + [Fact] [RequiresDocker] public async Task WithDataBindMountShouldPersistStateBetweenUsages() { diff --git a/tests/Aspire.Hosting.Tests/Aspire.Hosting.Tests.csproj b/tests/Aspire.Hosting.Tests/Aspire.Hosting.Tests.csproj index 3a599f4f687..e42422c60a9 100644 --- a/tests/Aspire.Hosting.Tests/Aspire.Hosting.Tests.csproj +++ b/tests/Aspire.Hosting.Tests/Aspire.Hosting.Tests.csproj @@ -74,8 +74,4 @@ - - - - diff --git a/tests/Aspire.Hosting.Tests/Utils/TestServiceProvider.cs b/tests/Aspire.Hosting.Tests/Utils/TestServiceProvider.cs index dd4f9682c00..aa801bb26f8 100644 --- a/tests/Aspire.Hosting.Tests/Utils/TestServiceProvider.cs +++ b/tests/Aspire.Hosting.Tests/Utils/TestServiceProvider.cs @@ -6,7 +6,7 @@ using Aspire.Hosting.Tests.Dcp; namespace Aspire.Hosting.Tests.Utils; -internal sealed class TestServiceProvider : IServiceProvider +public sealed class TestServiceProvider : IServiceProvider { private readonly ServiceContainer _serviceContainer = new ServiceContainer(); private TestServiceProvider() From 497e6338f656b8ad79e0821b832fce452a53a908 Mon Sep 17 00:00:00 2001 From: Sebastien Ros Date: Tue, 9 Jul 2024 06:00:52 -0700 Subject: [PATCH 14/17] Remove InternalVisibleTo --- src/Aspire.Hosting.Redis/Aspire.Hosting.Redis.csproj | 5 ----- .../Aspire.Hosting.Redis.Tests.csproj | 5 +++++ tests/Aspire.Hosting.Redis.Tests/RedisFunctionalTests.cs | 8 ++++---- tests/Aspire.Hosting.Tests/Aspire.Hosting.Tests.csproj | 1 + 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/Aspire.Hosting.Redis/Aspire.Hosting.Redis.csproj b/src/Aspire.Hosting.Redis/Aspire.Hosting.Redis.csproj index b62de7fdc2a..8a461c4fec6 100644 --- a/src/Aspire.Hosting.Redis/Aspire.Hosting.Redis.csproj +++ b/src/Aspire.Hosting.Redis/Aspire.Hosting.Redis.csproj @@ -20,9 +20,4 @@ - - - - - diff --git a/tests/Aspire.Hosting.Redis.Tests/Aspire.Hosting.Redis.Tests.csproj b/tests/Aspire.Hosting.Redis.Tests/Aspire.Hosting.Redis.Tests.csproj index 0bc1257c568..8e5ea5ace06 100644 --- a/tests/Aspire.Hosting.Redis.Tests/Aspire.Hosting.Redis.Tests.csproj +++ b/tests/Aspire.Hosting.Redis.Tests/Aspire.Hosting.Redis.Tests.csproj @@ -13,4 +13,9 @@ + + + + + diff --git a/tests/Aspire.Hosting.Redis.Tests/RedisFunctionalTests.cs b/tests/Aspire.Hosting.Redis.Tests/RedisFunctionalTests.cs index fffbcac5118..2468ddc8311 100644 --- a/tests/Aspire.Hosting.Redis.Tests/RedisFunctionalTests.cs +++ b/tests/Aspire.Hosting.Redis.Tests/RedisFunctionalTests.cs @@ -51,7 +51,7 @@ public async Task VerifyRedisResource() Assert.Equal("value", value); } - [Fact(Skip = "Debugging")] + [Fact] [RequiresDocker] public async Task WithDataVolumeShouldPersistStateBetweenUsages() { @@ -65,7 +65,7 @@ await VerifyDataPersistence( ); } - [Fact(Skip = "Debugging")] + [Fact] [RequiresDocker] public async Task WithDataVolumeWithCustomPersistenceInterval() { @@ -108,7 +108,7 @@ await VerifyDataPersistence( } } - [Fact(Skip = "Debugging")] + [Fact] [RequiresDocker] public async Task WithDataBindMountWithCustomPersistenceInterval() { @@ -138,7 +138,7 @@ await VerifyDataPersistence( } } - [Fact(Skip = "Debugging")] + [Fact] [RequiresDocker] public async Task PersistenceIsDisabledByDefault() { diff --git a/tests/Aspire.Hosting.Tests/Aspire.Hosting.Tests.csproj b/tests/Aspire.Hosting.Tests/Aspire.Hosting.Tests.csproj index e42422c60a9..ee9a9e14332 100644 --- a/tests/Aspire.Hosting.Tests/Aspire.Hosting.Tests.csproj +++ b/tests/Aspire.Hosting.Tests/Aspire.Hosting.Tests.csproj @@ -62,6 +62,7 @@ + From c55aa34af60b0afa38e3160e6960d48d8a860a69 Mon Sep 17 00:00:00 2001 From: Sebastien Ros Date: Tue, 9 Jul 2024 08:55:08 -0700 Subject: [PATCH 15/17] Delete volumes after usage --- .../Aspire.Hosting.Redis.Tests.csproj | 1 + .../RedisFunctionalTests.cs | 211 ++++++++++++------ 2 files changed, 146 insertions(+), 66 deletions(-) diff --git a/tests/Aspire.Hosting.Redis.Tests/Aspire.Hosting.Redis.Tests.csproj b/tests/Aspire.Hosting.Redis.Tests/Aspire.Hosting.Redis.Tests.csproj index 8e5ea5ace06..a987f4077f1 100644 --- a/tests/Aspire.Hosting.Redis.Tests/Aspire.Hosting.Redis.Tests.csproj +++ b/tests/Aspire.Hosting.Redis.Tests/Aspire.Hosting.Redis.Tests.csproj @@ -16,6 +16,7 @@ + diff --git a/tests/Aspire.Hosting.Redis.Tests/RedisFunctionalTests.cs b/tests/Aspire.Hosting.Redis.Tests/RedisFunctionalTests.cs index 2468ddc8311..b4a5aedfab5 100644 --- a/tests/Aspire.Hosting.Redis.Tests/RedisFunctionalTests.cs +++ b/tests/Aspire.Hosting.Redis.Tests/RedisFunctionalTests.cs @@ -1,15 +1,14 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Diagnostics; using Aspire.Components.Common.Tests; -using Aspire.Hosting.ApplicationModel; using Aspire.Hosting.Utils; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using StackExchange.Redis; using Xunit; -using Xunit.Sdk; namespace Aspire.Hosting.Redis.Tests; @@ -55,29 +54,83 @@ public async Task VerifyRedisResource() [RequiresDocker] public async Task WithDataVolumeShouldPersistStateBetweenUsages() { - var volumeName = "myvolume1"; - // Use a volume to do a snapshot save - await VerifyDataPersistence( - options => options.WithDataVolume(volumeName), - async redisClient => await redisClient.GetServers().First().SaveAsync(SaveType.BackgroundSave) - ); - } + var builder1 = TestDistributedApplicationBuilder.Create(); + var redis1 = builder1.AddRedis("redis"); - [Fact] - [RequiresDocker] - public async Task WithDataVolumeWithCustomPersistenceInterval() - { - var volumeName = "myvolume2"; - var snapshotInterval = TimeSpan.FromSeconds(1); + // Use a deterministic volume name to prevent them from exhausting the machines if deletion fails + var volumeName = VolumeNameGenerator.CreateVolumeName(redis1, nameof(WithDataVolumeShouldPersistStateBetweenUsages)); + redis1.WithDataVolume(volumeName); + + using (var app = builder1.Build()) + { + await app.StartAsync(); + + var hb = Host.CreateApplicationBuilder(); + + // BGSAVE is only available in admin mode, enable it for this instance + hb.Configuration.AddInMemoryCollection(new Dictionary + { + [$"ConnectionStrings:{redis1.Resource.Name}"] = $"{await redis1.Resource.GetConnectionStringAsync()},allowAdmin=true" + }); - // Use a volume to do a snapshot save with a custom interval + hb.AddRedisClient(redis1.Resource.Name); + + using (var host = hb.Build()) + { + await host.StartAsync(); - await VerifyDataPersistence( - options => options.WithDataVolume(volumeName).WithPersistence(snapshotInterval), - async redisClient => await Task.Delay(snapshotInterval + TimeSpan.FromSeconds(1)) - ); + var redisClient = host.Services.GetRequiredService(); + + var db = redisClient.GetDatabase(); + + await db.StringSetAsync("key", "value"); + + // Force Redis to save the keys (snapshotting) + // c.f. https://redis.io/docs/latest/operate/oss_and_stack/management/persistence/ + + await redisClient.GetServers().First().SaveAsync(SaveType.BackgroundSave); + } + + // Stops the container, or the Volume would still be in use + await app.StopAsync(); + } + + var builder2 = TestDistributedApplicationBuilder.Create(); + var redis2 = builder2.AddRedis("redis").WithDataVolume(volumeName); + + using (var app = builder2.Build()) + { + await app.StartAsync(); + + var hb = Host.CreateApplicationBuilder(); + + hb.Configuration.AddInMemoryCollection(new Dictionary + { + [$"ConnectionStrings:{redis2.Resource.Name}"] = await redis2.Resource.GetConnectionStringAsync() + }); + + hb.AddRedisClient(redis2.Resource.Name); + + using (var host = hb.Build()) + { + await host.StartAsync(); + + var redisClient = host.Services.GetRequiredService(); + + var db = redisClient.GetDatabase(); + + var value = await db.StringGetAsync("key"); + + Assert.Equal("value", value); + } + + // Stops the container, or the Volume would still be in use + await app.StopAsync(); + } + + AttemptDeleteDockerVolume(volumeName); } [Fact] @@ -93,40 +146,73 @@ public async Task WithDataBindMountShouldPersistStateBetweenUsages() // Use a bind mount to do a snapshot save - await VerifyDataPersistence( - options => options.WithDataBindMount(bindMountPath), - async redisClient => await redisClient.GetServers().First().SaveAsync(SaveType.BackgroundSave) - ); + var builder1 = TestDistributedApplicationBuilder.Create(); + var redis1 = builder1.AddRedis("redis").WithDataBindMount(bindMountPath); - try - { - File.Delete(bindMountPath); - } - catch + using (var app = builder1.Build()) { - // Don't fail test if we can't clean the temporary folder + await app.StartAsync(); + + var hb = Host.CreateApplicationBuilder(); + + // BGSAVE is only available in admin mode, enable it for this instance + hb.Configuration.AddInMemoryCollection(new Dictionary + { + [$"ConnectionStrings:{redis1.Resource.Name}"] = $"{await redis1.Resource.GetConnectionStringAsync()},allowAdmin=true" + }); + + hb.AddRedisClient(redis1.Resource.Name); + + using (var host = hb.Build()) + { + await host.StartAsync(); + + var redisClient = host.Services.GetRequiredService(); + + var db = redisClient.GetDatabase(); + + await db.StringSetAsync("key", "value"); + + // Force Redis to save the keys (snapshotting) + // c.f. https://redis.io/docs/latest/operate/oss_and_stack/management/persistence/ + + await redisClient.GetServers().First().SaveAsync(SaveType.BackgroundSave); + } + + await app.StopAsync(); } - } - [Fact] - [RequiresDocker] - public async Task WithDataBindMountWithCustomPersistenceInterval() - { - var bindMountPath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); + var builder2 = TestDistributedApplicationBuilder.Create(); + var redis2 = builder2.AddRedis("redis").WithDataBindMount(bindMountPath); - if (!Directory.Exists(bindMountPath)) + using (var app = builder2.Build()) { - Directory.CreateDirectory(bindMountPath); - } + await app.StartAsync(); - var snapshotInterval = TimeSpan.FromSeconds(1); + var hb = Host.CreateApplicationBuilder(); - // Use a bind mount to do a snapshot save with a custom interval + hb.Configuration.AddInMemoryCollection(new Dictionary + { + [$"ConnectionStrings:{redis2.Resource.Name}"] = await redis2.Resource.GetConnectionStringAsync() + }); - await VerifyDataPersistence( - options => options.WithDataBindMount(bindMountPath).WithPersistence(snapshotInterval), - async redisClient => await Task.Delay(snapshotInterval + TimeSpan.FromSeconds(1)) - ); + hb.AddRedisClient(redis2.Resource.Name); + + using (var host = hb.Build()) + { + await host.StartAsync(); + + var redisClient = host.Services.GetRequiredService(); + + var db = redisClient.GetDatabase(); + + var value = await db.StringGetAsync("key"); + + Assert.Equal("value", value); + } + + await app.StopAsync(); + } try { @@ -144,23 +230,9 @@ public async Task PersistenceIsDisabledByDefault() { // Checks that without enabling Redis Persistence the tests fail - await Assert.ThrowsAsync(async () => - await VerifyDataPersistence( - options => { }, - redisClient => Task.CompletedTask - ) - ); - } - - private static async Task VerifyDataPersistence( - Action> configureResource, - Func configureClient) - { var builder1 = TestDistributedApplicationBuilder.Create(); var redis1 = builder1.AddRedis("redis"); - configureResource?.Invoke(redis1); - using (var app = builder1.Build()) { await app.StartAsync(); @@ -184,17 +256,13 @@ private static async Task VerifyDataPersistence( var db = redisClient.GetDatabase(); await db.StringSetAsync("key", "value"); - - // Force Redis to save the keys (snapshotting) - // c.f. https://redis.io/docs/latest/operate/oss_and_stack/management/persistence/ - - await configureClient.Invoke(redisClient); } + + await app.StopAsync(); } var builder2 = TestDistributedApplicationBuilder.Create(); var redis2 = builder2.AddRedis("redis"); - configureResource?.Invoke(redis2); using (var app = builder2.Build()) { @@ -219,9 +287,20 @@ private static async Task VerifyDataPersistence( var value = await db.StringGetAsync("key"); - Assert.Equal("value", value); + Assert.True(value.IsNull); } + + await app.StopAsync(); } } + private static void AttemptDeleteDockerVolume(string volumeName) + { + if (Process.Start("docker", $"volume rm {volumeName}") is { } process) + { + process.WaitForExit(TimeSpan.FromSeconds(3)); + process.Kill(entireProcessTree: true); + process.Dispose(); + } + } } From 9bc54e9faee2c65a705bc134622f03ffa8770445 Mon Sep 17 00:00:00 2001 From: Sebastien Ros Date: Tue, 9 Jul 2024 09:52:26 -0700 Subject: [PATCH 16/17] Fix erroneous samples --- src/Aspire.Hosting.Garnet/GarnetBuilderExtensions.cs | 2 +- src/Aspire.Hosting.Valkey/ValkeyBuilderExtensions.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Aspire.Hosting.Garnet/GarnetBuilderExtensions.cs b/src/Aspire.Hosting.Garnet/GarnetBuilderExtensions.cs index 547800207f1..634a69eb444 100644 --- a/src/Aspire.Hosting.Garnet/GarnetBuilderExtensions.cs +++ b/src/Aspire.Hosting.Garnet/GarnetBuilderExtensions.cs @@ -96,7 +96,7 @@ public static IResourceBuilder WithDataVolume(this IResourceBuil /// Use to adjust Garnet persistence configuration, e.g.: /// /// var garnet = builder.AddGarnet("garnet") - /// .WithDataBindMount() + /// .WithDataBindMount("mydata") /// .WithPersistence(TimeSpan.FromSeconds(10), 5); /// /// diff --git a/src/Aspire.Hosting.Valkey/ValkeyBuilderExtensions.cs b/src/Aspire.Hosting.Valkey/ValkeyBuilderExtensions.cs index a4d4ed0f5ef..edbbe7c9c99 100644 --- a/src/Aspire.Hosting.Valkey/ValkeyBuilderExtensions.cs +++ b/src/Aspire.Hosting.Valkey/ValkeyBuilderExtensions.cs @@ -103,7 +103,7 @@ public static IResourceBuilder WithDataVolume(this IResourceBuil /// Use to adjust Valkey persistence configuration, e.g.: /// /// var valkey = builder.AddValkey("valkey") - /// .WithDataBindMount() + /// .WithDataBindMount("mydata") /// .WithPersistence(TimeSpan.FromSeconds(10), 5); /// /// From 69f4ea909241e4a1be70c7bbba4aee51076434c5 Mon Sep 17 00:00:00 2001 From: Sebastien Ros Date: Tue, 9 Jul 2024 11:17:59 -0700 Subject: [PATCH 17/17] Move AttemptDeleteDockerVolume to Utils class --- .../RedisFunctionalTests.cs | 13 +------------ .../Aspire.Hosting.Tests/Utils/DockerUtils.cs | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 12 deletions(-) create mode 100644 tests/Aspire.Hosting.Tests/Utils/DockerUtils.cs diff --git a/tests/Aspire.Hosting.Redis.Tests/RedisFunctionalTests.cs b/tests/Aspire.Hosting.Redis.Tests/RedisFunctionalTests.cs index b4a5aedfab5..31d9bd4e827 100644 --- a/tests/Aspire.Hosting.Redis.Tests/RedisFunctionalTests.cs +++ b/tests/Aspire.Hosting.Redis.Tests/RedisFunctionalTests.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics; using Aspire.Components.Common.Tests; using Aspire.Hosting.Utils; using Microsoft.Extensions.Configuration; @@ -130,7 +129,7 @@ public async Task WithDataVolumeShouldPersistStateBetweenUsages() await app.StopAsync(); } - AttemptDeleteDockerVolume(volumeName); + DockerUtils.AttemptDeleteDockerVolume(volumeName); } [Fact] @@ -293,14 +292,4 @@ public async Task PersistenceIsDisabledByDefault() await app.StopAsync(); } } - - private static void AttemptDeleteDockerVolume(string volumeName) - { - if (Process.Start("docker", $"volume rm {volumeName}") is { } process) - { - process.WaitForExit(TimeSpan.FromSeconds(3)); - process.Kill(entireProcessTree: true); - process.Dispose(); - } - } } diff --git a/tests/Aspire.Hosting.Tests/Utils/DockerUtils.cs b/tests/Aspire.Hosting.Tests/Utils/DockerUtils.cs new file mode 100644 index 00000000000..8a549988110 --- /dev/null +++ b/tests/Aspire.Hosting.Tests/Utils/DockerUtils.cs @@ -0,0 +1,19 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics; + +namespace Aspire.Hosting.Utils; + +public sealed class DockerUtils +{ + public static void AttemptDeleteDockerVolume(string volumeName) + { + if (Process.Start("docker", $"volume rm {volumeName}") is { } process) + { + process.WaitForExit(TimeSpan.FromSeconds(3)); + process.Kill(entireProcessTree: true); + process.Dispose(); + } + } +}