From 0ab2b4870f8ec41dec821b947b1b886ce772392b Mon Sep 17 00:00:00 2001 From: Qi Guo <979918879@qq.com> Date: Fri, 10 Apr 2026 11:07:15 +0800 Subject: [PATCH 1/2] test: cover root command wiring --- pkg/cmd/root/root_test.go | 102 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 pkg/cmd/root/root_test.go diff --git a/pkg/cmd/root/root_test.go b/pkg/cmd/root/root_test.go new file mode 100644 index 0000000..ab8c18e --- /dev/null +++ b/pkg/cmd/root/root_test.go @@ -0,0 +1,102 @@ +package root + +import ( + "os" + "path/filepath" + "runtime" + "strings" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "gopkg.in/yaml.v3" + + "github.com/api7/a6/internal/extension" + "github.com/api7/a6/pkg/cmd" + "github.com/api7/a6/pkg/iostreams" +) + +func TestNewCmdRoot_RegistersCoreCommandsAndFlags(t *testing.T) { + ios, _, _, _ := iostreams.Test() + + rootCmd := NewCmdRoot(&cmd.Factory{IOStreams: ios}) + + assert.Equal(t, "a6", rootCmd.Use) + assert.Equal(t, "Apache APISIX CLI", rootCmd.Short) + assert.True(t, rootCmd.SilenceUsage) + assert.True(t, rootCmd.SilenceErrors) + + require.NotNil(t, rootCmd.PersistentFlags().Lookup("output")) + require.NotNil(t, rootCmd.PersistentFlags().Lookup("context")) + require.NotNil(t, rootCmd.PersistentFlags().Lookup("server")) + require.NotNil(t, rootCmd.PersistentFlags().Lookup("api-key")) + require.NotNil(t, rootCmd.PersistentFlags().Lookup("verbose")) + require.NotNil(t, rootCmd.PersistentFlags().Lookup("force")) + + for _, name := range []string{ + "config", + "consumer", + "debug", + "extension", + "global-rule", + "plugin-config", + "route", + "service", + "upstream", + "version", + } { + found, _, err := rootCmd.Find([]string{name}) + require.NoError(t, err) + assert.NotNil(t, found) + } +} + +func TestNewCmdRoot_LoadsAndExecutesExtensionCommands(t *testing.T) { + if runtime.GOOS == "windows" { + t.Skip("shell-based extension execution test is unix-specific") + } + + configDir := t.TempDir() + t.Setenv("A6_CONFIG_DIR", configDir) + + resultPath := filepath.Join(t.TempDir(), "extension-result.txt") + t.Setenv("A6_ROOT_TEST_OUTPUT", resultPath) + + extDir := filepath.Join(configDir, "extensions", "a6-hello") + binaryName := "a6-hello" + binaryPath := filepath.Join(extDir, binaryName) + require.NoError(t, os.MkdirAll(extDir, 0o755)) + require.NoError(t, os.WriteFile(binaryPath, []byte("#!/bin/sh\nprintf '%s' \"$*\" > \"$A6_ROOT_TEST_OUTPUT\"\n"), 0o755)) + require.NoError(t, writeManifest(filepath.Join(extDir, "manifest.yaml"), extension.Manifest{ + Name: "hello", + Owner: "api7", + Repo: "a6-hello", + Version: "1.0.0", + Description: "test extension", + BinaryPath: binaryName, + })) + + ios, _, _, _ := iostreams.Test() + rootCmd := NewCmdRoot(&cmd.Factory{IOStreams: ios}) + rootCmd.SetArgs([]string{"hello", "arg-one", "arg-two"}) + + err := rootCmd.Execute() + require.NoError(t, err) + + content, err := os.ReadFile(resultPath) + require.NoError(t, err) + assert.Equal(t, "arg-one arg-two", strings.TrimSpace(string(content))) + + cmd, _, err := rootCmd.Find([]string{"hello"}) + require.NoError(t, err) + assert.Equal(t, "extension", cmd.GroupID) + assert.Equal(t, "test extension", cmd.Short) +} + +func writeManifest(path string, manifest extension.Manifest) error { + content, err := yaml.Marshal(&manifest) + if err != nil { + return err + } + return os.WriteFile(path, content, 0o644) +} From ca548f7ef69f472de5c56ae146c14b6b8c5f16a4 Mon Sep 17 00:00:00 2001 From: Qi Guo <979918879@qq.com> Date: Fri, 10 Apr 2026 11:52:56 +0800 Subject: [PATCH 2/2] test: tighten root command assertions --- pkg/cmd/root/root_test.go | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/pkg/cmd/root/root_test.go b/pkg/cmd/root/root_test.go index ab8c18e..5d8839e 100644 --- a/pkg/cmd/root/root_test.go +++ b/pkg/cmd/root/root_test.go @@ -17,6 +17,8 @@ import ( ) func TestNewCmdRoot_RegistersCoreCommandsAndFlags(t *testing.T) { + t.Setenv("A6_CONFIG_DIR", t.TempDir()) + ios, _, _, _ := iostreams.Test() rootCmd := NewCmdRoot(&cmd.Factory{IOStreams: ios}) @@ -47,7 +49,10 @@ func TestNewCmdRoot_RegistersCoreCommandsAndFlags(t *testing.T) { } { found, _, err := rootCmd.Find([]string{name}) require.NoError(t, err) - assert.NotNil(t, found) + require.NotNil(t, found) + assert.NotSame(t, rootCmd, found) + assert.Equal(t, name, found.Name()) + assert.True(t, strings.HasPrefix(found.Use, name)) } } @@ -87,10 +92,10 @@ func TestNewCmdRoot_LoadsAndExecutesExtensionCommands(t *testing.T) { require.NoError(t, err) assert.Equal(t, "arg-one arg-two", strings.TrimSpace(string(content))) - cmd, _, err := rootCmd.Find([]string{"hello"}) + foundCmd, _, err := rootCmd.Find([]string{"hello"}) require.NoError(t, err) - assert.Equal(t, "extension", cmd.GroupID) - assert.Equal(t, "test extension", cmd.Short) + assert.Equal(t, "extension", foundCmd.GroupID) + assert.Equal(t, "test extension", foundCmd.Short) } func writeManifest(path string, manifest extension.Manifest) error {