diff options
-rw-r--r-- | qtip/api/__main__.py | 11 | ||||
-rw-r--r-- | qtip/api/controllers/__init__.py | 0 | ||||
-rw-r--r-- | qtip/api/swagger/swagger.yaml | 9 | ||||
-rw-r--r-- | qtip/base/error.py | 16 | ||||
-rw-r--r-- | qtip/loader/file.py | 4 | ||||
-rw-r--r-- | qtip/loader/yaml_file.py | 4 | ||||
-rw-r--r-- | qtip/runner/__init__.py | 12 | ||||
-rw-r--r-- | qtip/util/dev.py | 17 | ||||
-rw-r--r-- | qtip/util/formula.py | 6 | ||||
-rw-r--r-- | requirements.txt | 4 | ||||
-rw-r--r-- | test-requirements.txt | 4 | ||||
-rw-r--r-- | tests/data/benchmarks/plan/compute.yaml | 46 | ||||
-rw-r--r-- | tests/unit/base/error_test.py | 48 | ||||
-rw-r--r-- | tests/unit/loader/plan_test.py | 2 | ||||
-rw-r--r-- | tests/unit/loader/yaml_file_test.py | 4 | ||||
-rw-r--r-- | tests/unit/util/dev_test.py | 32 | ||||
-rw-r--r-- | third-party/License/.gitrepo | 11 | ||||
-rw-r--r-- | third-party/License/README.md | 10 | ||||
-rwxr-xr-x | third-party/License/add_license.sh | 180 |
19 files changed, 390 insertions, 30 deletions
diff --git a/qtip/api/__main__.py b/qtip/api/__main__.py new file mode 100644 index 00000000..89298e6d --- /dev/null +++ b/qtip/api/__main__.py @@ -0,0 +1,11 @@ +import connexion + + +def main(): + app = connexion.App(__name__, specification_dir='swagger/') + app.add_api('swagger.yaml', base_path='/v1.0') + app.run(host='0.0.0.0', port='5000') + + +if __name__ == '__main__': + main() diff --git a/qtip/api/controllers/__init__.py b/qtip/api/controllers/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/qtip/api/controllers/__init__.py diff --git a/qtip/api/swagger/swagger.yaml b/qtip/api/swagger/swagger.yaml new file mode 100644 index 00000000..97a9c352 --- /dev/null +++ b/qtip/api/swagger/swagger.yaml @@ -0,0 +1,9 @@ +swagger: '2.0' +info: + title: QTIP-API +consumes: + - application/json +produces: + - application/json +paths: + #TODO (akhil) add paths
\ No newline at end of file diff --git a/qtip/base/error.py b/qtip/base/error.py index a055aa8d..f23d8cd9 100644 --- a/qtip/base/error.py +++ b/qtip/base/error.py @@ -12,16 +12,16 @@ class BaseError(Exception): pass -class InvalidContent(BaseError): +class InvalidContentError(BaseError): def __init__(self, filename, excinfo=None): self.filename = filename self.excinfo = excinfo -class NotFound(BaseError): - def __init__(self, module, package='qtip'): - self.package = package - self.module = module +class NotFoundError(BaseError): + def __init__(self, needle, heystack='qtip'): + self.needle = needle + self.heystack = heystack class ToBeDoneError(BaseError): @@ -29,9 +29,3 @@ class ToBeDoneError(BaseError): def __init__(self, method, module): self.method = method self.module = module - - -def make_tbd(method, module='qtip'): - def tbd(): - raise ToBeDoneError(method, module) - return tbd diff --git a/qtip/loader/file.py b/qtip/loader/file.py index 0ea4d5b6..038f57dd 100644 --- a/qtip/loader/file.py +++ b/qtip/loader/file.py @@ -12,7 +12,7 @@ from os import listdir from os import path from qtip.base.constant import BaseProp -from qtip.base.error import NotFound +from qtip.base.error import NotFoundError from qtip.loader.base import BaseLoader @@ -35,7 +35,7 @@ class FileLoader(BaseLoader): abspath = path.join(p, self.RELATIVE_PATH, name) if path.exists(abspath): return abspath - raise NotFound(name, paths) + raise NotFoundError(name, paths) @classmethod def list_all(cls, paths=None): diff --git a/qtip/loader/yaml_file.py b/qtip/loader/yaml_file.py index 8b78a47c..7ff838f9 100644 --- a/qtip/loader/yaml_file.py +++ b/qtip/loader/yaml_file.py @@ -10,7 +10,7 @@ from os import path import yaml -from qtip.base.error import InvalidContent +from qtip.base.error import InvalidContentError from qtip.base.constant import BaseProp from qtip.loader.file import FileLoader @@ -25,6 +25,6 @@ class YamlFileLoader(FileLoader): with open(abspath, 'r') as stream: content = yaml.safe_load(stream) if not isinstance(content, dict): - raise InvalidContent(abspath) + raise InvalidContentError(abspath) self.content = content self.name = content.get(BaseProp.NAME, path.splitext(name)[0]) diff --git a/qtip/runner/__init__.py b/qtip/runner/__init__.py index 79c38850..52c43a14 100644 --- a/qtip/runner/__init__.py +++ b/qtip/runner/__init__.py @@ -8,7 +8,7 @@ ############################################################################## from qtip.base.constant import PkgName, BaseProp -from qtip.base.error import NotFound +from qtip.base.error import NotFoundError from qtip.collector.stdout import StdoutCollector from qtip.driver.random import RandomDriver from qtip.reporter.console import ConsoleReporter @@ -28,16 +28,16 @@ class Runner(object): if driver_name == 'random': self.driver = RandomDriver() else: - raise NotFound(driver_name, heystack=PkgName.DRIVER) + raise NotFoundError(driver_name, heystack=PkgName.DRIVER) if collector_name == 'stdout': self.collector = StdoutCollector() else: - raise NotFound(collector_name, - heystack=PkgName.COLLECTOR) + raise NotFoundError(collector_name, + heystack=PkgName.COLLECTOR) if reporter_name == 'console': self.reporter = ConsoleReporter() else: - raise NotFound(reporter_name, - heystack=PkgName.REPORTER) + raise NotFoundError(reporter_name, + heystack=PkgName.REPORTER) diff --git a/qtip/util/dev.py b/qtip/util/dev.py new file mode 100644 index 00000000..b77bf1eb --- /dev/null +++ b/qtip/util/dev.py @@ -0,0 +1,17 @@ +############################################################################## +# Copyright (c) 2017 ZTE Corporation and others. +# +# 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 qtip.base.error import ToBeDoneError + + +def create_to_be_done(method, module='qtip'): + def tbd(): + raise ToBeDoneError(method, module) + return tbd diff --git a/qtip/util/formula.py b/qtip/util/formula.py index cdfbae86..e92d21f3 100644 --- a/qtip/util/formula.py +++ b/qtip/util/formula.py @@ -9,7 +9,7 @@ import numpy -from qtip.base.error import make_tbd +from qtip.util.dev import create_to_be_done from qtip.base.constant import FormulaName @@ -17,10 +17,10 @@ MAPPING = { FormulaName.ARITHMETIC_MEAN: numpy.mean, FormulaName.WEIGHTED_ARITHMETIC_MEAN: numpy.average, # TODO(yujunz) find or implement the method - FormulaName.GEOMETRIC_MEAN: make_tbd(FormulaName.GEOMETRIC_MEAN, __name__), + FormulaName.GEOMETRIC_MEAN: create_to_be_done(FormulaName.GEOMETRIC_MEAN, __name__), # TODO(yujunz) find or implement the method FormulaName.WEIGHTED_GEOMETRIC_MEAN: - make_tbd(FormulaName.GEOMETRIC_MEAN, __name__)} + create_to_be_done(FormulaName.GEOMETRIC_MEAN, __name__)} class Formula: diff --git a/requirements.txt b/requirements.txt index 4e4700c0..c51228f2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,8 +1,6 @@ click pyyaml paramiko -Flask -Flask-RESTful -flask-restful-swagger +connexion numpy pbr diff --git a/test-requirements.txt b/test-requirements.txt index a5080127..e434748e 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -9,3 +9,7 @@ coverage pykwalify mock pip_check_reqs +coverage +pytest-cov +pytest-faker +tox diff --git a/tests/data/benchmarks/plan/compute.yaml b/tests/data/benchmarks/plan/compute.yaml new file mode 100644 index 00000000..8529d8dc --- /dev/null +++ b/tests/data/benchmarks/plan/compute.yaml @@ -0,0 +1,46 @@ +############################################################################## +# Copyright (c) 2017 ZTE Corporation and others. +# +# 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 +############################################################################## +name: compute QPI +description: compute QPI profile +info: + facility: local + engineer: local +config: + driver: ansible + collectors: + - type: logfile + paths: + - '../../external/sysinfo' + logs: + - filename: top.log + parsers: + - type: grep + regex: 'Cpu\(s\):.+?(?P<cpu_idle>\d+\.\d)\sid' + - filename: inxi.log + parsers: + - type: grep + regex: '.+\s+Host:\s+(?P<hostname>.+)\sKernel' + - type: grep + regex: '.+\sMemory:\s+(?P<memory>.+MB)\s' + - type: grep + regex: '^CPU\(s\):\s+(?P<cpu>.+)' + - type: grep + regex: '.+\sDistro:\s+(?P<os>.+)' + - type: grep + regex: '.+\sKernel:\s+(?P<kernel>.+)\sConsole' + - type: grep + regex: '.+\s+HDD Total Size:\s+(?P<disk>.+)\s' + - type: grep + regex: '.+\sproduct:\s+(?P<product>.+)\sversion' + reporter: + name: console + # transform collected data into timeline + transformer: timeline +QPIs: + - compute.yaml diff --git a/tests/unit/base/error_test.py b/tests/unit/base/error_test.py new file mode 100644 index 00000000..2be6d695 --- /dev/null +++ b/tests/unit/base/error_test.py @@ -0,0 +1,48 @@ +############################################################### +# Copyright (c) 2017 ZTE Corporation +# +# 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 pytest + +from qtip.base.error import InvalidContentError +from qtip.base.error import NotFoundError +from qtip.base.error import ToBeDoneError + + +def test_invalid_content(faker): + filename = faker.file_name() + error = InvalidContentError(filename) + assert error.filename == filename + + +def test_not_found(faker): + package = faker.pystr() + module = faker.pystr() + error = NotFoundError(module) + assert error.needle == module + assert error.heystack == 'qtip' + + error = NotFoundError(module, package) + assert error.needle == module + assert error.heystack == package + + +@pytest.fixture +def method(faker): + return faker.pystr() + + +@pytest.fixture +def module(faker): + return faker.pystr() + + +def test_to_be_done(method, module): + error = ToBeDoneError(method, module) + assert error.method == method + assert error.module == module diff --git a/tests/unit/loader/plan_test.py b/tests/unit/loader/plan_test.py index d9869cb6..70ae2ad5 100644 --- a/tests/unit/loader/plan_test.py +++ b/tests/unit/loader/plan_test.py @@ -30,7 +30,7 @@ def test_init(plan): def test_list_all(benchmarks_root): plan_list = list(Plan.list_all(paths=[benchmarks_root])) - assert len(plan_list) is 1 + assert len(plan_list) is 2 for desc in plan_list: assert PlanProp.NAME in desc assert PlanProp.ABSPATH in desc diff --git a/tests/unit/loader/yaml_file_test.py b/tests/unit/loader/yaml_file_test.py index 17836946..0f0632c4 100644 --- a/tests/unit/loader/yaml_file_test.py +++ b/tests/unit/loader/yaml_file_test.py @@ -10,7 +10,7 @@ import os import pytest -from qtip.base.error import InvalidContent +from qtip.base.error import InvalidContentError from qtip.loader.yaml_file import YamlFileLoader @@ -28,6 +28,6 @@ def test_init(yaml_root, filename, expected): def test_invalid_content(yaml_root): - with pytest.raises(InvalidContent) as excinfo: + with pytest.raises(InvalidContentError) as excinfo: YamlFileLoader('invalid.yaml', [yaml_root]) assert 'invalid.yaml' in excinfo.value.filename diff --git a/tests/unit/util/dev_test.py b/tests/unit/util/dev_test.py new file mode 100644 index 00000000..021b1004 --- /dev/null +++ b/tests/unit/util/dev_test.py @@ -0,0 +1,32 @@ +############################################################### +# Copyright (c) 2017 ZTE Corporation +# +# 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 pytest + +from qtip.base.error import ToBeDoneError +from qtip.util.dev import create_to_be_done + + +def test_create_to_be_done(faker): + method = faker.pystr() + module = faker.pystr() + + tbd = create_to_be_done(method) + assert callable(tbd) + with pytest.raises(ToBeDoneError) as excinfo: + tbd() + assert excinfo.value.method == method + assert excinfo.value.module == 'qtip' + + tbd = create_to_be_done(method, module) + assert callable(tbd) + with pytest.raises(ToBeDoneError) as excinfo: + tbd() + assert excinfo.value.method == method + assert excinfo.value.module == module diff --git a/third-party/License/.gitrepo b/third-party/License/.gitrepo new file mode 100644 index 00000000..29cd5a75 --- /dev/null +++ b/third-party/License/.gitrepo @@ -0,0 +1,11 @@ +; DO NOT EDIT (unless you know what you are doing) +; +; This subdirectory is a git "subrepo", and this file is maintained by the +; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme +; +[subrepo] + remote = git@github.com:openzero-zte/License.git + branch = master + commit = 61489dae4453b66887d0d90a2244610a30f7e53c + parent = 3e443dff14a2be02b914e66f27b549d0ed4cc600 + cmdver = 0.3.0 diff --git a/third-party/License/README.md b/third-party/License/README.md new file mode 100644 index 00000000..0232de7e --- /dev/null +++ b/third-party/License/README.md @@ -0,0 +1,10 @@ +# License + +A script for checking and adding license header according to [OPNFV contribution guideline](https://wiki.opnfv.org/display/DEV/Contribution+Guidelines) + +## Quick Start + +``` +$ cd <project-folder> +$ curl https://raw.githubusercontent.com/Justin-chi/License/master/add_license.sh |bash +``` diff --git a/third-party/License/add_license.sh b/third-party/License/add_license.sh new file mode 100755 index 00000000..9b383c62 --- /dev/null +++ b/third-party/License/add_license.sh @@ -0,0 +1,180 @@ +#!/bin/bash +# Copyright justin.chigang@gmail.com +# +# 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. + +TMP_FILE=tmp.file +LICENSE_TOKEN="http://www.apache.org/licenses/LICENSE-2.0" + +function get_first_author() +{ + author=$(git log --reverse --pretty=format:"%ae" $1 | head -1) + substring=$(git log --reverse --pretty=format:"%ae" $1 | head -1 | awk -F@ '{print $2}') + case $substring in + huawei*) + echo "HUAWEI TECHNOLOGIES CO.,LTD" + ;; + orange*) + echo "Orange" + ;; + zte*) + echo "ZTE Corporation" + ;; + *) + echo "$author" + ;; + esac +} + +function get_latest_year() +{ + git log --pretty=format:"%ad" $1 | head -1 | awk '{print $5}' +} + +function gen_c_license() +{ +cat << EOF >$1 +/******************************************************************************* + * Copyright (c) $2 $3 and others. + * + * 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 + *******************************************************************************/ + +EOF +} + +function gen_xml_license() +{ +cat << EOF >$1 +<!-- + Copyright (c) $2 $3 and others. + + 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 +--> + +EOF +} + +function gen_bash_license() +{ +cat << EOF >$1 +############################################################################## +# Copyright (c) $2 $3 and others. +# +# 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 +############################################################################## + +EOF +} + +function add_c_license() +{ + C_LICENSE="c_license_header.tmp" + author=`get_first_author "$1"` + year=`get_latest_year "$1"` + gen_c_license $C_LICENSE $year "$author" + cat $C_LICENSE $1 > $TMP_FILE + rm -f $C_LICENSE + mv $TMP_FILE $1 +} + +function add_xml_license() +{ + XML_LICENSE="xml_license_header.tmp" + author=`get_first_author "$1"` + year=`get_latest_year "$1"` + gen_xml_license $XML_LICENSE $year "$author" + cat $XML_LICENSE $1 > $TMP_FILE + rm -f $XML_LICENSE + mv $TMP_FILE $1 +} + +function add_bash_license() +{ + BASH_LICENSE="bash_license_header.tmp" + author=`get_first_author "$1"` + year=`get_latest_year "$1"` + gen_bash_license $BASH_LICENSE $year "$author" + cat $1 | head -1 | grep "#!" > /dev/null + if [ $? -eq 0 ]; then + #insert 2 + sed -i "1 r $BASH_LICENSE" $1 + else + #sed -i "1 R $BASH_LICENSE" $1 + cat $BASH_LICENSE $1 > $TMP_FILE + mv $TMP_FILE $1 + fi + rm -f $BASH_LICENSE +} + +if [[ -z "$1" ]] || [[ ! -d "$1" ]]; then + echo "The directory is empty or not exist!" + echo "It will use the current directory." + nowdir=$(pwd) +else + nowdir=$(cd $1; pwd) +fi +echo "$nowdir" + +n=0 + +function Searchfile() +{ + cd $1 + + dirlist=$(ls) + for dirname in $dirlist + do + if [[ -d "$dirname" ]];then + n=$((n+4)) + cd $dirname + for i in $( seq 0 $n );do echo -n ' ';done;echo "$dirname ..." + Searchfile $(pwd) + cd .. + n=$((n-4)) + fi; + + filename=$dirname + if [[ -f "$filename" ]]; then + for i in $( seq 0 $n );do echo -n ' ';done;echo " |--$filename" + grep -rn $LICENSE_TOKEN $filename >/dev/null + if [ $? -eq 1 ]; then + if [ "${filename##*.}" = "c" -o "${filename##*.}" = "cpp" -o "${filename##*.}" = "java" ]; then + add_c_license $filename + for i in $( seq 0 $n );do echo -n ' ';done;echo " |--add license for $filename... " + elif [ "${filename##*.}" = "py" -o "${filename##*.}" = "yml" -o "${filename##*.}" = "yaml" -o "${filename##*.}" = "sh" ]; then + add_bash_license $filename + for i in $( seq 0 $n );do echo -n ' ';done;echo " |--add license for $filename... " + elif [ "${filename##*.}" = "xml" ]; then + add_xml_license $filename + for i in $( seq 0 $n );do echo -n ' ';done;echo " |--add license for $filename... " + fi; + fi; + fi; + done; +} + +Searchfile $nowdir + +# Revert changes of skipped files, e.g. __init__.py + +git checkout \*\*/__init__.py |