Skip to content
Open
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
8 changes: 4 additions & 4 deletions providers/gcp/services/cloudstorage/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"google.golang.org/api/option"

"github.com/LeanerCloud/cloud-commitments-go/pkg/common"
"github.com/LeanerCloud/cloud-commitments-go/providers/gcp/internal/billingcurrency"
"github.com/LeanerCloud/cloud-commitments-go/providers/gcp/internal/skulist"
"github.com/LeanerCloud/cloud-commitments-go/providers/gcp/internal/skumatch"
)
Expand Down Expand Up @@ -280,8 +281,6 @@ func (c *Client) getOrCreateBillingService(ctx context.Context) (BillingService,

// extractStoragePricingFromSKUs extracts on-demand and commitment pricing from SKU list.
func extractStoragePricingFromSKUs(skus []*cloudbilling.Sku, storageClass, region string) (onDemand, commitment float64, currency string, err error) {
currency = "USD"

for _, sku := range skus {
if !skuMatchesStorageClass(sku, storageClass, region) {
continue
Expand All @@ -295,8 +294,9 @@ func extractStoragePricingFromSKUs(skus []*cloudbilling.Sku, storageClass, regio
continue
}

if curr != "" {
currency = curr
currency, err = billingcurrency.Unify(currency, curr, sku.SkuId)
if err != nil {
return 0, 0, "", err
}

slot, slotErr := skumatch.Slot(sku)
Expand Down
64 changes: 64 additions & 0 deletions providers/gcp/services/cloudstorage/pricing_currency_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package cloudstorage

import (
"context"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"google.golang.org/api/cloudbilling/v1"
)

func currencySKU(id, description, usageType, region, currency string, nanos int64) *cloudbilling.Sku {
return &cloudbilling.Sku{
SkuId: id,
Description: description,
Category: &cloudbilling.Category{UsageType: usageType},
ServiceRegions: []string{region},
PricingInfo: []*cloudbilling.PricingInfo{{
PricingExpression: &cloudbilling.PricingExpression{
UsageUnit: "GiBy.mo",
TieredRates: []*cloudbilling.TierRate{{
UnitPrice: &cloudbilling.Money{CurrencyCode: currency, Nanos: nanos},
}},
},
}},
}
}

func TestGetStoragePricing_Currency(t *testing.T) {
const storageClass, region = "STANDARD", "us-central1"
tests := []struct {
name string
onDemandCur string
commitCur string
wantCurrency string
wantErr string
}{
{name: "consistent non-USD currency is returned as is", onDemandCur: "EUR", commitCur: "EUR", wantCurrency: "EUR"},
{name: "consistent USD", onDemandCur: "USD", commitCur: "USD", wantCurrency: "USD"},
{name: "on-demand and commitment currencies differ", onDemandCur: "USD", commitCur: "EUR", wantErr: "priced in EUR but earlier SKUs are priced in USD"},
{name: "commitment currency missing", onDemandCur: "EUR", commitCur: "", wantErr: "no currency code"},
{name: "on-demand currency missing", onDemandCur: "", commitCur: "EUR", wantErr: "no currency code"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
ctx := context.Background()
client, err := NewClient(ctx, "test-project", region)
require.NoError(t, err)
client.SetBillingService(&MockBillingService{skus: &cloudbilling.ListSkusResponse{Skus: []*cloudbilling.Sku{
currencySKU("od", storageClass+" Storage in "+region, "OnDemand", region, tt.onDemandCur, 26000000),
currencySKU("cud", storageClass+" Storage commitment in "+region, "Commit1Yr", region, tt.commitCur, 19500000),
}}})

got, err := client.getStoragePricing(ctx, storageClass, region, 1)
if tt.wantErr != "" {
require.Error(t, err)
assert.Contains(t, err.Error(), tt.wantErr)
return
}
require.NoError(t, err)
assert.Equal(t, tt.wantCurrency, got.Currency)
})
}
}