@@ -296,6 +296,143 @@ func TestNodePolicyResourceModel(t *testing.T) {
296296 }
297297 })
298298
299+ // Test LabelSelector with multiple MatchExpressions and multiple values
300+ t .Run ("LabelSelector_WithMultipleMatchExpressions" , func (t * testing.T ) {
301+ selector := & LabelSelector {
302+ MatchLabels : types .MapValueMust (types .StringType , map [string ]attr.Value {
303+ "app" : types .StringValue ("api" ),
304+ "env" : types .StringValue ("prod" ),
305+ }),
306+ MatchExpressions : types .ListValueMust (
307+ types.ObjectType {
308+ AttrTypes : map [string ]attr.Type {
309+ "key" : types .StringType ,
310+ "operator" : types .StringType ,
311+ "values" : types.ListType {ElemType : types .StringType },
312+ },
313+ },
314+ []attr.Value {
315+ types .ObjectValueMust (
316+ map [string ]attr.Type {
317+ "key" : types .StringType ,
318+ "operator" : types .StringType ,
319+ "values" : types.ListType {ElemType : types .StringType },
320+ },
321+ map [string ]attr.Value {
322+ "key" : types .StringValue ("instanceGenerations" ),
323+ "operator" : types .StringValue ("Gt" ),
324+ "values" : types .ListValueMust (types .StringType , []attr.Value {types .StringValue ("4" )}),
325+ },
326+ ),
327+ types .ObjectValueMust (
328+ map [string ]attr.Type {
329+ "key" : types .StringType ,
330+ "operator" : types .StringType ,
331+ "values" : types.ListType {ElemType : types .StringType },
332+ },
333+ map [string ]attr.Value {
334+ "key" : types .StringValue ("instanceFamily" ),
335+ "operator" : types .StringValue ("In" ),
336+ "values" : types .ListValueMust (types .StringType , []attr.Value {
337+ types .StringValue ("m5" ),
338+ types .StringValue ("m6i" ),
339+ types .StringValue ("m7i" ),
340+ }),
341+ },
342+ ),
343+ types .ObjectValueMust (
344+ map [string ]attr.Type {
345+ "key" : types .StringType ,
346+ "operator" : types .StringType ,
347+ "values" : types.ListType {ElemType : types .StringType },
348+ },
349+ map [string ]attr.Value {
350+ "key" : types .StringValue ("zone" ),
351+ "operator" : types .StringValue ("NotIn" ),
352+ "values" : types .ListValueMust (types .StringType , []attr.Value {
353+ types .StringValue ("us-west-2a" ),
354+ types .StringValue ("us-west-2b" ),
355+ }),
356+ },
357+ ),
358+ },
359+ ),
360+ }
361+
362+ // Test toProto
363+ ctx := context .Background ()
364+ proto , err := selector .toProto (ctx )
365+ if err != nil {
366+ t .Fatalf ("Expected no error, got %v" , err )
367+ }
368+ if proto == nil {
369+ t .Fatal ("Expected non-nil proto" )
370+ }
371+ if len (proto .MatchLabels ) != 2 {
372+ t .Errorf ("Expected 2 match labels, got %d" , len (proto .MatchLabels ))
373+ }
374+ if proto .MatchLabels ["app" ] != "api" {
375+ t .Errorf ("Expected app=api, got %s" , proto .MatchLabels ["app" ])
376+ }
377+ if proto .MatchLabels ["env" ] != "prod" {
378+ t .Errorf ("Expected env=prod, got %s" , proto .MatchLabels ["env" ])
379+ }
380+ if len (proto .MatchExpressions ) != 3 {
381+ t .Fatalf ("Expected 3 match expressions, got %d" , len (proto .MatchExpressions ))
382+ }
383+
384+ // Check first expression (Gt with single value)
385+ expr1 := proto .MatchExpressions [0 ]
386+ if expr1 .Key != "instanceGenerations" {
387+ t .Errorf ("Expected key=instanceGenerations, got %s" , expr1 .Key )
388+ }
389+ if expr1 .Operator != 5 { // GT = 5
390+ t .Errorf ("Expected operator=GT (5), got %d" , expr1 .Operator )
391+ }
392+ if len (expr1 .Values ) != 1 {
393+ t .Errorf ("Expected 1 value, got %d" , len (expr1 .Values ))
394+ }
395+ if expr1 .Values [0 ] != "4" {
396+ t .Errorf ("Expected value '4', got %s" , expr1 .Values [0 ])
397+ }
398+
399+ // Check second expression (In with multiple values)
400+ expr2 := proto .MatchExpressions [1 ]
401+ if expr2 .Key != "instanceFamily" {
402+ t .Errorf ("Expected key=instanceFamily, got %s" , expr2 .Key )
403+ }
404+ if expr2 .Operator != 1 { // IN = 1
405+ t .Errorf ("Expected operator=IN (1), got %d" , expr2 .Operator )
406+ }
407+ if len (expr2 .Values ) != 3 {
408+ t .Errorf ("Expected 3 values, got %d" , len (expr2 .Values ))
409+ }
410+ expectedValues := []string {"m5" , "m6i" , "m7i" }
411+ for i , expected := range expectedValues {
412+ if expr2 .Values [i ] != expected {
413+ t .Errorf ("Expected value[%d]='%s', got '%s'" , i , expected , expr2 .Values [i ])
414+ }
415+ }
416+
417+ // Check third expression (NotIn with multiple values)
418+ expr3 := proto .MatchExpressions [2 ]
419+ if expr3 .Key != "zone" {
420+ t .Errorf ("Expected key=zone, got %s" , expr3 .Key )
421+ }
422+ if expr3 .Operator != 2 { // NOT_IN = 2
423+ t .Errorf ("Expected operator=NOT_IN (2), got %d" , expr3 .Operator )
424+ }
425+ if len (expr3 .Values ) != 2 {
426+ t .Errorf ("Expected 2 values, got %d" , len (expr3 .Values ))
427+ }
428+ expectedZones := []string {"us-west-2a" , "us-west-2b" }
429+ for i , expected := range expectedZones {
430+ if expr3 .Values [i ] != expected {
431+ t .Errorf ("Expected value[%d]='%s', got '%s'" , i , expected , expr3 .Values [i ])
432+ }
433+ }
434+ })
435+
299436 // Test DisruptionPolicy with nested budgets (full toProto conversion)
300437 t .Run ("DisruptionPolicy_WithBudgets" , func (t * testing.T ) {
301438 policy := & DisruptionPolicy {
0 commit comments