Add smoketest support for published packages

the build_release.py tool now also downloads and verfyfies the
released packages from S3. It checks integrity based on the sha1
checksums and runs the smoketest against the specs in the current branch.
This commit is contained in:
Simon Willnauer 2013-12-23 10:19:48 +01:00
parent e4244268fa
commit af10b65fe1
1 changed files with 98 additions and 58 deletions

View File

@ -26,6 +26,8 @@ import hmac
import urllib import urllib
import fnmatch import fnmatch
import socket import socket
import urllib.request
from http.client import HTTPConnection from http.client import HTTPConnection
""" """
@ -114,7 +116,10 @@ def verify_mvn_java_version(version, mvn):
# Returns the hash of the current git HEAD revision # Returns the hash of the current git HEAD revision
def get_head_hash(): def get_head_hash():
return os.popen('git rev-parse --verify HEAD 2>&1').read().strip() return get_hash('HEAD')
def get_hash(version):
return os.popen('git rev-parse --verify %s 2>&1' % (version)).read().strip()
# Returns the name of the current branch # Returns the name of the current branch
def get_current_branch(): def get_current_branch():
@ -238,7 +243,7 @@ def build_release(run_tests=False, dry_run=True, cpus=1):
def wait_for_node_startup(host='127.0.0.1', port=9200,timeout=15): def wait_for_node_startup(host='127.0.0.1', port=9200,timeout=15):
for _ in range(timeout): for _ in range(timeout):
conn = HTTPConnection(host, port, timeout); conn = HTTPConnection(host, port, timeout)
try: try:
log('Waiting until node becomes available for 1 second') log('Waiting until node becomes available for 1 second')
time.sleep(1) time.sleep(1)
@ -268,8 +273,11 @@ def find_release_version(src_branch):
return match.group(1) return match.group(1)
raise RuntimeError('Could not find release version in branch %s' % src_branch) raise RuntimeError('Could not find release version in branch %s' % src_branch)
def artifact_names(release, path = ''):
return [os.path.join(path, 'elasticsearch-%s.%s' % (release, t)) for t in ['deb', 'tar.gz', 'zip']]
def get_artifacts(release): def get_artifacts(release):
common_artifacts = [os.path.join('target/releases/', 'elasticsearch-%s.%s' % (release, t)) for t in ['deb', 'tar.gz', 'zip']] common_artifacts = artifact_names(release, 'target/releases/')
for f in common_artifacts: for f in common_artifacts:
if not os.path.isfile(f): if not os.path.isfile(f):
raise RuntimeError('Could not find required artifact at %s' % f) raise RuntimeError('Could not find required artifact at %s' % f)
@ -300,7 +308,28 @@ def generate_checksums(files):
res = res + [os.path.join(directory, checksum_file), release_file] res = res + [os.path.join(directory, checksum_file), release_file]
return res return res
def smoke_test_release(release, files): def download_and_verify(release, files, base_url='https://download.elasticsearch.org/elasticsearch/elasticsearch'):
print('Downloading and verifying release %s from %s' % (release, base_url))
tmp_dir = tempfile.mkdtemp()
try:
downloaded_files = []
for file in files:
name = os.path.basename(file)
url = '%s/%s' % (base_url, name)
abs_file_path = os.path.join(tmp_dir, name)
print(' Downloading %s' % (url))
downloaded_files.append(abs_file_path)
urllib.request.urlretrieve(url, abs_file_path)
url = ''.join([url, '.sha1.txt'])
checksum_file = os.path.join(tmp_dir, ''.join([abs_file_path, '.sha1.txt']))
urllib.request.urlretrieve(url, checksum_file)
print(' Verifying checksum %s' % (checksum_file))
run('cd %s && sha1sum -c %s' % (tmp_dir, os.path.basename(checksum_file)))
smoke_test_release(release, downloaded_files, get_hash('v%s' % release))
finally:
shutil.rmtree(tmp_dir)
def smoke_test_release(release, files, expected_hash):
for release_file in files: for release_file in files:
if not os.path.isfile(release_file): if not os.path.isfile(release_file):
raise RuntimeError('Smoketest failed missing file %s' % (release_file)) raise RuntimeError('Smoketest failed missing file %s' % (release_file))
@ -329,7 +358,7 @@ def smoke_test_release(release, files):
raise RuntimeError('Expected version [%s] but was [%s]' % (release, version['number'])) raise RuntimeError('Expected version [%s] but was [%s]' % (release, version['number']))
if version['build_snapshot']: if version['build_snapshot']:
raise RuntimeError('Expected non snapshot version') raise RuntimeError('Expected non snapshot version')
if version['build_hash'].strip() != get_head_hash(): if version['build_hash'].strip() != expected_hash:
raise RuntimeError('HEAD hash does not match expected [%s] but got [%s]' % (get_head_hash(), version['build_hash'])) raise RuntimeError('HEAD hash does not match expected [%s] but got [%s]' % (get_head_hash(), version['build_hash']))
print(' Running REST Spec tests against package [%s]' % release_file) print(' Running REST Spec tests against package [%s]' % release_file)
run_mvn('test -Dtests.rest=%s -Dtests.class=*.*RestTests' % ("127.0.0.1:9200")) run_mvn('test -Dtests.rest=%s -Dtests.class=*.*RestTests' % ("127.0.0.1:9200"))
@ -418,7 +447,11 @@ if __name__ == '__main__':
help='The remote to push the release commit and tag to. Default is [origin]') help='The remote to push the release commit and tag to. Default is [origin]')
parser.add_argument('--publish', '-d', dest='dryrun', action='store_false', parser.add_argument('--publish', '-d', dest='dryrun', action='store_false',
help='Publishes the release. Disable by default.') help='Publishes the release. Disable by default.')
parser.add_argument('--smoke', '-s', dest='smoke', default='',
help='Smoke tests the given release')
parser.set_defaults(dryrun=True) parser.set_defaults(dryrun=True)
parser.set_defaults(smoke=None)
args = parser.parse_args() args = parser.parse_args()
src_branch = args.branch src_branch = args.branch
@ -426,6 +459,8 @@ if __name__ == '__main__':
run_tests = args.tests run_tests = args.tests
dry_run = args.dryrun dry_run = args.dryrun
cpus = args.cpus cpus = args.cpus
build = not args.smoke
smoke_test_version = args.smoke
if not dry_run: if not dry_run:
check_s3_credentials() check_s3_credentials()
print('WARNING: dryrun is set to "false" - this will push and publish the release') print('WARNING: dryrun is set to "false" - this will push and publish the release')
@ -436,6 +471,13 @@ if __name__ == '__main__':
print(' JAVA_HOME is [%s]' % JAVA_HOME) print(' JAVA_HOME is [%s]' % JAVA_HOME)
print(' Running with maven command: [%s] ' % (MVN)) print(' Running with maven command: [%s] ' % (MVN))
release_version = find_release_version(src_branch) release_version = find_release_version(src_branch)
if not smoke_test_version and not dry_run:
smoke_test_version = release_version
elif smoke_test_version:
print("Skipping build - smoketest only against version %s" % smoke_test_version)
if build:
head_hash = get_head_hash() head_hash = get_head_hash()
run_mvn('clean') # clean the env! run_mvn('clean') # clean the env!
print(' Release version: [%s]' % release_version) print(' Release version: [%s]' % release_version)
@ -458,7 +500,7 @@ if __name__ == '__main__':
build_release(run_tests=run_tests, dry_run=dry_run, cpus=cpus) build_release(run_tests=run_tests, dry_run=dry_run, cpus=cpus)
artifacts = get_artifacts(release_version) artifacts = get_artifacts(release_version)
artifacts_and_checksum = generate_checksums(artifacts) artifacts_and_checksum = generate_checksums(artifacts)
smoke_test_release(release_version, artifacts) smoke_test_release(release_version, artifacts, get_head_hash())
print(''.join(['-' for _ in range(80)])) print(''.join(['-' for _ in range(80)]))
print('Finish Release -- dry_run: %s' % dry_run) print('Finish Release -- dry_run: %s' % dry_run)
input('Press Enter to continue...') input('Press Enter to continue...')
@ -487,7 +529,5 @@ if __name__ == '__main__':
run('git tag -d v%s' % release_version) run('git tag -d v%s' % release_version)
# we delete this one anyways # we delete this one anyways
run('git branch -D %s' % (release_branch(release_version))) run('git branch -D %s' % (release_branch(release_version)))
if smoke_test_version:
download_and_verify(smoke_test_version, artifact_names(smoke_test_version))