diff --git a/internal/temporalcli/commands.server.go b/internal/temporalcli/commands.server.go index 90c5b2fe3..bd6bed6af 100644 --- a/internal/temporalcli/commands.server.go +++ b/internal/temporalcli/commands.server.go @@ -160,15 +160,20 @@ func (t *TemporalServerStartDevCommand) run(cctx *CommandContext, args []string) defer s.Stop() cctx.Printer.Printlnf("Temporal CLI %v\n", VersionString()) - cctx.Printer.Printlnf("%-17s %v:%v", "Temporal Server:", toFriendlyIp(opts.FrontendIP), opts.FrontendPort) + cctx.Printer.Printlnf("%-21s %v:%v", "Temporal Server:", toFriendlyIp(opts.FrontendIP), opts.FrontendPort) + if t.DbFilename == "" { + cctx.Printer.Printlnf("%-21s %v", "Temporal Persistence:", "in-memory") + } else { + cctx.Printer.Printlnf("%-21s %v", "Temporal Persistence:", t.DbFilename) + } // Only print HTTP port if explicitly provided to avoid promoting the unstable HTTP API. if opts.FrontendHTTPPort > 0 { - cctx.Printer.Printlnf("%-17s %v:%v", "Temporal HTTP:", toFriendlyIp(opts.FrontendIP), opts.FrontendHTTPPort) + cctx.Printer.Printlnf("%-21s %v:%v", "Temporal HTTP:", toFriendlyIp(opts.FrontendIP), opts.FrontendHTTPPort) } if !t.Headless { - cctx.Printer.Printlnf("%-17s http://%v:%v%v", "Temporal UI:", toFriendlyIp(opts.UIIP), opts.UIPort, opts.PublicPath) + cctx.Printer.Printlnf("%-21s http://%v:%v%v", "Temporal UI:", toFriendlyIp(opts.UIIP), opts.UIPort, opts.PublicPath) } - cctx.Printer.Printlnf("%-17s http://%v:%v/metrics", "Temporal Metrics:", toFriendlyIp(opts.FrontendIP), opts.MetricsPort) + cctx.Printer.Printlnf("%-21s http://%v:%v/metrics", "Temporal Metrics:", toFriendlyIp(opts.FrontendIP), opts.MetricsPort) <-cctx.Done() if !t.Parent.Parent.LogLevel.ChangedFromDefault { // The server routinely emits various warnings on shutdown. diff --git a/internal/temporalcli/commands.server_test.go b/internal/temporalcli/commands.server_test.go index 8c25558d9..26b92cf60 100644 --- a/internal/temporalcli/commands.server_test.go +++ b/internal/temporalcli/commands.server_test.go @@ -271,6 +271,93 @@ func TestServer_StartDev_WithSearchAttributes(t *testing.T) { } } +func TestServer_StartDev_BannerPersistenceInMemory(t *testing.T) { + h := NewCommandHarness(t) + defer h.Close() + + port := strconv.Itoa(devserver.MustGetFreePort("127.0.0.1")) + httpPort := strconv.Itoa(devserver.MustGetFreePort("127.0.0.1")) + resCh := make(chan *CommandResult, 1) + go func() { + resCh <- h.Execute("server", "start-dev", "-p", port, "--http-port", httpPort, "--headless") + }() + + // Wait until the server is dial-able, then cancel + var cl client.Client + h.EventuallyWithT(func(t *assert.CollectT) { + select { + case res := <-resCh: + require.NoError(t, res.Err) + require.Fail(t, "got early server result") + default: + } + var err error + cl, err = client.Dial(client.Options{HostPort: "127.0.0.1:" + port}) + assert.NoError(t, err) + }, 3*time.Second, 200*time.Millisecond) + defer cl.Close() + + h.CancelContext() + var res *CommandResult + select { + case <-time.After(20 * time.Second): + h.Fail("didn't cleanup after 20 seconds") + case res = <-resCh: + h.NoError(res.Err) + } + out := res.Stdout.String() + h.Contains(out, "Temporal Persistence:") + h.Contains(out, "in-memory") +} + +func TestServer_StartDev_BannerPersistenceFile(t *testing.T) { + h := NewCommandHarness(t) + defer h.Close() + + port := strconv.Itoa(devserver.MustGetFreePort("127.0.0.1")) + httpPort := strconv.Itoa(devserver.MustGetFreePort("127.0.0.1")) + // Use os.TempDir with an explicit defer-remove so Windows file-lock cleanup + // (os.RemoveAll in t.TempDir) does not race with a still-open SQLite handle. + dbFilename := filepath.Join(os.TempDir(), "devserver-banner-"+t.Name()+".sqlite") + t.Cleanup(func() { + _ = os.Remove(dbFilename) + _ = os.Remove(dbFilename + "-shm") + _ = os.Remove(dbFilename + "-wal") + }) + resCh := make(chan *CommandResult, 1) + go func() { + resCh <- h.Execute("server", "start-dev", "-p", port, "--http-port", httpPort, + "--headless", "--db-filename", dbFilename) + }() + + var cl client.Client + // File-backed server takes longer to start due to SQLite initialization. + h.EventuallyWithT(func(t *assert.CollectT) { + select { + case res := <-resCh: + require.NoError(t, res.Err) + require.Fail(t, "got early server result") + default: + } + var err error + cl, err = client.Dial(client.Options{HostPort: "127.0.0.1:" + port}) + assert.NoError(t, err) + }, 15*time.Second, 200*time.Millisecond) + defer cl.Close() + + h.CancelContext() + var res *CommandResult + select { + case <-time.After(20 * time.Second): + h.Fail("didn't cleanup after 20 seconds") + case res = <-resCh: + h.NoError(res.Err) + } + out := res.Stdout.String() + h.Contains(out, "Temporal Persistence:") + h.Contains(out, dbFilename) +} + type testLogger struct { t *testing.T }