- Add runtime-reconnect-config-refresh milestone and SDD - Archive m-runtime-reconnect-config-refresh task with full logs - Update edge/node domain rules, bootstrap, transport sessions - Update config package and node.yaml configuration - Update documentation and ROADMAP/PHASE files
171 lines
4.6 KiB
Go
171 lines
4.6 KiB
Go
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")
|
|
}
|
|
for _, want := range []string{"reconnect:", "interval_sec: 10", "max_attempts: 10"} {
|
|
if !strings.Contains(out.String(), want) {
|
|
t.Errorf("config print output missing %q\n---\n%s", want, out.String())
|
|
}
|
|
}
|
|
}
|
|
|
|
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)
|
|
}
|
|
}
|