Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Increase Coster test coverage #289

Merged
merged 1 commit into from
Oct 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions coster/.editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,10 @@ dotnet_diagnostic.CA2007.severity = none
# This is not a library. The code is only used in a console app where there is no SynchronizationContext
dotnet_diagnostic.MA0004.severity = none

# https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0007.md
# This is a personal preference
dotnet_diagnostic.MA0007.severity = none

# CSharp code style settings:
[*.cs]
# Newline settings
Expand Down
2 changes: 1 addition & 1 deletion coster/src/AzureVmCoster/Services/Pricer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public void EnsurePricingExists(List<InputVm> vms)
var missingFiles = vms
.Select(vm => new FileIdentifier(vm.Region, vm.OperatingSystem))
.Distinct(new FileIdentifierComparer())
.Where(fileIdentifier => !File.Exists($@"{_pricingDirectory}{fileIdentifier.PricingFilename}"))
.Where(fileIdentifier => !File.Exists($"{_pricingDirectory}{fileIdentifier.PricingFilename}"))
.ToList();

if (missingFiles.Count > 0)
Expand Down
16 changes: 2 additions & 14 deletions coster/tests/AzureVmCosterTests/AzureVmCosterTests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -35,20 +35,8 @@
</ItemGroup>

<ItemGroup>
<None Update="SampleInputs\*.csv">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>

<ItemGroup>
<None Update="SamplePricing\*.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>

<ItemGroup>
<None Update="TestPricing\*.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<None Update="TestFiles\**\*.*">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>

Expand Down
16 changes: 16 additions & 0 deletions coster/tests/AzureVmCosterTests/Models/FileIdentifierTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,20 @@ public static void GivenValidFilename_WhenFromFileInfo_ThenExpected()

actual.Should().BeEquivalentTo(expected);
}

[Theory]
[InlineData(@"E:\tmp\vm-pricing_some-region.json")]
[InlineData(@"E:\tmp\vm-pricing.json")]
[InlineData(@"E:\tmp\vm-pricing_some-region_some-operating-system.csv")]
public static void GivenInvalidFilename_WhenFromFileInfo_ThenThrows(string filePath)
{
// Arrange
var file = new FileInfo(filePath);

// Act
var actualException = Assert.Throws<ArgumentOutOfRangeException>(() => FileIdentifier.From(file));

// Assert
Assert.NotNull(actualException);
}
}
10 changes: 5 additions & 5 deletions coster/tests/AzureVmCosterTests/Services/InputVmParserTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public class InputVmParserTests
public void GivenExactMatchInputAndCultureWithPeriodDecimalPoint_WhenParse_ThenPreserveOrder()
{
// Arrange
var file = new FileInfo(@"SampleInputs/input-en-au.csv");
var file = new FileInfo("TestFiles/SampleInputs/input-en-au.csv");
var culture = new CultureInfo("en-au");

// Act
Expand All @@ -31,7 +31,7 @@ public void GivenExactMatchInputAndCultureWithPeriodDecimalPoint_WhenParse_ThenP
public void GivenExactMatchInputAndCultureWithPeriodDecimalPoint_WhenParse_ThenParseAllFields()
{
// Arrange
var file = new FileInfo(@"SampleInputs/input-en-au.csv");
var file = new FileInfo("TestFiles/SampleInputs/input-en-au.csv");
var culture = new CultureInfo("en-au");

// Act
Expand All @@ -46,7 +46,7 @@ public void GivenExactMatchInputAndCultureWithPeriodDecimalPoint_WhenParse_ThenP
public void GivenInputWithUnknownFieldsAndCultureWithPeriodDecimalPoint_WhenParse_ThenIgnoreUnknownFields()
{
// Arrange
var fileInfo = new FileInfo(@"SampleInputs/input-en-au-extra-fields.csv");
var fileInfo = new FileInfo("TestFiles/SampleInputs/input-en-au-extra-fields.csv");
var culture = new CultureInfo("en-au");

// Act
Expand All @@ -61,7 +61,7 @@ public void GivenInputWithUnknownFieldsAndCultureWithPeriodDecimalPoint_WhenPars
public void GivenExactMatchInputAndCultureWithCommaDecimalPoint_WhenParse_ThenParseAllFields()
{
// Arrange
var file = new FileInfo(@"SampleInputs/input-fr-fr.csv");
var file = new FileInfo("TestFiles/SampleInputs/input-fr-fr.csv");
var culture = new CultureInfo("fr-fr");

// Act
Expand All @@ -76,7 +76,7 @@ public void GivenExactMatchInputAndCultureWithCommaDecimalPoint_WhenParse_ThenPa
public void GivenRegionAndOperatingSystemWithUnexpectedCase_WhenParse_ThenLowerCase()
{
// Arrange
var file = new FileInfo("SampleInputs/input-en-au-wrong-case.csv");
var file = new FileInfo("TestFiles/SampleInputs/input-en-au-wrong-case.csv");
var culture = new CultureInfo("en-au");

// Act
Expand Down
96 changes: 86 additions & 10 deletions coster/tests/AzureVmCosterTests/Services/PricerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,15 @@ namespace AzureVmCosterTests.Services;

public class PricerTests
{
private readonly Pricer _target;

public PricerTests()
{
_target = new Pricer(@"SamplePricing/");
}
private readonly Pricer _target = new("TestFiles/SamplePricing/");

[Fact]
public void GivenMissingRegionAndMissingOperatingSystem_WhenEnsurePricingExists_ThenThrow()
{
// Arrange
var vms = new List<InputVm>
{
new InputVm {Region = "missing", OperatingSystem = "missing"}
new() {Region = "missing", OperatingSystem = "missing"}
};

// Act
Expand All @@ -34,7 +29,7 @@ public void GivenExistingRegionAndExistingOperatingSystem_WhenEnsurePricingExist
// Arrange
var vms = new List<InputVm>
{
new InputVm {Region = "region", OperatingSystem = "operating-system"}
new() {Region = "region", OperatingSystem = "operating-system"}
};

// Act
Expand All @@ -50,7 +45,7 @@ public void GivenExistingRegionAndMissingOperatingSystem_WhenEnsurePricingExists
// Arrange
var vms = new List<InputVm>
{
new InputVm {Region = "region", OperatingSystem = "missing"}
new() {Region = "region", OperatingSystem = "missing"}
};

// Act
Expand All @@ -66,7 +61,7 @@ public void GivenMissingRegionAndExistingOperatingSystem_WhenEnsurePricingExists
// Arrange
var vms = new List<InputVm>
{
new InputVm {Region = "missing", OperatingSystem = "operating-system"}
new() {Region = "missing", OperatingSystem = "operating-system"}
};

// Act
Expand Down Expand Up @@ -136,4 +131,85 @@ public void GivenExcludeList_WhenFilterPricing_ThenRemoveInstanceWithSameNameCas
// Assert
filteredPrices.Should().BeEmpty();
}

[Fact]
public void GivenMatchingPrice_WhenPrice_ThenPriceVm()
{
// Arrange
var vms = new List<InputVm>
{
InputVmBuilder.AsUsWestWindowsD2V3Equivalent()
};
var prices = new List<VmPricing>
{
VmPricingBuilder.AsUsWestWindowsD2V3()
};

// Act
var actualPricedVms = Pricer.Price(vms, prices);

// Assert
var expectedPricedVms = new List<PricedVm> { new(vms[0], prices[0]) };
actualPricedVms.Should().BeEquivalentTo(expectedPricedVms);
}

[Fact]
public void GivenNoMatchingPrice_WhenPrice_ThenHandleVmAsNoPrice()
{
// Arrange
var vms = new List<InputVm>
{
InputVmBuilder.AsUsWestWindowsD2V3Equivalent()
};
var prices = new List<VmPricing>();

// Act
var actualPricedVms = Pricer.Price(vms, prices);

// Assert
var expectedPricedVms = new List<PricedVm> { new(vms[0], null) };
actualPricedVms.Should().BeEquivalentTo(expectedPricedVms);
}

[Fact]
public void GivenVmWithoutCpuAndWithoutRam_WhenPrice_ThenUseMedianCpuAndRam()
{
// Arrange
var vmWithoutCpuWithoutRam = new InputVm
{
Name = "map-me-to-median",
OperatingSystem = "windows",
Region = "us-west"
};
var vms = new List<InputVm>
{
InputVmBuilder.AsUsWestWindowsD2V3Equivalent(),
InputVmBuilder.AsUsWestWindowsD4V3Equivalent(),
InputVmBuilder.AsUsWestWindowsD8V3Equivalent(),
InputVmBuilder.AsUsWestWindowsD16V3Equivalent(),
vmWithoutCpuWithoutRam
};
var medianPrice = VmPricingBuilder.AsUsWestWindowsD8V3();
var prices = new List<VmPricing>
{
VmPricingBuilder.AsUsWestWindowsD2V3(),
VmPricingBuilder.AsUsWestWindowsD4V3(),
medianPrice,
VmPricingBuilder.AsUsWestWindowsD16V3()
};

// Act
var actualPricedVms = Pricer.Price(vms, prices);

// Assert
var expectedPricedVms = new List<PricedVm>
{
new(vms[0], prices[0]),
new(vms[1], prices[1]),
new(vms[2], prices[2]),
new(vms[3], prices[3]),
new(vmWithoutCpuWithoutRam, medianPrice)
};
actualPricedVms.Should().BeEquivalentTo(expectedPricedVms);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@ namespace AzureVmCosterTests.Services;

public class VmPricingParserTests
{
private readonly VmPricingParser _parser = new("TestPricing/");

[Fact]
public async Task GivenValidPrice_ThenParseVm()
{
// Arrange
var parser = new VmPricingParser("TestFiles/TestPricing/");

// Act
var prices = await _parser.ParseAsync();
var prices = await parser.ParseAsync();

// Assert
var expectedPrices = new List<VmPricing>
Expand Down Expand Up @@ -38,4 +39,17 @@ public async Task GivenValidPrice_ThenParseVm()
};
prices.Should().BeEquivalentTo(expectedPrices);
}

[Fact]
public async Task GivenEmptyPriceFile_ThenHandleGracefully()
{
// Arrange
var parser = new VmPricingParser("TestFiles/EmptyPricing/");

// Act
var prices = await parser.ParseAsync();

// Assert
prices.Should().BeEmpty();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[
]
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,40 @@ public static InputVm AsUsWestWindowsD2V3Equivalent()
Cpu = 2
};
}

public static InputVm AsUsWestWindowsD4V3Equivalent()
{
return new InputVm
{
Name = "map-me-to-d4-v3",
OperatingSystem = "windows",
Ram = 16,
Region = "us-west",
Cpu = 4
};
}

public static InputVm AsUsWestWindowsD8V3Equivalent()
{
return new InputVm
{
Name = "map-me-to-d8-v3",
OperatingSystem = "windows",
Ram = 32,
Region = "us-west",
Cpu = 8
};
}

public static InputVm AsUsWestWindowsD16V3Equivalent()
{
return new InputVm
{
Name = "map-me-to-d16-v3",
OperatingSystem = "windows",
Ram = 64,
Region = "us-west",
Cpu = 16
};
}
}
Loading