Skip to content
13 changes: 9 additions & 4 deletions internal/temporalcli/commands.server.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
87 changes: 87 additions & 0 deletions internal/temporalcli/commands.server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
Loading