mirror of
https://github.com/BaaRai/ARTEX.git
synced 2026-11-14 04:00:54 +08:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a422a071f6 | ||
|
|
3b6eb2fd2c | ||
|
|
2ab1046746 | ||
|
|
c84f124cb4 |
+8
-2
@@ -633,14 +633,20 @@ LIMIT $1`, malformedIPAssetsSampled)
|
||||
if total == 0 {
|
||||
return "", nil
|
||||
}
|
||||
return malformedIPAssetWarningText(total, samples), nil
|
||||
}
|
||||
|
||||
// malformedIPAssetWarningText words the warning for total offending assets, of
|
||||
// which only samples are named; the ones left out are counted in the suffix.
|
||||
func malformedIPAssetWarningText(total int, samples []string) string {
|
||||
warning := fmt.Sprintf(
|
||||
"%d assets have an ip field that is not a valid IP; skipped for IP/CIDR scope matching (these assets will not be attributed to a company by subnet rules): %s",
|
||||
total, strings.Join(samples, ", "),
|
||||
)
|
||||
if total > len(samples) {
|
||||
warning += fmt.Sprintf(" and %d more", total)
|
||||
warning += fmt.Sprintf(" and %d more", total-len(samples))
|
||||
}
|
||||
return warning, nil
|
||||
return warning
|
||||
}
|
||||
|
||||
// UpdateScope replaces all scope rules for a company and reattributes.
|
||||
|
||||
@@ -458,3 +458,21 @@ func TestListCompanies(t *testing.T) {
|
||||
t.Error("ListCompanies: created company not found")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMalformedIPAssetWarningTextCountsOmitted(t *testing.T) {
|
||||
samples := []string{"#1 a", "#2 b", "#3 c", "#4 d", "#5 e"}
|
||||
// The suffix must count the assets left out, not repeat the total, otherwise
|
||||
// the operator is told about more bad rows than exist.
|
||||
got := malformedIPAssetWarningText(8, samples)
|
||||
if !strings.HasPrefix(got, "8 assets have an ip field") {
|
||||
t.Fatalf("the warning should lead with the total of 8, got %q", got)
|
||||
}
|
||||
if !strings.HasSuffix(got, ": #1 a, #2 b, #3 c, #4 d, #5 e and 3 more") {
|
||||
t.Fatalf("8 assets with 5 named should note the 3 omitted, got %q", got)
|
||||
}
|
||||
// When every offending asset is named there is nothing to add.
|
||||
got = malformedIPAssetWarningText(5, samples)
|
||||
if !strings.HasSuffix(got, ": #1 a, #2 b, #3 c, #4 d, #5 e") {
|
||||
t.Fatalf("5 assets with 5 named should have no suffix, got %q", got)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
// The cost ledger: profile prices (EUR per 1M tokens) turn token buckets into
|
||||
// EUR on the usage aggregation; unpriced profiles stay nil.
|
||||
func TestCostLedgerEurOnUsage(t *testing.T) {
|
||||
skipWithoutDSN(t)
|
||||
m, err := NewManager(t.TempDir(), "")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
||||
@@ -22,6 +22,7 @@ import (
|
||||
|
||||
func trafficEvidenceServer(t *testing.T) (*Server, *db.RecordedFinding, func(string, string, string) *httptest.ResponseRecorder) {
|
||||
t.Helper()
|
||||
skipWithoutDSN(t)
|
||||
m, err := NewManager(t.TempDir(), "")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
||||
@@ -103,6 +103,7 @@ func TestOllamaProviderWiresOpenAIProtocol(t *testing.T) {
|
||||
// loadProfileConfig accepts it, the task chain validates it, the failover pool
|
||||
// includes it, and the connection test completes against a fake Ollama.
|
||||
func TestOllamaKeylessProfileLifecycle(t *testing.T) {
|
||||
skipWithoutDSN(t)
|
||||
m, err := NewManager(t.TempDir(), "")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -180,6 +181,7 @@ func TestOllamaKeylessProfileLifecycle(t *testing.T) {
|
||||
// Model listing for an Ollama server works without an API key and tolerates a
|
||||
// base URL with or without the /v1 suffix.
|
||||
func TestOllamaListModels(t *testing.T) {
|
||||
skipWithoutDSN(t)
|
||||
var calls atomic.Value // []string paths
|
||||
fake := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
|
||||
@@ -18,6 +18,7 @@ import (
|
||||
// assigned raw, so a key saved with surrounding whitespace ran fine in
|
||||
// conversations but 401'd the connection test.
|
||||
func TestLLMTestStoredKeyFallbackIsTrimmed(t *testing.T) {
|
||||
skipWithoutDSN(t)
|
||||
m, err := NewManager(t.TempDir(), "")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -97,6 +98,7 @@ func TestLLMTestFallbackMatchesRuntimeNormalization(t *testing.T) {
|
||||
// (the list-view test button) fills provider/model/base_url from the row, so
|
||||
// the key lands on the configured host instead of the canonical default one.
|
||||
func TestLLMTestStoredProfileUsesProfileEndpoint(t *testing.T) {
|
||||
skipWithoutDSN(t)
|
||||
m, err := NewManager(t.TempDir(), "")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
// open-goal fingerprint is unchanged since the last completed round AND active
|
||||
// work exists (open or running intents). Every other combination plans.
|
||||
func TestPlannerQuietSkipEdge(t *testing.T) {
|
||||
skipWithoutDSN(t)
|
||||
m, err := NewManager(t.TempDir(), "")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -78,6 +79,7 @@ func TestPlannerQuietSkipEdge(t *testing.T) {
|
||||
// The quiet-mode switch is editable mid-run (#86): PATCHing plan_quiet_mode
|
||||
// updates both the stored row and the live Task the engine reads per round.
|
||||
func TestPlannerQuietModeToggleMidRun(t *testing.T) {
|
||||
skipWithoutDSN(t)
|
||||
m, err := NewManager(t.TempDir(), "")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
||||
@@ -32,3 +32,13 @@ func TestMain(m *testing.M) {
|
||||
defer conn.Exec(`SELECT pg_advisory_unlock(7337741002)`) //nolint:errcheck
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
|
||||
// skipWithoutDSN skips the test when neither ARTEX_PG_DSN nor a config file
|
||||
// supplies a database, so fixtures that t.Fatal on a NewManager error skip
|
||||
// instead of failing. A configured database that cannot be reached still fails.
|
||||
func skipWithoutDSN(t *testing.T) {
|
||||
t.Helper()
|
||||
if _, _, err := db.DSN(); err != nil {
|
||||
t.Skipf("no database config (%v) — skipping", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
// trafficEvidenceServer but without the finding plumbing.
|
||||
func ingestServer(t *testing.T) (*Server, func(method, path, body string) *httptest.ResponseRecorder) {
|
||||
t.Helper()
|
||||
skipWithoutDSN(t)
|
||||
m, err := NewManager(t.TempDir(), "")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
||||
Reference in New Issue
Block a user