#!/usr/bin/env python

from slickqa import SlickQA, ResultStatus, RunStatus
import datetime
import time

slick = SlickQA('http://localhost:8080', 'EP', '10.7', '5', 'My Testplan', environment_name='Example', test_run_group_name='example.py testruns')

results = []
results.append(slick.file_result("First Test", status=ResultStatus.NO_RESULT, runstatus=RunStatus.TO_BE_RUN))
results.append(slick.file_result("Second Test", status=ResultStatus.NO_RESULT, runstatus=RunStatus.TO_BE_RUN))
results.append(slick.file_result("Third Test", status=ResultStatus.NO_RESULT, runstatus=RunStatus.TO_BE_RUN))
results.append(slick.file_result("Fourth Test", status=ResultStatus.NO_RESULT, runstatus=RunStatus.TO_BE_RUN))
results.append(slick.file_result("Fifth Test", status=ResultStatus.NO_RESULT, runstatus=RunStatus.TO_BE_RUN))

# Now to run the tests

for result in results:
    result.started = datetime.datetime.now()
    result.runstatus = RunStatus.RUNNING

    # this updates slick with those properties we just set
    result.update()

    # pretend the test is running
    time.sleep(10)

    # add a log entry (will not automatically update the result in slick)
    result.add_log_entry("Log Entry, isn't it nice?", level="INFO", loggername="example.test")
    result.add_log_entry("Log Entry, isn't it nice?", level="ERROR", loggername="example.test")
    assert(isinstance(config, Configuration))
    print("\t Name: " + config.name + ", type: " + config.configurationType + ", id: " + config.id)

configs = slick.configurations.find(ConfigurationQuery(configurationType="ENVIRONMENT"))

print("\nThere are " + str(len(configs)) + " ENVIRONMENT configurations in slick:\n")
for config in configs:
    assert(isinstance(config, Configuration))
    print("\t Name: " + config.name + ", type: " + config.configurationType + ", filename: " + config.filename + ", id: " + config.id)

proj = slick.projects.findByName("Slickij Developer Project")
print("\nFound Project '%s' with %d components." % (proj.name, len(proj.components)))

# sample of how to use the higher level api
# this is good if you just need to shove the results up to slick and don't need to do anything tricky
slick_kahn = SlickQA(url, "test1", "1.0", "311", 'Smoke', 'smoky the bear')
if slick_kahn.is_connected:
    slick_kahn.add_log_entry("One message")
    slick_kahn.add_log_entry("two message")
    slick_kahn.file_result("tc1", ResultStatus.PASS, "I wanted it to pass", 2)
    slick_kahn.add_log_entry("new message")
    slick_kahn.add_log_entry("few message")
    slick_kahn.add_log_entry("dew message")
    slick_kahn.file_result("tc2", ResultStatus.FAIL, "I said FAIL!", 5)
    slick_kahn.add_log_entry("the sky is falling")
    slick_kahn.add_log_entry("so is my hair")
    slick_kahn.file_result("tc3", ResultStatus.SKIPPED, "darn straight Skippy!", 11)
    slick_kahn.add_log_entry("1")
    slick_kahn.add_log_entry("2")
    slick_kahn.add_log_entry("3")
    slick_kahn.add_log_entry("4")
Exemple #3
0
 def configure(self, options, conf):
     super(SlickAsSnotPlugin, self).configure(options, conf)
     global config, testrun
     assert isinstance(conf, nose.config.Config)
     if options.files is not None and len(options.files) > 0:
         config = parse_config(options.files)
     if not self.enabled:
         return
     self.use_existing_testrun = False
     if (
         hasattr(options, "slick_testrun_id")
         and hasattr(options, "slick_result_id")
         and options.slick_testrun_id is not None
         and options.slick_result_id is not None
     ):
         self.use_existing_testrun = True
         self.testrun_id = options.slick_testrun_id
         self.result_id = options.slick_result_id
     else:
         for required in ["slick_url", "slick_project_name"]:
             if (
                 (not hasattr(options, required))
                 or getattr(options, required) is None
                 or getattr(options, required) == ""
             ):
                 log.error("You can't use snot without specifying at least the slick url and the project name.")
                 self.enabled = False
                 return
     self.url = options.slick_url
     self.project_name = options.slick_project_name
     self.release = options.slick_release
     self.build = options.slick_build
     self.build_function = options.slick_build_from_function
     if self.build_function:
         try:
             self.build = call_function(self.build_function)
         except:
             log.warn(
                 "Problem occured calling build information from '%s': ",
                 self.build_function,
                 exc_info=sys.exc_info(),
             )
     self.testplan = options.slick_testplan
     self.testrun_name = options.slick_testrun_name
     self.environment_name = options.slick_environment_name
     self.testrun_group = options.slick_testrun_group
     self.mode = options.slick_mode
     self.requirement_add = options.requirement_add
     self.agent_name = options.slick_agent_name
     testrun = None
     if self.use_existing_testrun:
         self.slick = SlickConnection(self.url)
         testrun = self.slick.testruns(options.slick_testrun_id).get()
         make_testrun_updatable(testrun, self.slick)
     else:
         self.slick = SlickQA(
             self.url,
             self.project_name,
             self.release,
             self.build,
             self.testplan,
             self.testrun_name,
             self.environment_name,
             self.testrun_group,
         )
         testrun = self.slick.testrun
         if self.mode == "schedule":
             testrun.attributes = {"scheduled": "true"}
             testrun.update()
     self.new_requires = options.new_requires
     root_logger = logging.getLogger()
     self.loghandler = LogCapturingHandler()
     root_logger.addHandler(self.loghandler)
     root_logger.setLevel(logging.DEBUG)
Exemple #4
0
class SlickAsSnotPlugin(nose.plugins.Plugin):
    name = "snot"
    score = 1800

    def options(self, parser, env=os.environ):
        super(SlickAsSnotPlugin, self).options(parser, env=env)
        parser.add_option(
            "--slick-url",
            action="store",
            default=env.get("SLICK_URL"),
            metavar="SLICK_URL",
            dest="slick_url",
            help="the base url of the slick web app [SLICK_URL]",
        )
        parser.add_option(
            "--slick-project-name",
            action="store",
            default=env.get("SLICK_PROJECT_NAME"),
            metavar="SLICK_PROJECT_NAME",
            dest="slick_project_name",
            help="the name of the project in slick to use [SLICK_PROJECT_NAME]",
        )
        parser.add_option(
            "--slick-release",
            action="store",
            default=env.get("SLICK_RELEASE"),
            metavar="SLICK_RELEASE",
            dest="slick_release",
            help="the release under which to file the results in slick [SLICK_RELEASE]",
        )
        parser.add_option(
            "--slick-build",
            action="store",
            default=env.get("SLICK_BUILD"),
            metavar="SLICK_BUILD",
            dest="slick_build",
            help="the build under which to file the results in slick [SLICK_BUILD]",
        )
        parser.add_option(
            "--slick-build-from-function",
            action="store",
            default=env.get("SLICK_BUILD_FROM_FUNCTION"),
            metavar="SLICK_BUILD_FROM_FUNCTION",
            dest="slick_build_from_function",
            help="get the slick build from a function.  The parameter should be the module and function name to call [SLICK_BUILD_FROM_FUNCTION].",
        )
        parser.add_option(
            "--slick-testplan",
            action="store",
            default=env.get("SLICK_TESTPLAN"),
            metavar="SLICK_TESTPLAN",
            dest="slick_testplan",
            help="the testplan to link the testrun to in slick [SLICK_TESTPLAN]",
        )
        parser.add_option(
            "--slick-testrun-name",
            action="store",
            default=env.get("SLICK_TESTRUN_NAME"),
            metavar="SLICK_TESTRUN_NAME",
            dest="slick_testrun_name",
            help="the name of the testrun to create in slick [SLICK_TESTRUN_NAME]",
        )
        parser.add_option(
            "--slick-environment-name",
            action="store",
            default=env.get("SLICK_ENVIRONMENT_NAME"),
            metavar="SLICK_ENVIRONMENT_NAME",
            dest="slick_environment_name",
            help="the name of the environment in slick to use in the testrun [SLICK_ENVIRONMENT_NAME]",
        )
        parser.add_option(
            "--slick-testrun-group",
            action="store",
            default=env.get("SLICK_TESTRUN_GROUP"),
            metavar="SLICK_TESTRUN_GROUP",
            dest="slick_testrun_group",
            help="the name of the testrun group in slick to add this testrun to (optional) [SLICK_ENVIRONMENT_NAME]",
        )
        parser.add_option(
            "--slick-agent-name",
            action="store",
            default=env.get("SLICK_AGENT_NAME"),
            metavar="SLICK_AGENT_NAME",
            dest="slick_agent_name",
            help="what to put in slick's hostname field in the result.",
        )
        schedule_results_default = "normal"
        if "SLICK_SCHEDULE_RESULTS" in env:
            schedule_results_default = "schedule"
        parser.add_option(
            "--slick-schedule-results",
            action="store_const",
            const="schedule",
            default=schedule_results_default,
            metavar="SLICK_SCHEDULE_RESULTS",
            dest="slick_mode",
            help="Schedule empty results in slick, but do not run the tests",
        )
        parser.add_option(
            "--slick-schedule-add-requirement",
            action="store",
            default=env.get("SLICK_SCHEDULE_ADD_REQUIREMENT"),
            metavar="SLICK_SCHEDULE_ADD_REQUIREMENT",
            dest="requirement_add",
            help="Add a requirement to all results when scheduling.",
        )
        parser.add_option(
            "--slick-schedule-new-requires",
            action="store_true",
            dest="new_requires",
            help="apply the requires directly on the result as an attribute.",
        )
        parser.add_option(
            "--slick-testrun-id",
            action="store",
            default=env.get("SLICK_TESTRUN_ID"),
            metavar="SLICK_TESTRUN_ID",
            dest="slick_testrun_id",
            help="Instead of creating a new testrun, use an existing one.",
        )
        parser.add_option(
            "--slick-result-id",
            action="store",
            default=env.get("SLICK_RESULT_ID"),
            metavar="SLICK_RESULT_ID",
            dest="slick_result_id",
            help="Instead of creating a new result in the testrun, update an existing one.",
        )

        # Make sure the log capture doesn't show slick related logging statements
        if "NOSE_LOGFILTER" in env:
            env["NOSE_LOGFILTER"] = env.get("NOSE_LOGFILTER") + ",-slick,-requests,-slick-reporter"
        else:
            env["NOSE_LOGFILTER"] = "-slick,-requests,-slick-reporter"

    def configure(self, options, conf):
        super(SlickAsSnotPlugin, self).configure(options, conf)
        global config, testrun
        assert isinstance(conf, nose.config.Config)
        if options.files is not None and len(options.files) > 0:
            config = parse_config(options.files)
        if not self.enabled:
            return
        self.use_existing_testrun = False
        if (
            hasattr(options, "slick_testrun_id")
            and hasattr(options, "slick_result_id")
            and options.slick_testrun_id is not None
            and options.slick_result_id is not None
        ):
            self.use_existing_testrun = True
            self.testrun_id = options.slick_testrun_id
            self.result_id = options.slick_result_id
        else:
            for required in ["slick_url", "slick_project_name"]:
                if (
                    (not hasattr(options, required))
                    or getattr(options, required) is None
                    or getattr(options, required) == ""
                ):
                    log.error("You can't use snot without specifying at least the slick url and the project name.")
                    self.enabled = False
                    return
        self.url = options.slick_url
        self.project_name = options.slick_project_name
        self.release = options.slick_release
        self.build = options.slick_build
        self.build_function = options.slick_build_from_function
        if self.build_function:
            try:
                self.build = call_function(self.build_function)
            except:
                log.warn(
                    "Problem occured calling build information from '%s': ",
                    self.build_function,
                    exc_info=sys.exc_info(),
                )
        self.testplan = options.slick_testplan
        self.testrun_name = options.slick_testrun_name
        self.environment_name = options.slick_environment_name
        self.testrun_group = options.slick_testrun_group
        self.mode = options.slick_mode
        self.requirement_add = options.requirement_add
        self.agent_name = options.slick_agent_name
        testrun = None
        if self.use_existing_testrun:
            self.slick = SlickConnection(self.url)
            testrun = self.slick.testruns(options.slick_testrun_id).get()
            make_testrun_updatable(testrun, self.slick)
        else:
            self.slick = SlickQA(
                self.url,
                self.project_name,
                self.release,
                self.build,
                self.testplan,
                self.testrun_name,
                self.environment_name,
                self.testrun_group,
            )
            testrun = self.slick.testrun
            if self.mode == "schedule":
                testrun.attributes = {"scheduled": "true"}
                testrun.update()
        self.new_requires = options.new_requires
        root_logger = logging.getLogger()
        self.loghandler = LogCapturingHandler()
        root_logger.addHandler(self.loghandler)
        root_logger.setLevel(logging.DEBUG)

    def prepareTest(self, testsuite):
        if not self.enabled:
            return
        self.results = dict()
        for test in get_tests(testsuite):
            assert isinstance(test, nose.case.Test)
            if self.use_existing_testrun:
                result = self.slick.results(self.result_id).get()
                make_result_updatable(result, self.slick)
                self.results[test.id()] = result
            else:
                testmethod = test.test._testMethodName
                if testmethod == "runTest" and hasattr(test.test, "test"):
                    testmethod = "test"

                testdata = DocStringMetaData(getattr(test.test, testmethod))
                if not hasattr(testdata, "automationId"):
                    testdata.automationId = test.id()
                if not hasattr(testdata, "automationTool"):
                    testdata.automationTool = "python-nose"
                if not hasattr(testdata, "automationKey"):
                    # build key
                    address = list(test.address())
                    testfile = os.path.relpath(address[0])
                    module_name = os.path.basename(address[0])[:-3]
                    if module_name == address[1]:
                        address.pop(1)
                    testdata.automationKey = "{0}:{1}".format(testfile, address[1])
                    if len(address) > 2:
                        try:
                            testdata.automationKey = ".".join([testdata.automationKey] + address[2:])
                        except:
                            pass
                slicktest = Testcase()
                slicktest.name = testdata.name
                if (
                    "{" in testdata.name
                    and "}" in testdata.name
                    and hasattr(test.test, "arg")
                    and test.test.arg is not None
                    and len(test.test.arg) > 0
                ):
                    slicktest.name = testdata.name.format(*test.test.arg)
                slicktest.automationId = testdata.automationId
                slicktest.automationTool = testdata.automationTool
                result_attributes = {}
                requirements = None
                if self.mode == "schedule" and self.requirement_add is not None and self.requirement_add != "":
                    result_attributes[self.requirement_add] = "required"
                    if self.new_requires:
                        requirements = [self.requirement_add]
                try:
                    actual_test_method = getattr(test.test, testmethod)
                    if hasattr(actual_test_method, REQUIRES_ATTRIBUTE):
                        requires_value = getattr(actual_test_method, REQUIRES_ATTRIBUTE)
                        if self.new_requires:
                            if requirements is None:
                                requirements = []
                            requirements.extend(requires_value)
                        for requirement in requires_value:
                            result_attributes[requirement] = "required"
                except:
                    log.error("Error occurred while trying to build attributes.", exc_info=sys.exc_info)
                if self.mode == "schedule":
                    result_attributes["scheduled"] = "true"
                try:
                    for attribute in [
                        "automationConfiguration",
                        "automationKey",
                        "author",
                        "purpose",
                        "requirements",
                        "tags",
                    ]:
                        if (
                            attribute is not None
                            and hasattr(testdata, attribute)
                            and getattr(testdata, attribute) is not None
                        ):
                            data = getattr(testdata, attribute)
                            if "{" in data and "}" in data and test.test.arg is not None and len(test.test.arg) > 0:
                                data = data.format(*test.test.arg)
                            setattr(slicktest, attribute, data)
                    slicktest.project = self.slick.project.create_reference()
                    if hasattr(testdata, "component"):
                        comp_name = testdata.component
                        if (
                            comp_name is not None
                            and "{" in comp_name
                            and "}" in comp_name
                            and hasattr(test.test, "arg")
                            and test.test.arg is not None
                            and len(test.test.arg) > 0
                        ):
                            comp_name = comp_name.format(*test.test.arg)
                        component = self.slick.get_component(comp_name)
                        if component is None:
                            component = self.slick.create_component(comp_name)
                        slicktest.component = component.create_reference()
                    if hasattr(testdata, "steps"):
                        slicktest.steps = []
                        for step in testdata.steps:
                            slickstep = Step()
                            slickstep.name = step
                            if (
                                step is not None
                                and "{" in step
                                and "}" in step
                                and test.test.arg is not None
                                and len(test.test.arg) > 0
                            ):
                                slickstep.name = step.format(*test.test.arg)
                            if hasattr(testdata, "expectedResults") and len(testdata.expectedResults) > len(
                                slicktest.steps
                            ):
                                expectedResult = testdata.expectedResults[len(slicktest.steps)]
                                slickstep.expectedResult = expectedResult
                                if (
                                    expectedResult is not None
                                    and "{" in expectedResult
                                    and "}" in expectedResult
                                    and test.test.arg is not None
                                    and len(test.test.arg) > 0
                                ):
                                    slickstep.expectedResult = expectedResult.format(*test.test.arg)
                            slicktest.steps.append(slickstep)
                except:
                    log.error("Error occured when parsing for test {}:".format(test.id()), exc_info=sys.exc_info())
                runstatus = RunStatus.TO_BE_RUN
                if self.mode == "schedule":
                    runstatus = RunStatus.SCHEDULED
                if requirements is not None:
                    requirements.sort()
                self.results[test.id()] = self.slick.file_result(
                    slicktest.name,
                    ResultStatus.NO_RESULT,
                    reason="not yet run",
                    runlength=0,
                    testdata=slicktest,
                    runstatus=runstatus,
                    attributes=result_attributes,
                    requires=requirements,
                )
        if self.enabled and self.mode == "schedule":
            sys.exit(0)

    def beforeTest(self, test):
        if not self.enabled:
            return
        if self.mode == "schedule":
            raise SkipTest()

    def startTest(self, test):
        if not self.enabled:
            return
        if test.id() in self.results:
            result = self.results[test.id()]
            assert isinstance(result, Result)
            if self.agent_name is not None:
                result.hostname = self.agent_name
            result.runstatus = RunStatus.RUNNING
            result.started = datetime.datetime.now()
            result.reason = ""
            if hasattr(result, "config") and not hasattr(result.config, "configId"):
                del result.config
            if hasattr(result, "component") and not hasattr(result.component, "id"):
                del result.component
            result.update()
            global current_result
            current_result = result

    def afterTest(self, test):
        """Clear capture buffer.
        """
        if (
            hasattr(sys.stdout, "__class__")
            and hasattr(sys.stdout.__class__, "__name__")
            and sys.stdout.__class__.__name__ == "StringIO"
        ):
            add_file("Nose Capture.txt", sys.stdout)

    def addSlickResult(self, test, resultstatus=ResultStatus.PASS, err=None):
        if not self.enabled:
            return
        if self.mode == "schedule":
            sys.exit(0)
            return
        if test.id() in self.results:
            result = self.results[test.id()]
            assert isinstance(result, Result)
            result.runstatus = RunStatus.FINISHED
            result.status = resultstatus
            result.finished = datetime.datetime.now()
            result.runlength = int((result.finished - result.started).total_seconds() * 1000)
            if err is not None:
                # log capture and stderr/stdout capture are appended to the message.  We don't want those showing up
                # in the reason
                reason_lines = None
                if sys.version_info[0] == 2:
                    reason_lines = traceback.format_exception(*err)
                else:
                    reason_lines = traceback.format_exception(*err, chain=not isinstance(err[1], str))
                message_parts = reason_lines[-1].split("\n")
                reason_lines[-1] = message_parts[0]
                capture = None
                if len(message_parts) > 2:
                    capture = "\n".join(message_parts[1:])
                    reason_lines.reverse()
                result.reason = "\n".join(reason_lines)

            if hasattr(result, "config") and not hasattr(result.config, "configId"):
                del result.config
            if hasattr(result, "component") and not hasattr(result.component, "id"):
                del result.component
            result.update()
        else:
            log.error("Unrecognized test %s", test.id())

    def addSuccess(self, test):
        if not self.enabled:
            return
        if self.mode == "schedule":
            sys.exit(0)
            return
        self.addSlickResult(test)

    def addError(self, test, err):
        if not self.enabled:
            return
        if self.mode == "schedule":
            sys.exit(0)
            return
        if err[0] is SkipTest:
            self.addSlickResult(test, ResultStatus.SKIPPED, err)
        elif err[0] is PassedOnRetry:
            self.addSlickResult(test, ResultStatus.PASSED_ON_RETRY, err)
        else:
            self.addSlickResult(test, ResultStatus.BROKEN_TEST, err)

    def addFailure(self, test, err):
        if not self.enabled:
            return
        if self.mode == "schedule":
            sys.exit(0)
            return
        self.addSlickResult(test, ResultStatus.FAIL, err)

    def finalize(self, result):
        global testrun
        if not self.enabled or self.mode == "schedule":
            return
        elif self.use_existing_testrun:
            testrun = self.slick.testruns(testrun.id).get()
            if testrun.resultsByStatus.NO_RESULT == 0:
                # finish testrun
                testrun.runFinished = int(round(time.time() * 1000))
                testrun.state = RunStatus.FINISHED
                self.slick.testruns(testrun).update()
        self.slick.finish_testrun()
#!/usr/bin/env python

from slickqa import SlickQA, ResultStatus, RunStatus
import datetime
import time

slick = SlickQA('http://localhost:8080',
                'EP',
                '10.7',
                '5',
                'My Testplan',
                environment_name='Example',
                test_run_group_name='example.py testruns')

results = []
results.append(
    slick.file_result("First Test",
                      status=ResultStatus.NO_RESULT,
                      runstatus=RunStatus.TO_BE_RUN))
results.append(
    slick.file_result("Second Test",
                      status=ResultStatus.NO_RESULT,
                      runstatus=RunStatus.TO_BE_RUN))
results.append(
    slick.file_result("Third Test",
                      status=ResultStatus.NO_RESULT,
                      runstatus=RunStatus.TO_BE_RUN))
results.append(
    slick.file_result("Fourth Test",
                      status=ResultStatus.NO_RESULT,
                      runstatus=RunStatus.TO_BE_RUN))
Exemple #6
0
    ConfigurationQuery(configurationType="ENVIRONMENT"))

print("\nThere are " + str(len(configs)) +
      " ENVIRONMENT configurations in slick:\n")
for config in configs:
    assert (isinstance(config, Configuration))
    print("\t Name: " + config.name + ", type: " + config.configurationType +
          ", filename: " + config.filename + ", id: " + config.id)

proj = slick.projects.findByName("Slickij Developer Project")
print("\nFound Project '%s' with %d components." %
      (proj.name, len(proj.components)))

# sample of how to use the higher level api
# this is good if you just need to shove the results up to slick and don't need to do anything tricky
slick_kahn = SlickQA(url, "test1", "1.0", "311", 'Smoke', 'smoky the bear')
if slick_kahn.is_connected:
    slick_kahn.add_log_entry("One message")
    slick_kahn.add_log_entry("two message")
    slick_kahn.file_result("tc1", ResultStatus.PASS, "I wanted it to pass", 2)
    slick_kahn.add_log_entry("new message")
    slick_kahn.add_log_entry("few message")
    slick_kahn.add_log_entry("dew message")
    slick_kahn.file_result("tc2", ResultStatus.FAIL, "I said FAIL!", 5)
    slick_kahn.add_log_entry("the sky is falling")
    slick_kahn.add_log_entry("so is my hair")
    slick_kahn.file_result("tc3", ResultStatus.SKIPPED,
                           "darn straight Skippy!", 11)
    slick_kahn.add_log_entry("1")
    slick_kahn.add_log_entry("2")
    slick_kahn.add_log_entry("3")