blob: bac62802b6bbeded2358c69bb0e780c8b1639a4a [file] [log] [blame]
// Copyright 2020 The LUCI Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package tqtesting
// RunOption influences behavior of Run call.
type RunOption interface {
isOption()
}
// StopWhenDrained will stop the scheduler after it finishes executing the
// last task and there are no more tasks scheduled.
//
// It is naturally racy if there are other goroutines that submit tasks
// concurrently. In this situation there may be a pending queue of tasks even
// if Run stops.
func StopWhenDrained() RunOption {
return stopWhenDrained{}
}
type stopWhenDrained struct{}
func (stopWhenDrained) isOption() {}
// StopAfterTask will stop the scheduler after it finishes executing a task of
// the given task class ID.
func StopAfterTask(taskClassID string) RunOption {
return StopAfter(func(t *Task) bool { return t.Class == taskClassID })
}
// StopAfter will stop the scheduler if the given function returns true,
// given the just finished task.
func StopAfter(f func(t *Task) bool) RunOption {
return stopAfter{f}
}
type stopAfter struct {
examine func(t *Task) bool
}
func (stopAfter) isOption() {}
// StopBeforeTask will stop the scheduler if the next task to be executed has
// the given task class ID.
//
// The same caveats of StopBefore also apply for StopBeforeTask.
func StopBeforeTask(taskClassID string) RunOption {
return StopBefore(func(t *Task) bool { return t.Class == taskClassID })
}
// StopBefore will stop the scheduler if the given function returns true,
// given the next task to be executed.
//
// If such next task has specified ETA, StopBeforeTask does NOT provide any
// guarantee about what `clock.Now` returns by the time Run stops.
//
// It is naturally racy if there are other goroutines that submit tasks
// concurrently. In this situation there may be a different next task (by ETA)
// when Run stops.
func StopBefore(f func(t *Task) bool) RunOption {
return stopBefore{f}
}
type stopBefore struct {
examine func(t *Task) bool
}
func (stopBefore) isOption() {}
// ParallelExecute instructs the scheduler to call executor's Execute method
// in a separate goroutine instead of serially in Run.
//
// This more closely resembles real-life behavior but may introduce more
// unpredictability into tests due to races.
func ParallelExecute() RunOption {
return parallelExecute{}
}
type parallelExecute struct{}
func (parallelExecute) isOption() {}