package statistik import ( "context" "os" "path/filepath" "testing" "time" "munin/internal/store" "munin/internal/workspace" ) // testUmgebung legt eine Kontroll-Datenbank mit zwei Workspaces an, je einem // Projekt darin. func testUmgebung(t *testing.T) (*store.ControlStore, *workspace.Manager, []store.Workspace) { t.Helper() ctx := context.Background() ordner := t.TempDir() wsOrdner := filepath.Join(ordner, "workspaces") if err := os.MkdirAll(wsOrdner, 0750); err != nil { t.Fatal(err) } speicher := store.NewSQLite(filepath.Join(ordner, "control.db"), wsOrdner) control, err := speicher.OpenControl() if err != nil { t.Fatal(err) } t.Cleanup(func() { control.Close() }) manager := workspace.NewManager(speicher) t.Cleanup(func() { manager.Close() }) var liste []store.Workspace for _, name := range []string{"Vertrieb", "Entwicklung"} { ws, err := control.CreateWorkspace(ctx, name) if err != nil { t.Fatal(err) } offen, err := manager.Get(ws.ID) if err != nil { t.Fatal(err) } if _, err := offen.Store.CreateProject(ctx, ws.ID, "allgemein", "Allgemein "+name, ""); err != nil { t.Fatal(err) } liste = append(liste, ws) } return control, manager, liste } // TestErhebung zählt über alle Workspaces zusammen, füllt jeden Tag des // Zeitraums und trennt aktive von ruhigen Projekten. func TestErhebung(t *testing.T) { control, manager, liste := testUmgebung(t) ctx := context.Background() // Im Workspace "Vertrieb" schreibt ein Agent einen Eintrag. offen, _ := manager.Get(liste[0].ID) projekte, _ := offen.Store.ListProjects(ctx, liste[0].ID) if _, err := offen.Store.PutEntry(ctx, store.EntryWrite{ ProjectID: projekte[0].ID, Slug: "notiz", Title: "Notiz", Content: "x", Source: store.SourceAgent, }); err != nil { t.Fatal(err) } offen.Store.LogAudit(ctx, store.AuditEvent{ ProjectID: projekte[0].ID, Actor: "agent", Action: store.ActionEntryWrite, Source: store.SourceMCP, }) stand := NewSammler(control, manager).Aktuell(ctx, time.Now()) if len(stand.Fehler) > 0 { t.Fatalf("Fehler: %v", stand.Fehler) } if len(stand.Workspaces) != 2 || stand.Workspaces[0].Name != "Entwicklung" { t.Errorf("Workspaces %+v, erwartet zwei, nach Name sortiert", stand.Workspaces) } if stand.Summe.Projekte != 2 || stand.Summe.Eintraege != 1 { t.Errorf("Summe %+v, erwartet 2 Projekte und 1 Eintrag", stand.Summe) } if stand.Belegung.Daten <= 0 { t.Error("keine Belegung gezählt") } if stand.Schemastand == "" { t.Error("Schemastand fehlt") } if len(stand.Tage) != Tage { t.Fatalf("%d Tage, erwartet %d", len(stand.Tage), Tage) } heute := stand.Tage[len(stand.Tage)-1] if heute.SchreibenAgent != 1 || heute.Datum.Format("2006-01-02") != time.Now().UTC().Format("2006-01-02") { t.Errorf("letzter Tag %+v, erwartet heute mit einem Schreibvorgang", heute) } if len(stand.Projekte) != 1 || stand.Projekte[0].Workspace != "Vertrieb" { t.Errorf("aktive Projekte %+v, erwartet nur das im Vertrieb", stand.Projekte) } if len(stand.Ruhig) != 1 || stand.Ruhig[0].Workspace != "Entwicklung" { t.Errorf("ruhige Projekte %+v, erwartet nur das in der Entwicklung", stand.Ruhig) } } // TestMindestAbstand: Innerhalb von MindestAbstand kommt der gemerkte Stand // zurück, danach ein neuer — der sich die Wartezahl des vorigen merkt. func TestMindestAbstand(t *testing.T) { control, manager, _ := testUmgebung(t) ctx := context.Background() s := NewSammler(control, manager) jetzt := time.Now() erster := s.Aktuell(ctx, jetzt) if zweiter := s.Aktuell(ctx, jetzt.Add(time.Minute)); !zweiter.Erhoben.Equal(erster.Erhoben) { t.Error("nach einer Minute neu gezählt, erwartet den gemerkten Stand") } dritter := s.Aktuell(ctx, jetzt.Add(MindestAbstand+time.Second)) if dritter.Erhoben.Equal(erster.Erhoben) { t.Fatal("nach MindestAbstand nicht neu gezählt") } if !dritter.VorherErhoben.Equal(erster.Erhoben) { t.Errorf("VorherErhoben = %v, erwartet den ersten Stand %v", dritter.VorherErhoben, erster.Erhoben) } }