package cli import ( "bytes" "context" "errors" "strings" "testing" "git.cloudinit.dev/coreci/orca/internal/emitter" ) func TestNftCmd_Registered(t *testing.T) { found := false for _, c := range rootCmd.Commands() { if c.Name() == "nft" { found = true break } } if !found { t.Fatal("nft command not registered on root") } } func TestNftShowCmd(t *testing.T) { _, cleanup := initTestEnv(t) defer cleanup() origTransport := nftTransportOverride origPeer := nftLeadPeerOverride defer func() { nftTransportOverride = origTransport nftLeadPeerOverride = origPeer }() nftLeadPeerOverride = "lead" want := "table inet orca-ingress { dnat }" nftTransportOverride = &mockNftTransport{ execOut: map[string][]byte{ "nft list table inet orca-ingress": []byte(want), }, } resetRootFlags(t) var buf bytes.Buffer rootCmd.SetOut(&buf) rootCmd.SetErr(&buf) rootCmd.SetArgs([]string{"nft", "show"}) if err := rootCmd.Execute(); err != nil { t.Fatalf("nft show: %v", err) } if !strings.Contains(buf.String(), want) { t.Errorf("nft show output missing %q:\n%s", want, buf.String()) } } func TestNftShowCmd_PeerFlag(t *testing.T) { _, cleanup := initTestEnv(t) defer cleanup() origTransport := nftTransportOverride defer func() { nftTransportOverride = origTransport }() mt := &mockNftTransport{ execOut: map[string][]byte{"nft list table inet orca-ingress": []byte("ok")}, } nftTransportOverride = mt resetRootFlags(t) var buf bytes.Buffer rootCmd.SetOut(&buf) rootCmd.SetErr(&buf) rootCmd.SetArgs([]string{"nft", "show", "--peer", "node-2"}) if err := rootCmd.Execute(); err != nil { t.Fatalf("nft show: %v", err) } } func TestNftDiffCmd_NoDrift(t *testing.T) { _, cleanup := initTestEnv(t) defer cleanup() origTransport := nftTransportOverride origPeer := nftLeadPeerOverride defer func() { nftTransportOverride = origTransport nftLeadPeerOverride = origPeer }() nftLeadPeerOverride = "lead" // Use the full default nft render so the diff detects no drift rendered, rerr := emitter.NftEmitter{}.RenderNftConfig(emitter.NftClusterConfig{}) if rerr != nil { t.Fatalf("render: %v", rerr) } live := string(rendered[0].Content) nftTransportOverride = &mockNftTransport{ execOut: map[string][]byte{ "nft list table inet orca-ingress": []byte(live), }, } resetRootFlags(t) var buf bytes.Buffer rootCmd.SetOut(&buf) rootCmd.SetErr(&buf) rootCmd.SetArgs([]string{"nft", "diff", "--against", "txn-123"}) if err := rootCmd.Execute(); err != nil { t.Fatalf("nft diff: %v", err) } if !strings.Contains(buf.String(), "no drift") { t.Errorf("expected no drift, got:\n%s", buf.String()) } } func TestNftDiffCmd_RequiresAgainst(t *testing.T) { _, cleanup := initTestEnv(t) defer cleanup() resetRootFlags(t) var buf bytes.Buffer rootCmd.SetOut(&buf) rootCmd.SetErr(&buf) rootCmd.SetArgs([]string{"nft", "diff"}) if err := rootCmd.Execute(); err == nil { t.Fatal("expected error for missing --against, got nil") } } func TestNftRateLimitSetCmd(t *testing.T) { _, cleanup := initTestEnv(t) defer cleanup() origTransport := nftTransportOverride origPeer := nftLeadPeerOverride defer func() { nftTransportOverride = origTransport nftLeadPeerOverride = origPeer }() nftLeadPeerOverride = "lead" mt := &mockNftTransport{ execOut: map[string][]byte{}, } nftTransportOverride = mt resetRootFlags(t) var buf bytes.Buffer rootCmd.SetOut(&buf) rootCmd.SetErr(&buf) rootCmd.SetArgs([]string{"nft", "rate", "limit", "set", "--rate", "250"}) if err := rootCmd.Execute(); err != nil { t.Fatalf("nft rate limit set: %v", err) } if !strings.Contains(buf.String(), "rate-limit set to 250/s burst 500") { t.Errorf("unexpected output:\n%s", buf.String()) } } func TestNftRateLimitSetCmd_RequiresRate(t *testing.T) { _, cleanup := initTestEnv(t) defer cleanup() resetRootFlags(t) var buf bytes.Buffer rootCmd.SetOut(&buf) rootCmd.SetErr(&buf) rootCmd.SetArgs([]string{"nft", "rate", "limit", "set"}) if err := rootCmd.Execute(); err == nil { t.Fatal("expected error for missing --rate, got nil") } } func TestNftCountryBlockAddCmd(t *testing.T) { _, cleanup := initTestEnv(t) defer cleanup() origTransport := nftTransportOverride origPeer := nftLeadPeerOverride defer func() { nftTransportOverride = origTransport nftLeadPeerOverride = origPeer }() nftLeadPeerOverride = "lead" mt := &mockNftTransport{execOut: map[string][]byte{}} nftTransportOverride = mt resetRootFlags(t) var buf bytes.Buffer rootCmd.SetOut(&buf) rootCmd.SetErr(&buf) rootCmd.SetArgs([]string{"nft", "country", "block", "add", "RU,CN"}) if err := rootCmd.Execute(); err != nil { t.Fatalf("nft country block add: %v", err) } if !strings.Contains(buf.String(), "added 2 country code(s)") { t.Errorf("unexpected output:\n%s", buf.String()) } } func TestNftCountryBlockAddCmd_BadCode(t *testing.T) { _, cleanup := initTestEnv(t) defer cleanup() resetRootFlags(t) var buf bytes.Buffer rootCmd.SetOut(&buf) rootCmd.SetErr(&buf) rootCmd.SetArgs([]string{"nft", "country", "block", "add", "USA"}) if err := rootCmd.Execute(); err == nil { t.Fatal("expected error for bad country code, got nil") } } func TestNftDoctorAliasCmd(t *testing.T) { _, cleanup := initTestEnv(t) defer cleanup() origTransport := nftTransportOverride origPeer := nftLeadPeerOverride defer func() { nftTransportOverride = origTransport nftLeadPeerOverride = origPeer }() nftLeadPeerOverride = "lead" nftTransportOverride = &mockNftTransport{ execOut: map[string][]byte{ "nft list table inet orca-ingress": []byte("dnat to 127.0.0.1:8443 dnat to 127.0.0.1:8080 ora_rl"), }, } resetRootFlags(t) var buf bytes.Buffer rootCmd.SetOut(&buf) rootCmd.SetErr(&buf) rootCmd.SetArgs([]string{"nft", "doctor"}) if err := rootCmd.Execute(); err != nil { t.Fatalf("nft doctor: %v", err) } if !strings.Contains(buf.String(), "nft:table") { t.Errorf("nft doctor alias did not run doctor nft checks:\n%s", buf.String()) } } func TestNftShowCmd_ExecError(t *testing.T) { _, cleanup := initTestEnv(t) defer cleanup() origTransport := nftTransportOverride origPeer := nftLeadPeerOverride defer func() { nftTransportOverride = origTransport nftLeadPeerOverride = origPeer }() nftLeadPeerOverride = "lead" nftTransportOverride = &mockNftTransport{ execErr: map[string]error{ "nft list table inet orca-ingress": errors.New("connection refused"), }, } resetRootFlags(t) var buf bytes.Buffer rootCmd.SetOut(&buf) rootCmd.SetErr(&buf) rootCmd.SetArgs([]string{"nft", "show"}) if err := rootCmd.Execute(); err == nil { t.Fatal("expected error from exec failure, got nil") } } var _ context.Context = context.Background()