From a198a6337314ce432e0a1e6533d3e8ee4e0e8cdb Mon Sep 17 00:00:00 2001 From: Troy Dai Date: Wed, 12 Apr 2017 15:32:34 -0700 Subject: [PATCH] Initiate Jenkins pipeline (#2840) * Initiate Jenkins pipeline 1. Add build task 2. Add basic performance test task 3. Add performance measure script --- .gitignore | 3 +++ Jenkinsfile | 29 ++++++++++++++++++++ scripts/jenkins_archive.sh | 24 +++++++++++++++++ scripts/jenkins_build.sh | 26 ++++++++++++++++++ scripts/jenkins_perf.sh | 27 +++++++++++++++++++ scripts/performance/measure.py | 48 ++++++++++++++++++++++++++++++++++ 6 files changed, 157 insertions(+) create mode 100644 Jenkinsfile create mode 100755 scripts/jenkins_archive.sh create mode 100755 scripts/jenkins_build.sh create mode 100755 scripts/jenkins_perf.sh create mode 100644 scripts/performance/measure.py diff --git a/.gitignore b/.gitignore index fc479e986..7346003bc 100644 --- a/.gitignore +++ b/.gitignore @@ -77,3 +77,6 @@ test_results/ # Code coverage .coverage + +# CI output +artifacts/ \ No newline at end of file diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 000000000..a6f8e4dd9 --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,29 @@ +pipeline { + agent none + triggers { pollSCM('H/3 * * * *') } + stages { + stage ('Build') { + agent any + steps { + sh 'pip install -U virtualenv' + sh 'python -m virtualenv --clear env' + sh './scripts/jenkins_build.sh' + sh './scripts/jenkins_archive.sh' + } + post { + always { deleteDir() } + } + } + stage ('Performance-Test') { + agent { label 'perf-ubuntu-a0' } + steps { + sh 'pip install -U virtualenv' + sh 'python -m virtualenv --clear env' + sh './scripts/jenkins_perf.sh' + } + post { + always { deleteDir() } + } + } + } +} diff --git a/scripts/jenkins_archive.sh b/scripts/jenkins_archive.sh new file mode 100755 index 000000000..4422c60bd --- /dev/null +++ b/scripts/jenkins_archive.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash + +# Archive build + +set -x + +if [ -z $BUILD_NUMBER ]; then + echo "Environment variable BUILD_NUMBER is missing." + exit 1 +fi + +export +echo "build branch $BRANCH_NAME" + +version=$(printf '%.8d' $BUILD_NUMBER) +echo "Version number: $version" + +if [ -d /var/build_share ]; then + echo 'Directory /var/build_share is found. The artifacts will be archived there.' + mkdir -p /var/build_share/$BRANCH_NAME/$version + cp -R ./artifacts/ /var/build_share/$BRANCH_NAME/$version +else + echo 'Directory /var/build_share is not found. Exit without taking any actions.' +fi diff --git a/scripts/jenkins_build.sh b/scripts/jenkins_build.sh new file mode 100755 index 000000000..b12e2e093 --- /dev/null +++ b/scripts/jenkins_build.sh @@ -0,0 +1,26 @@ +# Build packages in Jenkins server. +# The script expects a virtualenv created under ./env folder as prerequisite + +set -x # do not echo command to prevent accidentally expose secrets + +. ./env/bin/activate + +echo 'Build Azure CLI and its command modules ' + +if [ -d ./artifacts ]; then + rm -rf ./artifacts +fi + +mkdir -p ./artifacts/build +artifacts=$(cd ./artifacts/build && pwd) + +working_dir=$(pwd) +for setup_file in $(find src -name 'setup.py'); do + cd $(dirname $setup_file) + echo "" + echo "Components at $(pwd) is being built ..." + python setup.py sdist -d $artifacts bdist_wheel -d $artifacts + cd $working_dir +done + +echo 'Build completed.' \ No newline at end of file diff --git a/scripts/jenkins_perf.sh b/scripts/jenkins_perf.sh new file mode 100755 index 000000000..355b34eec --- /dev/null +++ b/scripts/jenkins_perf.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash + +# Run performance in jenkins build + +. ./env/bin/activate + +echo "Run performance test on $(hostname)" + +if [ -z %BUILD_NUMBER ]; then + echo "Environment variable BUILD_NUMBER is missing." + exit 1 +fi + +version=$(printf '%.8d' $BUILD_NUMBER) +echo "Version number: $version" + +echo 'Before install' +which az +pip list + +build_folder=/var/build_share/$BRANCH_NAME/$version +echo "Install build from $build_folder" + +python -m pip install azure-cli --find-links file://$build_folder/artifacts/build -v +python -m pip freeze + +python ./scripts/performance/measure.py diff --git a/scripts/performance/measure.py b/scripts/performance/measure.py new file mode 100644 index 000000000..8cf6ad2b5 --- /dev/null +++ b/scripts/performance/measure.py @@ -0,0 +1,48 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- + +import sys +from subprocess import check_output, STDOUT + +def mean(data): + """Return the sample arithmetic mean of data.""" + n = len(data) + if n < 1: + raise ValueError('len < 1') + return sum(data)/float(n) + + +def sq_deviation(data): + """Return sum of square deviations of sequence data.""" + c = mean(data) + return sum((x-c)**2 for x in data) + + +def pstdev(data): + """Calculates the population standard deviation.""" + n = len(data) + if n < 2: + raise ValueError('len < 2') + ss = sq_deviation(data) + return (ss/n) ** 0.5 + + +real = [] +user = [] +syst = [] +loop = 100 + +for i in range(loop): + lines = check_output(['time -p az'], shell=True, stderr=STDOUT).split('\n') + real_time = float(lines[-4].split()[1]) + real.append(float(lines[-4].split()[1])) + user.append(float(lines[-3].split()[1])) + syst.append(float(lines[-2].split()[1])) + sys.stdout.write('Loop {} => {} \n'.format(i, real_time)) + sys.stdout.flush() + +print('Real: mean => {} \t pstdev => {}'.format(mean(real), pstdev(real))) +print('User: mean => {} \t pstdev => {}'.format(mean(user), pstdev(user))) +print('Syst: mean => {} \t pstdev => {}'.format(mean(syst), pstdev(syst)))