package main import ( "bytes" "path/filepath" "strings" "testing" "iop/packages/go/version" ) func TestRootCmdIncludesOperationalCommands(t *testing.T) { root := rootCmd() want := map[string]bool{ "serve": false, "version": false, "config": false, "setup": false, } for _, c := range root.Commands() { if _, ok := want[c.Name()]; ok { want[c.Name()] = true } } for name, ok := range want { if !ok { t.Errorf("root command missing %q", name) } } cfg, _, err := root.Find([]string{"config"}) if err != nil { t.Fatalf("find config: %v", err) } subs := map[string]bool{"print": false, "check": false} for _, c := range cfg.Commands() { if _, ok := subs[c.Name()]; ok { subs[c.Name()] = true } } for name, ok := range subs { if !ok { t.Errorf("config subcommand missing %q", name) } } } func TestVersionCmdPrintsVersion(t *testing.T) { root := rootCmd() var out bytes.Buffer root.SetOut(&out) root.SetErr(&out) root.SetArgs([]string{"version"}) if err := root.Execute(); err != nil { t.Fatalf("execute: %v", err) } got := strings.TrimSpace(out.String()) if got != version.Version { t.Fatalf("version output = %q, want %q", got, version.Version) } } func TestConfigCheckCmdLoadsNodeConfig(t *testing.T) { root := rootCmd() var out bytes.Buffer root.SetOut(&out) root.SetErr(&out) root.SetArgs([]string{"config", "check", "--config", "../../../../configs/node.yaml"}) if err := root.Execute(); err != nil { t.Fatalf("execute: %v\n%s", err, out.String()) } if !strings.Contains(out.String(), "OK") { t.Fatalf("expected OK in output, got %q", out.String()) } } func TestConfigPrintCmdPrintsResolvedConfig(t *testing.T) { root := rootCmd() var out bytes.Buffer root.SetOut(&out) root.SetErr(&out) root.SetArgs([]string{"config", "print", "--config", "../../../../configs/node.yaml"}) if err := root.Execute(); err != nil { t.Fatalf("execute: %v\n%s", err, out.String()) } if out.Len() == 0 { t.Fatal("expected non-empty YAML output") } } func TestSetupDryRunUsesNodeDefaults(t *testing.T) { cfgFile = "configs/node.yaml" // reset to root default root := rootCmd() var out bytes.Buffer root.SetOut(&out) root.SetErr(&out) root.SetArgs([]string{"setup", "--dry-run", "--binary", "/usr/local/bin/iop-node"}) if err := root.Execute(); err != nil { t.Fatalf("execute: %v\n%s", err, out.String()) } s := out.String() for _, want := range []string{ "/etc/iop/node.yaml", "/var/lib/iop/node", "/etc/systemd/system/iop-node.service", "/usr/local/bin/iop-node serve --config /etc/iop/node.yaml", "--- unit preview ---", "--- config preview ---", } { if !strings.Contains(s, want) { t.Errorf("dry-run output missing %q\n---\n%s", want, s) } } if strings.Contains(s, "configs/node.yaml") { t.Errorf("setup default leaked root dev config path: %s", s) } } func TestSetupDryRunAcceptsExplicitConfig(t *testing.T) { cfgFile = "configs/node.yaml" // reset root := rootCmd() var out bytes.Buffer root.SetOut(&out) root.SetErr(&out) custom := filepath.Join(t.TempDir(), "node.yaml") root.SetArgs([]string{"--config", custom, "setup", "--dry-run", "--binary", "/usr/local/bin/iop-node"}) if err := root.Execute(); err != nil { t.Fatalf("execute: %v\n%s", err, out.String()) } if !strings.Contains(out.String(), custom) { t.Errorf("explicit config not used; output:\n%s", out.String()) } } func TestSetupDryRunConfigSubcmdPosition(t *testing.T) { cfgFile = "configs/node.yaml" // reset root := rootCmd() var out bytes.Buffer root.SetOut(&out) root.SetErr(&out) custom := filepath.Join(t.TempDir(), "node.yaml") root.SetArgs([]string{"setup", "--config", custom, "--dry-run", "--binary", "/usr/local/bin/iop-node"}) if err := root.Execute(); err != nil { t.Fatalf("execute: %v\n%s", err, out.String()) } if !strings.Contains(out.String(), custom) { t.Errorf("subcommand-position --config not used; output:\n%s", out.String()) } } func TestSetupHelpShowsNodeDefault(t *testing.T) { cfgFile = "configs/node.yaml" // reset root := rootCmd() var out bytes.Buffer root.SetOut(&out) root.SetErr(&out) root.SetArgs([]string{"setup", "--help"}) _ = root.Execute() s := out.String() if strings.Contains(s, `"configs/node.yaml"`) { t.Errorf("setup --help must not show dev default configs/node.yaml; output:\n%s", s) } if !strings.Contains(s, "/etc/iop/node.yaml") { t.Errorf("setup --help must show /etc/iop/node.yaml; output:\n%s", s) } }