diff --git a/temporalcli/commands.gen.go b/temporalcli/commands.gen.go index 818bbc33..eec0bc7c 100644 --- a/temporalcli/commands.gen.go +++ b/temporalcli/commands.gen.go @@ -1304,6 +1304,7 @@ type TemporalScheduleListCommand struct { Command cobra.Command Long bool ReallyLong bool + Query string } func NewTemporalScheduleListCommand(cctx *CommandContext, parent *TemporalScheduleCommand) *TemporalScheduleListCommand { @@ -1320,6 +1321,7 @@ func NewTemporalScheduleListCommand(cctx *CommandContext, parent *TemporalSchedu s.Command.Args = cobra.NoArgs s.Command.Flags().BoolVarP(&s.Long, "long", "l", false, "Include detailed information.") s.Command.Flags().BoolVar(&s.ReallyLong, "really-long", false, "Include even more detailed information that's not really usable in table form.") + s.Command.Flags().StringVarP(&s.Query, "query", "q", "", "Filter results using given List Filter.") s.Command.Run = func(c *cobra.Command, args []string) { if err := s.run(cctx, args); err != nil { cctx.Options.Fail(err) diff --git a/temporalcli/commands.schedule.go b/temporalcli/commands.schedule.go index bafa6fac..e458ba91 100644 --- a/temporalcli/commands.schedule.go +++ b/temporalcli/commands.schedule.go @@ -9,6 +9,8 @@ import ( "time" "github.com/temporalio/cli/temporalcli/internal/printer" + "google.golang.org/protobuf/encoding/protojson" + commonpb "go.temporal.io/api/common/v1" enumspb "go.temporal.io/api/enums/v1" schedpb "go.temporal.io/api/schedule/v1" @@ -16,7 +18,6 @@ import ( "go.temporal.io/sdk/client" "go.temporal.io/sdk/converter" "go.temporal.io/server/common/primitives/timestamp" - "google.golang.org/protobuf/encoding/protojson" ) type printableSchedule struct { @@ -378,6 +379,7 @@ func (c *TemporalScheduleListCommand) run(cctx *CommandContext, args []string) e res, err := cl.WorkflowService().ListSchedules(cctx, &workflowservice.ListSchedulesRequest{ Namespace: c.Parent.Namespace, NextPageToken: token, + Query: c.Query, }) if err != nil { return err @@ -397,7 +399,9 @@ func (c *TemporalScheduleListCommand) run(cctx *CommandContext, args []string) e return nil } - res, err := cl.ScheduleClient().List(cctx, client.ScheduleListOptions{}) + res, err := cl.ScheduleClient().List(cctx, client.ScheduleListOptions{ + Query: c.Query, + }) if err != nil { return err } diff --git a/temporalcli/commands.schedule_test.go b/temporalcli/commands.schedule_test.go index 30adc711..ec216743 100644 --- a/temporalcli/commands.schedule_test.go +++ b/temporalcli/commands.schedule_test.go @@ -11,7 +11,11 @@ import ( "regexp" "time" + "github.com/stretchr/testify/assert" "github.com/temporalio/cli/temporalcli" + + "go.temporal.io/api/enums/v1" + "go.temporal.io/api/operatorservice/v1" "go.temporal.io/sdk/workflow" ) @@ -173,42 +177,66 @@ func (s *SharedServerSuite) TestSchedule_CreateDescribe_SearchAttributes_Memo() } func (s *SharedServerSuite) TestSchedule_List() { - schedId, _, res := s.createSchedule("--interval", "10d") + res := s.Execute( + "operator", "search-attribute", "create", + "--address", s.Address(), + "--name", "TestSchedule_List", + "--type", "keyword", + ) s.NoError(res.Err) - // table - - s.Eventually(func() bool { + s.EventuallyWithT(func(t *assert.CollectT) { res = s.Execute( - "schedule", "list", + "operator", "search-attribute", "list", "--address", s.Address(), + "-o", "json", ) - s.NoError(res.Err) - out := res.Stdout.String() - return AssertContainsOnSameLine(out, schedId, "DevWorkflow", "false") == nil + assert.NoError(t, res.Err) + var jsonOut operatorservice.ListSearchAttributesResponse + assert.NoError(t, temporalcli.UnmarshalProtoJSONWithOptions(res.Stdout.Bytes(), &jsonOut, true)) + assert.Equal(t, enums.INDEXED_VALUE_TYPE_KEYWORD, jsonOut.CustomAttributes["TestSchedule_List"]) }, 10*time.Second, time.Second) - // table long + schedId, _, res := s.createSchedule( + "--interval", + "10d", + "--schedule-search-attribute", `TestSchedule_List="here"`, + ) + s.NoError(res.Err) + + // table really-long res = s.Execute( "schedule", "list", "--address", s.Address(), - "--long", + "--really-long", ) s.NoError(res.Err) out := res.Stdout.String() + s.ContainsOnSameLine(out, schedId, "DevWorkflow", "0s" /*jitter*/, "false", "nil" /*memo*/) + s.ContainsOnSameLine(out, "TestSchedule_List") + + // table + + res = s.Execute( + "schedule", "list", + "--address", s.Address(), + ) + s.NoError(res.Err) + out = res.Stdout.String() + s.ContainsOnSameLine(out, schedId, "DevWorkflow", "false") - // table really-long + // table long res = s.Execute( "schedule", "list", "--address", s.Address(), - "--really-long", + "--long", ) s.NoError(res.Err) out = res.Stdout.String() - s.ContainsOnSameLine(out, schedId, "DevWorkflow", "0s" /*jitter*/, "false", "nil" /*memo*/) + s.ContainsOnSameLine(out, schedId, "DevWorkflow", "false") // json @@ -249,6 +277,69 @@ func (s *SharedServerSuite) TestSchedule_List() { ok = ok || j.ScheduleId == schedId } s.True(ok, "schedule not found in jsonl result") + + // JSON query (match) + + res = s.Execute( + "schedule", "list", + "--address", s.Address(), + "--query", "TestSchedule_List = 'here'", + "-o", "json", + ) + s.NoError(res.Err) + s.NoError(json.Unmarshal(res.Stdout.Bytes(), &j)) + ok = false + for _, entry := range j { + ok = ok || entry.ScheduleId == schedId + } + s.True(ok, "schedule not found in json result") + + // query (match) + + res = s.Execute( + "schedule", "list", + "--address", s.Address(), + "--query", "TestSchedule_List = 'here'", + ) + s.NoError(res.Err) + out = res.Stdout.String() + s.ContainsOnSameLine(out, schedId, "DevWorkflow", "false") + + // JSON query (no matches) + + res = s.Execute( + "schedule", "list", + "--address", s.Address(), + "--query", "TestSchedule_List = 'notHere'", + "-o", "json", + ) + s.NoError(res.Err) + s.NoError(json.Unmarshal(res.Stdout.Bytes(), &j)) + ok = false + for _, entry := range j { + ok = ok || entry.ScheduleId == schedId + } + s.False(ok, "schedule found in json result, but should not be found") + + // query (no matches) + + res = s.Execute( + "schedule", "list", + "--address", s.Address(), + "--query", "TestSchedule_List = 'notHere'", + ) + s.NoError(res.Err) + out = res.Stdout.String() + s.NotContainsf(out, schedId, "schedule found, but should not be found") + + // query (invalid query field) + + res = s.Execute( + "schedule", "list", + "--address", s.Address(), + "--query", "unknownField = 'notHere'", + ) + s.Error(res.Err) } func (s *SharedServerSuite) TestSchedule_Toggle() { diff --git a/temporalcli/commandsmd/commands.md b/temporalcli/commandsmd/commands.md index da4834a4..898b8bb4 100644 --- a/temporalcli/commandsmd/commands.md +++ b/temporalcli/commandsmd/commands.md @@ -633,6 +633,7 @@ The `temporal schedule list` command lists all Schedules in a namespace. * `--long`, `-l` (bool) - Include detailed information. * `--really-long` (bool) - Include even more detailed information that's not really usable in table form. +* `--query`, `-q` (string) - Filter results using given List Filter. ### temporal schedule toggle: Pauses or unpauses a Schedule.