Updated Branches:
  refs/heads/4.2 66b7b7e25 -> 1e4bbf8a4

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1e4bbf8a/tools/marvin/marvin/misc/build/xen.cfg
----------------------------------------------------------------------
diff --git a/tools/marvin/marvin/misc/build/xen.cfg 
b/tools/marvin/marvin/misc/build/xen.cfg
new file mode 100644
index 0000000..bdeacda
--- /dev/null
+++ b/tools/marvin/marvin/misc/build/xen.cfg
@@ -0,0 +1,225 @@
+{
+    "zones": [
+        {
+            "name": "z0", 
+            "guestcidraddress": "10.1.1.0/24", 
+            "dns2": "8.8.8.8", 
+            "dns1": "8.8.8.8", 
+            "physical_networks": [
+                {
+                    "name": "z0-pnet", 
+                    "providers": [
+                        {
+                            "broadcastdomainrange": "ZONE", 
+                            "name": "VirtualRouter"
+                        }, 
+                        {
+                            "broadcastdomainrange": "ZONE", 
+                            "name": "VpcVirtualRouter"
+                        }, 
+                        {
+                            "broadcastdomainrange": "ZONE", 
+                            "name": "InternalLbVm"
+                        }
+                    ], 
+                    "broadcastdomainrange": "Zone", 
+                    "vlan": "2001-2050", 
+                    "traffictypes": [
+                        {
+                            "typ": "Guest"
+                        }, 
+                        {
+                            "typ": "Management"
+                        }, 
+                        {
+                            "typ": "Public"
+                        }
+                    ], 
+                    "isolationmethods": [
+                        "VLAN"
+                    ]
+                }
+            ], 
+            "securitygroupenabled": "false", 
+            "ipranges": [
+                {
+                    "startip": "10.208.10.10", 
+                    "endip": "10.208.10.62", 
+                    "netmask": "255.255.255.192", 
+                    "vlan": "100", 
+                    "gateway": "10.208.10.1"
+                }, 
+                {
+                    "startip": "10.208.10.66", 
+                    "endip": "10.208.10.126", 
+                    "netmask": "255.255.255.192", 
+                    "vlan": "101", 
+                    "gateway": "10.208.10.65"
+                }
+            ], 
+            "networktype": "Advanced", 
+            "pods": [
+                {
+                    "endip": "10.208.8.75", 
+                    "name": "z0p0", 
+                    "startip": "10.208.8.70", 
+                    "netmask": "255.255.255.192", 
+                    "clusters": [
+                        {
+                            "clustername": "z0p0c0", 
+                            "hypervisor": "XenServer", 
+                            "hosts": [
+                                {
+                                    "username": "root", 
+                                    "url": "http://apache-81-3";, 
+                                    "password": "password"
+                                }, 
+                                {
+                                    "username": "root", 
+                                    "url": "http://apache-81-2";, 
+                                    "password": "password"
+                                }
+                            ], 
+                            "clustertype": "CloudManaged", 
+                            "primaryStorages": [
+                                {
+                                    "url": 
"nfs://nfs.fmt.vmops.com:/export/automation/acs/primary", 
+                                    "name": "z0p0c0ps0"
+                                }, 
+                                {
+                                    "url": 
"nfs://nfs.fmt.vmops.com:/export/automation/acs/primary1", 
+                                    "name": "z0p0c0ps1"
+                                }
+                            ]
+                        }
+                    ], 
+                    "gateway": "10.208.8.65"
+                }, 
+                {
+                    "endip": "10.208.8.205", 
+                    "name": "z0p1", 
+                    "startip": "10.208.8.200", 
+                    "netmask": "255.255.255.192", 
+                    "clusters": [
+                        {
+                            "clustername": "z0p1c0", 
+                            "hypervisor": "XenServer", 
+                            "hosts": [
+                                {
+                                    "username": "root", 
+                                    "url": "http://apache-83-1";, 
+                                    "password": "password"
+                                }
+                            ], 
+                            "clustertype": "CloudManaged", 
+                            "primaryStorages": [
+                                {
+                                    "url": 
"nfs://nfs.fmt.vmops.com:/export/automation/acs/primary2", 
+                                    "name": "z0p1c0ps0"
+                                }
+                            ]
+                        }
+                    ], 
+                    "gateway": "10.208.8.193"
+                }
+            ], 
+            "internaldns1": "10.208.8.5", 
+            "internaldns2": "10.208.8.5", 
+            "secondaryStorages": [
+                {
+                    "url": 
"nfs://nfs.fmt.vmops.com:/export/automation/acs/secondary", 
+                    "provider": "NFS"
+                }
+            ]
+        }
+    ], 
+    "dbSvr": {
+        "dbSvr": "cloudstack-centos63", 
+        "passwd": "cloud", 
+        "db": "cloud", 
+        "port": 3306, 
+        "user": "cloud"
+    }, 
+    "logger": [
+        {
+            "name": "TestClient", 
+            "file": "/var/log/testclient.log"
+        }, 
+        {
+            "name": "TestCase", 
+            "file": "/var/log/testcase.log"
+        }
+    ], 
+    "globalConfig": [
+        {
+            "name": "storage.cleanup.interval", 
+            "value": "120"
+        }, 
+        {
+            "name": "direct.agent.load.size", 
+            "value": "1000"
+        }, 
+        {
+            "name": "default.page.size", 
+            "value": "10000"
+        }, 
+        {
+            "name": "account.cleanup.interval", 
+            "value": "120"
+        }, 
+        {
+            "name": "workers", 
+            "value": "10"
+        }, 
+        {
+            "name": "vm.op.wait.interval", 
+            "value": "5"
+        }, 
+        {
+            "name": "network.gc.interval", 
+            "value": "120"
+        }, 
+        {
+            "name": "guest.domain.suffix", 
+            "value": "sandbox.xen"
+        }, 
+        {
+            "name": "expunge.delay", 
+            "value": "60"
+        }, 
+        {
+            "name": "vm.allocation.algorithm", 
+            "value": "random"
+        }, 
+        {
+            "name": "expunge.interval", 
+            "value": "60"
+        }, 
+        {
+            "name": "enable.dynamic.scale.vm", 
+            "value": "true"
+        }, 
+        {
+            "name": "instance.name", 
+            "value": "QA"
+        }, 
+        {
+            "name": "expunge.workers", 
+            "value": "3"
+        }, 
+        {
+            "name": "secstorage.allowed.internal.sites", 
+            "value": 
"10.208.8.0/26,10.208.8.65/26,10.208.8.128/26,10.208.8.192/26,10.208.13.194/32"
+        }, 
+        {
+            "name": "check.pod.cidrs", 
+            "value": "true"
+        }
+    ], 
+    "mgtSvr": [
+        {
+            "mgtSvrIp": "cloudstack-centos63", 
+            "port": 8096
+        }
+    ]
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1e4bbf8a/tools/marvin/marvin/misc/build/xen.properties
----------------------------------------------------------------------
diff --git a/tools/marvin/marvin/misc/build/xen.properties 
b/tools/marvin/marvin/misc/build/xen.properties
new file mode 100644
index 0000000..cffa28c
--- /dev/null
+++ b/tools/marvin/marvin/misc/build/xen.properties
@@ -0,0 +1,86 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you 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.
+
+
+[globals]
+#global settings in cloudstack
+expunge.delay=60
+expunge.interval=60
+storage.cleanup.interval=120
+account.cleanup.interval=120
+network.gc.interval=120
+expunge.workers=3
+workers=10
+vm.allocation.algorithm=random
+vm.op.wait.interval=5
+guest.domain.suffix=sandbox.xen
+instance.name=QA
+direct.agent.load.size=1000
+default.page.size=10000
+check.pod.cidrs=true
+secstorage.allowed.internal.sites=10.208.8.0/26,10.208.8.65/26,10.208.8.128/26,10.208.8.192/26,10.208.13.194/32
+enable.dynamic.scale.vm=true
+[environment]
+dns1=8.8.8.8
+dns2=8.8.8.8
+internal_dns1=10.208.8.5
+internal_dns2=10.208.8.5
+mshost=cloudstack-centos63
+mysql.host=cloudstack-centos63
+mysql.cloud.user=cloud
+mysql.cloud.passwd=cloud
+[cloudstack]
+hypervisor=XenServer
+host.password=password
+
+#Zone 1
+z0.guest.vlan=2001-2050
+
+z0p0.private.gateway=10.208.8.65
+z0p0.private.pod.startip=10.208.8.70
+z0p0.private.pod.endip=10.208.8.75
+z0p0.private.netmask=255.255.255.192
+
+z0p0.public.gateway=10.208.10.1
+z0p0.public.vlan.startip=10.208.10.10
+z0p0.public.vlan.endip=10.208.10.62
+z0p0.public.netmask=255.255.255.192
+z0p0.public.vlan=100
+
+z0p0c0h0.host=apache-81-3
+z0p0c0h1.host=apache-81-2
+
+z0p0c0ps0.primary.pool=nfs://nfs.fmt.vmops.com:/export/automation/acs/primary
+z0p0c0ps1.primary.pool=nfs://nfs.fmt.vmops.com:/export/automation/acs/primary1
+
+z0p1.private.gateway=10.208.8.193
+z0p1.private.pod.startip=10.208.8.200
+z0p1.private.pod.endip=10.208.8.205
+z0p1.private.netmask=255.255.255.192
+
+z0p1.public.gateway=10.208.10.65
+z0p1.public.vlan.startip=10.208.10.66
+z0p1.public.vlan.endip=10.208.10.126
+z0p1.public.netmask=255.255.255.192
+z0p1.public.vlan=101
+
+z0p1c0h0.host=apache-83-1
+
+z0p1c0ps0.primary.pool=nfs://nfs.fmt.vmops.com:/export/automation/acs/primary2
+
+
+z0.secondary.pool=nfs://nfs.fmt.vmops.com:/export/automation/acs/secondary

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1e4bbf8a/tools/marvin/marvin/misc/build/xunitmp/setup.py
----------------------------------------------------------------------
diff --git a/tools/marvin/marvin/misc/build/xunitmp/setup.py 
b/tools/marvin/marvin/misc/build/xunitmp/setup.py
new file mode 100644
index 0000000..b5ad6d8
--- /dev/null
+++ b/tools/marvin/marvin/misc/build/xunitmp/setup.py
@@ -0,0 +1,46 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version .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-.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.
+
+import os
+from setuptools import setup
+
+def read(fname):
+    return open(os.path.join(os.path.dirname(__file__), fname)).read().strip()
+
+VERSION = '0.1.0'
+
+setup(
+    name = "xunitmultiprocess",
+    version = VERSION,
+    author = "Prasanna Santhanam",
+    author_email = "[email protected]",
+    description = "Run tests written using CloudStack's Marvin testclient",
+    license = 'ASL .0',
+    classifiers = [
+        "Intended Audience :: Developers",
+        "Topic :: Software Development :: Testing",
+        "Programming Language :: Python",
+        ],
+
+    py_modules = ['xunitmultiprocess'],
+    zip_safe = False,
+    
+    entry_points = {
+        'nose.plugins': ['xunitmultiprocess = xunitmultiprocess:Xunitmp']
+        },
+    install_requires = ['nose'],
+)

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1e4bbf8a/tools/marvin/marvin/misc/build/xunitmp/xunitmultiprocess.py
----------------------------------------------------------------------
diff --git a/tools/marvin/marvin/misc/build/xunitmp/xunitmultiprocess.py 
b/tools/marvin/marvin/misc/build/xunitmp/xunitmultiprocess.py
new file mode 100644
index 0000000..950a2e3
--- /dev/null
+++ b/tools/marvin/marvin/misc/build/xunitmp/xunitmultiprocess.py
@@ -0,0 +1,274 @@
+
+"""This plugin provides test results in the standard XUnit XML format.
+
+It was designed for the `Hudson`_ continuous build system but will
+probably work for anything else that understands an XUnit-formatted XML
+representation of test results.
+
+Add this shell command to your builder ::
+
+    nosetests --with-xunitmp
+
+And by default a file named nosetests.xml will be written to the
+working directory.
+
+In a Hudson builder, tick the box named "Publish JUnit test result report"
+under the Post-build Actions and enter this value for Test report XMLs::
+
+    **/nosetests.xml
+
+If you need to change the name or location of the file, you can set the
+``--xunit-file`` option.
+
+Here is an abbreviated version of what an XML test report might look like::
+
+    <?xml version="1.0" encoding="UTF-8"?>
+    <testsuite name="nosetests" tests="1" errors="1" failures="0" skip="0">
+        <testcase classname="path_to_test_suite.TestSomething"
+                  name="test_it" time="0">
+            <error type="exceptions.TypeError" message="oops, wrong type">
+            Traceback (most recent call last):
+            ...
+            TypeError: oops, wrong type
+            </error>
+        </testcase>
+    </testsuite>
+
+.. _Hudson: https://hudson.dev.java.net/
+
+"""
+__author__ = "original xunit author, Rosen Diankov ([email protected])"
+
+import doctest
+import os
+import traceback
+import re
+import inspect
+from nose.plugins.base import Plugin
+from nose.exc import SkipTest
+from time import time
+from xml.sax import saxutils
+from nose.pyversion import UNICODE_STRINGS
+import sys
+import multiprocessing
+globalxunitmanager = multiprocessing.Manager()
+globalxunitstream = globalxunitmanager.list() # used for gathering statistics
+globalxunitstats = multiprocessing.Array('i',[0]*4)
+
+# Invalid XML characters, control characters 0-31 sans \t, \n and \r
+CONTROL_CHARACTERS = re.compile(r"[\000-\010\013\014\016-\037]")
+
+def xml_safe(value):
+    """Replaces invalid XML characters with '?'."""
+    return CONTROL_CHARACTERS.sub('?', value)
+
+def escape_cdata(cdata):
+    """Escape a string for an XML CDATA section."""
+    return xml_safe(cdata).replace(']]>', ']]>]]&gt;<![CDATA[')
+
+def nice_classname(obj):
+    """Returns a nice name for class object or class instance.
+
+        >>> nice_classname(Exception()) # doctest: +ELLIPSIS
+        '...Exception'
+        >>> nice_classname(Exception) # doctest: +ELLIPSIS
+        '...Exception'
+
+    """
+    if inspect.isclass(obj):
+        cls_name = obj.__name__
+    else:
+        cls_name = obj.__class__.__name__
+    mod = inspect.getmodule(obj)
+    if mod:
+        name = mod.__name__
+        # jython
+        if name.startswith('org.python.core.'):
+            name = name[len('org.python.core.'):]
+        return "%s.%s" % (name, cls_name)
+    else:
+        return cls_name
+
+def exc_message(exc_info):
+    """Return the exception's message."""
+    exc = exc_info[1]
+    if exc is None:
+        # str exception
+        result = exc_info[0]
+    else:
+        try:
+            result = str(exc)
+        except UnicodeEncodeError:
+            try:
+                result = unicode(exc)
+            except UnicodeError:
+                # Fallback to args as neither str nor
+                # unicode(Exception(u'\xe6')) work in Python < 2.6
+                result = exc.args[0]
+    return xml_safe(result)
+
+class Xunitmp(Plugin):
+    """This plugin provides test results in the standard XUnit XML format."""
+    name = 'xunitmp'
+    score = 499 # necessary for it to go after capture
+    encoding = 'UTF-8'
+    xunitstream = None
+    xunitstats = None
+    xunit_file = None
+
+    def _timeTaken(self):
+        if hasattr(self, '_timer'):
+            taken = time() - self._timer
+        else:
+            # test died before it ran (probably error in setup())
+            # or success/failure added before test started probably 
+            # due to custom TestResult munging
+            taken = 0.0
+        return taken
+
+    def _quoteattr(self, attr):
+        """Escape an XML attribute. Value can be unicode."""
+        attr = xml_safe(attr)
+        if isinstance(attr, unicode) and not UNICODE_STRINGS:
+            attr = attr.encode(self.encoding)
+        return saxutils.quoteattr(attr)
+
+    def options(self, parser, env):
+        """Sets additional command line options."""
+        Plugin.options(self, parser, env)
+        parser.add_option(
+            '--xml-file', action='store',
+            dest='xunit_file', metavar="FILE",
+            default=env.get('NOSE_XUNI_FILE', 'nosetests.xml'),
+            help=("Path to xml file to store the xunit report in. "
+                  "Default is nosetests.xml in the working directory "
+                  "[NOSE_XUNIT_FILE]"))
+        parser.add_option(
+            '--xunit-header', action='store',
+            dest='xunit_header', metavar="HEADER",
+            default=env.get('NOSE_XUNIT_HEADER', ''),
+            help=("The attributes of the <testsuite> report that will be 
created, in particular 'package' and 'name' should be filled."
+                  "[NOSE_XUNIT_HEADER]"))
+
+    def configure(self, options, config):
+        """Configures the xunit plugin."""
+        Plugin.configure(self, options, config)
+        self.config = config
+        if self.enabled:
+            self.xunitstream = globalxunitstream
+            self.xunitstats = globalxunitstats
+            for i in range(4):
+                self.xunitstats[i] = 0
+            self.xunit_file = options.xunit_file
+            self.xunit_header = options.xunit_header
+
+    def report(self, stream):
+        """Writes an Xunit-formatted XML file
+
+        The file includes a report of test errors and failures.
+
+        """
+        stats = {'errors': self.xunitstats[0], 'failures': self.xunitstats[1], 
'passes': self.xunitstats[2], 'skipped': self.xunitstats[3] }
+        stats['encoding'] = self.encoding
+        stats['total'] = (stats['errors'] + stats['failures'] + 
stats['passes'] + stats['skipped'])
+        stats['header'] = self.xunit_header
+        if UNICODE_STRINGS:
+            error_report_file = open(self.xunit_file, 'w', 
encoding=self.encoding)
+        else:
+            error_report_file = open(self.xunit_file, 'w')
+        error_report_file.write(
+            '<?xml version="1.0" encoding="%(encoding)s"?>'
+            '<testsuite %(header)s tests="%(total)d" '
+            'errors="%(errors)d" failures="%(failures)d" '
+            'skip="%(skipped)d">' % stats)
+        while len(self.xunitstream) > 0:
+            error_report_file.write(self.xunitstream.pop(0))
+        #error_report_file.write('<properties><property name="myproperty" 
value="1.5"/></properties>')
+        error_report_file.write('</testsuite>')
+        error_report_file.close()
+        if self.config.verbosity > 1:
+            stream.writeln("-" * 70)
+            stream.writeln("XML: %s" % error_report_file.name)
+
+    def startTest(self, test):
+        """Initializes a timer before starting a test."""
+        self._timer = time()
+
+    def addstream(self,xml):
+        try:
+            self.xunitstream.append(xml)
+        except Exception, e:
+            print 'xunitmultiprocess add stream len=%d,%s'%(len(xml),str(e))
+            
+    def addError(self, test, err, capt=None):
+        """Add error output to Xunit report.
+        """
+        taken = self._timeTaken()
+        if issubclass(err[0], SkipTest):
+            type = 'skipped'
+            self.xunitstats[3] += 1
+        else:
+            type = 'error'
+            self.xunitstats[0] += 1
+        tb = ''.join(traceback.format_exception(*err))
+        try:
+            id=test.shortDescription()
+            if id is None:
+                id = test.id()
+        except AttributeError:
+            id=''
+        id = id.split('.')
+        name = self._quoteattr(id[-1])
+        systemout = ''
+#        if test.capturedOutput is not None:
+#            systemout = 
'<system-out><![CDATA['+escape_cdata(str(test.capturedOutput))+']]></system-out>'
+        xml = """<testcase classname=%(cls)s name=%(name)s time="%(taken)f">
+%(systemout)s
+<%(type)s type=%(errtype)s message=%(message)s><![CDATA[%(tb)s]]>
+</%(type)s></testcase>
+""" %{'cls': self._quoteattr('.'.join(id[:-1])), 'name': 
self._quoteattr(name), 'taken': taken, 'type': type, 'errtype': 
self._quoteattr(nice_classname(err[0])), 'message': 
self._quoteattr(exc_message(err)), 'tb': escape_cdata(tb), 
'systemout':systemout}
+        self.addstream(xml)
+
+    def addFailure(self, test, err, capt=None, tb_info=None):
+        """Add failure output to Xunit report.
+        """
+        taken = self._timeTaken()
+        tb = ''.join(traceback.format_exception(*err))
+        self.xunitstats[1] += 1
+        try:
+            id=test.shortDescription()
+            if id is None:
+                id = test.id()
+        except AttributeError:
+            id=''
+        id = id.split('.')
+        name = self._quoteattr(id[-1])
+        systemout = ''
+#        if test.capturedOutput is not None:
+#            systemout = 
'<system-out><![CDATA['+escape_cdata(str(test.capturedOutput))+']]></system-out>'
+        xml = """<testcase classname=%(cls)s name=%(name)s time="%(taken)f">
+%(systemout)s
+<failure type=%(errtype)s message=%(message)s><![CDATA[%(tb)s]]>
+</failure></testcase>
+""" %{'cls': self._quoteattr('.'.join(id[:-1])), 'name': 
self._quoteattr(name), 'taken': taken, 'errtype': 
self._quoteattr(nice_classname(err[0])), 'message': 
self._quoteattr(exc_message(err)), 'tb': escape_cdata(tb), 
'systemout':systemout}
+        self.addstream(xml)
+
+    def addSuccess(self, test, capt=None):
+        """Add success output to Xunit report.
+        """
+        taken = self._timeTaken()
+        self.xunitstats[2] += 1
+        try:
+            id=test.shortDescription()
+            if id is None:
+                id = test.id()
+        except AttributeError:
+            id=''
+        id = id.split('.')
+        name = self._quoteattr(id[-1])
+        systemout=''
+#        if test.capturedOutput is not None:
+#            systemout = 
'<system-out><![CDATA['+escape_cdata(str(test.capturedOutput))+']]></system-out>'
+        xml = """<testcase classname=%(cls)s name=%(name)s time="%(taken)f" 
>%(systemout)s</testcase>
+""" % {'cls': self._quoteattr('.'.join(id[:-1])), 'name': 
self._quoteattr(name), 'taken': taken, 'systemout':systemout }
+        self.addstream(xml)

Reply via email to