Implement setting worker state
authorAleksander Mistewicz <a.mistewicz@samsung.com>
Thu, 8 Jun 2017 13:00:34 +0000 (15:00 +0200)
committerMaciej Wereski <m.wereski@partner.samsung.com>
Wed, 20 Sep 2017 09:51:16 +0000 (11:51 +0200)
In order to perform maintenance, Worker should be in a proper state.
Administrator should set state to MAINTENANCE before taking action
and set it back to IDLE so it will return to the pool.

Change-Id: I44e2c64645e3643c16e8484c746ae4a233a6d232
Signed-off-by: Aleksander Mistewicz <a.mistewicz@samsung.com>
Reviewed-on: https://mcdsrvbld02.digital.local/review/49059
Reviewed-by: Maciej Wereski <m.wereski@partner.samsung.com>
Tested-by: Maciej Wereski <m.wereski@partner.samsung.com>
workers/error.go
workers/worker_list_test.go
workers/workers.go
workers/workers_test.go

index bd51509..0ebe8bc 100644 (file)
@@ -33,4 +33,10 @@ var (
        // ErrNotInMaintenance is returned when Deregister is called for a worker not in MAINTENANCE state.
        // Only workers in MAINTENANCE state can be removed from the list.
        ErrNotInMaintenance = errors.New("Worker is not in MAINTENANCE state")
+       // ErrWrongStateArgument is returned when SetState is called with incorrect state argument.
+       // Worker state can be changed by Admin to IDLE or MAINTENANCE only.
+       ErrWrongStateArgument = errors.New("Only state changes to IDLE and MAINTENANCE are allowed")
+       // ErrForbiddenStateChange is returned when transition from state, Worker is in,
+       // to state, SetState has been called with, is forbidden.
+       ErrForbiddenStateChange = errors.New("Invalid state transition was requested")
 )
index 2800cbf..92ce1fa 100644 (file)
@@ -205,5 +205,61 @@ var _ = Describe("WorkerList", func() {
                                }
                        })
                })
+
+               Describe("SetState", func() {
+                       It("should fail to SetState of nonexistent worker", func() {
+                               uuid := randomUUID()
+                               err := wl.SetState(uuid, MAINTENANCE)
+                               Expect(err).To(Equal(ErrWorkerNotFound))
+                       })
+
+                       It("should work to SetState for valid transitions", func() {
+                               validTransitions := [][]WorkerState{
+                                       {MAINTENANCE, IDLE},
+                                       {IDLE, MAINTENANCE},
+                                       {RUN, MAINTENANCE},
+                                       {FAIL, MAINTENANCE},
+                               }
+                               for _, transition := range validTransitions {
+                                       fromState, toState := transition[0], transition[1]
+                                       wl.workers[worker].State = fromState
+                                       err := wl.SetState(worker, toState)
+                                       Expect(err).ToNot(HaveOccurred())
+                                       Expect(wl.workers[worker].State).To(Equal(toState))
+                               }
+                       })
+
+                       It("should fail to SetState for invalid transitions", func() {
+                               invalidTransitions := [][]WorkerState{
+                                       {RUN, IDLE},
+                                       {FAIL, IDLE},
+                               }
+                               for _, transition := range invalidTransitions {
+                                       fromState, toState := transition[0], transition[1]
+                                       wl.workers[worker].State = fromState
+                                       err := wl.SetState(worker, toState)
+                                       Expect(err).To(Equal(ErrForbiddenStateChange))
+                                       Expect(wl.workers[worker].State).To(Equal(fromState))
+                               }
+                       })
+
+                       It("should fail to SetState for incorrect state argument", func() {
+                               invalidArgument := [][]WorkerState{
+                                       {MAINTENANCE, RUN},
+                                       {MAINTENANCE, FAIL},
+                                       {IDLE, FAIL},
+                                       {IDLE, RUN},
+                                       {RUN, FAIL},
+                                       {FAIL, RUN},
+                               }
+                               for _, transition := range invalidArgument {
+                                       fromState, toState := transition[0], transition[1]
+                                       wl.workers[worker].State = fromState
+                                       err := wl.SetState(worker, toState)
+                                       Expect(err).To(Equal(ErrWrongStateArgument))
+                                       Expect(wl.workers[worker].State).To(Equal(fromState))
+                               }
+                       })
+               })
        })
 })
index ff21f09..b265f73 100644 (file)
@@ -78,7 +78,20 @@ func (wl *WorkerList) SetFail(uuid WorkerUUID, reason string) error {
 
 // SetState is an implementation of SetState from Workers interface.
 func (wl *WorkerList) SetState(uuid WorkerUUID, state WorkerState) error {
-       return ErrNotImplemented
+       // Only state transitions to IDLE or MAINTENANCE are allowed.
+       if state != MAINTENANCE && state != IDLE {
+               return ErrWrongStateArgument
+       }
+       worker, ok := wl.workers[uuid]
+       if !ok {
+               return ErrWorkerNotFound
+       }
+       // State transitions to IDLE are allowed from MAINTENANCE state only.
+       if state == IDLE && worker.State != MAINTENANCE {
+               return ErrForbiddenStateChange
+       }
+       worker.State = state
+       return nil
 }
 
 // SetGroups is an implementation of SetGroups from Workers interface.
index dc2fed5..8247544 100644 (file)
@@ -38,10 +38,6 @@ var _ = Describe("WorkerList", func() {
                        groups Groups       = nil
                )
 
-               By("SetState")
-               err = wl.SetState(uuid, MAINTENANCE)
-               Expect(err).To(Equal(ErrNotImplemented))
-
                By("SetGroups")
                err = wl.SetGroups(uuid, groups)
                Expect(err).To(Equal(ErrNotImplemented))