diff --git a/cmd/configure.go b/cmd/configure.go index 9bd82c6273..726b150198 100644 --- a/cmd/configure.go +++ b/cmd/configure.go @@ -99,7 +99,6 @@ func NewCmdInit() *cobra.Command { fmt.Println("No default project, skip.") } platform.ConfigIns.Timeout = platform.DefaultTimeoutSec - platform.ConfigIns.BaseURL = platform.DefaultBaseURL platform.ConfigIns.MaxRetryTimes = sdk.Int(platform.DefaultMaxRetryTimes) platform.ConfigIns.Active = true fmt.Printf("Configured default base url:%s\n", platform.ConfigIns.BaseURL) diff --git a/cmd/configure_test.go b/cmd/configure_test.go index e90cd82d9b..58b7b3f0ce 100644 --- a/cmd/configure_test.go +++ b/cmd/configure_test.go @@ -6,9 +6,13 @@ import ( "io/ioutil" "net/http" "net/http/httptest" + "os" "path/filepath" "strings" "testing" + "time" + + sdk "github.com/ucloud/ucloud-sdk-go/ucloud" "github.com/ucloud/ucloud-cli/cmd/internal/platform" ) @@ -203,3 +207,96 @@ func TestInitSaveOverwritesExistingOAuthOnlyProfile(t *testing.T) { got.AccessToken, got.RefreshToken, got.ExpiresAt) } } + +// stubStdin 把 os.Stdin 换成预置内容的临时文件,驱动 init 流程里的 fmt.Scanf 交互 +func stubStdin(t *testing.T, input string) { + t.Helper() + f, err := os.CreateTemp(t.TempDir(), "stdin") + if err != nil { + t.Fatal(err) + } + if _, err := f.WriteString(input); err != nil { + t.Fatal(err) + } + if _, err := f.Seek(0, io.SeekStart); err != nil { + t.Fatal(err) + } + old := os.Stdin + os.Stdin = f + t.Cleanup(func() { + os.Stdin = old + f.Close() + }) +} + +// 回归:init 交互中用户输入的自定义 base-url 必须落盘。曾在流程末尾无条件回填 +// DefaultBaseURL,导致输入的专属云域名只在远程校验期生效、存盘的却是主站默认值, +// 且回显的也是覆盖后的值,用户无从察觉。 +func TestInitPersistsUserSuppliedBaseURL(t *testing.T) { + gateway := fakeGatewayServer(t) + defer gateway.Close() + + dir := t.TempDir() + cfgPath := filepath.Join(dir, "config.json") + credPath := filepath.Join(dir, "credential.json") + + m, err := platform.NewAggConfigManager(cfgPath, credPath) + if err != nil { + t.Fatal(err) + } + // 全新 init 现场:profile 尚未落盘,BaseURL 为包级默认值。timeout/max-retry 取小值让 + // 远程校验打本地假网关时快速收敛(init 末尾仍会把二者重置为各自默认值) + cfg := &platform.AggConfig{ + Profile: platform.DefaultProfile, + BaseURL: platform.DefaultBaseURL, + Timeout: 3, + MaxRetryTimes: sdk.Int(0), + } + + oldCfgPath, oldCredPath := platform.ConfigFilePath, platform.CredentialFilePath + oldM, oldC := platform.AggConfigListIns, platform.ConfigIns + oldCC, oldAC, oldRT := platform.ClientConfig, platform.AuthCredential, activeRuntime + // Run 末尾的 InitConfig 按包级路径读写配置,指向临时目录避免污染真实 ~/.ucloud + platform.ConfigFilePath, platform.CredentialFilePath = cfgPath, credPath + platform.AggConfigListIns, platform.ConfigIns = m, cfg + // ConfigPublicKey/ConfigPrivateKey 直接写 AuthCredential,为 nil 会 panic + platform.AuthCredential = &platform.CredentialConfig{} + // 末尾 printHello 经 activeRuntime 取 client:钉到假网关,避免测试真的打外网 + platform.ClientConfig = &sdk.Config{BaseUrl: gateway.URL, Timeout: 3 * time.Second} + setActiveRuntimeFromBaseGlobals() + defer func() { + platform.ConfigFilePath, platform.CredentialFilePath = oldCfgPath, oldCredPath + platform.AggConfigListIns, platform.ConfigIns = oldM, oldC + platform.ClientConfig, platform.AuthCredential, activeRuntime = oldCC, oldAC, oldRT + }() + + // init 依次 Scanf 读取:public-key、private-key、base-url、是否上传日志 + stubStdin(t, fmt.Sprintf("pub\npri\n%s\nno\n", gateway.URL)) + + cmd := NewCmdInit() + cmd.Run(cmd, nil) + + // 重新读盘验证持久化,而非只看内存 + m2, err := platform.NewAggConfigManager(cfgPath, credPath) + if err != nil { + t.Fatal(err) + } + got, ok := m2.GetAggConfigByProfile(platform.DefaultProfile) + if !ok { + t.Fatal("profile default missing after reload") + } + if got.BaseURL != gateway.URL { + t.Errorf("base_url on disk = %q, want user supplied %q (init must not overwrite it with the default %q)", + got.BaseURL, gateway.URL, platform.DefaultBaseURL) + } + // 同一流程里 init 本就该落的默认值,不能被本次修复带偏 + if got.Timeout != platform.DefaultTimeoutSec { + t.Errorf("timeout_sec on disk = %d, want default %d", got.Timeout, platform.DefaultTimeoutSec) + } + if got.MaxRetryTimes == nil || *got.MaxRetryTimes != platform.DefaultMaxRetryTimes { + t.Errorf("max_retry_times on disk = %v, want default %d", got.MaxRetryTimes, platform.DefaultMaxRetryTimes) + } + if !got.Active { + t.Error("active on disk = false, want true") + } +}