| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242 |
- package azure
- import (
- "fmt"
- "testing"
- "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2021-11-01/compute"
- "github.com/Azure/azure-sdk-for-go/services/preview/commerce/mgmt/2015-06-01-preview/commerce"
- "github.com/stretchr/testify/require"
- "github.com/opencost/opencost/core/pkg/util/mathutil"
- "github.com/opencost/opencost/pkg/cloud/models"
- )
- func TestParseAzureSubscriptionID(t *testing.T) {
- cases := []struct {
- input string
- expected string
- }{
- {
- input: "azure:///subscriptions/0badafdf-1234-abcd-wxyz-123456789/...",
- expected: "0badafdf-1234-abcd-wxyz-123456789",
- },
- {
- input: "azure:/subscriptions/0badafdf-1234-abcd-wxyz-123456789/...",
- expected: "",
- },
- {
- input: "azure:///subscriptions//",
- expected: "",
- },
- {
- input: "",
- expected: "",
- },
- }
- for _, test := range cases {
- result := ParseAzureSubscriptionID(test.input)
- if result != test.expected {
- t.Errorf("Input: %s, Expected: %s, Actual: %s", test.input, test.expected, result)
- }
- }
- }
- func TestConvertMeterToPricings(t *testing.T) {
- regions := map[string]string{
- "useast": "US East",
- "japanwest": "Japan West",
- "australiasoutheast": "Australia Southeast",
- "norwaywest": "Norway West",
- }
- baseCPUPrice := "0.30000"
- meterInfo := func(category, subcategory, name, region string, rate float64) commerce.MeterInfo {
- return commerce.MeterInfo{
- MeterCategory: &category,
- MeterSubCategory: &subcategory,
- MeterName: &name,
- MeterRegion: ®ion,
- MeterRates: map[string]*float64{"0": &rate},
- }
- }
- t.Run("windows", func(t *testing.T) {
- info := meterInfo("Virtual Machines", "D2 Series Windows", "D2s v3", "AU Southeast", 0.3)
- results, err := convertMeterToPricings(info, regions, baseCPUPrice)
- require.NoError(t, err)
- require.Nil(t, results)
- })
- t.Run("storage", func(t *testing.T) {
- info := meterInfo("Storage", "Some SSD type", "P4 are good", "US East", 2000)
- results, err := convertMeterToPricings(info, regions, baseCPUPrice)
- require.NoError(t, err)
- expected := map[string]*AzurePricing{
- "useast,premium_ssd": {
- PV: &models.PV{Cost: "0.085616", Region: "useast"},
- },
- }
- require.Equal(t, expected, results)
- })
- t.Run("virtual machines", func(t *testing.T) {
- info := meterInfo("Virtual Machines", "Eav4/Easv4 Series", "E96a v4/E96as v4 Low Priority", "JA West", 10)
- results, err := convertMeterToPricings(info, regions, baseCPUPrice)
- require.NoError(t, err)
- expected := map[string]*AzurePricing{
- "japanwest,Standard_E96a_v4,preemptible": {
- Node: &models.Node{Cost: "10.000000", BaseCPUPrice: "0.30000", UsageType: "preemptible"},
- },
- "japanwest,Standard_E96as_v4,preemptible": {
- Node: &models.Node{Cost: "10.000000", BaseCPUPrice: "0.30000", UsageType: "preemptible"},
- },
- }
- require.Equal(t, expected, results)
- })
- }
- func TestAzure_findCostForDisk(t *testing.T) {
- var loc string = "location"
- var size int32 = 1
- az := &Azure{
- Pricing: map[string]*AzurePricing{
- "location,nil": nil,
- "location,nilpv": {
- PV: nil,
- },
- "location,ssd": {
- PV: &models.PV{
- Cost: "1",
- },
- },
- },
- }
- testCases := []struct {
- name string
- disk *compute.Disk
- exp float64
- expErr error
- }{
- {
- "disk is nil",
- nil,
- 0.0,
- fmt.Errorf("disk is empty"),
- },
- {
- "nil location",
- &compute.Disk{
- Location: nil,
- Sku: &compute.DiskSku{
- Name: "ssd",
- },
- DiskProperties: &compute.DiskProperties{
- DiskSizeGB: &size,
- },
- },
- 0.0,
- fmt.Errorf("failed to find pricing for key: ,ssd"),
- },
- {
- "nil disk properties",
- &compute.Disk{
- Location: &loc,
- Sku: &compute.DiskSku{
- Name: "ssd",
- },
- DiskProperties: nil,
- },
- 0.0,
- fmt.Errorf("disk properties are nil"),
- },
- {
- "nil disk size",
- &compute.Disk{
- Location: &loc,
- Sku: &compute.DiskSku{
- Name: "ssd",
- },
- DiskProperties: &compute.DiskProperties{
- DiskSizeGB: nil,
- },
- },
- 0.0,
- fmt.Errorf("disk size is nil"),
- },
- {
- "sku does not exist",
- &compute.Disk{
- Location: &loc,
- Sku: &compute.DiskSku{
- Name: "doesnotexist",
- },
- DiskProperties: &compute.DiskProperties{
- DiskSizeGB: &size,
- },
- },
- 0.0,
- fmt.Errorf("failed to find pricing for key: location,doesnotexist"),
- },
- {
- "pricing is nil",
- &compute.Disk{
- Sku: &compute.DiskSku{
- Name: "nil",
- },
- DiskProperties: &compute.DiskProperties{
- DiskSizeGB: &size,
- },
- },
- 0.0,
- fmt.Errorf("failed to find pricing for key: location,nil"),
- },
- {
- "pricing.PV is nil",
- &compute.Disk{
- Sku: &compute.DiskSku{
- Name: "nilpv",
- },
- DiskProperties: &compute.DiskProperties{
- DiskSizeGB: &size,
- },
- },
- 0.0,
- fmt.Errorf("pricing for key 'location,nilpv' has nil PV"),
- },
- {
- "valid (ssd)",
- &compute.Disk{
- Location: &loc,
- Sku: &compute.DiskSku{
- Name: "ssd",
- },
- DiskProperties: &compute.DiskProperties{
- DiskSizeGB: &size,
- },
- },
- 730.0,
- nil,
- },
- }
- for _, tc := range testCases {
- t.Run(tc.name, func(t *testing.T) {
- act, actErr := az.findCostForDisk(tc.disk)
- if actErr != nil && tc.expErr == nil {
- t.Fatalf("unexpected error: %s", actErr)
- }
- if tc.expErr != nil && actErr == nil {
- t.Fatalf("missing expected error: %s", tc.expErr)
- }
- if !mathutil.Approximately(tc.exp, act) {
- t.Fatalf("expected value %f; got %f", tc.exp, act)
- }
- })
- }
- }
|