// 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")
)
}
})
})
+
+ 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))
+ }
+ })
+ })
})
})
// 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.