func()

in plugins/teststeps/sleep/sleep.go [71:116]


func (ss *sleepStep) Run(ctx xcontext.Context, ch test.TestStepChannels, params test.TestStepParameters, ev testevent.Emitter, resumeState json.RawMessage) (json.RawMessage, error) {
	dur, err := getDuration(params)
	if err != nil {
		return nil, err
	}
	fn := func(ctx xcontext.Context, target *teststeps.TargetWithData) error {
		var deadline time.Time
		// copy, can be different per target
		var sleepTime = dur

		// handle resume
		if target.Data != nil {
			ssd := sleepStepData{}
			if err := json.Unmarshal(target.Data, &ssd); err != nil {
				return fmt.Errorf("invalid resume state: %w", err)
			}
			deadline = time.Unix(ssd.DeadlineMS/1000, (ssd.DeadlineMS%1000)*1000000)
			sleepTime = time.Until(deadline)
			ctx.Debugf("restored with %v unix, in %s", ssd.DeadlineMS, time.Until(deadline))
		} else {
			deadline = time.Now().Add(dur)
		}

		// now sleep
		select {
		case <-time.After(sleepTime):
			return nil
		case <-ctx.Until(xcontext.ErrPaused):
			ctx.Debugf("%s: Paused with %s left", target.Target, time.Until(deadline))
			ssd := &sleepStepData{
				DeadlineMS: deadline.UnixNano() / 1000000,
			}
			var err error
			target.Data, err = json.Marshal(ssd)
			if err != nil {
				return err
			}
			return xcontext.ErrPaused
		case <-ctx.Done():
			ctx.Debugf("%s: Cancelled with %s left", target.Target, time.Until(deadline))
		}
		return nil
	}

	return teststeps.ForEachTargetWithResume(ctx, ch, resumeState, 1, fn)
}