package handlers import ( "testing" ) func TestParseNFTCounters_ParsesCounterAndEgid(t *testing.T) { // nft list output shows `counter packets N bytes M` with actual values // (zero when unused). Template emits `counter comment "egid:X"`; // nft expands that to `counter packets N bytes M comment "egid:X"`. input := ` table inet edgeguard { chain input { type filter hook input priority 0; policy drop; tcp dport 22 ct state new limit rate 10/minute accept comment "anti-lockout: SSH" tcp dport 80 counter packets 0 bytes 0 accept comment "egid:1" ip saddr 10.0.0.0/8 tcp dport 443 counter packets 1234 bytes 567890 accept comment "egid:2" ip saddr 1.2.3.4 drop comment "egid:3" tcp dport 8080 log prefix "edgeguard:4 " group 0 counter packets 7 bytes 420 reject comment "egid:4" } } ` counters := parseNFTCounters(input) if len(counters) != 3 { t.Fatalf("expected 3 counters (egid:1,2,4), got %d: %+v", len(counters), counters) } byID := map[int64]ruleCounter{} for _, c := range counters { byID[c.RuleID] = c } // egid:1 — zero counters are valid if c, ok := byID[1]; !ok { t.Error("missing counter for egid:1") } else if c.Packets != 0 || c.Bytes != 0 { t.Errorf("egid:1 want packets=0 bytes=0, got packets=%d bytes=%d", c.Packets, c.Bytes) } // egid:2 — non-zero counters if c, ok := byID[2]; !ok { t.Error("missing counter for egid:2") } else if c.Packets != 1234 || c.Bytes != 567890 { t.Errorf("egid:2 want packets=1234 bytes=567890, got packets=%d bytes=%d", c.Packets, c.Bytes) } // egid:3 — line has no counter keyword → must not appear if _, ok := byID[3]; ok { t.Error("egid:3 has no counter statement and must not appear in output") } // egid:4 — counter + log + reject if _, ok := byID[4]; !ok { t.Error("missing counter for egid:4") } } func TestParseNFTCounters_EmptyOutput(t *testing.T) { if counters := parseNFTCounters(""); len(counters) != 0 { t.Errorf("expected empty result, got %+v", counters) } } func TestParseNFTCounters_NoRules(t *testing.T) { input := "table inet edgeguard {\n chain input {\n }\n}\n" if counters := parseNFTCounters(input); len(counters) != 0 { t.Errorf("expected empty result for table with no operator rules, got %+v", counters) } }