Add test for runner build limit

An admin can set the max build a specific executor can run, create a test case
scenario to check if we return the correct errors.
parent af343971
Pipeline #48898478 (#7157) passed with stages
in 29 minutes and 8 seconds
package commands
import (
func TestProcessRunner_BuildLimit(t *testing.T) {
cfg := common.RunnerConfig{
Limit: 2,
RequestConcurrency: 10,
RunnerSettings: common.RunnerSettings{
Executor: "multi-runner-build-limit",
jobData := common.JobResponse{
ID: 1,
Steps: []common.Step{
Name: "sleep",
Script: common.StepScript{"sleep 10"},
Timeout: 15,
When: "",
AllowFailure: false,
mJobTrace := common.MockJobTrace{}
defer mJobTrace.AssertExpectations(t)
mJobTrace.On("SetFailuresCollector", mock.Anything)
mJobTrace.On("Write", mock.Anything).Return(0, nil)
mJobTrace.On("SetCancelFunc", mock.Anything)
mJobTrace.On("Fail", mock.Anything, mock.Anything)
mNetwork := common.MockNetwork{}
defer mNetwork.AssertExpectations(t)
mNetwork.On("RequestJob", mock.Anything, mock.Anything).Return(&jobData, true)
mNetwork.On("ProcessJob", mock.Anything, mock.Anything).Return(&mJobTrace)
var runningBuilds uint32
e := common.MockExecutor{}
defer e.AssertExpectations(t)
e.On("Prepare", mock.Anything, mock.Anything, mock.Anything).Return(nil)
e.On("Shell").Return(&common.ShellScriptInfo{Shell: "script-shell"})
e.On("Finish", mock.Anything).Return(nil).Maybe()
e.On("Run", mock.Anything).Run(func(args mock.Arguments) {
atomic.AddUint32(&runningBuilds, 1)
// Simulate work to fill up build queue.
time.Sleep(1 * time.Second)
p := common.MockExecutorProvider{}
defer p.AssertExpectations(t)
p.On("Acquire", mock.Anything).Return(nil, nil)
p.On("Release", mock.Anything, mock.Anything).Return(nil).Maybe()
p.On("GetFeatures", mock.Anything).Return(nil)
common.RegisterExecutor("multi-runner-build-limit", &p)
cmd := RunCommand{
network: &mNetwork,
buildsHelper: newBuildsHelper(),
configOptionsWithListenAddress: configOptionsWithListenAddress{
configOptions: configOptions{
config: &common.Config{
User: "git",
runners := make(chan *common.RunnerConfig)
// Start 5 builds.
wg := sync.WaitGroup{}
for i := 0; i < 5; i++ {
go func(i int) {
defer wg.Done()
cmd.processRunner(i, &cfg, runners)
// Wait until at least two builds have started.
for atomic.LoadUint32(&runningBuilds) < 2 {
time.Sleep(10 * time.Millisecond)
err := cmd.processRunner(6, &cfg, runners)
assert.EqualError(t, err, "failed to request job, runner limit met")
// Wait for all builds to finish.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment