package controllers import ( "apiserver/models" "apiserver/store" "apiserver/utils" "sync" "testing" "go.uber.org/zap" ) func resetHostControlState() { store.InitStores() utils.Log = zap.NewNop() } // TestPreCheckHostControlRequest_AllFlag verifies that when hostname is ["all"], // the returned bool is true. func TestPreCheckHostControlRequest_AllFlag(t *testing.T) { resetHostControlState() req := &models.HostControlRequest{ ControlAction: "close", Hostname: []string{"all"}, } allFlag, err := preCheckHostControlRequest(req) if err != nil { t.Fatalf("unexpected error: %v", err) } if !allFlag { t.Error("expected allFlag=true when hostname is [\"all\"]") } } // TestPreCheckHostControlRequest_NotAll verifies that when hostname is a // specific host, the returned bool is false. func TestPreCheckHostControlRequest_NotAll(t *testing.T) { resetHostControlState() req := &models.HostControlRequest{ ControlAction: "open", Hostname: []string{"node01"}, } allFlag, err := preCheckHostControlRequest(req) if err != nil { t.Fatalf("unexpected error: %v", err) } if allFlag { t.Error("expected allFlag=false when hostname is [\"node01\"]") } } // TestPreCheckHostControlRequest_NoRace verifies that concurrent calls to // preCheckHostControlRequest do not share state via a package-level variable. func TestPreCheckHostControlRequest_NoRace(t *testing.T) { t.Parallel() resetHostControlState() var wg sync.WaitGroup const goroutines = 50 results := make([]bool, goroutines) errors := make([]error, goroutines) for i := 0; i < goroutines; i++ { wg.Add(1) go func(idx int) { defer wg.Done() var req models.HostControlRequest if idx%2 == 0 { req = models.HostControlRequest{ ControlAction: "close", Hostname: []string{"all"}, } } else { req = models.HostControlRequest{ ControlAction: "open", Hostname: []string{"node01"}, } } results[idx], errors[idx] = preCheckHostControlRequest(&req) }(i) } wg.Wait() for i := 0; i < goroutines; i++ { if errors[i] != nil { t.Errorf("goroutine %d: unexpected error: %v", i, errors[i]) continue } if i%2 == 0 && !results[i] { t.Errorf("goroutine %d: expected allFlag=true for [\"all\"]", i) } if i%2 != 0 && results[i] { t.Errorf("goroutine %d: expected allFlag=false for [\"node01\"]", i) } } } // TestPreCheckHostControlRequest_InvalidAction verifies that an unsupported // action returns an error. func TestPreCheckHostControlRequest_InvalidAction(t *testing.T) { resetHostControlState() req := &models.HostControlRequest{ ControlAction: "invalid_action", Hostname: []string{"node01"}, } _, err := preCheckHostControlRequest(req) if err == nil { t.Error("expected error for invalid action, got nil") } } // TestPreCheckHostControlRequest_CommentTooLong verifies that a comment // exceeding 512 characters returns an error. func TestPreCheckHostControlRequest_CommentTooLong(t *testing.T) { resetHostControlState() longComment := make([]byte, 513) for i := range longComment { longComment[i] = 'a' } req := &models.HostControlRequest{ ControlAction: "close", Hostname: []string{"node01"}, Comment: string(longComment), } _, err := preCheckHostControlRequest(req) if err == nil { t.Error("expected error for comment exceeding 512 chars, got nil") } }