package main import ( "context" "net/http" "net/http/httptest" "strings" "testing" "git.cin.su/m/Assistant/adapters/models" "git.cin.su/m/Assistant/contracts/capability" "git.cin.su/m/Assistant/contracts/cognitive" ) type qualificationProvider struct{} func (qualificationProvider) Probe(context.Context) models.ProviderProbe { return models.ProviderProbe{Health: capability.HealthAvailable} } func (qualificationProvider) Discover(context.Context) ([]models.DiscoveredModel, models.ProviderProbe) { return []models.DiscoveredModel{{ProviderModelID: "model-a"}, {ProviderModelID: "model-b"}}, models.ProviderProbe{Health: capability.HealthAvailable} } func (qualificationProvider) Advise(_ context.Context, request cognitive.AdvisoryRequest) (cognitive.AdvisoryResponse, error) { if err := models.ValidateAdvisoryRequest(request); err != nil { return cognitive.AdvisoryResponse{}, err } return cognitive.AdvisoryResponse{Version: request.Version, RequestID: request.RequestID, AdvisoryText: "reachable", FinishReason: cognitive.FinishCompleted}, nil } func TestModelQualificationUsesDiscoveredModelsAndLeavesQualityUnrated(t *testing.T) { provider := qualificationProvider{} mux := http.NewServeMux() mux.Handle("POST /v1/provider-discovery/{provider}/qualify", modelQualificationHandler(map[string]providerRegistration{"gpu": {ProviderInstanceID: "gpu", Provider: provider, Discovery: provider}}, "owner")) server := httptest.NewServer(mux) defer server.Close() request := httptest.NewRequest(http.MethodPost, server.URL+"/v1/provider-discovery/gpu/qualify", strings.NewReader(`{"prompt":"ready","max_output_bytes":128}`)) request.Header.Set("Content-Type", "application/json") response := httptest.NewRecorder() mux.ServeHTTP(response, request) if response.Code != http.StatusOK { t.Fatalf("qualification status=%d body=%s", response.Code, response.Body.String()) } if !strings.Contains(response.Body.String(), `"status":"REACHABLE"`) || !strings.Contains(response.Body.String(), `"category":"UNRATED"`) || strings.Contains(response.Body.String(), `"quality_assessed":true`) { t.Fatalf("qualification overclaimed quality: %s", response.Body.String()) } } func TestModelQualificationRejectsUnboundedOutput(t *testing.T) { provider := qualificationProvider{} mux := http.NewServeMux() mux.Handle("POST /v1/provider-discovery/{provider}/qualify", modelQualificationHandler(map[string]providerRegistration{"cpu": {ProviderInstanceID: "cpu", Provider: provider, Discovery: provider}}, "owner")) request := httptest.NewRequest(http.MethodPost, "/v1/provider-discovery/cpu/qualify", strings.NewReader(`{"prompt":"ready","max_output_bytes":8192}`)) request.Header.Set("Content-Type", "application/json") response := httptest.NewRecorder() mux.ServeHTTP(response, request) if response.Code != http.StatusBadRequest { t.Fatalf("unbounded qualification status=%d", response.Code) } } type qualificationObserverStub struct { observations []capability.ModelQualificationObservation } func (s *qualificationObserverStub) ObserveQualification(_ context.Context, value capability.ModelQualificationObservation) error { s.observations = append(s.observations, value) return nil } func TestModelQualificationPersistsReachabilityWithoutQuality(t *testing.T) { provider := qualificationProvider{} observer := &qualificationObserverStub{} mux := http.NewServeMux() mux.Handle("POST /v1/provider-discovery/{provider}/qualify", modelQualificationHandler(map[string]providerRegistration{"cpu": {ProviderInstanceID: "cpu", Provider: provider, Discovery: provider}}, "owner", observer)) request := httptest.NewRequest(http.MethodPost, "/v1/provider-discovery/cpu/qualify", strings.NewReader(`{"prompt":"ready","max_output_bytes":128,"model_ids":["model-a"]}`)) request.Header.Set("Content-Type", "application/json") response := httptest.NewRecorder() mux.ServeHTTP(response, request) if response.Code != http.StatusOK || len(observer.observations) != 1 { t.Fatalf("qualification persistence status=%d observations=%d body=%s", response.Code, len(observer.observations), response.Body.String()) } if err := observer.observations[0].Validate(); err != nil || observer.observations[0].Status != capability.ModelQualificationReachable { t.Fatalf("invalid qualification observation: %+v err=%v", observer.observations[0], err) } }