summaryrefslogtreecommitdiffstats
path: root/docker/Dockerfile.centos7
blob: f9b944fe1e8b832ff269743d9fa4d87f9d596f5a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
##############################################################################
# Copyright (c) 2019 opnfv.
#
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Apache License, Version 2.0
# which accompanies this distribution, and is available at
# http://www.apache.org/licenses/LICENSE-2.0
##############################################################################

FROM centos:centos7
MAINTAINER Tomofumi Hayashi <tohayash@redhat.com>
LABEL version="0.1" description="OPNFV Dovetail Docker Container"

ARG BRANCH=master

RUN yum update -y && yum install -y sudo iproute epel-release && \
        yum install -y python3-pip git docker && \
        sed -ie 's/requiretty/!requiretty/g' /etc/sudoers

ENV HOME /home/opnfv
ENV REPOS_DIR ${HOME}/dovetail
WORKDIR /home/opnfv

RUN git config --global http.sslVerify false && \
    git clone --depth 1 -b $BRANCH https://git.opnfv.org/dovetail ${REPOS_DIR} && \
    pip3 install -U pip3 && \
    pip3 install -r ${REPOS_DIR}/requirements.txt && \
    pip3 install -e . && \
    mkdir -p ${REPOS_DIR}/results

WORKDIR ${REPOS_DIR}/dovetail
a0000 } /* Generic.Traceback */ .highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */ .highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */ .highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */ .highlight .kp { color: #008800 } /* Keyword.Pseudo */ .highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */ .highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */ .highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */ .highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */ .highlight .na { color: #336699 } /* Name.Attribute */ .highlight .nb { color: #003388 } /* Name.Builtin */ .highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ .highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ .highlight .nd { color: #555555 } /* Name.Decorator */ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
#!/usr/bin/env python
#
# grakiss.wanglei@huawei.com
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Apache License, Version 2.0
# which accompanies this distribution, and is available at
# http://www.apache.org/licenses/LICENSE-2.0
#
import json
import urllib2
import re

import utils.dovetail_logger as dt_logger
import utils.dovetail_utils as dt_utils

from conf.dovetail_config import *
from testcase import *

logger = dt_logger.Logger('report.py').getLogger()

def get_pass_str(passed):
    if passed:
        return 'PASS'
    else:
        return 'FAIL'

class Report:

    results = {'functest':{},'yardstick':{}}

    @classmethod
    def check_result(cls, testcase, db_result):
        checker = CheckerFactory.create(testcase.script_type())
        checker.check(testcase, db_result)

    @classmethod
    def generate(cls, scenario_yaml):
        report = ''

        report += '\n\
+=============================================================================+\n\
|                                   report                                    | \n\
+-----------------------------------------------------------------------------+\n'
        report += '|scenario: %s\n' % scenario_yaml['name']
        for testcase_name in scenario_yaml['testcase_list']:
            testcase = Testcase.get(testcase_name)
            report += '|   [testcase]: %s\t\t\t\t[%s]\n' % (testcase_name, get_pass_str(testcase.passed()))
            report += '|   |-objective: %s\n' % testcase.objective()
            if testcase.sub_testcase() is not None:
                for subtest in testcase.sub_testcase():
                    report += '|       |-%s \t\t [%s]\n' % (subtest, get_pass_str(testcase.sub_testcase_passed(subtest)))
            report += '+-----------------------------------------------------------------------------+\n'

        logger.info(report)
        cls.save(report)
        return report

    #save to disk as default
    @classmethod
    def save(cls, report):
        report_file_path = dovetail_config['report_file']
        try:
            with open(os.path.join(dovetail_config['result_dir'], report_file_path),'w') as report_file:
                report_file.write(report)
            logger.info('save report to %s' % report_file_path)
        except Exception as e:
            logger.error('Failed to save: %s' % report_file_path)

    @classmethod
    def get_result(cls, testcase):
        script_testcase = testcase.script_testcase()
        type = testcase.script_type()
        crawler = CrawlerFactory.create(type)

        if script_testcase in cls.results[type]:
            return cls.results[type][script_testcase]

        result = crawler.crawl(script_testcase)

        if result is not None:
            cls.results[type][script_testcase] = result
            testcase.script_result_acquired(True)
            logger.debug('testcase: %s -> result acquired' % script_testcase)
        else:
            retry = testcase.increase_retry()
            logger.debug('testcase: %s -> result acquired retry:%d' % (script_testcase, retry))
        return result

class CrawlerFactory:

    @classmethod
    def create(cls, type):
        if type == 'functest':
            return FunctestCrawler()

        if type == 'yardstick':
            return YardstickCrawler()

        return None

class FunctestCrawler:

    def __init__(self):
        self.type = 'functest'

    def crawl(self, testcase=None):
        store_type = dovetail_config[self.type]['result']['store_type']
        if store_type == 'file':
            return self.crawl_from_file(testcase)

        if store_type == 'url':
            return self.crawl_from_url(testcase)

    def crawl_from_file(self, testcase=None):
        file_path = os.path.join(dovetail_config['result_dir'],dovetail_config[self.type]['result']['file_path'])
        if not os.path.exists(file_path):
            logger.info('result file not found: %s' % file_path)
            return None

        try:
            with open(file_path, 'r') as myfile:
                output = myfile.read()
            error_logs = ""

            for match in re.findall('(.*?)[. ]*FAILED', output):
                error_logs += match

            criteria = 'PASS'
            failed_num = int(re.findall(' - Failed: (\d*)', output)[0])
            if failed_num != 0:
                criteria = 'FAIL'

            match =  re.findall('Ran: (\d*) tests in (\d*)\.\d* sec.', output)
            num_tests, dur_sec_int = match[0]
            json_results = {'criteria':criteria,'details':{"timestart": '', "duration": int(dur_sec_int),
                            "tests": int(num_tests), "failures": failed_num,
                            "errors": error_logs}}
            logger.debug('Results: %s' % str(json_results))
            return json_results
        except Exception as e:
            logger.error('Cannot read content from the file: %s, exception: %s' % (file_path, e))
            return None

    def crawl_from_url(self, testcase=None):
        url = dovetail_config[self.type]['result']['db_url'] % testcase
        logger.debug("Query to rest api: %s" % url)
        try:
            data = json.load(urllib2.urlopen(url))
            return data['results'][0]
        except Exception as e:
            logger.error("Cannot read content from the url: %s, exception: %s" % (url, e))
            return None

class YardstickCrawler:

    def __init__(self):
        self.type = 'yardstick'

    def crawl(self, testcase=None):
        return None

class CheckerFactory:

    @classmethod
    def create(cls,type):
        if type == 'functest':
            return FunctestChecker()

        if type == 'yardstick':
            return YardstickChecker()

        return None

class ResultChecker:

    def check(cls):
        return 'PASS'

class FunctestChecker:

    def check(cls, testcase, db_result):
        if not db_result:
            for sub_testcase in testcase.sub_testcase():
                testcase.sub_testcase_passed(sub_testcase,False)
            return

        testcase.passed(db_result['criteria'] == 'PASS')

        if testcase.sub_testcase() is None:
            return

        if testcase.testcase['passed'] == True:
            for sub_testcase in testcase.sub_testcase():
                testcase.sub_testcase_passed(sub_testcase, True)
            return

        all_passed = True
        for sub_testcase in testcase.sub_testcase():
            logger.debug('check sub_testcase:%s' % sub_testcase)
            if sub_testcase in db_result['details']['errors']:
                testcase.sub_testcase_passed(sub_testcase, False)
                all_passed = False
            else:
                testcase.sub_testcase_passed(sub_testcase, True)

        testcase.passed(all_passed)

class YardstickChecker:

    def check(cls, testcase, result):
        return 'PASS'