-
Notifications
You must be signed in to change notification settings - Fork 1
/
runAssignment.groovy
149 lines (133 loc) · 4.42 KB
/
runAssignment.groovy
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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
import static edu.ucsb.cs.anacapa.pipeline.Lib.*
def call(body) {
def config = [:]
body.resolveStrategy = Closure.DELEGATE_FIRST
body.delegate = config
body()
def git_provider_domain = config.git_provider_domain.trim()
def course_org = config.course_org.trim()
def lab_name = config.lab_name.trim()
def credentials_id = config.credentials_id.trim()
def spec_file = ".anacapa/assignment_spec.json"
def assignment = [:]
node {
stage('Start runAssignment') {
sh "echo 'Creating/Updating ${git_provider_domain}/${course_org}/assignment-${lab_name}'"
}
}
node('submit') {
stage("Checkout Assignment Reference Repo") {
// start with a clean workspace
step([$class: 'WsCleanup'])
checkout scm: [
$class: 'GitSCM',
branches: [[name: "**/master"]],
userRemoteConfigs: [[
url:"https://${git_provider_domain}/${course_org}/assignment-${lab_name}.git",
credentialsId: "${credentials_id}",
]]
]
dir(".anacapa") {
dir("build_data") {
sh 'touch .keep'
stash name: "build_data"
}
dir("test_data") {
sh 'touch .keep'
stash name: "test_data"
}
dir("expected_outputs") {
sh 'touch .keep'
stash name: "expected_outputs"
}
}
stash name: 'fresh'
}
/* Make sure the assignment spec conforms to the proper conventions */
stage('validateJSON') {
assignment = parseJSON(readFile(spec_file))
// TODO: insert validation step here...
// * This allows us to guarantee that the object has certain properties
if (assignment == null) { sh 'fail' }
}
/* for each test group */
def testables = assignment['testables']
for (int index = 0; index < testables.size(); index++) {
def i = index
def curtest = testables[index]
run_test_group(curtest)
}
}
}
def solution_output_name(testable, test_case) {
return slugify("${testable.test_name}_${test_case.command}_solution")
}
def save_result(command, output_name) {
sh "${command} > ${output_name}"
archiveArtifacts artifacts: "${output_name}", fingerprint: true
}
def run_test_group(testable) {
stage(testable['test_name']) {
// assume built at first
def built = true
// clean up the workspace for this particular test group and start fresh
step([$class: 'WsCleanup'])
unstash 'fresh'
/* Try to build the binaries for the current test group */
try {
unstash 'build_data'
// execute the desired build command
sh testable.build_command
// save this state so each individual test case can run independently
stash name: slugify(testable.test_name)
} catch (e) {
// if something went wrong building this test case, assume all
// test cases will fail
built = false
println(e)
}
if (built) {
println("Successfully built!")
for (int i = 0; i < testable.test_cases.size(); i++) {
def index = i
run_test_case(testable, testable.test_cases[index])
}
} else {
println("Build Failed... Checking for expectd output file")
for (int i = 0; i < testable.test_cases.size(); i++) {
def index = i
def expected = testable.test_cases[index]['expected'] - ".anacapa/expected_outputs/"
def output_name = solution_output_name(testable, testable.test_cases[index])
// if we needed to generate, fail because that's not possible.
if (expected.equals('generate')) { sh 'fail' }
unstash 'expected_outputs'
save_result("cat ${expected}", output_name)
}
}
}
}
def run_test_case(testable, test_case) {
def command = test_case.command
def expected = test_case['expected'] - ".anacapa/expected_outputs/"
def output_name = solution_output_name(testable, test_case)
try {
// refresh the workspace to facilitate test case independence
step([$class: 'WsCleanup'])
unstash name: unstash(testable.test_name)
// save the output for this test case
if (expected.equals('generate')) {
unstash 'test_data'
save_result(test_case.command, output_name)
} else {
unstash 'expected_outputs'
save_result("cat ${expected}", output_name)
}
} catch (e) {
println("Failed to run test case")
println(e)
if (! expected.equals('generate')) {
unstash 'expected_outputs'
save_result("cat ${expected}", output_name)
}
}
}