File: single_test.go

package info (click to toggle)
gitlab-ci-multi-runner 14.10.1-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 31,248 kB
  • sloc: sh: 1,694; makefile: 384; asm: 79; ruby: 68
file content (125 lines) | stat: -rw-r--r-- 3,194 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
//go:build !integration
// +build !integration

package commands

import (
	"context"
	"io/ioutil"
	"os"
	"syscall"
	"testing"
	"time"

	"github.com/stretchr/testify/mock"

	"gitlab.com/gitlab-org/gitlab-runner/common"
)

func init() {
	s := common.MockShell{}
	s.On("GetName").Return("script-shell")
	s.On("GenerateScript", mock.Anything, mock.Anything).Return("script", nil)
	common.RegisterShell(&s)
}

type jobSimulation func(mock.Arguments)

func TestSingleRunnerSigquit(t *testing.T) {
	var sendQuitSignal func()

	job := func(_ mock.Arguments) {
		sendQuitSignal()
		// simulate some real work while while sigquit get handled
		time.Sleep(time.Second)
	}

	single, cleanup := mockingExecutionStack(t, "test-sigquit", 1, job)
	defer cleanup()

	sendQuitSignal = func() {
		single.interruptSignals <- syscall.SIGQUIT
	}

	single.Execute(nil)
}

func TestSingleRunnerMaxBuilds(t *testing.T) {
	maxBuilds := 7

	single, cleanup := mockingExecutionStack(t, "test-max-build", maxBuilds, nil)
	defer cleanup()

	single.Execute(nil)
}

func newRunSingleCommand(executorName string, network common.Network) *RunSingleCommand {
	return &RunSingleCommand{
		network: network,
		RunnerConfig: common.RunnerConfig{
			RunnerSettings: common.RunnerSettings{
				Executor: executorName,
			},
			RunnerCredentials: common.RunnerCredentials{
				URL:   "http://example.com",
				Token: "_test_token_",
			},
		},
		interruptSignals: make(chan os.Signal),
	}
}

func mockingExecutionStack(
	t *testing.T,
	executorName string,
	maxBuilds int,
	job jobSimulation,
) (*RunSingleCommand, func()) {
	// mocking the whole stack
	e := common.MockExecutor{}
	p := common.MockExecutorProvider{}
	mockNetwork := common.MockNetwork{}

	// Network
	jobData := common.JobResponse{}
	_, cancel := context.WithCancel(context.Background())
	jobTrace := common.Trace{Writer: ioutil.Discard}
	jobTrace.SetCancelFunc(cancel)
	jobTrace.SetAbortFunc(cancel)
	mockNetwork.On("RequestJob", mock.Anything, mock.Anything, mock.Anything).Return(&jobData, true).Times(maxBuilds)
	processJob := mockNetwork.On("ProcessJob", mock.Anything, mock.Anything).Return(&jobTrace, nil).Times(maxBuilds)
	if job != nil {
		processJob.Run(job)
	}

	// ExecutorProvider
	p.On("CanCreate").Return(true).Once()
	p.On("GetDefaultShell").Return("bash").Once()
	p.On("GetFeatures", mock.Anything).Return(nil).Times(maxBuilds + 1)

	p.On("Create").Return(&e).Times(maxBuilds)
	p.On("Acquire", mock.Anything).Return(&common.MockExecutorData{}, nil).Times(maxBuilds)
	p.On("Release", mock.Anything, mock.Anything).Return(nil).Times(maxBuilds)

	// Executor
	e.On("Prepare", mock.Anything, mock.Anything, mock.Anything).Return(nil).Times(maxBuilds)
	e.On("Finish", nil).Times(maxBuilds)
	e.On("Cleanup").Times(maxBuilds)

	// Run script successfully
	e.On("Shell").Return(&common.ShellScriptInfo{Shell: "script-shell"})
	e.On("Run", mock.Anything).Return(nil)

	common.RegisterExecutorProvider(executorName, &p)

	single := newRunSingleCommand(executorName, &mockNetwork)
	single.MaxBuilds = maxBuilds
	cleanup := func() {
		e.AssertExpectations(t)
		p.AssertExpectations(t)
		mockNetwork.AssertExpectations(t)
		cancel()
	}

	return single, cleanup
}