<commit_before>#  Copyright 2008-2009 Nokia Siemens Networks Oyj
#
#  Licensed 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.

import os

from robot import utils
from robot.common import BaseTestSuite, BaseTestCase
from robot.parsing import TestCaseFile, TestDataDirectory
from robot.parsing.settings import Fixture
from robot.errors import ExecutionFailed, DataError
from robot.variables import GLOBAL_VARIABLES
from robot.output import LOGGER

from fixture import Setup, Teardown, SuiteSetupListener, SuiteTearDownListener,\
    TestSetupListener, TestTeardownListener
from timeouts import TestTimeout
from keywords import Keywords
from namespace import Namespace
from runerrors import SuiteRunErrors, TestRunErrors
from userkeyword import UserLibrary
from context import ExecutionContext

def TestSuite(datasources, settings):
    datasources = [ utils.normpath(path) for path in datasources ]
    suite_names = settings['SuiteNames']
    if not datasources:
        raise DataError("No data sources given.")
    elif len(datasources) > 1:
        suitedatas = []
        for datasource in datasources:
            try:
                suitedatas.append(_get_directory_or_file_suite(datasource, suite_names))
            except DataError:
                pass
        # FIXME: needs to be implemented
        suite = RunnableMultiTestSuite(suitedatas)
    else:
        suitedata = _get_directory_or_file_suite(datasources[0], suite_names)
        suite = RunnableTestSuite(suitedata)
    suite.set_options(settings)
    return suite

def _get_directory_or_file_suite(path, suite_names):
    if os.path.isdir(path):
        return TestDataDirectory(source=path) #FIXME: filter suites: , suite_names)
    return TestCaseFile(source=path)

class RunnableTestSuite(BaseTestSuite):

    def __init__(self, data, parent=None):
        BaseTestSuite.__init__(self, data.name, data.source, parent)
        self.variables = GLOBAL_VARIABLES.copy()
        self.variables.set_from_variable_table(data.variable_table)
        self.source = data.source
        self.doc = data.setting_table.doc.value
        self.metadata = self._get_metadata(data.setting_table.metadata)
        self.imports = data.setting_table.imports
        self.user_keywords = UserLibrary(data.keyword_table.keywords)
        self.setup = Setup(data.setting_table.suite_setup.name,
                           data.setting_table.suite_setup.args)
        self.teardown = Teardown(data.setting_table.suite_teardown.name,
                                 data.setting_table.suite_teardown.args)
        for suite in data.children:
            RunnableTestSuite(suite, parent=self)
        for test in data.testcase_table:
            RunnableTestCase(test, parent=self)
        self._run_mode_exit_on_failure = False
        self._run_mode_dry_run = False

    def _get_metadata(self, metadata):
        meta = {}
        for item in metadata:
            meta[item.name] = item.value
        return meta

    def run(self, output, parent=None, errors=None):
        context = self._start_run(output, parent, errors)
        self._run_setup(context)
        self._run_sub_suites(context)
        self._run_tests(context)
        self._report_status(context)
        self._run_teardown(context)
        self._end_run(context)

    def _start_run(self, output, parent, errors):
        if not errors:
            errors = SuiteRunErrors(self._run_mode_exit_on_failure)
        self.run_errors = errors
        self.run_errors.start_suite()
        self.status = 'RUNNING'
        self.starttime = utils.get_timestamp()
        parent_vars = parent.context.get_current_vars() if parent else None
        self.context = ExecutionContext(Namespace(self, parent_vars), output,
                                        self._run_mode_dry_run)
        self._set_variable_dependent_metadata(self.context)
        output.start_suite(self)
        return self.context

    def _set_variable_dependent_metadata(self, context):
        errors = []
        self.doc = context.replace_vars_from_setting('Documentation', self.doc,
                                                     errors)
        self.setup.replace_variables(context.get_current_vars())
        self.teardown.replace_variables(context.get_current_vars())
        for name, value in self.metadata.items():
            self.metadata[name] = context.replace_vars_from_setting(name, value,
                                                                    errors)
        if errors:
            self.run_errors.suite_init_err('Suite initialization failed:\n%s'
                                            % '\n'.join(errors))

    def _run_setup(self, context):
        if self.run_errors.is_suite_setup_allowed():
            self.setup.run(context, SuiteSetupListener(self))
            self.run_errors.setup_executed()

    def _run_teardown(self, context):
        if self.run_errors.is_suite_teardown_allowed():
            self.teardown.run(context, SuiteTearDownListener(self))

    def _run_sub_suites(self, context):
        for suite in self.suites:
            suite.run(context.output, self, self.run_errors)

    def _run_tests(self, context):
        executed_tests = []
        for test in self.tests:
            normname = utils.normalize(test.name)
            if normname in executed_tests:
                LOGGER.warn("Multiple test cases with name '%s' executed in "
                            "test suite '%s'"% (test.name, self.longname))
            executed_tests.append(normname)
            test.run(context, self.run_errors)
            context.set_prev_test_variables(test)

    def _report_status(self, context):
        self.set_status()
        self.message = self.run_errors.suite_error()
        context.report_suite_status(self.status, self.get_full_message())

    def _end_run(self, context):
        self.endtime = utils.get_timestamp()
        self.elapsedtime = utils.get_elapsed_time(self.starttime, self.endtime)
        context.copy_prev_test_vars_to_global()
        context.end_suite(self)
        self.run_errors.end_suite()

class RunnableTestCase(BaseTestCase):

    def __init__(self, tc_data, parent):
        BaseTestCase.__init__(self, tc_data.name, parent)
        self.doc = tc_data.doc.value
        setup = tc_data.setup.is_set() and tc_data.setup or self._get_parent_test_setup(tc_data.parent.parent)
        self.setup = Setup(setup.name, setup.args)
        teardown = tc_data.teardown.is_set() and tc_data.teardown or self._get_parent_test_teardown(tc_data.parent.parent)
        self.teardown = Teardown(teardown.name, teardown.args)
        self.tags = self._get_tags(tc_data)
        self.timeout = TestTimeout(tc_data.timeout.value, tc_data.timeout.message)
        self.keywords = Keywords(tc_data.steps)

    def run(self, context, suite_errors):
        self._suite_errors = suite_errors
        self._start_run(context)
        if self.run_errors.is_allowed_to_run():
            self._run(context)
        else:
            self._not_allowed_to_run()
        self._end_run(context)

    def _start_run(self, context):
        self.run_errors = TestRunErrors(self._suite_errors)
        self.status = 'RUNNING'
        self.starttime = utils.get_timestamp()
        self.run_errors.init_err(self._init_test(context))
        context.start_test(self)

    def _init_test(self, context):
        errors = []
        self.doc = context.replace_vars_from_setting('Documentation', self.doc,
                                                     errors)
        self.setup.replace_variables(context.get_current_vars())
        self.teardown.replace_variables(context.get_current_vars())
        self.tags = utils.normalize_tags(context.replace_vars_from_setting('Tags',
                                                                           self.tags,
                                                                           errors))
        self.timeout.replace_variables(context.get_current_vars())
        if errors:
            return 'Test case initialization failed:\n%s' % '\n'.join(errors)
        if not self.keywords:
            return 'Test case contains no keywords'
        return None

    def _run(self, context):
        self.timeout.start()
        self._run_setup(context)
        if not self.run_errors.setup_failed():
            try:
                self.keywords.run(context)
            except ExecutionFailed, err:
                self.run_errors.kw_err(unicode(err))
                self.keyword_failed(err)
        context.set_test_status_before_teardown(*self._report_status())
        self._run_teardown(context)
        self._report_status_after_teardown()

    def keyword_failed(self, err):
        self.timeout.set_keyword_timeout(err.timeout)
        self._suite_errors.test_failed(exit=err.exit)

    def _run_setup(self, context):
        self.setup.run(context, TestSetupListener(self))

    def _report_status(self):
        message = self.run_errors.get_message()
        if message:
            self.status = 'FAIL'
            self.message = message
        else:
            self.status = 'PASS'
        return self.message, self.status

    def _run_teardown(self, context):
        self.teardown.run(context, TestTeardownListener(self))

    def _report_status_after_teardown(self):
        if self.run_errors.teardown_failed():
            self.status = 'FAIL'
            self.message = self.run_errors.get_teardown_message(self.message)
        if self.status == 'PASS' and self.timeout.timed_out():
            self.status = 'FAIL'
            self.message = self.timeout.get_message()
        if self.status == 'FAIL':
            self._suite_errors.test_failed(critical=self.critical=='yes')

    def _not_allowed_to_run(self):
        self.status = 'FAIL'
        self.message = self.run_errors.parent_or_init_error()

    def _end_run(self, context):
        self.endtime = utils.get_timestamp()
        self.elapsedtime = utils.get_elapsed_time(self.starttime, self.endtime)
        context.end_test(self)

    def _get_tags(self, tc_data):
        force_tags = self._get_parent_force_tags(tc_data.parent.parent)
        tc_tags = tc_data.tags.is_set() and tc_data.tags.value or \
                    tc_data.parent.parent.setting_table.default_tags.value
        return list(set(tc_tags + force_tags))

    def _get_parent_force_tags(self, data):
        parent_tags = data.parent and self._get_parent_force_tags(data.parent) or []
        return data.setting_table.force_tags.value + parent_tags

    def _get_parent_test_setup(self, data):
        if data.setting_table.test_setup.is_set():
            return data.setting_table.test_setup
        return data.parent and self._get_parent_test_setup(data.parent) or Fixture()

    def _get_parent_test_teardown(self, data):
        if data.setting_table.test_teardown.is_set():
            return data.setting_table.test_teardown
        return data.parent and self._get_parent_test_teardown(data.parent) or Fixture()

<commit_msg>added multisourcesuite<commit_after>#  Copyright 2008-2009 Nokia Siemens Networks Oyj
#
#  Licensed 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.

import os

from robot import utils
from robot.common import BaseTestSuite, BaseTestCase
from robot.parsing import TestCaseFile, TestDataDirectory
from robot.parsing.settings import Fixture
from robot.errors import ExecutionFailed, DataError
from robot.variables import GLOBAL_VARIABLES
from robot.output import LOGGER

from fixture import Setup, Teardown, SuiteSetupListener, SuiteTearDownListener,\
    TestSetupListener, TestTeardownListener
from timeouts import TestTimeout
from keywords import Keywords
from namespace import Namespace
from runerrors import SuiteRunErrors, TestRunErrors
from userkeyword import UserLibrary
from context import ExecutionContext

def TestSuite(datasources, settings):
    datasources = [ utils.normpath(path) for path in datasources ]
    suite_names = settings['SuiteNames']
    if not datasources:
        raise DataError("No data sources given.")
    elif len(datasources) > 1:
        suitedatas = []
        for datasource in datasources:
            try:
                suitedatas.append(_get_directory_or_file_suite(datasource, suite_names))
            except DataError:
                pass
        # FIXME: needs to be implemented
        suite = RunnableMultiTestSuite(suitedatas)
    else:
        suitedata = _get_directory_or_file_suite(datasources[0], suite_names)
        suite = RunnableTestSuite(suitedata)
    suite.set_options(settings)
    return suite

def _get_directory_or_file_suite(path, suite_names):
    if os.path.isdir(path):
        return TestDataDirectory(source=path) #FIXME: filter suites: , suite_names)
    return TestCaseFile(source=path)

class RunnableTestSuite(BaseTestSuite):

    def __init__(self, data, parent=None):
        BaseTestSuite.__init__(self, data.name, data.source, parent)
        self.variables = GLOBAL_VARIABLES.copy()
        self.variables.set_from_variable_table(data.variable_table)
        self.source = data.source
        self.doc = data.setting_table.doc.value
        self.metadata = self._get_metadata(data.setting_table.metadata)
        self.imports = data.setting_table.imports
        self.user_keywords = UserLibrary(data.keyword_table.keywords)
        self.setup = Setup(data.setting_table.suite_setup.name,
                           data.setting_table.suite_setup.args)
        self.teardown = Teardown(data.setting_table.suite_teardown.name,
                                 data.setting_table.suite_teardown.args)
        for suite in data.children:
            RunnableTestSuite(suite, parent=self)
        for test in data.testcase_table:
            RunnableTestCase(test, parent=self)
        self._run_mode_exit_on_failure = False
        self._run_mode_dry_run = False

    def _get_metadata(self, metadata):
        meta = {}
        for item in metadata:
            meta[item.name] = item.value
        return meta

    def run(self, output, parent=None, errors=None):
        context = self._start_run(output, parent, errors)
        self._run_setup(context)
        self._run_sub_suites(context)
        self._run_tests(context)
        self._report_status(context)
        self._run_teardown(context)
        self._end_run(context)

    def _start_run(self, output, parent, errors):
        if not errors:
            errors = SuiteRunErrors(self._run_mode_exit_on_failure)
        self.run_errors = errors
        self.run_errors.start_suite()
        self.status = 'RUNNING'
        self.starttime = utils.get_timestamp()
        parent_vars = parent.context.get_current_vars() if parent else None
        self.context = ExecutionContext(Namespace(self, parent_vars), output,
                                        self._run_mode_dry_run)
        self._set_variable_dependent_metadata(self.context)
        output.start_suite(self)
        return self.context

    def _set_variable_dependent_metadata(self, context):
        errors = []
        self.doc = context.replace_vars_from_setting('Documentation', self.doc,
                                                     errors)
        self.setup.replace_variables(context.get_current_vars())
        self.teardown.replace_variables(context.get_current_vars())
        for name, value in self.metadata.items():
            self.metadata[name] = context.replace_vars_from_setting(name, value,
                                                                    errors)
        if errors:
            self.run_errors.suite_init_err('Suite initialization failed:\n%s'
                                            % '\n'.join(errors))

    def _run_setup(self, context):
        if self.run_errors.is_suite_setup_allowed():
            self.setup.run(context, SuiteSetupListener(self))
            self.run_errors.setup_executed()

    def _run_teardown(self, context):
        if self.run_errors.is_suite_teardown_allowed():
            self.teardown.run(context, SuiteTearDownListener(self))

    def _run_sub_suites(self, context):
        for suite in self.suites:
            suite.run(context.output, self, self.run_errors)

    def _run_tests(self, context):
        executed_tests = []
        for test in self.tests:
            normname = utils.normalize(test.name)
            if normname in executed_tests:
                LOGGER.warn("Multiple test cases with name '%s' executed in "
                            "test suite '%s'"% (test.name, self.longname))
            executed_tests.append(normname)
            test.run(context, self.run_errors)
            context.set_prev_test_variables(test)

    def _report_status(self, context):
        self.set_status()
        self.message = self.run_errors.suite_error()
        context.report_suite_status(self.status, self.get_full_message())

    def _end_run(self, context):
        self.endtime = utils.get_timestamp()
        self.elapsedtime = utils.get_elapsed_time(self.starttime, self.endtime)
        context.copy_prev_test_vars_to_global()
        context.end_suite(self)
        self.run_errors.end_suite()

class RunnableMultiTestSuite(RunnableTestSuite):

    def __init__(self, suitedatas):
        BaseTestSuite.__init__(self, name='')
        self.variables = GLOBAL_VARIABLES.copy()
        self.doc = ''
        self.imports = []
        # FIXME: remove if possible
        #self.user_keywords = UserLibrary(data.keyword_table.keywords)
        self.setup = Setup(None, None)
        self.teardown = Teardown(None, None)
        for suite in suitedatas:
            RunnableTestSuite(suite, parent=self)
        self._run_mode_exit_on_failure = False
        self._run_mode_dry_run = False

class RunnableTestCase(BaseTestCase):

    def __init__(self, tc_data, parent):
        BaseTestCase.__init__(self, tc_data.name, parent)
        self.doc = tc_data.doc.value
        setup = tc_data.setup.is_set() and tc_data.setup or self._get_parent_test_setup(tc_data.parent.parent)
        self.setup = Setup(setup.name, setup.args)
        teardown = tc_data.teardown.is_set() and tc_data.teardown or self._get_parent_test_teardown(tc_data.parent.parent)
        self.teardown = Teardown(teardown.name, teardown.args)
        self.tags = self._get_tags(tc_data)
        self.timeout = TestTimeout(tc_data.timeout.value, tc_data.timeout.message)
        self.keywords = Keywords(tc_data.steps)

    def run(self, context, suite_errors):
        self._suite_errors = suite_errors
        self._start_run(context)
        if self.run_errors.is_allowed_to_run():
            self._run(context)
        else:
            self._not_allowed_to_run()
        self._end_run(context)

    def _start_run(self, context):
        self.run_errors = TestRunErrors(self._suite_errors)
        self.status = 'RUNNING'
        self.starttime = utils.get_timestamp()
        self.run_errors.init_err(self._init_test(context))
        context.start_test(self)

    def _init_test(self, context):
        errors = []
        self.doc = context.replace_vars_from_setting('Documentation', self.doc,
                                                     errors)
        self.setup.replace_variables(context.get_current_vars())
        self.teardown.replace_variables(context.get_current_vars())
        self.tags = utils.normalize_tags(context.replace_vars_from_setting('Tags',
                                                                           self.tags,
                                                                           errors))
        self.timeout.replace_variables(context.get_current_vars())
        if errors:
            return 'Test case initialization failed:\n%s' % '\n'.join(errors)
        if not self.keywords:
            return 'Test case contains no keywords'
        return None

    def _run(self, context):
        self.timeout.start()
        self._run_setup(context)
        if not self.run_errors.setup_failed():
            try:
                self.keywords.run(context)
            except ExecutionFailed, err:
                self.run_errors.kw_err(unicode(err))
                self.keyword_failed(err)
        context.set_test_status_before_teardown(*self._report_status())
        self._run_teardown(context)
        self._report_status_after_teardown()

    def keyword_failed(self, err):
        self.timeout.set_keyword_timeout(err.timeout)
        self._suite_errors.test_failed(exit=err.exit)

    def _run_setup(self, context):
        self.setup.run(context, TestSetupListener(self))

    def _report_status(self):
        message = self.run_errors.get_message()
        if message:
            self.status = 'FAIL'
            self.message = message
        else:
            self.status = 'PASS'
        return self.message, self.status

    def _run_teardown(self, context):
        self.teardown.run(context, TestTeardownListener(self))

    def _report_status_after_teardown(self):
        if self.run_errors.teardown_failed():
            self.status = 'FAIL'
            self.message = self.run_errors.get_teardown_message(self.message)
        if self.status == 'PASS' and self.timeout.timed_out():
            self.status = 'FAIL'
            self.message = self.timeout.get_message()
        if self.status == 'FAIL':
            self._suite_errors.test_failed(critical=self.critical=='yes')

    def _not_allowed_to_run(self):
        self.status = 'FAIL'
        self.message = self.run_errors.parent_or_init_error()

    def _end_run(self, context):
        self.endtime = utils.get_timestamp()
        self.elapsedtime = utils.get_elapsed_time(self.starttime, self.endtime)
        context.end_test(self)

    def _get_tags(self, tc_data):
        force_tags = self._get_parent_force_tags(tc_data.parent.parent)
        tc_tags = tc_data.tags.is_set() and tc_data.tags.value or \
                    tc_data.parent.parent.setting_table.default_tags.value
        return list(set(tc_tags + force_tags))

    def _get_parent_force_tags(self, data):
        parent_tags = data.parent and self._get_parent_force_tags(data.parent) or []
        return data.setting_table.force_tags.value + parent_tags

    def _get_parent_test_setup(self, data):
        if data.setting_table.test_setup.is_set():
            return data.setting_table.test_setup
        return data.parent and self._get_parent_test_setup(data.parent) or Fixture()

    def _get_parent_test_teardown(self, data):
        if data.setting_table.test_teardown.is_set():
            return data.setting_table.test_teardown
        return data.parent and self._get_parent_test_teardown(data.parent) or Fixture()

<|endoftext|>


<commit_before>#########################################################################
# Copyright 2013 Cloud Sidekick
#
# Licensed 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.
#########################################################################

import urllib2
import httplib
import base64
import re
import time

try:
    import xml.etree.cElementTree as ET
except (AttributeError, ImportError):
    import xml.etree.ElementTree as ET

try:
    ET.ElementTree.iterfind
except AttributeError as ex:
    del(ET)
    import etree.ElementTree as ET

def get_node_values(xml, path, attribs=[], elems=[], other=""):
    """Given an xml string and path, returns a list of dictionary objects.

    Arguments:
    xml -- a string of properly formatted xml
    path -- an Xpath path.
            See http://docs.python.org/2/library/xml.etree.elementtree.html#supported-xpath-syntax
    attribs -- an optional list of xml node attribute names to retrieve the values for.
            "*" will retrieve all attributes per node found.
    elems -- an optional list of xml child elements to retrieve the text value for.
            "*" will retrieve all child elements per node found.
    other -- if the attribute or element is not found, return this value (e.g. "" or None)

    Example:

    print get_node_values(z, "./NetworkConnection", elems=["MACAddress", "IpAddress"],
        attribs=["network", "needsCustomization", "aaaaaaaa"], other=None)

    Might return a list of two interfaces with the following dictionary values:

    [{'needsCustomization': 'false', 'aaaaaaaa': None, 'IpAddress': '212.54.150.58', 'network': 'Direct Internet connection', 'MACAddress': '00:50:56:01:02:eb'}, {'needsCustomization': 'false', 'aaaaaaaa': None, 'IpAddress': '212.54.150.82', 'network': 'Direct Internet connection', 'MACAddress': '00:50:56:01:02:e7'}]
    """

    result = []
    root = ET.fromstring(xml)
    if not path.startswith("./"):
        path = "./" + path
    nodes = root.findall(path)

    for n in nodes:
        node_result = {}
        if "*" in attribs:
            node_result = n.attrib
            # we don't care about the rest of the list, move on to elems
        else:
            for a in attribs:
                if a in n.attrib.keys():
                    node_result[a] = n.attrib.get(a)
                else:
                    node_result[a] = other
        if "*" in elems:
            for e in n:
                node_result[e.tag] = e.text
                # we don't care about the rest of the list, move on to the next node
        else:
            for e in elems:
                node_result[e] = n.findtext(e, other)
        result.append(node_result)
    del(root)
    # don't forget: result will be a list, empty if path is not found
    return result

class VCloudConn():
    """Example:
    conn = vcloudpy.VCloudConn(user, password, endpoint, debug=True)
    """

    def __init__(self, user, password, endpoint, protocol="https", api_version="1.5",
        path="/api", timeout=10, debug=False):
        """Initiallizes the VCloudConn class.

        Will automatically use parameters and establish connection to vCloud endpoint.

        Arguments:
        user -- vCloud userid in the form of user@orgid
        password -- vCloud user's password
        endpoint -- vCloud server endpoint, e.g. iad.vcloudservice.vmware.com
        protocol -- optional, http or https (default), most likely https
        api_version -- optional, usually either 5.1 (default) or 1.5
        path -- optional, api uri path, most likely don't change
        timeout -- optional, timeout in seconds for all http connections with vCloud, default 10
        debug -- optional, prints html responses from vCloud, True or False (default)
        """

        self.api_version = api_version
        self.timeout = timeout
        self.debug = debug
        self.base_url = "%s://%s%s" % (protocol.lower(), endpoint, path)

        # ok, we should be able to login now
        self._login(user, password)

    def _login(self, user, password):
        """Handles login duties, retrieves authorization token"""

        if self.api_version is None:
            self.api_version = self._determine_version(self.base_url + "/versions")
        auth_url = self.base_url + "/sessions"
        req = urllib2.Request(auth_url)
        auth = "Basic " + base64.urlsafe_b64encode("%s:%s" % (user, password))
        req.add_header("Authorization", auth)
        req.get_method = lambda: "POST"

        # this should be in a try / except with more specific error messages
        result = self._send_request(req)
        self.auth_token = result.info().getheader("x-vcloud-authorization")

    def _xml_del_ns(self, xml):
        """A helper function that strips namespaces from xml text"""

        try:
            p = re.compile("xmlns=*[\"\"][^\"\"]*[\"\"]")
            allmatches = p.finditer(xml)
            for match in allmatches:
                xml = xml.replace(match.group(), "")
        except Exception as e:
            raise Exception(e)

        return xml

    def _determine_version(self, url):

        req = urllib2.Request(url)
        response = self._send_request(req)
        xml = self._xml_del_ns(response.read())
        versions = get_node_values(xml, "VersionInfo", elems=["Version"])
        lv = []
        for v in versions:
            lv.append(v["Version"])
        lv.sort()
        lv.reverse()
        return lv[0]

    def _make_request(self, url, verb, data=None, type=None):
        """Constructs the vCloud api request to send"""

        url = url.replace(" ", "+")
        req = urllib2.Request(url)
        req.add_header("x-vcloud-authorization", self.auth_token)
        if type:
            req.add_header("Content-Type", type)
        req.get_method = lambda: verb
        if data:
            req.add_data(data)
        response = self._send_request(req)
        # out of laziness, we will strip the namespaces to make xpath work worry free
        return self._xml_del_ns(response.read())

    def _send_request(self, req):
        """Sends the request and handles errors"""

        req.add_header("Accept", "application/*+xml;version=%s" % self.api_version)
        if self.debug:
            print("vCloud api version being used: %s" % (self.api_version))
        reattempt = True
        attempt = 1
        reattempt_http_codes = [401]
        delay = 1
        attempts_allowed = 10

        while reattempt is True and attempt <= attempts_allowed:
            try:
                response = urllib2.urlopen(req, timeout=self.timeout)
            except urllib2.HTTPError, e:
                if e.code in reattempt_http_codes and attempt < attempts_allowed:
                    print("HTTPError, will reattempt = %s, %s, %s\n%s" % (str(e.code), e.msg, e.read(), req.get_full_url()))
                    attempt += 1
                    time.sleep(delay)
                    continue
                else:
                    raise Exception("HTTPError = %s, %s, %s\n%s" % (str(e.code), e.msg, e.read(), req.get_full_url()))
            except urllib2.URLError, e:
                raise Exception("URLError = %s\n%s" % (str(e.reason), req.get_full_url()))
            except httplib.HTTPException, e:
                raise Exception("HTTPException")
            except Exception:
                import traceback
                raise Exception("generic exception: " + traceback.format_exc())
            else:
                # got here, request was successful, break out
                reattempt = False

        if self.debug:
            print(response.info())
            r = response.read()
            print(r)

        return response

    def logout(self):
        """Handles the logout duties"""

        self.make_method_request("session", "DELETE")
        self.auth_token = None

    def make_href_request_path(self, href, verb="GET", data=None, type=None):
        """Used to retrieve an object using a full path"""

        return self._make_request(href, verb, data, type)

    def make_method_request(self, method, verb="GET"):
        """Used to make a method request."""

        full_url = self.base_url + "/" + method
        return self._make_request(full_url, verb)

<commit_msg>changed default timeout to 30 seconds<commit_after>#########################################################################
# Copyright 2013 Cloud Sidekick
#
# Licensed 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.
#########################################################################

import urllib2
import httplib
import base64
import re
import time

try:
    import xml.etree.cElementTree as ET
except (AttributeError, ImportError):
    import xml.etree.ElementTree as ET

try:
    ET.ElementTree.iterfind
except AttributeError as ex:
    del(ET)
    import etree.ElementTree as ET

def get_node_values(xml, path, attribs=[], elems=[], other=""):
    """Given an xml string and path, returns a list of dictionary objects.

    Arguments:
    xml -- a string of properly formatted xml
    path -- an Xpath path.
            See http://docs.python.org/2/library/xml.etree.elementtree.html#supported-xpath-syntax
    attribs -- an optional list of xml node attribute names to retrieve the values for.
            "*" will retrieve all attributes per node found.
    elems -- an optional list of xml child elements to retrieve the text value for.
            "*" will retrieve all child elements per node found.
    other -- if the attribute or element is not found, return this value (e.g. "" or None)

    Example:

    print get_node_values(z, "./NetworkConnection", elems=["MACAddress", "IpAddress"],
        attribs=["network", "needsCustomization", "aaaaaaaa"], other=None)

    Might return a list of two interfaces with the following dictionary values:

    [{'needsCustomization': 'false', 'aaaaaaaa': None, 'IpAddress': '212.54.150.58', 'network': 'Direct Internet connection', 'MACAddress': '00:50:56:01:02:eb'}, {'needsCustomization': 'false', 'aaaaaaaa': None, 'IpAddress': '212.54.150.82', 'network': 'Direct Internet connection', 'MACAddress': '00:50:56:01:02:e7'}]
    """

    result = []
    root = ET.fromstring(xml)
    if not path.startswith("./"):
        path = "./" + path
    nodes = root.findall(path)

    for n in nodes:
        node_result = {}
        if "*" in attribs:
            node_result = n.attrib
            # we don't care about the rest of the list, move on to elems
        else:
            for a in attribs:
                if a in n.attrib.keys():
                    node_result[a] = n.attrib.get(a)
                else:
                    node_result[a] = other
        if "*" in elems:
            for e in n:
                node_result[e.tag] = e.text
                # we don't care about the rest of the list, move on to the next node
        else:
            for e in elems:
                node_result[e] = n.findtext(e, other)
        result.append(node_result)
    del(root)
    # don't forget: result will be a list, empty if path is not found
    return result

class VCloudConn():
    """Example:
    conn = vcloudpy.VCloudConn(user, password, endpoint, debug=True)
    """

    def __init__(self, user, password, endpoint, protocol="https", api_version="1.5",
        path="/api", timeout=30, debug=False):
        """Initiallizes the VCloudConn class.

        Will automatically use parameters and establish connection to vCloud endpoint.

        Arguments:
        user -- vCloud userid in the form of user@orgid
        password -- vCloud user's password
        endpoint -- vCloud server endpoint, e.g. iad.vcloudservice.vmware.com
        protocol -- optional, http or https (default), most likely https
        api_version -- optional, usually either 5.1 (default) or 1.5
        path -- optional, api uri path, most likely don't change
        timeout -- optional, timeout in seconds for all http connections with vCloud, default 30
        debug -- optional, prints html responses from vCloud, True or False (default)
        """

        self.api_version = api_version
        self.timeout = timeout
        self.debug = debug
        self.base_url = "%s://%s%s" % (protocol.lower(), endpoint, path)

        # ok, we should be able to login now
        self._login(user, password)

    def _login(self, user, password):
        """Handles login duties, retrieves authorization token"""

        if self.api_version is None:
            self.api_version = self._determine_version(self.base_url + "/versions")
        auth_url = self.base_url + "/sessions"
        req = urllib2.Request(auth_url)
        auth = "Basic " + base64.urlsafe_b64encode("%s:%s" % (user, password))
        req.add_header("Authorization", auth)
        req.get_method = lambda: "POST"

        # this should be in a try / except with more specific error messages
        result = self._send_request(req)
        self.auth_token = result.info().getheader("x-vcloud-authorization")

    def _xml_del_ns(self, xml):
        """A helper function that strips namespaces from xml text"""

        try:
            p = re.compile("xmlns=*[\"\"][^\"\"]*[\"\"]")
            allmatches = p.finditer(xml)
            for match in allmatches:
                xml = xml.replace(match.group(), "")
        except Exception as e:
            raise Exception(e)

        return xml

    def _determine_version(self, url):

        req = urllib2.Request(url)
        response = self._send_request(req)
        xml = self._xml_del_ns(response.read())
        versions = get_node_values(xml, "VersionInfo", elems=["Version"])
        lv = []
        for v in versions:
            lv.append(v["Version"])
        lv.sort()
        lv.reverse()
        return lv[0]

    def _make_request(self, url, verb, data=None, type=None):
        """Constructs the vCloud api request to send"""

        url = url.replace(" ", "+")
        req = urllib2.Request(url)
        req.add_header("x-vcloud-authorization", self.auth_token)
        if type:
            req.add_header("Content-Type", type)
        req.get_method = lambda: verb
        if data:
            req.add_data(data)
        response = self._send_request(req)
        # out of laziness, we will strip the namespaces to make xpath work worry free
        return self._xml_del_ns(response.read())

    def _send_request(self, req):
        """Sends the request and handles errors"""

        req.add_header("Accept", "application/*+xml;version=%s" % self.api_version)
        if self.debug:
            print("vCloud api version being used: %s" % (self.api_version))
        reattempt = True
        attempt = 1
        reattempt_http_codes = [401]
        delay = 1
        attempts_allowed = 10

        while reattempt is True and attempt <= attempts_allowed:
            try:
                response = urllib2.urlopen(req, timeout=self.timeout)
            except urllib2.HTTPError, e:
                if e.code in reattempt_http_codes and attempt < attempts_allowed:
                    print("HTTPError, will reattempt = %s, %s, %s\n%s" % (str(e.code), e.msg, e.read(), req.get_full_url()))
                    attempt += 1
                    time.sleep(delay)
                    continue
                else:
                    raise Exception("HTTPError = %s, %s, %s\n%s" % (str(e.code), e.msg, e.read(), req.get_full_url()))
            except urllib2.URLError, e:
                raise Exception("URLError = %s\n%s" % (str(e.reason), req.get_full_url()))
            except httplib.HTTPException, e:
                raise Exception("HTTPException")
            except Exception:
                import traceback
                raise Exception("generic exception: " + traceback.format_exc())
            else:
                # got here, request was successful, break out
                reattempt = False

        if self.debug:
            print(response.info())
            r = response.read()
            print(r)

        return response

    def logout(self):
        """Handles the logout duties"""

        self.make_method_request("session", "DELETE")
        self.auth_token = None

    def make_href_request_path(self, href, verb="GET", data=None, type=None):
        """Used to retrieve an object using a full path"""

        return self._make_request(href, verb, data, type)

    def make_method_request(self, method, verb="GET"):
        """Used to make a method request."""

        full_url = self.base_url + "/" + method
        return self._make_request(full_url, verb)

<|endoftext|>


<commit_before>#  Copyright 2008-2009 Nokia Siemens Networks Oyj
#
#  Licensed 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.

from robot import utils
from robot.common import BaseTestSuite, BaseTestCase
from robot.parsing import TestSuiteData
from robot.errors import ExecutionFailed
from robot.variables import GLOBAL_VARIABLES
from robot.output import LOGGER

from fixture import Setup, Teardown
from timeouts import TestTimeout
from keywords import Keywords
from namespace import Namespace
from runerrors import SuiteRunErrors, TestRunErrors
from userkeyword import UserLibrary

def TestSuite(datasources, settings):
    suitedata = TestSuiteData(datasources, settings['SuiteNames'])
    suite = RunnableTestSuite(suitedata)
    suite.set_options(settings)
    return suite

class RunnableTestSuite(BaseTestSuite):

    def __init__(self, data, testdefaults=None, parent=None):
        BaseTestSuite.__init__(self, data.name, data.source, parent)
        self.variables = GLOBAL_VARIABLES.copy()
        self.variables.set_from_variable_table(data.variables)
        self.source = data.source
        self.doc = data.doc or ''
        self.metadata = data.metadata
        self.imports = data.imports
        self.user_keywords = UserLibrary(data.user_keywords)
        self.setup = data.suite_setup or []
        self.teardown = data.suite_teardown or []
        if not testdefaults:
            testdefaults = _TestCaseDefaults()
        testdefaults.add_defaults(data)
        for suite in data.suites:
            RunnableTestSuite(suite, testdefaults.copy(), parent=self)
        for test in data.tests:
            RunnableTestCase(test, testdefaults, parent=self)
        self._run_mode_exit_on_failure = False
        self.exit_requiring_err_occured = False

    def run(self, output, parent=None, errors=None):
        self._start_run(output, parent, errors)
        self._run_setup(output)
        self._run_sub_suites(output)
        self._run_tests(output)
        self._report_status(output)
        self._run_teardown(output)
        self._end_run(output)

    def _start_run(self, output, parent, errors):
        if not errors:
            errors = SuiteRunErrors(self._run_mode_exit_on_failure)
        self._run_errors = errors
        self._run_errors.start_suite()
        self._init_run(parent)
        self._set_variable_dependent_metadata(self.namespace.variables)
        output.start_suite(self)

    def _init_run(self, parent):
        self.status = 'RUNNING'
        self.starttime = utils.get_timestamp()
        self.namespace = Namespace(self, parent)
        self.namespace.variables['${SUITE_NAME}'] = self.longname
        self.namespace.variables['${SUITE_SOURCE}'] = self.source

    def _set_variable_dependent_metadata(self, variables):
        errors = []
        self.doc = variables.replace_meta('Documentation', self.doc, errors)
        self.setup = Setup(variables.replace_meta('Setup', self.setup, errors))
        self.teardown = Teardown(
            variables.replace_meta('Teardown', self.teardown, errors))
        for name, value in self.metadata.items():
            self.metadata[name] = variables.replace_meta(name, value, errors)
        if errors:
            self._run_errors.suite_init_err('Suite initialization failed:\n%s'
                                            % '\n'.join(errors))

    def _run_setup(self, output):
        if self._run_errors.is_suite_setup_allowed():
            self._run_errors.suite_setup_err(self._run_fixture(self.setup, output))

    def _run_teardown(self, output):
        if self._run_errors.is_suite_teardown_allowed():
            td_err = self._run_fixture(self.teardown, output)
            if td_err:
                self.suite_teardown_failed('Suite teardown failed:\n%s' % td_err)

    def _run_fixture(self, fixture, output):
        if fixture:
            try:
                fixture.run(output, self.namespace)
            except ExecutionFailed:
                return utils.get_error_message()
        return None

    def _run_sub_suites(self, output):
        for suite in self.suites:
            suite.run(output, self, self._run_errors)

    def _run_tests(self, output):
        executed_tests = []
        for test in self.tests:
            normname = utils.normalize(test.name)
            if normname in executed_tests:
                LOGGER.warn("Multiple test cases with name '%s' executed in "
                            "test suite '%s'"% (test.name, self.longname))
            executed_tests.append(normname)
            test.run(output, self.namespace, self._run_errors)
            self._set_prev_test_variables(self.namespace.variables, test)

    def _report_status(self, output):
        self.set_status()
        self.message = self._run_errors.suite_error()
        self.namespace.variables['${SUITE_STATUS}'] = self.status
        self.namespace.variables['${SUITE_MESSAGE}'] = self.get_full_message()

    def _end_run(self, output):
        self.endtime = utils.get_timestamp()
        self.elapsedtime = utils.get_elapsed_time(self.starttime, self.endtime)
        self._set_prev_test_variables(GLOBAL_VARIABLES, varz=self.namespace.variables)
        output.end_suite(self)
        self.namespace.end_suite()
        self._run_errors.end_suite()

    def _set_prev_test_variables(self, destination, test=None, varz=None):
        if test:
            name, status, message = test.name, test.status, test.message
        else:
            name, status, message = varz['${PREV_TEST_NAME}'], \
                    varz['${PREV_TEST_STATUS}'], varz['${PREV_TEST_MESSAGE}']
        destination['${PREV_TEST_NAME}'] = name
        destination['${PREV_TEST_STATUS}'] = status
        destination['${PREV_TEST_MESSAGE}'] = message

class RunnableTestCase(BaseTestCase):

    def __init__(self, data, defaults, parent):
        BaseTestCase.__init__(self, data.name, parent)
        self.doc = data.doc or ''
        self.setup = utils.get_not_none(data.setup, defaults.test_setup)
        self.teardown = utils.get_not_none(data.teardown,
                                           defaults.test_teardown)
        self.tags = defaults.force_tags \
                    + utils.get_not_none(data.tags, defaults.default_tags)
        self.timeout = utils.get_not_none(data.timeout, defaults.test_timeout)
        self.keywords = Keywords(data.keywords)
        self.exit_on_failure = False

    def run(self, output, namespace, suite_errors):
        self._suite_errors = suite_errors
        self._start_run(output, namespace)
        if self._run_errors.is_allowed_to_run():
            self._run(output, namespace)
        else:
            self._not_allowed_to_run()
        self._end_run(output, namespace)

    def _start_run(self, output, namespace):
        self._run_errors = TestRunErrors(self._suite_errors)
        self.status = 'RUNNING'
        self.starttime = utils.get_timestamp()
        self._run_errors.init_err(self._init_test(namespace.variables))
        namespace.start_test(self)
        output.start_test(self)

    def _init_test(self, varz):
        errors = []
        self.doc = varz.replace_meta('Documentation', self.doc, errors)
        self.setup = Setup(varz.replace_meta('Setup', self.setup, errors))
        self.teardown = Teardown(
            varz.replace_meta('Teardown', self.teardown, errors))
        self.tags = utils.normalize_tags(
            varz.replace_meta('Tags', self.tags, errors))
        self.timeout = TestTimeout(
            *varz.replace_meta('Timeout', self.timeout, errors))
        if errors:
            return 'Test case initialization failed:\n%s' % '\n'.join(errors)
        if not self.keywords:
            return 'Test case contains no keywords'

    def _run(self, output, namespace):
        self.init_ctx(namespace)
        self.timeout.start()
        self._run_setup(output, namespace)
        if not self._run_errors.setup_failed():
            try:
                self.keywords.run(output, namespace)
            except ExecutionFailed, err:
                self._run_errors.kw_err(unicode(err))
                self.timeout.set_keyword_timeout(err.timeout)
                self._suite_errors.test_failed(exit=err.exit)
        self._report_status(namespace)
        self._run_teardown(output, namespace)
        self._report_status_after_teardown()

    def init_ctx(self, namespace):
        namespace.variables['${TEST_NAME}'] = self.name
        namespace.variables['@{TEST_TAGS}'] = self.tags

    def _run_setup(self, output, namespace):
        if self.setup:
            self._run_fixture(self.setup, output, namespace,
                              self._run_errors.setup_err)

    def _report_status(self, namespace):
        message = self._run_errors.get_message()
        if message:
            self.status = 'FAIL'
            self.message = message
        else:
            self.status = 'PASS'
        namespace.variables['${TEST_MESSAGE}'] = self.message
        namespace.variables['${TEST_STATUS}'] = self.status

    def _run_teardown(self, output, namespace):
        if self.teardown:
            self._run_fixture(self.teardown, output, namespace,
                              self._run_errors.teardown_err)

    def _report_status_after_teardown(self):
        if self._run_errors.teardown_failed():
            self.status = 'FAIL'
            self.message = self._run_errors.get_teardown_message(self.message)
        if self.status == 'PASS' and self.timeout.timed_out():
            self.status = 'FAIL'
            self.message = self.timeout.get_message()
        if self.status == 'FAIL':
            self._suite_errors.test_failed(critical=self.critical=='yes')

    def _not_allowed_to_run(self):
        self.status = 'FAIL'
        self.message = self._run_errors.parent_or_init_error()

    def _end_run(self, output, namespace):
        self.endtime = utils.get_timestamp()
        self.elapsedtime = utils.get_elapsed_time(self.starttime, self.endtime)
        output.end_test(self)
        namespace.end_test()

    def _run_fixture(self, fixture, output, namespace, error_reporter):
        try:
            fixture.run(output, namespace)
        except ExecutionFailed, err:
            self.timeout.set_keyword_timeout(err.timeout)
            self._suite_errors.test_failed(exit=err.exit)
            error_reporter(unicode(err))

class _TestCaseDefaults:

    def __init__(self):
        self.force_tags = []
        self.default_tags = []
        self.test_setup = []
        self.test_teardown = []
        self.test_timeout = []

    def add_defaults(self, suite):
        if suite.force_tags:
            self.force_tags.extend(suite.force_tags)
        if suite.default_tags:
            self.default_tags = suite.default_tags
        if suite.test_setup:
            self.test_setup = suite.test_setup
        if suite.test_teardown:
            self.test_teardown = suite.test_teardown
        if suite.test_timeout:
            self.test_timeout = suite.test_timeout

    def copy(self):
        copy = _TestCaseDefaults()
        copy.force_tags = self.force_tags[:]
        copy.default_tags = self.default_tags[:]
        copy.test_setup = self.test_setup[:]
        copy.test_teardown = self.test_teardown[:]
        copy.test_timeout = self.test_timeout[:]
        return copy
<commit_msg>Cleanup<commit_after>#  Copyright 2008-2009 Nokia Siemens Networks Oyj
#
#  Licensed 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.

from robot import utils
from robot.common import BaseTestSuite, BaseTestCase
from robot.parsing import TestSuiteData
from robot.errors import ExecutionFailed
from robot.variables import GLOBAL_VARIABLES
from robot.output import LOGGER

from fixture import Setup, Teardown
from timeouts import TestTimeout
from keywords import Keywords
from namespace import Namespace
from runerrors import SuiteRunErrors, TestRunErrors
from userkeyword import UserLibrary

def TestSuite(datasources, settings):
    suitedata = TestSuiteData(datasources, settings['SuiteNames'])
    suite = RunnableTestSuite(suitedata)
    suite.set_options(settings)
    return suite

class RunnableTestSuite(BaseTestSuite):

    def __init__(self, data, testdefaults=None, parent=None):
        BaseTestSuite.__init__(self, data.name, data.source, parent)
        self.variables = GLOBAL_VARIABLES.copy()
        self.variables.set_from_variable_table(data.variables)
        self.source = data.source
        self.doc = data.doc or ''
        self.metadata = data.metadata
        self.imports = data.imports
        self.user_keywords = UserLibrary(data.user_keywords)
        self.setup = data.suite_setup or []
        self.teardown = data.suite_teardown or []
        if not testdefaults:
            testdefaults = _TestCaseDefaults()
        testdefaults.add_defaults(data)
        for suite in data.suites:
            RunnableTestSuite(suite, testdefaults.copy(), parent=self)
        for test in data.tests:
            RunnableTestCase(test, testdefaults, parent=self)
        self._run_mode_exit_on_failure = False
        self.exit_requiring_err_occured = False

    def run(self, output, parent=None, errors=None):
        self._start_run(output, parent, errors)
        self._run_setup(output)
        self._run_sub_suites(output)
        self._run_tests(output)
        self._report_status(output)
        self._run_teardown(output)
        self._end_run(output)

    def _start_run(self, output, parent, errors):
        if not errors:
            errors = SuiteRunErrors(self._run_mode_exit_on_failure)
        self._run_errors = errors
        self._run_errors.start_suite()
        self._init_run(parent)
        self._set_variable_dependent_metadata(self.namespace.variables)
        output.start_suite(self)

    def _init_run(self, parent):
        self.status = 'RUNNING'
        self.starttime = utils.get_timestamp()
        self.namespace = Namespace(self, parent)
        self.namespace.variables['${SUITE_NAME}'] = self.longname
        self.namespace.variables['${SUITE_SOURCE}'] = self.source

    def _set_variable_dependent_metadata(self, variables):
        errors = []
        self.doc = variables.replace_meta('Documentation', self.doc, errors)
        self.setup = Setup(variables.replace_meta('Setup', self.setup, errors))
        self.teardown = Teardown(
            variables.replace_meta('Teardown', self.teardown, errors))
        for name, value in self.metadata.items():
            self.metadata[name] = variables.replace_meta(name, value, errors)
        if errors:
            self._run_errors.suite_init_err('Suite initialization failed:\n%s'
                                            % '\n'.join(errors))

    def _run_setup(self, output):
        if self._run_errors.is_suite_setup_allowed():
            self._run_errors.suite_setup_err(self._run_fixture(self.setup, output))

    def _run_teardown(self, output):
        if self._run_errors.is_suite_teardown_allowed():
            td_err = self._run_fixture(self.teardown, output)
            if td_err:
                self.suite_teardown_failed('Suite teardown failed:\n%s' % td_err)

    def _run_fixture(self, fixture, output):
        if fixture:
            try:
                fixture.run(output, self.namespace)
            except ExecutionFailed:
                return utils.get_error_message()
        return None

    def _run_sub_suites(self, output):
        for suite in self.suites:
            suite.run(output, self, self._run_errors)

    def _run_tests(self, output):
        executed_tests = []
        for test in self.tests:
            normname = utils.normalize(test.name)
            if normname in executed_tests:
                LOGGER.warn("Multiple test cases with name '%s' executed in "
                            "test suite '%s'"% (test.name, self.longname))
            executed_tests.append(normname)
            test.run(output, self.namespace, self._run_errors)
            self._set_prev_test_variables(self.namespace.variables, test)

    def _report_status(self, output):
        self.set_status()
        self.message = self._run_errors.suite_error()
        self.namespace.variables['${SUITE_STATUS}'] = self.status
        self.namespace.variables['${SUITE_MESSAGE}'] = self.get_full_message()

    def _end_run(self, output):
        self.endtime = utils.get_timestamp()
        self.elapsedtime = utils.get_elapsed_time(self.starttime, self.endtime)
        self._set_prev_test_variables(GLOBAL_VARIABLES, varz=self.namespace.variables)
        output.end_suite(self)
        self.namespace.end_suite()
        self._run_errors.end_suite()

    def _set_prev_test_variables(self, destination, test=None, varz=None):
        if test:
            name, status, message = test.name, test.status, test.message
        else:
            name, status, message = varz['${PREV_TEST_NAME}'], \
                    varz['${PREV_TEST_STATUS}'], varz['${PREV_TEST_MESSAGE}']
        destination['${PREV_TEST_NAME}'] = name
        destination['${PREV_TEST_STATUS}'] = status
        destination['${PREV_TEST_MESSAGE}'] = message

class RunnableTestCase(BaseTestCase):

    def __init__(self, data, defaults, parent):
        BaseTestCase.__init__(self, data.name, parent)
        self.doc = data.doc or ''
        self.setup = utils.get_not_none(data.setup, defaults.test_setup)
        self.teardown = utils.get_not_none(data.teardown,
                                           defaults.test_teardown)
        self.tags = defaults.force_tags \
                    + utils.get_not_none(data.tags, defaults.default_tags)
        self.timeout = utils.get_not_none(data.timeout, defaults.test_timeout)
        self.keywords = Keywords(data.keywords)
        self.exit_on_failure = False

    def run(self, output, namespace, suite_errors):
        self._suite_errors = suite_errors
        self._start_run(output, namespace)
        if self._run_errors.is_allowed_to_run():
            self._run(output, namespace)
        else:
            self._not_allowed_to_run()
        self._end_run(output, namespace)

    def _start_run(self, output, namespace):
        self._run_errors = TestRunErrors(self._suite_errors)
        self.status = 'RUNNING'
        self.starttime = utils.get_timestamp()
        self._run_errors.init_err(self._init_test(namespace.variables))
        namespace.start_test(self)
        output.start_test(self)

    def _init_test(self, varz):
        errors = []
        self.doc = varz.replace_meta('Documentation', self.doc, errors)
        self.setup = Setup(varz.replace_meta('Setup', self.setup, errors))
        self.teardown = Teardown(
            varz.replace_meta('Teardown', self.teardown, errors))
        self.tags = utils.normalize_tags(
            varz.replace_meta('Tags', self.tags, errors))
        self.timeout = TestTimeout(
            *varz.replace_meta('Timeout', self.timeout, errors))
        if errors:
            return 'Test case initialization failed:\n%s' % '\n'.join(errors)
        if not self.keywords:
            return 'Test case contains no keywords'

    def _run(self, output, namespace):
        self._init_context(namespace)
        self.timeout.start()
        self._run_setup(output, namespace)
        if not self._run_errors.setup_failed():
            try:
                self.keywords.run(output, namespace)
            except ExecutionFailed, err:
                self._run_errors.kw_err(unicode(err))
                self.timeout.set_keyword_timeout(err.timeout)
                self._suite_errors.test_failed(exit=err.exit)
        self._report_status(namespace)
        self._run_teardown(output, namespace)
        self._report_status_after_teardown()

    def _init_context(self, namespace):
        namespace.variables['${TEST_NAME}'] = self.name
        namespace.variables['@{TEST_TAGS}'] = self.tags

    def _run_setup(self, output, namespace):
        if self.setup:
            self._run_fixture(self.setup, output, namespace,
                              self._run_errors.setup_err)

    def _report_status(self, namespace):
        message = self._run_errors.get_message()
        if message:
            self.status = 'FAIL'
            self.message = message
        else:
            self.status = 'PASS'
        namespace.variables['${TEST_MESSAGE}'] = self.message
        namespace.variables['${TEST_STATUS}'] = self.status

    def _run_teardown(self, output, namespace):
        if self.teardown:
            self._run_fixture(self.teardown, output, namespace,
                              self._run_errors.teardown_err)

    def _report_status_after_teardown(self):
        if self._run_errors.teardown_failed():
            self.status = 'FAIL'
            self.message = self._run_errors.get_teardown_message(self.message)
        if self.status == 'PASS' and self.timeout.timed_out():
            self.status = 'FAIL'
            self.message = self.timeout.get_message()
        if self.status == 'FAIL':
            self._suite_errors.test_failed(critical=self.critical=='yes')

    def _not_allowed_to_run(self):
        self.status = 'FAIL'
        self.message = self._run_errors.parent_or_init_error()

    def _end_run(self, output, namespace):
        self.endtime = utils.get_timestamp()
        self.elapsedtime = utils.get_elapsed_time(self.starttime, self.endtime)
        output.end_test(self)
        namespace.end_test()

    def _run_fixture(self, fixture, output, namespace, error_reporter):
        try:
            fixture.run(output, namespace)
        except ExecutionFailed, err:
            self.timeout.set_keyword_timeout(err.timeout)
            self._suite_errors.test_failed(exit=err.exit)
            error_reporter(unicode(err))

class _TestCaseDefaults:

    def __init__(self):
        self.force_tags = []
        self.default_tags = []
        self.test_setup = []
        self.test_teardown = []
        self.test_timeout = []

    def add_defaults(self, suite):
        if suite.force_tags:
            self.force_tags.extend(suite.force_tags)
        if suite.default_tags:
            self.default_tags = suite.default_tags
        if suite.test_setup:
            self.test_setup = suite.test_setup
        if suite.test_teardown:
            self.test_teardown = suite.test_teardown
        if suite.test_timeout:
            self.test_timeout = suite.test_timeout

    def copy(self):
        copy = _TestCaseDefaults()
        copy.force_tags = self.force_tags[:]
        copy.default_tags = self.default_tags[:]
        copy.test_setup = self.test_setup[:]
        copy.test_teardown = self.test_teardown[:]
        copy.test_timeout = self.test_timeout[:]
        return copy
<|endoftext|>


<commit_before>"""
Interface to pygraphviz AGraph class.

Usage

 >>> from networkx import *
 >>> G=complete_graph(5)
 >>> A=to_agraph(G)
 >>> H=from_agraph(A)

"""
__author__ = """Aric Hagberg (hagberg@lanl.gov)"""
#    Copyright (C) 2004-2006 by
#    Aric Hagberg <hagberg@lanl.gov>
#    Dan Schult <dschult@colgate.edu>
#    Pieter Swart <swart@lanl.gov>
#    Distributed under the terms of the GNU Lesser General Public License
#    http://www.gnu.org/copyleft/lesser.html
import os
import sys
from networkx.utils import _get_fh
try:
    import pygraphviz
except ImportError:
    raise

def from_agraph(A,create_using=None):
    """Return a NetworkX XGraph or XDiGraph from a pygraphviz graph.

    >>> X=from_agraph(A)

    The XGraph X will have a dictionary X.graph_attr containing
    the default graphviz attributes for graphs, nodes and edges.

    Default node attributes will be in the dictionary X.node_attr
    which is keyed by node.

    Edge attributes will be returned as edge data in the graph X.

    If you want a Graph with no attributes attached instead of an XGraph
    with attributes use

    >>> G=Graph(X)

    """
    import networkx
    if A.is_strict():
        multiedges=False
        selfloops=False
    else:
        multiedges=True
        selfloops=True

    if create_using is None:
        if A.is_undirected():
            create_using=networkx.XGraph(multiedges=multiedges,
                                         selfloops=selfloops)
        else:
            create_using=networkx.XDiGraph(multiedges=multiedges,
                                           selfloops=selfloops)

    # assign defaults
    N=networkx.empty_graph(0,create_using)
    N.name=str(A)
    node_attr={}
    # add nodes, attributes to N.node_attr
    for n in A.nodes():
        N.add_node(n)
        node_attr[n]=n.attr

    # add edges, attributes attached to edge
    for e in A.edges():
        if len(e)==2:
            u,v=e
        else:
            u,v,k=e
        if hasattr(N,'allow_multiedges')==True: # XGraph
            N.add_edge(u,v,e.attr)
        else: # Graph
            N.add_edge(u,v)

    # add default attributes for graph, nodes, and edges
    # hang them on N.graph_attr
    if hasattr(N,'allow_multiedges')==True: # XGraph
        N.graph_attr={}
        N.graph_attr['graph']=A.graph_attr
        N.graph_attr['node']=A.node_attr
        N.graph_attr['edge']=A.edge_attr
        N.node_attr=node_attr

    return N

def to_agraph(N, graph_attr=None, node_attr=None, edge_attr=None,
              strict=True):
    """Return a pygraphviz graph from a NetworkX graph N.

    If N is a Graph or DiGraph, graphviz attributes can
    be supplied through the arguments

    graph_attr:  dictionary with default attributes for graph, nodes, and edges
                 keyed by 'graph', 'node', and 'edge' to attribute dictionaries

    node_attr: dictionary keyed by node to node attribute dictionary

    edge_attr: dictionary keyed by edge tuple to edge attribute dictionary

    If N is an XGraph or XDiGraph an attempt will be made first
    to copy properties attached to the graph (see from_agraph)
    and then updated with the calling arguments if any.

    """
    directed=N.is_directed()
    if hasattr(N,'allow_multiedges'):
        if N.multiedges:
            strict=False
    if hasattr(N,'allow_selfloops'):
        if N.selfloops:
            strict=False
    A=pygraphviz.AGraph(name=N.name,strict=strict,directed=directed)

    # default graph attributes
    try:
        A.graph_attr.update(N.graph_attr['graph'])
    except:
        pass
    try:
        A.graph_attr.update(graph_attr['graph'])
    except:
        pass
    # default node attributes
    try:
        A.node_attr.update(N.graph_attr['node'])
    except:
        pass
    try:
        A.node_attr.update(graph_attr['node'])
    except:
        pass
    # default edge attributes
    try:
        A.edge_attr.update(N.graph_attr['edge'])
    except:
        pass
    try:
        A.edge_attr.update(graph_attr['edge'])
    except:
        pass

    # add nodes
    for n in N.nodes_iter():
        A.add_node(n)
        node=pygraphviz.Node(A,n)
        # try node attributes attached to graph
        try:
            if n in N.node_attr:
                node.attr.update(N.node_attr[n])
        except:
            pass
        # update with attributes from calling parameters
        try:
            if n in node_attr:
                node.attr.update(node_attr[n])
        except:
            pass

    # loop over edges
    for e in N.edges_iter():
        if len(e)==2:
            (u,v)=e
            data=None
        else:
            (u,v,data)=e

        if data is None: # no data, just add edge
            A.add_edge(u,v)
            edge=pygraphviz.Edge(A,u,v)
        else: # could have list of edge data or single edge data
            try:
                N.allow_multiedges()==True
                dlist=N.get_edge(u,v)
            except:
                dlist=[N.get_edge(u,v)]
            for d in dlist:
                A.add_edge(u,v)
                edge=pygraphviz.Edge(A,u,v)
                if hasattr(d,"__getitem__"):
                    edge.attr.update(d)
        # update from calling argument
        try:  # e might not be hashable
            if (u,v) in edge_attr:
                edge.attr.update(edge_attr[(u,v)])
        except:
            pass

    return A

def write_dot(G,path):
    """Write NetworkX graph G to Graphviz dot format on path.

    Path can be a string or a file handle.
    """
    A=to_agraph(G)
    A.write(path)
    return

def read_dot(path,create_using=None):
    """Return a NetworkX XGraph or XdiGraph from a dot file on path.

    Path can be a string or a file handle.

    """
    A=pygraphviz.AGraph(file=path)
    return from_agraph(A)

def graphviz_layout(G,prog='neato',root=None, args=''):
    """
    Create layout using graphviz.
    Returns a dictionary of positions keyed by node.

    >>> from networkx import *
    >>> G=petersen_graph()
    >>> pos=graphviz_layout(G)
    >>> pos=graphviz_layout(G,prog='dot')

    This is a wrapper for pygraphviz_layout.

    """
    return pygraphviz_layout(G,prog=prog,root=root,args=args)

def pygraphviz_layout(G,prog='neato',root=None, args=''):
    """
    Create layout using pygraphviz and graphviz.
    Returns a dictionary of positions keyed by node.

    >>> from networkx import *
    >>> G=petersen_graph()
    >>> pos=pygraphviz_layout(G)
    >>> pos=pygraphviz_layout(G,prog='dot')

    """
    A=to_agraph(G)
    A.layout(prog=prog,args=args)
    node_pos={}
    for n in G.nodes():
        node=pygraphviz.Node(A,n)
        try:
            xx,yy=node.attr["pos"].split(',')
            node_pos[n]=(float(xx),float(yy))
        except:
            print "no position for node",n
            node_pos[n]=(0.0,0.0)
    return node_pos

def _test_suite():
    import doctest
    suite = doctest.DocFileSuite('tests/drawing/nx_agraph.txt',package='networkx')
    return suite

if __name__ == "__main__":
    import os
    import sys
    import unittest
    if sys.version_info[:2] < (2, 4):
        print "Python version 2.4 or later required for tests (%d.%d detected)." %  sys.version_info[:2]
        sys.exit(-1)
    # directory of networkx package (relative to this)
    nxbase=sys.path[0]+os.sep+os.pardir
    sys.path.insert(0,nxbase) # prepend to search path
    unittest.TextTestRunner().run(_test_suite())

<commit_msg>Modify to_agraph() to make multiedges work.<commit_after>"""
Interface to pygraphviz AGraph class.

Usage

 >>> from networkx import *
 >>> G=complete_graph(5)
 >>> A=to_agraph(G)
 >>> H=from_agraph(A)

"""
__author__ = """Aric Hagberg (hagberg@lanl.gov)"""
#    Copyright (C) 2004-2008 by
#    Aric Hagberg <hagberg@lanl.gov>
#    Dan Schult <dschult@colgate.edu>
#    Pieter Swart <swart@lanl.gov>
#    Distributed under the terms of the GNU Lesser General Public License
#    http://www.gnu.org/copyleft/lesser.html
import os
import sys
from networkx.utils import _get_fh
try:
    import pygraphviz
except ImportError:
    raise

def from_agraph(A,create_using=None):
    """Return a NetworkX XGraph or XDiGraph from a pygraphviz graph.

    >>> X=from_agraph(A)

    The XGraph X will have a dictionary X.graph_attr containing
    the default graphviz attributes for graphs, nodes and edges.

    Default node attributes will be in the dictionary X.node_attr
    which is keyed by node.

    Edge attributes will be returned as edge data in the graph X.

    If you want a Graph with no attributes attached instead of an XGraph
    with attributes use

    >>> G=Graph(X)

    """
    import networkx
    if A.is_strict():
        multiedges=False
        selfloops=False
    else:
        multiedges=True
        selfloops=True

    if create_using is None:
        if A.is_undirected():
            create_using=networkx.XGraph(multiedges=multiedges,
                                         selfloops=selfloops)
        else:
            create_using=networkx.XDiGraph(multiedges=multiedges,
                                           selfloops=selfloops)

    # assign defaults
    N=networkx.empty_graph(0,create_using)
    N.name=str(A)
    node_attr={}
    # add nodes, attributes to N.node_attr
    for n in A.nodes():
        N.add_node(n)
        node_attr[n]=n.attr

    # add edges, attributes attached to edge
    for e in A.edges():
        if len(e)==2:
            u,v=e
        else:
            u,v,k=e
        if hasattr(N,'allow_multiedges')==True: # XGraph
            attr=dict((k,v) for k,v in e.attr.items() if v!='')
            N.add_edge(u,v,attr)
        else: # Graph
            N.add_edge(u,v)

    # add default attributes for graph, nodes, and edges
    # hang them on N.graph_attr
    if hasattr(N,'allow_multiedges')==True: # XGraph
        N.graph_attr={}
        N.graph_attr['graph']=A.graph_attr
        N.graph_attr['node']=A.node_attr
        N.graph_attr['edge']=A.edge_attr
        N.node_attr=node_attr

    return N

def to_agraph(N, graph_attr=None, node_attr=None, strict=True):
    """Return a pygraphviz graph from a NetworkX graph N.

    If N is a Graph or DiGraph, graphviz attributes can
    be supplied through the arguments

    graph_attr:  dictionary with default attributes for graph, nodes, and edges
                 keyed by 'graph', 'node', and 'edge' to attribute dictionaries

    node_attr: dictionary keyed by node to node attribute dictionary

    If N is an XGraph or XDiGraph an attempt will be made first
    to copy properties attached to the graph (see from_agraph)
    and then updated with the calling arguments if any.

    """
    directed=N.is_directed()
    if hasattr(N,'allow_multiedges'):
        if N.multiedges:
            strict=False
    if hasattr(N,'allow_selfloops'):
        if N.selfloops:
            strict=False
    A=pygraphviz.AGraph(name=N.name,strict=strict,directed=directed)

    # default graph attributes
    try:
        A.graph_attr.update(N.graph_attr['graph'])
    except:
        pass
    try:
        A.graph_attr.update(graph_attr['graph'])
    except:
        pass
    # default node attributes
    try:
        A.node_attr.update(N.graph_attr['node'])
    except:
        pass
    try:
        A.node_attr.update(graph_attr['node'])
    except:
        pass
    # default edge attributes
    try:
        A.edge_attr.update(N.graph_attr['edge'])
    except:
        pass
    try:
        A.edge_attr.update(graph_attr['edge'])
    except:
        pass

    # add nodes
    for n in N.nodes_iter():
        A.add_node(n)
        node=pygraphviz.Node(A,n)
        # try node attributes attached to graph
        try:
            if n in N.node_attr:
                node.attr.update(N.node_attr[n])
        except:
            pass
        # update with attributes from calling parameters
        try:
            if n in node_attr:
                node.attr.update(node_attr[n])
        except:
            pass

    # loop over edges
    for e in N.edges_iter():
        if len(e)==2:
            (u,v)=e
            d=None
        else:
            (u,v,d)=e

        if d is None:
            # no data, just add edge
            A.add_edge(u,v)
        else:
            if hasattr(d,"__getitem__"):
                # edge data is dictionary-like, treat it as attributes
                # check for user assigned key
                if 'key' in d:
                    key=d['key']
                    del d['key']
                else:
                    key=str(d)
                data=d
            else:
                # edge data is some other object
                key=str(d)
                data={'data':key}
            A.add_edge(u,v,key=key,**data)
            edge=pygraphviz.Edge(A,u,v,key)

    return A

def write_dot(G,path):
    """Write NetworkX graph G to Graphviz dot format on path.

    Path can be a string or a file handle.
    """
    A=to_agraph(G)
    A.write(path)
    return

def read_dot(path,create_using=None):
    """Return a NetworkX XGraph or XdiGraph from a dot file on path.

    Path can be a string or a file handle.

    """
    A=pygraphviz.AGraph(file=path)
    return from_agraph(A)

def graphviz_layout(G,prog='neato',root=None, args=''):
    """
    Create layout using graphviz.
    Returns a dictionary of positions keyed by node.

    >>> from networkx import *
    >>> G=petersen_graph()
    >>> pos=graphviz_layout(G)
    >>> pos=graphviz_layout(G,prog='dot')

    This is a wrapper for pygraphviz_layout.

    """
    return pygraphviz_layout(G,prog=prog,root=root,args=args)

def pygraphviz_layout(G,prog='neato',root=None, args=''):
    """
    Create layout using pygraphviz and graphviz.
    Returns a dictionary of positions keyed by node.

    >>> from networkx import *
    >>> G=petersen_graph()
    >>> pos=pygraphviz_layout(G)
    >>> pos=pygraphviz_layout(G,prog='dot')

    """
    A=to_agraph(G)
    A.layout(prog=prog,args=args)
    node_pos={}
    for n in G.nodes():
        node=pygraphviz.Node(A,n)
        try:
            xx,yy=node.attr["pos"].split(',')
            node_pos[n]=(float(xx),float(yy))
        except:
            print "no position for node",n
            node_pos[n]=(0.0,0.0)
    return node_pos

def _test_suite():
    import doctest
    suite = doctest.DocFileSuite('tests/drawing/nx_agraph.txt',package='networkx')
    return suite

if __name__ == "__main__":
    import os
    import sys
    import unittest
    if sys.version_info[:2] < (2, 4):
        print "Python version 2.4 or later required for tests (%d.%d detected)." %  sys.version_info[:2]
        sys.exit(-1)
    # directory of networkx package (relative to this)
    nxbase=sys.path[0]+os.sep+os.pardir
    sys.path.insert(0,nxbase) # prepend to search path
    unittest.TextTestRunner().run(_test_suite())

<|endoftext|>


<commit_before>import deepchem as dc
import tensorflow as tensorflow
from deepchem.models.tensorgraph.layers import Layer,Input,Dense,Hingeloss,Label,Feature
from deepchem.models.tensorgraph.layers import ReduceMean,InputFifoQueue,ReLU

class Scscore(TensorGraph):
	tg=dc.models.TensorGraph(tensorboard=True, model_dir='/tmp/scscore',use_queue=True)

	Input1=InputFifoQueue()

	hidden_1=Dense(out_channels=300,in_layer=Input1,activation_fn=tf.nn.relu)
	hidden_2=Dense(out_channels=300,in_layer=hidden_1,activation_fn=tf.nn.relu)
	hidden_3=Dense(out_channels=300,in_layer=hidden_2,activation_fn=tf.nn.relu)
	hidden_4=Dense(out_channels=300,in_layer=hidden_3,activation_fn=tf.nn.relu)
	hidden_5=Dense(out_channels=300,in_layer=hidden_4,activation_fn=tf.nn.relu)

	label=Label(shape=(300,))

	loss=Hingeloss(in_layers=[label,hidden_5])
	tg.set_loss(loss)
	output=Sigmoid(in_layers=[hidden_5])
	tg.add_output(output)<commit_msg>adding scscore<commit_after>import deepchem as dc
import tensorflow as tensorflow
from deepchem.models.tensorgraph.layers import Layer, Input, Dense, Hingeloss, Label, Feature
from deepchem.models.tensorgraph.layers import ReduceMean, InputFifoQueue, ReLU

class Scscore(TensorGraph):
  tg = dc.models.TensorGraph(
      tensorboard=True, model_dir='/tmp/scscore', use_queue=True)

  Input1 = InputFifoQueue()

  hidden_1 = Dense(out_channels=300, in_layer=Input1, activation_fn=tf.nn.relu)
  hidden_2 = Dense(
      out_channels=300, in_layer=hidden_1, activation_fn=tf.nn.relu)
  hidden_3 = Dense(
      out_channels=300, in_layer=hidden_2, activation_fn=tf.nn.relu)
  hidden_4 = Dense(
      out_channels=300, in_layer=hidden_3, activation_fn=tf.nn.relu)
  hidden_5 = Dense(
      out_channels=300, in_layer=hidden_4, activation_fn=tf.nn.relu)

  label = Label(shape=(300,))

  loss = Hingeloss(in_layers=[label, hidden_5])
  tg.set_loss(loss)
  output = Sigmoid(in_layers=[hidden_5])
  tg.add_output(output)
<|endoftext|>


<commit_before>__title__ = 'vcspull'
__package_name__ = 'vcspull'
__description__ = 'Manage git, mercurial and svn repositories through CLI. Configure with JSON / YAML files.'
__version__ = '0.2.2'
__author__ = 'Tony Narlock'
__email__ = 'tony@git-pull.com'
__license__ = 'BSD'
__copyright__ = 'Copyright 2013-2015 Tony Narlock'
<commit_msg>Update copyright year<commit_after>__title__ = 'vcspull'
__package_name__ = 'vcspull'
__description__ = 'Manage git, mercurial and svn repositories through CLI. Configure with JSON / YAML files.'
__version__ = '0.2.2'
__author__ = 'Tony Narlock'
__email__ = 'tony@git-pull.com'
__license__ = 'BSD'
__copyright__ = 'Copyright 2013-2016 Tony Narlock'
<|endoftext|>