package domain import ( "math" "strconv" "strings" "testing" ) func TestValidateExecutionTargetSettings(t *testing.T) { valid := ExecutionTarget{ Temperature: 1, MaxTokens: 1, TopP: 0.5, TimeoutSeconds: 1, } type testCase struct { name string change func(*ExecutionTarget) wantErr string } tests := []testCase{ {name: "temperature lower boundary", change: func(v *ExecutionTarget) { v.Temperature = 0 }}, {name: "temperature finite lower neighbor", change: func(v *ExecutionTarget) { v.Temperature = math.Nextafter(0, 1) }}, {name: "temperature finite upper neighbor", change: func(v *ExecutionTarget) { v.Temperature = math.Nextafter(2, 0) }}, {name: "temperature upper boundary", change: func(v *ExecutionTarget) { v.Temperature = 2 }}, {name: "temperature below lower boundary", change: func(v *ExecutionTarget) { v.Temperature = math.Nextafter(0, math.Inf(-1)) }, wantErr: "temperature"}, {name: "temperature above upper boundary", change: func(v *ExecutionTarget) { v.Temperature = math.Nextafter(2, math.Inf(1)) }, wantErr: "temperature"}, {name: "temperature NaN", change: func(v *ExecutionTarget) { v.Temperature = math.NaN() }, wantErr: "temperature"}, {name: "temperature positive infinity", change: func(v *ExecutionTarget) { v.Temperature = math.Inf(1) }, wantErr: "temperature"}, {name: "temperature negative infinity", change: func(v *ExecutionTarget) { v.Temperature = math.Inf(-1) }, wantErr: "temperature"}, {name: "max tokens lower boundary", change: func(v *ExecutionTarget) { v.MaxTokens = 0 }}, {name: "max tokens finite neighbor", change: func(v *ExecutionTarget) { v.MaxTokens = 1 }}, {name: "max tokens below lower boundary", change: func(v *ExecutionTarget) { v.MaxTokens = -1 }, wantErr: "max_tokens"}, {name: "top p lower boundary", change: func(v *ExecutionTarget) { v.TopP = 0 }}, {name: "top p finite lower neighbor", change: func(v *ExecutionTarget) { v.TopP = math.Nextafter(0, 1) }}, {name: "top p finite upper neighbor", change: func(v *ExecutionTarget) { v.TopP = math.Nextafter(1, 0) }}, {name: "top p upper boundary", change: func(v *ExecutionTarget) { v.TopP = 1 }}, {name: "top p below lower boundary", change: func(v *ExecutionTarget) { v.TopP = math.Nextafter(0, math.Inf(-1)) }, wantErr: "top_p"}, {name: "top p above upper boundary", change: func(v *ExecutionTarget) { v.TopP = math.Nextafter(1, math.Inf(1)) }, wantErr: "top_p"}, {name: "top p NaN", change: func(v *ExecutionTarget) { v.TopP = math.NaN() }, wantErr: "top_p"}, {name: "top p positive infinity", change: func(v *ExecutionTarget) { v.TopP = math.Inf(1) }, wantErr: "top_p"}, {name: "top p negative infinity", change: func(v *ExecutionTarget) { v.TopP = math.Inf(-1) }, wantErr: "top_p"}, {name: "timeout lower boundary", change: func(v *ExecutionTarget) { v.TimeoutSeconds = 0 }}, {name: "timeout finite neighbor", change: func(v *ExecutionTarget) { v.TimeoutSeconds = 1 }}, {name: "timeout below lower boundary", change: func(v *ExecutionTarget) { v.TimeoutSeconds = -1 }, wantErr: "timeout_seconds"}, } if strconv.IntSize == 64 { durationLimit := maxExecutionTimeoutSeconds tests = append(tests, testCase{name: "timeout duration boundary", change: func(v *ExecutionTarget) { v.TimeoutSeconds = int(durationLimit) }}, testCase{name: "timeout above duration boundary", change: func(v *ExecutionTarget) { v.TimeoutSeconds = int(durationLimit) + 1 }, wantErr: "timeout_seconds"}, ) } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { target := valid tt.change(&target) err := ValidateExecutionTargetSettings(target) if tt.wantErr == "" { if err != nil { t.Fatalf("validate execution settings: %v", err) } return } if err == nil || !strings.Contains(err.Error(), tt.wantErr) { t.Fatalf("error = %v, want diagnostic containing %q", err, tt.wantErr) } }) } }