Skip to content
Closed
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: 5 additions & 3 deletions providers/azure/services/compute/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -798,9 +798,11 @@ func (c *ComputeClient) cachedSKULookup(ctx context.Context, skuName string) (vm
// GetValidResourceTypes — a SKU listed for a different region is not
// safe to attribute to a recommendation in this client's region).
//
// Returns nil on pager-create or page-fetch error so the
// sync.Once-gated cache field stays nil and cachedSKULookup falls back
// to the empty-fields path. The fetch error is logged WARN once.
// Returns nil on pager-create, page-fetch error, or context cancellation
// so the sync.Once-gated cache field stays nil and cachedSKULookup falls
// back to the empty-fields path. Errors and cancellation are logged WARN
// once; context.Canceled/DeadlineExceeded are treated as terminal
// (feedback_ctx_cancel_terminal.md).
func (c *ComputeClient) fetchSKUCatalogue(ctx context.Context) map[string]vmSKUEntry {
pager, err := c.createResourceSKUsPager()
if err != nil {
Expand Down
29 changes: 29 additions & 0 deletions providers/azure/services/compute/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1083,6 +1083,35 @@ func TestComputeClient_ConvertAzureVMRecommendation_PagerErrorFallsBack(t *testi
assert.Equal(t, 0.0, details.MemoryGB, "MemoryGB left at 0 when catalogue fetch fails")
}

// TestComputeClient_FetchSKUCatalogue_CancelledContextFallsBack asserts
// that a cancelled context is terminal in the SKU catalogue pagination
// loop — the catalogue returns nil and Details.VCPU/MemoryGB stay at 0,
// but the conversion itself succeeds (graceful-degradation contract).
// Pins feedback_ctx_cancel_terminal.md for the compute SKU path.
func TestComputeClient_FetchSKUCatalogue_CancelledContextFallsBack(t *testing.T) {
client := NewClient(nil, "test-subscription", "eastus")

ctx, cancel := context.WithCancel(context.Background())
cancel() // cancel immediately so ctx.Err() is set on first loop iteration

mockPager := &vmSKUCatalogueMockPager{
pages: []armcompute.ResourceSKUsClientListResponse{
{
ResourceSKUsResult: armcompute.ResourceSKUsResult{
Value: []*armcompute.ResourceSKU{
buildVMSKU("Standard_D2s_v3", "eastus", 2, "8"),
},
},
},
},
}
client.SetResourceSKUsPager(mockPager)

result := client.fetchSKUCatalogue(ctx)
assert.Nil(t, result, "cancelled context must return nil catalogue")
assert.Equal(t, 0, mockPager.pageHits, "NextPage must not be called after context is already cancelled")
}

// TestComputeClient_ConvertAzureVMRecommendation_NoMatchLeavesFieldsZero
// asserts that when the recommendation's SKU isn't in the catalogue
// (e.g. SKU listed for another region only), VCPU/MemoryGB stay at 0
Expand Down
Loading