blob: 1e7f23d5032a3abecfbe0c2ec91048efe68364ea [file] [log] [blame]
#!/usr/bin/python
# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Script to validate the output of generate_au_zip.py.
This does NOT validate older versions of au_generator.zip, only the zip files
generated by the matching version of generate_au_zip.py.
"""
import logging
import optparse
import os
import shutil
import subprocess
import tempfile
import generate_au_zip
class TestFailure(Exception):
"""An exception showing we failed to verify the current au-generator.zip."""
pass
def FailWithError(msg):
"""Fail the current test.
Args:
msg: User readable reason for failing the test.
Raises:
TestFailure always raised.
"""
logging.error(msg)
raise TestFailure(msg)
def ExpandAuGeneratorZip(zip_file, working_dir):
"""Expand the au-generator.zip file out into a working directory.
Args:
zip_file: The file name of the zip file to expand.
working_dir: The directory into which to expand the zip file.
Raises:
TestFailure: Raised if the zip fails to expand.
"""
cmd = ['unzip', '-o', '-d', working_dir, zip_file]
logging.debug('Extracting with: %s', ' '.join(cmd))
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
p.communicate()
if p.returncode != 0:
FailWithError('Failed: %s' % ' '.join(cmd))
def VerifyBinariesPresent(working_dir):
"""Verify that all expected executables from the zip are present.
Check the expanded zip contents to see if all expected executable files
are present.
Args:
working_dir: Directory in which expected binaries should be findable.
Raises:
TestFailure if an expected executable is missing.
"""
for src_filename in generate_au_zip.EXECUTABLE_FILES:
basename = os.path.basename(src_filename)
expected_name = os.path.join(working_dir, basename)
logging.debug('Expecting executable: %s', expected_name)
if not os.path.isfile(expected_name):
FailWithError('Expected file not found: %s' % expected_name)
def VerifyLinking(working_dir):
"""Verify that binary executables are executable outside of the chroot.
Run each of the binary executables outside of the chroot with --help and
see if they can startup and shutdown correctly. This mostly validates
that problems with dynamic linking are properly handled.
Args:
working_dir: Directory in which expected binaries should be present.
Raises:
TestFailure if an expected executable is missing.
"""
for src_filename in generate_au_zip.BINARY_EXECUTABLES:
basename = os.path.basename(src_filename)
expected_name = os.path.join(working_dir, basename)
cmd = [expected_name, '--help']
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
output, _ = p.communicate()
# We expect --help to either succeed, or fail with 1.
if p.returncode not in (0, 1):
FailWithError('%s failed outside chroot with:\n%s' %
(expected_name, output))
def main():
"""Main function to start the script"""
parser = optparse.OptionParser()
parser.add_option(
'-d', '--debug', dest='debug', action='store_true',
default=False, help='Verbose [%default]',)
parser.add_option(
'-o', '--output-dir', dest='output_dir',
default='/tmp/au-generator',
help='The output location for copying the zipfile [%default]')
parser.add_option(
'-z', '--zip-name', dest='zip_name',
default='au-generator.zip', help='Name of the zip file. [%default]')
logging_format = '%(asctime)s - %(filename)s - %(levelname)-8s: %(message)s'
date_format = '%Y/%m/%d %H:%M:%S'
logging.basicConfig(level=logging.INFO, format=logging_format,
datefmt=date_format)
(options, _) = parser.parse_args()
if options.debug:
logging.getLogger().setLevel(logging.DEBUG)
logging.debug('Options are %s ', options)
working_dir = None
try:
working_dir = tempfile.mkdtemp(suffix='au', prefix='tmp')
logging.debug('Using tempdir = %s', working_dir)
zip_file = os.path.join(options.output_dir, options.zip_name)
ExpandAuGeneratorZip(zip_file, working_dir)
VerifyBinariesPresent(working_dir)
VerifyLinking(working_dir)
logging.info('SUCCESS for: %s', zip_file)
finally:
if working_dir:
shutil.rmtree(working_dir, ignore_errors=True)
logging.debug('Removed tempdir = %s', working_dir)
if __name__ == '__main__':
main()