From bef1cfca66d34a594f3d7d46683ac0435d1f99d9 Mon Sep 17 00:00:00 2001 From: Mike Aizatsky Date: Fri, 14 Oct 2016 14:06:14 -0700 Subject: [PATCH] [infra] experimenting with test results --- infra/libfuzzer-pipeline-test.groovy | 164 +++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 infra/libfuzzer-pipeline-test.groovy diff --git a/infra/libfuzzer-pipeline-test.groovy b/infra/libfuzzer-pipeline-test.groovy new file mode 100644 index 000000000..1dfdd93f6 --- /dev/null +++ b/infra/libfuzzer-pipeline-test.groovy @@ -0,0 +1,164 @@ +// Copyright 2016 Google Inc. +// +// 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. +// +//////////////////////////////////////////////////////////////////////////////// + +def call(body) { + // evaluate the body block, and collect configuration into the object + def config = [:] + body.resolveStrategy = Closure.DELEGATE_FIRST + body.delegate = config + body() + + // Mandatory configuration + def gitUrl = config["git"] + assert gitUrl : "git should be specified" + + // Optional configuration + def projectName = config["name"] ?: env.JOB_BASE_NAME + def dockerfile = config["dockerfile"] ?: "oss-fuzz/$projectName/Dockerfile" + def sanitizers = config["sanitizers"] ?: ["address"] + def checkoutDir = config["checkoutDir"] ?: projectName + def dockerContextDir = config["dockerContextDir"] + + def date = java.time.format.DateTimeFormatter.ofPattern("yyyyMMddHHmm") + .format(java.time.LocalDateTime.now()) + + node { + def workspace = pwd() + def revisionsFile = "$workspace/${projectName}.rev" + def dockerTag = "ossfuzz/$projectName" + echo "Building $dockerTag" + + // rm files with docker first to use the same user + sh "docker run --rm -v $workspace/out:/out ubuntu /bin/sh -c 'rm -rvf /out/*'" + sh "rm -rf $workspace/out" + sh "mkdir -p $workspace/out" + + stage("docker image") { + def revisions = [:] + dir('oss-fuzz') { + git url: "https://github.com/google/oss-fuzz.git" + } + + dir(checkoutDir) { + git url: gitUrl + revisions[gitUrl] = sh(returnStdout: true, script: 'git rev-parse HEAD').trim() + } + + if (dockerContextDir == null) { + dockerContextDir = new File(dockerfile) + .getParentFile() + .getPath(); + } + + sh "docker build -t $dockerTag -f $dockerfile $dockerContextDir" + + def revText = groovy.json.JsonOutput.toJson(revisions) + writeFile file: revisionsFile, text: revText + echo "revisions: $revText" + } + + for (int i = 0; i < sanitizers.size(); i++) { + def sanitizer = sanitizers[i] + dir(sanitizer) { + def out = "$workspace/out/$sanitizer" + sh "mkdir $out" + stage("$sanitizer sanitizer") { + // Run image to produce fuzzers + sh "docker run -v $workspace/$checkoutDir:/src/$checkoutDir -v $out:/out -e SANITIZER_FLAGS=\"-fsanitize=$sanitizer\" -t $dockerTag" + } + } + } + + // Run each of resulting fuzzers. + stage("running fuzzers") { + def resultsDir = "$workspace/test-results" + sh "rm -rf $resultsDir" + sh "mkdir -p $resultsDir" + dir ('out') { + def fuzzersFound = 0 + sh "ls -alR" + for (int i = 0; i < sanitizers.size(); i++) { + def sanitizer = sanitizers[i] + dir (sanitizer) { + def d = pwd() + def files = findFiles() + for (int j = 0; j < files.size(); j++) { + def file = files[j] + if (file.directory) { continue } + if (!new File(d, file.name).canExecute()) { + echo "skipping: $file" + continue + } + sh "docker run --rm -v $d:/out -t ossfuzz/libfuzzer-runner /out/$file -runs=32" + fuzzersFound += 1 + } + + def testReport = "\n" + + "\n" + + " \n" + + " \n" + + " \n" + + "\n"; + writeFile file:"$resultsDir/TEST-${sanitizer}.xml", text:testReport + sh "cat $resultsDir/TEST-${sanitizer}.xml" + } + } + sh "ls -al $resultsDir/" + step([$class: 'JUnitResultArchiver', testResults: '**/TEST-*.xml']) + echo "Tested $fuzzersFound fuzzer" + if (!fuzzersFound) { + error "no fuzzers found"; + } + } + + stage("uploading") { + dir('out') { + for (int i = 0; i < sanitizers.size(); i++) { + def sanitizer = sanitizers[i] + dir (sanitizer) { + def zipFile = "$projectName-$sanitizer-${date}.zip" + def revFile = "$projectName-$sanitizer-${date}.rev" + sh "cp $revisionsFile $revFile" + sh "zip -j $zipFile *" + sh "gsutil cp $zipFile gs://clusterfuzz-builds/$projectName/" + sh "gsutil cp $revFile gs://clusterfuzz-builds/$projectName/" + } + } + } + } + + stage("pushing image") { + docker.withRegistry('', 'docker-login') { + docker.image(dockerTag).push() + } + } + } + } + + echo 'Done' +} + +return this;