func (manager *DrainManager) StartDrain(name, uri string, retry retry.Retryer) { manager.mux.Lock() defer manager.mux.Unlock() var stateChangeFn state.StateChangedFn _, exists := manager.stmMap[name] if exists { // Stop the running drain first. manager.stopDrain(name, false) } else { stateChangeFn = func(state state.State, rev int64) { manager.stateCache.SetState(name, state, rev) } } process, err := NewDrainProcess(name, uri) if err != nil { log.Error(process.Logf("Couldn't create drain: %v", err)) return } drainStm := state.NewStateMachine("Drain", process, retry, stateChangeFn) manager.stmMap[name] = drainStm if err = drainStm.SendAction(state.START); err != nil { log.Fatalf("Failed to start drain %s; %v", name, err) } }
func TestRetry(t *testing.T) { seq := Sequence([]interface{}{ SeqAction(state.START), SeqDelay(20 * time.Millisecond), SeqState("RUNNING|RETRYING|STARTING"), SeqDelay(100 * time.Millisecond), SeqState("FATAL"), }) seq.Test( t, state.NewStateMachine( "DummyProcess", &MockProcess{ "retry", time.Duration(10 * time.Millisecond), fmt.Errorf("exiting after 10ms"), nil}, &ThriceRetryer{}, nil)) }
// Test the simplest case: start with no retrying, catch expected // error exit. func TestSimple(t *testing.T) { seq := Sequence([]interface{}{ SeqAction(state.START), SeqDelay(20 * time.Millisecond), SeqState("RUNNING"), SeqDelay(150 * time.Millisecond), SeqState("FATAL"), }) seq.Test( t, state.NewStateMachine( "DummyProcess", &MockProcess{ "simple", time.Duration(100 * time.Millisecond), fmt.Errorf("error after 100 milliseconds"), nil}, &NoopRetryer{}, nil)) }
// Test stopping of a running process. func TestStop(t *testing.T) { seq := Sequence([]interface{}{ SeqAction(state.START), SeqDelay(20 * time.Millisecond), SeqState("RUNNING"), SeqAction(state.STOP), SeqDelay(20 * time.Millisecond), SeqState("STOPPED"), }) seq.Test( t, state.NewStateMachine( "DummyProcess", &MockProcess{ "stop", time.Duration(0), nil, nil}, &NoopRetryer{}, nil)) }