@@ -241,6 +241,112 @@ func (s *WatcherStoreTestSuite) TestInstanceWatcher() {
241241 }
242242}
243243
244+ func (s * WatcherStoreTestSuite ) TestScaleSetInstanceWatcher () {
245+ consumer , err := watcher .RegisterConsumer (
246+ s .ctx , "instance-test" ,
247+ watcher .WithEntityTypeFilter (common .InstanceEntityType ),
248+ watcher .WithAny (
249+ watcher .WithOperationTypeFilter (common .CreateOperation ),
250+ watcher .WithOperationTypeFilter (common .UpdateOperation ),
251+ watcher .WithOperationTypeFilter (common .DeleteOperation )),
252+ )
253+ s .Require ().NoError (err )
254+ s .Require ().NotNil (consumer )
255+ s .T ().Cleanup (func () { consumer .Close () })
256+ consumeEvents (consumer )
257+
258+ ep := garmTesting .CreateDefaultGithubEndpoint (s .ctx , s .store , s .T ())
259+ creds := garmTesting .CreateTestGithubCredentials (s .ctx , "test-creds" , s .store , s .T (), ep )
260+ s .T ().Cleanup (func () { s .store .DeleteGithubCredentials (s .ctx , creds .ID ) })
261+
262+ repo , err := s .store .CreateRepository (s .ctx , "test-owner" , "test-repo" , creds .Name , "test-secret" , params .PoolBalancerTypeRoundRobin )
263+ s .Require ().NoError (err )
264+ s .Require ().NotEmpty (repo .ID )
265+ s .T ().Cleanup (func () { s .store .DeleteRepository (s .ctx , repo .ID ) })
266+
267+ entity , err := repo .GetEntity ()
268+ s .Require ().NoError (err )
269+
270+ createScaleSetParams := params.CreateScaleSetParams {
271+ ProviderName : "test-provider" ,
272+ Name : "test-scaleset" ,
273+ Image : "test-image" ,
274+ Flavor : "test-flavor" ,
275+ MinIdleRunners : 0 ,
276+ MaxRunners : 1 ,
277+ OSType : commonParams .Linux ,
278+ OSArch : commonParams .Amd64 ,
279+ }
280+
281+ scaleSet , err := s .store .CreateEntityScaleSet (s .ctx , entity , createScaleSetParams )
282+ s .Require ().NoError (err )
283+ s .Require ().NotEmpty (scaleSet .ID )
284+ s .T ().Cleanup (func () { s .store .DeleteScaleSetByID (s .ctx , scaleSet .ID ) })
285+
286+ createInstanceParams := params.CreateInstanceParams {
287+ Name : "test-instance" ,
288+ OSType : commonParams .Linux ,
289+ OSArch : commonParams .Amd64 ,
290+ Status : commonParams .InstanceCreating ,
291+ }
292+ instance , err := s .store .CreateScaleSetInstance (s .ctx , scaleSet .ID , createInstanceParams )
293+ s .Require ().NoError (err )
294+ s .Require ().NotEmpty (instance .ID )
295+
296+ select {
297+ case event := <- consumer .Watch ():
298+ s .Require ().Equal (common.ChangePayload {
299+ EntityType : common .InstanceEntityType ,
300+ Operation : common .CreateOperation ,
301+ Payload : instance ,
302+ }, event )
303+ asInstance , ok := event .Payload .(params.Instance )
304+ s .Require ().True (ok )
305+ s .Require ().Equal (instance .Name , "test-instance" )
306+ s .Require ().Equal (asInstance .Name , "test-instance" )
307+ case <- time .After (1 * time .Second ):
308+ s .T ().Fatal ("expected payload not received" )
309+ }
310+
311+ updateParams := params.UpdateInstanceParams {
312+ RunnerStatus : params .RunnerActive ,
313+ }
314+
315+ updatedInstance , err := s .store .UpdateInstance (s .ctx , instance .Name , updateParams )
316+ s .Require ().NoError (err )
317+
318+ select {
319+ case event := <- consumer .Watch ():
320+ s .Require ().Equal (common.ChangePayload {
321+ EntityType : common .InstanceEntityType ,
322+ Operation : common .UpdateOperation ,
323+ Payload : updatedInstance ,
324+ }, event )
325+ case <- time .After (1 * time .Second ):
326+ s .T ().Fatal ("expected payload not received" )
327+ }
328+
329+ err = s .store .DeleteInstanceByName (s .ctx , updatedInstance .Name )
330+ s .Require ().NoError (err )
331+
332+ select {
333+ case event := <- consumer .Watch ():
334+ s .Require ().Equal (common.ChangePayload {
335+ EntityType : common .InstanceEntityType ,
336+ Operation : common .DeleteOperation ,
337+ Payload : params.Instance {
338+ ID : updatedInstance .ID ,
339+ Name : updatedInstance .Name ,
340+ ProviderID : updatedInstance .ProviderID ,
341+ AgentID : updatedInstance .AgentID ,
342+ ScaleSetID : updatedInstance .ScaleSetID ,
343+ },
344+ }, event )
345+ case <- time .After (1 * time .Second ):
346+ s .T ().Fatal ("expected payload not received" )
347+ }
348+ }
349+
244350func (s * WatcherStoreTestSuite ) TestPoolWatcher () {
245351 consumer , err := watcher .RegisterConsumer (
246352 s .ctx , "pool-test" ,
@@ -362,6 +468,134 @@ func (s *WatcherStoreTestSuite) TestPoolWatcher() {
362468 }
363469}
364470
471+ func (s * WatcherStoreTestSuite ) TestScaleSetWatcher () {
472+ consumer , err := watcher .RegisterConsumer (
473+ s .ctx , "scaleset-test" ,
474+ watcher .WithEntityTypeFilter (common .ScaleSetEntityType ),
475+ watcher .WithAny (
476+ watcher .WithOperationTypeFilter (common .CreateOperation ),
477+ watcher .WithOperationTypeFilter (common .UpdateOperation ),
478+ watcher .WithOperationTypeFilter (common .DeleteOperation )),
479+ )
480+ s .Require ().NoError (err )
481+ s .Require ().NotNil (consumer )
482+ s .T ().Cleanup (func () { consumer .Close () })
483+ consumeEvents (consumer )
484+
485+ ep := garmTesting .CreateDefaultGithubEndpoint (s .ctx , s .store , s .T ())
486+ creds := garmTesting .CreateTestGithubCredentials (s .ctx , "test-creds" , s .store , s .T (), ep )
487+ s .T ().Cleanup (func () {
488+ if err := s .store .DeleteGithubCredentials (s .ctx , creds .ID ); err != nil {
489+ s .T ().Logf ("failed to delete Github credentials: %v" , err )
490+ }
491+ })
492+
493+ repo , err := s .store .CreateRepository (s .ctx , "test-owner" , "test-repo" , creds .Name , "test-secret" , params .PoolBalancerTypeRoundRobin )
494+ s .Require ().NoError (err )
495+ s .Require ().NotEmpty (repo .ID )
496+ s .T ().Cleanup (func () { s .store .DeleteRepository (s .ctx , repo .ID ) })
497+
498+ entity , err := repo .GetEntity ()
499+ s .Require ().NoError (err )
500+
501+ createScaleSetParams := params.CreateScaleSetParams {
502+ ProviderName : "test-provider" ,
503+ Name : "test-scaleset" ,
504+ Image : "test-image" ,
505+ Flavor : "test-flavor" ,
506+ MinIdleRunners : 0 ,
507+ MaxRunners : 1 ,
508+ OSType : commonParams .Linux ,
509+ OSArch : commonParams .Amd64 ,
510+ Tags : []string {"test-tag" },
511+ }
512+ scaleSet , err := s .store .CreateEntityScaleSet (s .ctx , entity , createScaleSetParams )
513+ s .Require ().NoError (err )
514+ s .Require ().NotEmpty (scaleSet .ID )
515+
516+ select {
517+ case event := <- consumer .Watch ():
518+ s .Require ().Equal (common.ChangePayload {
519+ EntityType : common .ScaleSetEntityType ,
520+ Operation : common .CreateOperation ,
521+ Payload : scaleSet ,
522+ }, event )
523+ asScaleSet , ok := event .Payload .(params.ScaleSet )
524+ s .Require ().True (ok )
525+ s .Require ().Equal (scaleSet .Image , "test-image" )
526+ s .Require ().Equal (asScaleSet .Image , "test-image" )
527+ case <- time .After (1 * time .Second ):
528+ s .T ().Fatal ("expected payload not received" )
529+ }
530+
531+ updateParams := params.UpdateScaleSetParams {
532+ Flavor : "updated-flavor" ,
533+ }
534+
535+ callbackFn := func (old , newScaleSet params.ScaleSet ) error {
536+ s .Require ().Equal (old .ID , newScaleSet .ID )
537+ s .Require ().Equal (old .Flavor , "test-flavor" )
538+ s .Require ().Equal (newScaleSet .Flavor , "updated-flavor" )
539+ return nil
540+ }
541+ updatedScaleSet , err := s .store .UpdateEntityScaleSet (s .ctx , entity , scaleSet .ID , updateParams , callbackFn )
542+ s .Require ().NoError (err )
543+
544+ select {
545+ case event := <- consumer .Watch ():
546+ s .Require ().Equal (common.ChangePayload {
547+ EntityType : common .ScaleSetEntityType ,
548+ Operation : common .UpdateOperation ,
549+ Payload : updatedScaleSet ,
550+ }, event )
551+ case <- time .After (1 * time .Second ):
552+ s .T ().Fatal ("expected payload not received" )
553+ }
554+
555+ err = s .store .SetScaleSetLastMessageID (s .ctx , updatedScaleSet .ID , 99 )
556+ s .Require ().NoError (err )
557+
558+ select {
559+ case event := <- consumer .Watch ():
560+ asScaleSet , ok := event .Payload .(params.ScaleSet )
561+ s .Require ().True (ok )
562+ s .Require ().Equal (asScaleSet .ID , updatedScaleSet .ID )
563+ s .Require ().Equal (asScaleSet .LastMessageID , int64 (99 ))
564+ case <- time .After (1 * time .Second ):
565+ s .T ().Fatal ("expected payload not received" )
566+ }
567+
568+ err = s .store .SetScaleSetDesiredRunnerCount (s .ctx , updatedScaleSet .ID , 5 )
569+ s .Require ().NoError (err )
570+
571+ select {
572+ case event := <- consumer .Watch ():
573+ asScaleSet , ok := event .Payload .(params.ScaleSet )
574+ s .Require ().True (ok )
575+ s .Require ().Equal (asScaleSet .ID , updatedScaleSet .ID )
576+ s .Require ().Equal (asScaleSet .DesiredRunnerCount , 5 )
577+ case <- time .After (1 * time .Second ):
578+ s .T ().Fatal ("expected payload not received" )
579+ }
580+
581+ err = s .store .DeleteScaleSetByID (s .ctx , scaleSet .ID )
582+ s .Require ().NoError (err )
583+
584+ select {
585+ case event := <- consumer .Watch ():
586+ // We updated last message ID and desired runner count above.
587+ updatedScaleSet .DesiredRunnerCount = 5
588+ updatedScaleSet .LastMessageID = 99
589+ s .Require ().Equal (common.ChangePayload {
590+ EntityType : common .ScaleSetEntityType ,
591+ Operation : common .DeleteOperation ,
592+ Payload : updatedScaleSet ,
593+ }, event )
594+ case <- time .After (1 * time .Second ):
595+ s .T ().Fatal ("expected payload not received" )
596+ }
597+ }
598+
365599func (s * WatcherStoreTestSuite ) TestControllerWatcher () {
366600 consumer , err := watcher .RegisterConsumer (
367601 s .ctx , "controller-test" ,
0 commit comments