@@ -116,3 +116,183 @@ func TestCmdAgentList(t *testing.T) {
116116 }
117117 })
118118}
119+
120+ func TestAgentListStateFilter (t * testing.T ) {
121+ t .Parallel ()
122+
123+ paused := true
124+ notPaused := false
125+
126+ agents := []buildkite.Agent {
127+ {ID : "1" , Name : "running-agent" , Job : & buildkite.Job {ID : "job-1" }},
128+ {ID : "2" , Name : "idle-agent" },
129+ {ID : "3" , Name : "paused-agent" , Paused : & paused },
130+ {ID : "4" , Name : "idle-not-paused" , Paused : & notPaused },
131+ }
132+
133+ tests := []struct {
134+ state string
135+ want []string // agent IDs
136+ }{
137+ {"running" , []string {"1" }},
138+ {"RUNNING" , []string {"1" }},
139+ {"idle" , []string {"2" , "4" }},
140+ {"paused" , []string {"3" }},
141+ {"" , []string {"1" , "2" , "3" , "4" }},
142+ }
143+
144+ for _ , tt := range tests {
145+ t .Run (tt .state , func (t * testing.T ) {
146+ t .Parallel ()
147+
148+ s := httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
149+ w .Header ().Set ("Content-Type" , "application/json" )
150+ page := r .URL .Query ().Get ("page" )
151+ if page == "" || page == "1" {
152+ json .NewEncoder (w ).Encode (agents )
153+ } else {
154+ json .NewEncoder (w ).Encode ([]buildkite.Agent {})
155+ }
156+ }))
157+ defer s .Close ()
158+
159+ apiClient , _ := buildkite .NewOpts (buildkite .WithBaseURL (s .URL ))
160+ conf := config .New (afero .NewMemMapFs (), nil )
161+ conf .SelectOrganization ("test" , true )
162+
163+ factory := & factory.Factory {
164+ RestAPIClient : apiClient ,
165+ Config : conf ,
166+ }
167+
168+ cmd := agent .NewCmdAgentList (factory )
169+ args := []string {"-o" , "json" }
170+ if tt .state != "" {
171+ args = append (args , "--state" , tt .state )
172+ }
173+ cmd .SetArgs (args )
174+
175+ var buf bytes.Buffer
176+ cmd .SetOut (& buf )
177+
178+ if err := cmd .Execute (); err != nil {
179+ t .Fatal (err )
180+ }
181+
182+ var result []buildkite.Agent
183+ if err := json .Unmarshal (buf .Bytes (), & result ); err != nil {
184+ t .Fatal (err )
185+ }
186+
187+ if len (result ) != len (tt .want ) {
188+ t .Errorf ("got %d agents, want %d" , len (result ), len (tt .want ))
189+ }
190+
191+ for i , id := range tt .want {
192+ if i >= len (result ) || result [i ].ID != id {
193+ t .Errorf ("agent %d: got ID %q, want %q" , i , result [i ].ID , id )
194+ }
195+ }
196+ })
197+ }
198+ }
199+
200+ func TestAgentListInvalidState (t * testing.T ) {
201+ t .Parallel ()
202+
203+ conf := config .New (afero .NewMemMapFs (), nil )
204+ conf .SelectOrganization ("test" , true )
205+
206+ factory := & factory.Factory {
207+ Config : conf ,
208+ }
209+
210+ cmd := agent .NewCmdAgentList (factory )
211+ cmd .SetArgs ([]string {"--state" , "invalid" })
212+
213+ err := cmd .Execute ()
214+ if err == nil {
215+ t .Fatal ("expected error for invalid state, got nil" )
216+ }
217+
218+ if ! strings .Contains (err .Error (), "invalid state" ) {
219+ t .Errorf ("expected error to mention 'invalid state', got: %v" , err )
220+ }
221+ }
222+
223+ func TestAgentListTagsFilter (t * testing.T ) {
224+ t .Parallel ()
225+
226+ agents := []buildkite.Agent {
227+ {ID : "1" , Name : "default-linux" , Metadata : []string {"queue=default" , "os=linux" }},
228+ {ID : "2" , Name : "deploy-macos" , Metadata : []string {"queue=deploy" , "os=macos" }},
229+ {ID : "3" , Name : "default-macos" , Metadata : []string {"queue=default" , "os=macos" }},
230+ {ID : "4" , Name : "no-metadata" },
231+ }
232+
233+ tests := []struct {
234+ name string
235+ tags []string
236+ want []string
237+ }{
238+ {"single tag" , []string {"queue=default" }, []string {"1" , "3" }},
239+ {"multiple tags AND" , []string {"queue=default" , "os=linux" }, []string {"1" }},
240+ {"no match" , []string {"queue=nonexistent" }, []string {}},
241+ {"no tags filter" , []string {}, []string {"1" , "2" , "3" , "4" }},
242+ }
243+
244+ for _ , tt := range tests {
245+ t .Run (tt .name , func (t * testing.T ) {
246+ t .Parallel ()
247+
248+ s := httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
249+ w .Header ().Set ("Content-Type" , "application/json" )
250+ page := r .URL .Query ().Get ("page" )
251+ if page == "" || page == "1" {
252+ json .NewEncoder (w ).Encode (agents )
253+ } else {
254+ json .NewEncoder (w ).Encode ([]buildkite.Agent {})
255+ }
256+ }))
257+ defer s .Close ()
258+
259+ apiClient , _ := buildkite .NewOpts (buildkite .WithBaseURL (s .URL ))
260+ conf := config .New (afero .NewMemMapFs (), nil )
261+ conf .SelectOrganization ("test" , true )
262+
263+ factory := & factory.Factory {
264+ RestAPIClient : apiClient ,
265+ Config : conf ,
266+ }
267+
268+ cmd := agent .NewCmdAgentList (factory )
269+ args := []string {"-o" , "json" }
270+ for _ , tag := range tt .tags {
271+ args = append (args , "--tags" , tag )
272+ }
273+ cmd .SetArgs (args )
274+
275+ var buf bytes.Buffer
276+ cmd .SetOut (& buf )
277+
278+ if err := cmd .Execute (); err != nil {
279+ t .Fatal (err )
280+ }
281+
282+ var result []buildkite.Agent
283+ if err := json .Unmarshal (buf .Bytes (), & result ); err != nil {
284+ t .Fatal (err )
285+ }
286+
287+ if len (result ) != len (tt .want ) {
288+ t .Errorf ("got %d agents, want %d" , len (result ), len (tt .want ))
289+ }
290+
291+ for i , id := range tt .want {
292+ if i >= len (result ) || result [i ].ID != id {
293+ t .Errorf ("agent %d: got ID %q, want %q" , i , result [i ].ID , id )
294+ }
295+ }
296+ })
297+ }
298+ }
0 commit comments