@@ -11,6 +11,7 @@ import (
1111 "io"
1212 "net/http"
1313 "net/http/httptest"
14+ "os"
1415 "strings"
1516 "testing"
1617
@@ -21,33 +22,49 @@ import (
2122 computev1 "go.goms.io/fleet/apis/protos/azure/compute/v1"
2223)
2324
25+ const (
26+ testTenantID = "test-tenant-id"
27+ )
28+
2429func TestNewAttributeBasedVMSizeRecommenderClient (t * testing.T ) {
2530 tests := []struct {
2631 name string
32+ tenantID string
2733 serverAddress string
2834 httpClient * http.Client
2935 wantClient * AttributeBasedVMSizeRecommenderClient
3036 wantErr bool
3137 }{
38+ {
39+ name : "with missing tenant ID environment variable" ,
40+ serverAddress : "https://example.com" ,
41+ httpClient : http .DefaultClient ,
42+ wantClient : nil ,
43+ wantErr : true ,
44+ },
3245 {
3346 name : "with empty server address" ,
47+ tenantID : testTenantID ,
3448 serverAddress : "" ,
3549 httpClient : http .DefaultClient ,
3650 wantClient : nil ,
3751 wantErr : true ,
3852 },
3953 {
4054 name : "with nil HTTP client" ,
55+ tenantID : testTenantID ,
4156 serverAddress : "http://localhost:8080" ,
4257 httpClient : nil ,
4358 wantClient : nil ,
4459 wantErr : true ,
4560 },
4661 {
47- name : "with both server address and HTTP client" ,
62+ name : "with all fields properly set" ,
63+ tenantID : testTenantID ,
4864 serverAddress : "https://example.com" ,
4965 httpClient : http .DefaultClient ,
5066 wantClient : & AttributeBasedVMSizeRecommenderClient {
67+ tenantID : testTenantID ,
5168 baseURL : "https://example.com" ,
5269 httpClient : http .DefaultClient ,
5370 },
@@ -57,6 +74,11 @@ func TestNewAttributeBasedVMSizeRecommenderClient(t *testing.T) {
5774
5875 for _ , tt := range tests {
5976 t .Run (tt .name , func (t * testing.T ) {
77+ original := os .Getenv (tenantIDEnvVarName )
78+ _ = os .Setenv (tenantIDEnvVarName , tt .tenantID )
79+ defer func () {
80+ _ = os .Setenv (tenantIDEnvVarName , original )
81+ }()
6082 got , gotErr := NewAttributeBasedVMSizeRecommenderClient (tt .serverAddress , tt .httpClient )
6183 if (gotErr != nil ) != tt .wantErr {
6284 t .Errorf ("NewAttributeBasedVMSizeRecommenderClient() error = %v, wantErr %v" , gotErr , tt .wantErr )
@@ -204,29 +226,42 @@ func TestClient_GenerateAttributeBasedRecommendations(t *testing.T) {
204226
205227 for _ , tt := range tests {
206228 t .Run (tt .name , func (t * testing.T ) {
207- // Create mock server
229+ // Set tenant ID environment variable to create client.
230+ original := os .Getenv (tenantIDEnvVarName )
231+ _ = os .Setenv (tenantIDEnvVarName , testTenantID )
232+ defer func () {
233+ _ = os .Setenv (tenantIDEnvVarName , original )
234+ }()
235+ // Create mock server.
208236 server := httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
209- // Verify request method
237+ // Verify request method.
210238 if r .Method != http .MethodPost {
211239 t .Errorf ("got %s, want POST request" , r .Method )
212240 }
213241
214- // Verify headers
242+ // Verify headers.
215243 if r .Header .Get ("Content-Type" ) != "application/json" {
216244 t .Errorf ("got %s, want Content-Type: application/json" , r .Header .Get ("Content-Type" ))
217245 }
218246 if r .Header .Get ("Accept" ) != "application/json" {
219247 t .Errorf ("got %s, want Accept: application/json" , r .Header .Get ("Accept" ))
220248 }
249+ if r .Header .Get ("Grpc-Metadata-subscriptionTenantID" ) != testTenantID {
250+ t .Errorf ("got %s, want Grpc-Metadata-subscriptionTenantID: %s" ,
251+ r .Header .Get ("Grpc-Metadata-subscriptionTenantID" ), testTenantID )
252+ }
253+ if r .Header .Get ("Grpc-Metadata-clientRequestID" ) == "" {
254+ t .Error ("Grpc-Metadata-clientRequestID header is missing" )
255+ }
221256
222- // Verify URL path if request is not nil
257+ // Verify URL path if request is not nil.
223258 if tt .request != nil && tt .request .SubscriptionId != "" && tt .request .Location != "" {
224259 wantPath := fmt .Sprintf (recommendationsPathTemplate , tt .request .SubscriptionId , tt .request .Location )
225260 if r .URL .Path != wantPath {
226261 t .Errorf ("got %s, want path %s" , r .URL .Path , wantPath )
227262 }
228263
229- // Verify request body using protojson for proper proto3 oneof support
264+ // Verify request body using protojson for proper proto3 oneof support.
230265 body , err := io .ReadAll (r .Body )
231266 if err != nil {
232267 t .Fatalf ("failed to read request body: %v" , err )
@@ -243,24 +278,24 @@ func TestClient_GenerateAttributeBasedRecommendations(t *testing.T) {
243278 }
244279 }
245280
246- // Write mock response
281+ // Write mock response.
247282 w .WriteHeader (tt .mockStatusCode )
248283 if _ , err := w .Write ([]byte (tt .mockResponse )); err != nil {
249284 t .Fatalf ("failed to write response: %v" , err )
250285 }
251286 }))
252287 defer server .Close ()
253288
254- // Create client
289+ // Create client.
255290 client , err := NewAttributeBasedVMSizeRecommenderClient (server .URL , http .DefaultClient )
256291 if err != nil {
257292 t .Errorf ("failed to create client: %v" , err )
258293 }
259294
260- // Execute request
295+ // Execute request.
261296 got , err := client .GenerateAttributeBasedRecommendations (context .Background (), tt .request )
262297
263- // Check error
298+ // Check error.
264299 if (err != nil ) != tt .wantErr {
265300 t .Errorf ("GenerateAttributeBasedRecommendations() error = %v, wantErr %v" , err , tt .wantErr )
266301 return
@@ -271,7 +306,7 @@ func TestClient_GenerateAttributeBasedRecommendations(t *testing.T) {
271306 return
272307 }
273308
274- // Compare response
309+ // Compare response.
275310 if ! proto .Equal (tt .wantResponse , got ) {
276311 t .Errorf ("GenerateAttributeBasedRecommendations() = %+v, want %+v" , got , tt .wantResponse )
277312 }
0 commit comments