[Erp5-report] r40400 luke - in /erp5/trunk/utils/erp5.appliance.test: ./ src/

nobody at svn.erp5.org nobody at svn.erp5.org
Fri Nov 19 10:05:26 CET 2010


Author: luke
Date: Fri Nov 19 10:05:26 2010
New Revision: 40400

URL: http://svn.erp5.org?rev=40400&view=rev
Log:
 - initial import of ERP5 Appliance testing system

Added:
    erp5/trunk/utils/erp5.appliance.test/
    erp5/trunk/utils/erp5.appliance.test/CHANGES.txt   (with props)
    erp5/trunk/utils/erp5.appliance.test/MANIFEST.in
    erp5/trunk/utils/erp5.appliance.test/README.txt   (with props)
    erp5/trunk/utils/erp5.appliance.test/setup.cfg
    erp5/trunk/utils/erp5.appliance.test/setup.py
    erp5/trunk/utils/erp5.appliance.test/src/
    erp5/trunk/utils/erp5.appliance.test/src/test.py   (with props)

Added: erp5/trunk/utils/erp5.appliance.test/CHANGES.txt
URL: http://svn.erp5.org/erp5/trunk/utils/erp5.appliance.test/CHANGES.txt?rev=40400&view=auto
==============================================================================
--- erp5/trunk/utils/erp5.appliance.test/CHANGES.txt (added)
+++ erp5/trunk/utils/erp5.appliance.test/CHANGES.txt [utf8] Fri Nov 19 10:05:26 2010
@@ -0,0 +1,5 @@
+1.0 (unreleased)
+----------------
+
+ - Initial version
+   [Łukasz Nowak]

Propchange: erp5/trunk/utils/erp5.appliance.test/CHANGES.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Added: erp5/trunk/utils/erp5.appliance.test/MANIFEST.in
URL: http://svn.erp5.org/erp5/trunk/utils/erp5.appliance.test/MANIFEST.in?rev=40400&view=auto
==============================================================================
--- erp5/trunk/utils/erp5.appliance.test/MANIFEST.in (added)
+++ erp5/trunk/utils/erp5.appliance.test/MANIFEST.in [utf8] Fri Nov 19 10:05:26 2010
@@ -0,0 +1 @@
+include CHANGES.txt

Added: erp5/trunk/utils/erp5.appliance.test/README.txt
URL: http://svn.erp5.org/erp5/trunk/utils/erp5.appliance.test/README.txt?rev=40400&view=auto
==============================================================================
--- erp5/trunk/utils/erp5.appliance.test/README.txt (added)
+++ erp5/trunk/utils/erp5.appliance.test/README.txt [utf8] Fri Nov 19 10:05:26 2010
@@ -0,0 +1 @@
+Tests ERP5 Appliance https://svn.erp5.org/repos/public/erp5/trunk/buildout/

Propchange: erp5/trunk/utils/erp5.appliance.test/README.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Added: erp5/trunk/utils/erp5.appliance.test/setup.cfg
URL: http://svn.erp5.org/erp5/trunk/utils/erp5.appliance.test/setup.cfg?rev=40400&view=auto
==============================================================================
--- erp5/trunk/utils/erp5.appliance.test/setup.cfg (added)
+++ erp5/trunk/utils/erp5.appliance.test/setup.cfg [utf8] Fri Nov 19 10:05:26 2010
@@ -0,0 +1,3 @@
+[egg_info]
+tag_build = dev
+tag_svn_revision = 1

Added: erp5/trunk/utils/erp5.appliance.test/setup.py
URL: http://svn.erp5.org/erp5/trunk/utils/erp5.appliance.test/setup.py?rev=40400&view=auto
==============================================================================
--- erp5/trunk/utils/erp5.appliance.test/setup.py (added)
+++ erp5/trunk/utils/erp5.appliance.test/setup.py [utf8] Fri Nov 19 10:05:26 2010
@@ -0,0 +1,35 @@
+from setuptools import setup
+
+name = "erp5.appliance.test"
+version = '1.0'
+
+def r(n): return open(n).read()
+
+setup(
+    name=name,
+    version=version,
+    author='Lukasz Nowak',
+    author_email='luke at nexedi.com',
+    description="ERP5 Appliance testing system",
+    long_description=r('README.txt') + '\n' + r('CHANGES.txt'),
+    license="GPL",
+    keywords="erp5 appliance test",
+    classifiers=[
+      "Environment :: Console",
+      "Intended Audience :: Developers",
+      "License :: OSI Approved :: GNU General Public License (GPL)",
+      "Operating System :: POSIX",
+      "Topic :: Software Development :: Testing",
+      ],
+    package_dir={'':'src'},
+    url='http://svn.erp5.org/erp5/trunk/utils/%s' % name,
+    py_modules=['test'],
+    install_requires=['pexpect'],
+    entry_points="""
+    [console_scripts]
+    erp5apptest212 = test:main212
+    erp5apptest212ex = test:mainex212
+    erp5apptest28 = test:main28
+    erp5apptest28ex = test:mainex28
+    """,
+    )

Added: erp5/trunk/utils/erp5.appliance.test/src/test.py
URL: http://svn.erp5.org/erp5/trunk/utils/erp5.appliance.test/src/test.py?rev=40400&view=auto
==============================================================================
--- erp5/trunk/utils/erp5.appliance.test/src/test.py (added)
+++ erp5/trunk/utils/erp5.appliance.test/src/test.py [utf8] Fri Nov 19 10:05:26 2010
@@ -0,0 +1,641 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# Copyright (c) 2010 Nexedi SA and Contributors. All Rights Reserved.
+#                    Lukasz Nowak <luke at nexedi.com>
+#                    Romain Courteaud <romain at nexedi.com>
+#
+# WARNING: This program as such is intended to be used by professional
+# programmers who take the whole responsibility of assessing all potential
+# consequences resulting from its eventual inadequacies and bugs
+# End users who are looking for a ready-to-use solution with commercial
+# guarantees and support are strongly advised to contract a Free Software
+# Service Company
+#
+# This program is Free Software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+##############################################################################
+import os
+import sys
+import shutil
+import subprocess
+import time
+import signal
+import logging
+from logging import StreamHandler, FileHandler
+from optparse import OptionParser, Option
+import ConfigParser
+import pexpect
+import urlparse
+import uuid
+import urllib
+import tempfile
+import httplib
+import mimetools
+import mimetypes
+import stat
+import zipfile
+
+CONFIG_SECTION = "appliancetest"
+
+TB_SEP = "============================================================="\
+    "========="
+def get_content_type(f):
+  return mimetypes.guess_type(f.name)[0] or 'application/octet-stream'
+
+class ConnectionHelper:
+  def __init__(self, url):
+    self.conn = urlparse.urlparse(url)
+    if self.conn.scheme == 'http':
+      connection_type = httplib.HTTPConnection
+    else:
+      connection_type = httplib.HTTPSConnection
+    self.connection_type = connection_type
+
+  def _connect(self):
+    self.connection = self.connection_type(self.conn.hostname + ':' +
+        str(self.conn.port))
+
+  def POST(self, path, parameter_dict, file_list=None):
+    self._connect()
+    parameter_dict.update(
+      __ac_name = self.conn.username,
+      __ac_password = self.conn.password
+        )
+    header_dict = {'Content-type': "application/x-www-form-urlencoded"}
+    if file_list is None:
+      body = urllib.urlencode(parameter_dict)
+    else:
+      boundary = mimetools.choose_boundary()
+      header_dict['Content-type'] = 'multipart/form-data; boundary=%s' %(
+          boundary,)
+      body = ''
+      for k,v in parameter_dict.iteritems():
+        body += '--%s\r\n' % boundary
+        body += 'Content-Disposition: form-data; name="%s"\r\n' % k
+        body += '\r\n'
+        body += '%s\r\n' % v
+      for name, filename in file_list:
+        f = open(filename,'r')
+        body += '--%s\r\n' % boundary
+        body += 'Content-Disposition: form-data; name="%s"; filename="%s"\r\n'%(
+            name, name)
+        body += 'Content-Type: %s\r\n' % get_content_type(f)
+        body += 'Content-Length: %d\r\n' % os.fstat(f.fileno())[stat.ST_SIZE]
+        body += '\r\n'
+        body += f.read()
+        f.close()
+        body +='\r\n'
+
+    self.connection.request("POST", self.conn.path + '/' + path,
+          body, header_dict)
+    self.response = self.connection.getresponse()
+
+def getMachineIdString(config):
+  """Returns machine identification string"""
+  kw = dict(stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+  idstr = subprocess.Popen(["uname", "-m"], **kw).communicate()[0].strip()
+
+  # try to detect gcc version
+  try:
+    gcc_list = subprocess.Popen(["gcc", "-v"], **kw).communicate()[0].split(
+        '\n')
+    for gcc in gcc_list:
+      if gcc.startswith('gcc version'):
+        idstr += ' gcc:' + gcc.split()[2]
+        break
+  except IndexError:
+    pass
+
+  # try to detect python version
+  try:
+    python = subprocess.Popen([config.python, '-V'], **kw).communicate(0)[0]
+    idstr += ' py:' + python.split()[1].strip()
+  except IndexError:
+    pass
+
+  # try to detect libc version
+  try:
+    libdir = os.path.sep + 'lib'
+    for libso in os.listdir(libdir):
+      if libso.startswith('libc.') and os.path.islink(os.path.join(libdir,
+        libso)):
+        libc = os.readlink(os.path.join(libdir, libso))
+        if libc.endswith('.so'):
+          idstr += ' libc:' + libc.split('-')[1][:-3]
+        else:
+          idstr += ' ' + libc
+        break
+  except IndexError:
+    pass
+
+  return idstr
+
+def getDistributionList():
+  """Returns list of all detected distribution flavours"""
+  detected_list = []
+  a = detected_list.append
+  for distro_file in [
+      '/etc/SuSE-release',
+      '/etc/debian_version',
+      '/etc/lsb-release',
+      '/etc/mandrake-release',
+      '/etc/mandrakelinux-release',
+      '/etc/mandriva-release',
+      '/etc/redhat-lsb',
+      '/etc/redhat-release',
+      ]:
+    if os.path.exists(distro_file):
+      for line in open(distro_file).readlines():
+        line = line.strip()
+        if line not in detected_list:
+          a(line)
+
+  return detected_list
+
+class ERP5TestReportHandler(FileHandler):
+  def __init__(self, url, machine_id, suite_name):
+    # random test id
+    self.test_id = uuid.uuid4()
+    self.connection_helper = ConnectionHelper(url)
+    # register real handler to store logfile
+    self.logfilename = tempfile.mkstemp()[1]
+    FileHandler.__init__(self, self.logfilename)
+    # report that test is running
+    self.suite_name = suite_name
+    self.connection_helper.POST('TestResultModule_reportRunning', dict(
+      test_suite=self.suite_name + ' ' + machine_id ,
+      test_report_id=self.test_id,
+      ))
+
+  def close(self):
+    FileHandler.close(self)
+    # make file parsable by erp5_test_results
+    tempcmd = tempfile.mkstemp()[1]
+    tempcmd2 = tempfile.mkstemp()[1]
+    tempout = tempfile.mkstemp()[1]
+    templog = tempfile.mkstemp()[1]
+    log_lines = open(self.logfilename, 'r').readlines()
+    distribution_info = '\n'.join(getDistributionList())
+    tl = open(templog, 'w')
+    tl.write(TB_SEP + '\n')
+    tl.write(distribution_info+'\n')
+    for log_line in log_lines:
+      starts = log_line.startswith
+      if starts('Ran') or starts('FAILED') or starts('OK') or starts(TB_SEP):
+        continue
+      if starts('ERROR: ') or starts('FAIL: '):
+        tl.write('internal-test: '+log_line)
+        continue
+      tl.write(log_line)
+
+    tl.write(TB_SEP + '\n')
+    tl.write('\n' + self.ran_trick)
+    tl.close()
+    open(tempcmd, 'w').write("""svn info dummy""")
+    open(tempcmd2, 'w').write(self.suite_name)
+    open(tempout, 'w').write("""Detected distribution:
+%s
+Revision: %s""" % (distribution_info, self.revision))
+    # create nice zip archive
+    tempzip = tempfile.mkstemp()[1]
+    zip = zipfile.ZipFile(tempzip, 'w')
+    zip.write(tempcmd, 'dummy/001/cmdline')
+    zip.write(tempout, 'dummy/001/stdout')
+    zip.write(templog, 'dummy/001/stderr')
+    zip.write(tempout, '%s/002/stdout' % self.suite_name)
+    zip.write(templog, '%s/002/stderr' % self.suite_name)
+    zip.write(tempcmd2, '%s/002/cmdline' % self.suite_name)
+    zip.close()
+    os.unlink(self.logfilename)
+    os.unlink(templog)
+    os.unlink(tempcmd)
+    os.unlink(tempout)
+    os.unlink(tempcmd2)
+
+    # post it to ERP5
+    self.connection_helper.POST('TestResultModule_reportCompleted', dict(
+      test_report_id=self.test_id),
+      file_list=[('filepath', tempzip)]
+      )
+    os.unlink(tempzip)
+
+class SubFailed(Exception):
+  pass
+
+class TimeoutException(Exception):
+  pass
+
+instance_buildout_first_run = """[buildout]
+extends-cache = instance-profiles/extends-cache
+extends =
+  profiles/development-2.12.cfg
+  instance-profiles/software-home.inc
+
+parts =
+  mysql-instance
+  oood-instance
+  supervisor-instance"""
+
+instance_buildout_complete = instance_buildout_first_run + """
+  runUnitTest"""
+
+def detectRevision(config, path):
+  revision_command = ['svn', 'info', '--non-interactive',
+                      '--trust-server-cert', path]
+  config.logger.info('Checking revision: %r\n' % revision_command)
+  revision_popen = subprocess.Popen(revision_command,
+      stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+  std, err = revision_popen.communicate()
+  if revision_popen.returncode != 0:
+    config.logger.error('Revision checking failed!: %r\n' % revision_command)
+    err = err[:-1]
+    config.logger.error("%s", err)
+    raise SubFailed
+  for line in std.split('\n'):
+    if 'Last Changed Rev' in line:
+      strumpf, revision = line.split(':')
+  return int(revision.strip(' '))
+
+def callWithTimeout(command_list, config, timeout=60, cwd=None,
+    input_list=None):
+
+  def timeout_handler(signum, frame):
+    raise TimeoutException()
+
+  old_handler = signal.signal(signal.SIGALRM, timeout_handler)
+  signal.signal(signal.SIGALRM, timeout_handler)
+  signal.alarm(timeout)
+  command = None
+  try:
+    returncode = None
+    config.logger.info(
+        'Calling %r with timeout %s\n' % (command_list, timeout))
+    command = pexpect.spawn(" ".join(command_list), timeout=timeout, cwd=cwd)
+    isalive = True
+    while isalive:
+      if input_list is not None:
+        for input in input_list:
+          command.expect(input[0])
+          command.sendline(input[1])
+          time.sleep(1)
+      line = command.readline()
+      if line:
+        line = line[:-1]
+        config.logger.debug("%s", line.rstrip('\n').rstrip('\r'))
+      isalive = command.isalive()
+    for line in command.readlines():
+      config.logger.debug("%s", line.rstrip('\n').rstrip('\r'))
+    command.close()
+    returncode = command.exitstatus
+  except TimeoutException:
+    config.logger.error(
+      'Command %r run exceeded timeout %s, killed\n' % (command_list, timeout))
+    returncode = 1
+    command.close()
+  finally:
+    if command is not None:
+      command.kill(signal.SIGKILL)
+    signal.signal(signal.SIGALRM, old_handler)
+  signal.alarm(0)
+  if returncode != 0:
+    raise SubFailed
+  return returncode
+
+def run_once(config, software_path, instance_path,
+    previous_software_revision=-1):
+  status = False
+  begin = time.time()
+  # Checkout/update public buildout repository
+  if os.path.isdir(software_path):
+    checkout_command = [
+        'svn', 'up', '--non-interactive', '--trust-server-cert',
+        software_path]
+  else:
+    checkout_command = [
+        'svn', 'co', '--non-interactive', '--trust-server-cert',
+        'https://svn.erp5.org/repos/public/erp5/trunk/buildout/',
+        software_path]
+  callWithTimeout(checkout_command, config)
+
+  # Do not continue if unneeded
+  revision = detectRevision(config, software_path)
+  if revision == previous_software_revision:
+    return
+  # Configure ERP5 test reporting handler
+  erp5_handler = None
+  if config.erp5_log is not None:
+    config.logger.debug('Configuring external logging system.')
+    erp5_handler = ERP5TestReportHandler(config.erp5_log,
+        getMachineIdString(config), "ERP5Appliance212")
+    config.logger.addHandler(erp5_handler)
+    erp5_handler.revision = revision
+  exc_info = None
+  try:
+    # Download bootstrap file
+    download_command = ['curl', '-o', 'bootstrap.py',
+      'http://svn.zope.org/*checkout*/zc.buildout/trunk/bootstrap/bootstrap.py']
+    callWithTimeout(download_command, config, cwd=software_path)
+
+    # Bootstrap buildout
+    bootstrap_command = [config.python, '-S', 'bootstrap.py',
+                         '-c', 'buildout-2.12.cfg']
+    callWithTimeout(bootstrap_command, config, timeout=600, cwd=software_path)
+
+    # Install software
+    buildout_command = ['%s/bin/buildout' % software_path,
+                        '-v', '-c', 'buildout-2.12.cfg']
+    callWithTimeout(buildout_command, config, timeout=14400, cwd=software_path)
+
+    # Assert software
+    assert_command = [config.python, 'tests/assertSoftware.py']
+    callWithTimeout(assert_command, config, timeout=600, cwd=software_path)
+
+    # Create instance place
+    if not os.path.exists(instance_path):
+      mkdir = ['mkdir', instance_path]
+      callWithTimeout(mkdir, config)
+
+    # Links
+    link_command = ['ln', '-s']
+    for link_path, destination_path in [
+        (os.path.join(software_path, 'instance-profiles'), 'instance-profiles'),
+        (os.path.join(software_path, 'profiles'), 'profiles'),
+        (os.path.join(software_path, 'software-profiles'), 'software-profiles')]:
+      if not os.path.exists(destination_path):
+        callWithTimeout(link_command + [link_path],
+                        config, cwd=instance_path)
+
+    # Create buildout profile
+    file(os.path.join(instance_path, 'buildout.cfg'), 'w').write(
+        instance_buildout_first_run)
+
+    # Bootstrap instance
+    instance_bootstrap = [os.path.join(software_path, 'bin', 'bootstrap2.6')]
+    callWithTimeout(instance_bootstrap, config, cwd=instance_path)
+
+    # Run buildout for first time
+    instance_buildout = [os.path.join(instance_path, 'bin', 'buildout')]
+    callWithTimeout(instance_buildout, config, cwd=instance_path)
+
+    # Start supervisor in foreground mode and have control over its process
+    # as in the end it have to be cleanly shutdown
+    supervisord_command = [os.path.join(instance_path, 'bin', 'supervisord'),
+        '-n']
+    supervisord_popen = subprocess.Popen(supervisord_command, cwd=instance_path)
+    supervisord_popen.poll()
+    # Wait 10 seconds, to give supervisord chance to start required services
+    time.sleep(10)
+    try:
+      # Populate mysql database
+      mysql_command = [os.path.join(instance_path, 'var', 'bin', 'mysql'),
+          '-h', '127.0.0.1', '-u', 'root']
+      callWithTimeout(mysql_command,
+          config, cwd=instance_path, input_list=[
+            ("mysql> ", "create database development_site;"),
+            ("mysql> ", "grant all privileges on development_site.* to "
+              "'development_user'@'localhost' identified by "
+              "'development_password';"),
+            ("mysql> ", "grant all privileges on development_site.* to "
+              "'development_user'@'127.0.0.1' identified by "
+              "'development_password';"),
+            ("mysql> ", "create database test212;"),
+            ("mysql> ", "grant all privileges on test212.* to "
+              "'test'@'localhost';"),
+            ("mysql> ", "grant all privileges on test212.* to "
+              "'test'@'127.0.0.1';"),
+            ("mysql> ", "exit")])
+      # Update profile
+      file(os.path.join(instance_path, 'buildout.cfg'), 'w').write(
+        instance_buildout_complete)
+      # Re run buildout
+      callWithTimeout(instance_buildout, config, timeout=600, cwd=instance_path)
+      # Run a test from readme
+      test_run_command = [os.path.join(instance_path, 'bin', 'runUnitTest'),
+          'testClassTool']
+      callWithTimeout(test_run_command, config, timeout=1200, cwd=instance_path)
+      # check basic functionality of test -- catalog and dms
+      bt5_directory = os.path.join(instance_path, 'bt5')
+      try:
+        if not os.path.exists(bt5_directory):
+          os.mkdir(bt5_directory)
+        # Get needed business template
+        for bt5 in ['erp5_base', 'erp5_ingestion', 'erp5_ingestion_mysql_'
+            'innodb_catalog', 'erp5_web', 'erp5_dms']:
+          callWithTimeout(['svn', 'export', '--non-interactive',
+            '--trust-server-cert',
+            'https://svn.erp5.org/repos/public/erp5/trunk/bt5/' + bt5,
+            os.path.join(bt5_directory, bt5)], config, timeout=600)
+        # Check that catalog is working
+        for test in ['testERP5Catalog.TestERP5Catalog.'
+            'test_04_SearchFolderWithDeletedObjects', 'testDms.TestDocument.'
+            'testOOoDocument_get_size']:
+          test_run_command = [os.path.join(instance_path, 'bin', 'runUnitTest'),
+            '--bt5_path=%s/bt5' % instance_path, test]
+          callWithTimeout(test_run_command, config, timeout=1200,
+              cwd=instance_path)
+      finally:
+        if os.path.exists(bt5_directory):
+          shutil.rmtree(bt5_directory)
+    finally:
+      # Stop supervisor
+      while supervisord_popen.poll() is None:
+        # send SIGKILL
+        supervisord_popen.terminate()
+        # give some time to terminate services
+        time.sleep(5)
+  except SubFailed:
+    pass
+  except:
+    exc_info = sys.exc_info()
+    raise
+  else:
+    status = True
+  finally:
+    if exc_info is not None:
+      config.logger.warning('Test stopped with exception:\n', exc_info=exc_info)
+    ran_trick_list = ["------------------------------------------------------"
+        "----------------"]
+    a = ran_trick_list.append
+    a('Ran 1 test in %.2fs' % (time.time() - begin,))
+    if status:
+      a('OK')
+    else:
+      a('FAILED (failures=1)')
+    if erp5_handler is not None:
+      erp5_handler.ran_trick = '\n'.join(ran_trick_list)
+      config.logger.removeHandler(erp5_handler)
+
+def run(config):
+  software_path = os.path.abspath(os.path.join(config.run_directory_path,
+                                               'software_checkout'))
+  instance_path = os.path.abspath(os.path.join(config.run_directory_path,
+                                               'instances'))
+  sleep_period = 600
+
+  # Define loglevel
+  if config.verbose:
+    log_level = logging.DEBUG
+  else:
+    log_level = logging.ERROR
+  config.logger.setLevel(log_level)
+
+  # Configure file logging functionnality
+  if config.log_file is not None:
+    file_handler = FileHandler(config.log_file)
+    config.logger.addHandler(file_handler)
+
+  # Configure stdout logging functionnality
+  if config.stdout:
+    stream_handler = StreamHandler()
+    config.logger.addHandler(stream_handler)
+
+  # If software_path exists, it means that a previous run fails.
+  # Clean up by deleting previous run
+  if not config.update:
+    for path in software_path, instance_path:
+      if os.path.exists(path):
+        config.logger.debug('Deleting existing directory %s' % path)
+        shutil.rmtree(path)
+
+  while 1:
+    # Run buildout once
+    run_once(config, software_path, instance_path)
+    # Clean directory
+    if not config.update:
+      for path in software_path, instance_path:
+        if os.path.exists(path):
+          config.logger.debug('Deleting existing directory %s' % path)
+          shutil.rmtree(path)
+
+    if config.runonce:
+      config.logger.debug('Run finished')
+      break
+
+    # Sleep some time
+    config.logger.debug('Sleeping for %s seconds' % sleep_period)
+    time.sleep(sleep_period)
+
+
+class Parser(OptionParser):
+  """
+  Parse all arguments.
+  """
+  def __init__(self, usage=None, version=None):
+    """
+    Initialize all options possibles.
+    """
+    OptionParser.__init__(self, usage=usage, version=version,
+                          option_list=[
+      Option("-l", "--log_file",
+             help="The path of the log file",
+             type=str),
+      Option("-v", "--verbose",
+             help="Display more logs",
+             action="store_true",
+             default=False,
+             dest="verbose"),
+      Option("-u", "--update",
+             help="Do not clean work environnment",
+             action="store_true",
+             default=False,
+             dest="update"),
+      Option("-o", "--runonce",
+             help="Quit after first run",
+             action="store_true",
+             default=False),
+      Option("-s", "--stdout",
+             help="Display logs on stdout",
+             action="store_true",
+             default=False),
+      Option("-e", "--erp5_log",
+             help="URI of ERP5 site where log shall be pushed, "
+             "in form http[s]://user:password at host/path/to/module",
+             type=str),
+      Option("-p", "--python",
+             help="Python binary to use to run buildout.",
+             type=str,
+             default="python2.6"),
+      Option("-c", "--config",
+             help="Configuration file. Command line arguments will override.",
+             type=str)
+    ])
+
+  def check_args(self):
+    """
+    Check arguments
+    """
+    (options, args) = self.parse_args()
+    if len(args) != 1:
+      self.error("Incorrect number of arguments")
+    run_directory_path, = args
+
+    if not os.path.exists(run_directory_path):
+      self.error("Run directory %s shall exist" % run_directory_path)
+
+    return options, run_directory_path
+
+
+class Config:
+  def setConfig(self, option_dict, run_directory_path):
+    """
+    Set options given by parameters.
+    """
+    # Set options parameters
+    for option, value in option_dict.__dict__.items():
+      setattr(self, option, value)
+    self.run_directory_path = run_directory_path
+    self.logger = logging.getLogger("erp5app212test")
+
+
+def main212():
+  """Test ERP5 Appliance for 2.12 with full checkout."""
+  usage = "usage: erp5app212test [options] RUN_DIRECTORY"
+
+  try:
+    # Parse arguments
+    config = Config()
+    config.setConfig(*Parser(usage=usage).check_args())
+    if config.config is not None:
+      if not os.path.exists(config.config):
+        raise ValueError("Configuration file %r cannot be found." %
+            config.config)
+      else:
+        file_config = ConfigParser.SafeConfigParser()
+        file_config.read(config.config)
+        file_config = dict(file_config.items(CONFIG_SECTION))
+        for k,v in file_config.iteritems():
+          if getattr(config, k) is None:
+            setattr(config, k, v)
+
+    run(config)
+    return_code = 0
+  except SystemExit, err:
+    # Catch exception raise by optparse
+    return_code = err
+
+  sys.exit(return_code)
+
+def mainex212():
+  """Test ERP5 Appliance for 2.12 with buildout extends."""
+  raise NotImplementedError
+
+def main28():
+  """Test ERP5 Appliance for 2.8 with full checkout."""
+  raise NotImplementedError
+
+def mainex28():
+  """Test ERP5 Appliance for 2.8 with buildout extends."""
+  raise NotImplementedError

Propchange: erp5/trunk/utils/erp5.appliance.test/src/test.py
------------------------------------------------------------------------------
    svn:executable = 




More information about the Erp5-report mailing list