diff options
Diffstat (limited to 'utils/test')
-rwxr-xr-x | utils/test/reporting/reporting/functest/reporting-status.py | 20 | ||||
-rw-r--r-- | utils/test/reporting/reporting/reporting.yaml | 3 | ||||
-rw-r--r-- | utils/test/reporting/reporting/utils/reporting_utils.py | 43 | ||||
-rw-r--r-- | utils/test/testapi/.gitignore | 7 | ||||
-rw-r--r-- | utils/test/testapi/3rd_party/static/testapi-ui/Gruntfile.js | 155 | ||||
-rw-r--r-- | utils/test/testapi/3rd_party/static/testapi-ui/package.json | 18 | ||||
-rw-r--r-- | utils/test/testapi/docs/Makefile | 20 | ||||
-rw-r--r-- | utils/test/testapi/docs/conf.py | 165 | ||||
-rw-r--r-- | utils/test/testapi/docs/developer/devguide/api.rst | 10 | ||||
-rw-r--r-- | utils/test/testapi/docs/developer/devguide/framework.rst (renamed from utils/test/testapi/README.rst) | 14 | ||||
-rw-r--r-- | utils/test/testapi/docs/developer/devguide/index.rst | 18 | ||||
-rw-r--r-- | utils/test/testapi/docs/developer/devguide/overview.rst | 98 | ||||
-rw-r--r-- | utils/test/testapi/docs/developer/devguide/swagger-ui.rst | 10 | ||||
-rw-r--r-- | utils/test/testapi/docs/developer/devguide/testapi-client.rst | 10 | ||||
-rw-r--r-- | utils/test/testapi/docs/developer/devguide/web-portal.rst | 10 | ||||
-rw-r--r-- | utils/test/testapi/docs/index.rst | 20 | ||||
-rw-r--r-- | utils/test/testapi/etc/config.ini | 3 | ||||
-rw-r--r-- | utils/test/testapi/opnfv_testapi/cmd/server.py | 2 | ||||
-rw-r--r-- | utils/test/testapi/opnfv_testapi/common/check.py | 16 | ||||
-rw-r--r-- | utils/test/testapi/opnfv_testapi/common/config.py | 2 | ||||
-rw-r--r-- | utils/test/testapi/opnfv_testapi/common/message.py | 4 | ||||
-rw-r--r-- | utils/test/testapi/opnfv_testapi/handlers/__init__.py (renamed from utils/test/testapi/opnfv_testapi/tests/unit/resources/__init__.py) | 0 | ||||
-rw-r--r-- | utils/test/testapi/opnfv_testapi/handlers/base_handlers.py (renamed from utils/test/testapi/opnfv_testapi/resources/handlers.py) | 7 | ||||
-rw-r--r-- | utils/test/testapi/opnfv_testapi/handlers/pod_handlers.py (renamed from utils/test/testapi/opnfv_testapi/resources/pod_handlers.py) | 6 | ||||
-rw-r--r-- | utils/test/testapi/opnfv_testapi/handlers/project_handlers.py (renamed from utils/test/testapi/opnfv_testapi/resources/project_handlers.py) | 6 | ||||
-rw-r--r-- | utils/test/testapi/opnfv_testapi/handlers/result_handlers.py (renamed from utils/test/testapi/opnfv_testapi/resources/result_handlers.py) | 20 | ||||
-rw-r--r-- | utils/test/testapi/opnfv_testapi/handlers/root_handlers.py (renamed from utils/test/testapi/opnfv_testapi/ui/root.py) | 4 | ||||
-rw-r--r-- | utils/test/testapi/opnfv_testapi/handlers/scenario_handlers.py (renamed from utils/test/testapi/opnfv_testapi/resources/scenario_handlers.py) | 6 | ||||
-rw-r--r-- | utils/test/testapi/opnfv_testapi/handlers/sign_handlers.py (renamed from utils/test/testapi/opnfv_testapi/ui/auth/sign.py) | 4 | ||||
-rw-r--r-- | utils/test/testapi/opnfv_testapi/handlers/testcase_handlers.py (renamed from utils/test/testapi/opnfv_testapi/resources/testcase_handlers.py) | 6 | ||||
-rw-r--r-- | utils/test/testapi/opnfv_testapi/handlers/user_handlers.py | 25 | ||||
-rw-r--r-- | utils/test/testapi/opnfv_testapi/models/__init__.py (renamed from utils/test/testapi/opnfv_testapi/resources/__init__.py) | 0 | ||||
-rw-r--r-- | utils/test/testapi/opnfv_testapi/models/base_models.py (renamed from utils/test/testapi/opnfv_testapi/resources/models.py) | 4 | ||||
-rw-r--r-- | utils/test/testapi/opnfv_testapi/models/pod_models.py (renamed from utils/test/testapi/opnfv_testapi/resources/pod_models.py) | 8 | ||||
-rw-r--r-- | utils/test/testapi/opnfv_testapi/models/project_models.py (renamed from utils/test/testapi/opnfv_testapi/resources/project_models.py) | 10 | ||||
-rw-r--r-- | utils/test/testapi/opnfv_testapi/models/result_models.py (renamed from utils/test/testapi/opnfv_testapi/resources/result_models.py) | 14 | ||||
-rw-r--r-- | utils/test/testapi/opnfv_testapi/models/scenario_models.py (renamed from utils/test/testapi/opnfv_testapi/resources/scenario_models.py) | 22 | ||||
-rw-r--r-- | utils/test/testapi/opnfv_testapi/models/testcase_models.py (renamed from utils/test/testapi/opnfv_testapi/resources/testcase_models.py) | 10 | ||||
-rw-r--r-- | utils/test/testapi/opnfv_testapi/models/user_models.py | 9 | ||||
-rw-r--r-- | utils/test/testapi/opnfv_testapi/router/url_mappings.py | 31 | ||||
-rw-r--r-- | utils/test/testapi/opnfv_testapi/tests/UI/e2e/podsControllerSpec.js | 188 | ||||
-rw-r--r-- | utils/test/testapi/opnfv_testapi/tests/UI/karma.conf.js | 14 | ||||
-rw-r--r-- | utils/test/testapi/opnfv_testapi/tests/UI/protractor-conf.js | 18 | ||||
-rw-r--r-- | utils/test/testapi/opnfv_testapi/tests/unit/common/test_config.py | 3 | ||||
-rw-r--r-- | utils/test/testapi/opnfv_testapi/tests/unit/executor.py | 2 | ||||
-rw-r--r-- | utils/test/testapi/opnfv_testapi/tests/unit/handlers/__init__.py (renamed from utils/test/testapi/opnfv_testapi/ui/__init__.py) | 0 | ||||
-rw-r--r-- | utils/test/testapi/opnfv_testapi/tests/unit/handlers/scenario-c1.json (renamed from utils/test/testapi/opnfv_testapi/tests/unit/resources/scenario-c1.json) | 0 | ||||
-rw-r--r-- | utils/test/testapi/opnfv_testapi/tests/unit/handlers/scenario-c2.json (renamed from utils/test/testapi/opnfv_testapi/tests/unit/resources/scenario-c2.json) | 0 | ||||
-rw-r--r-- | utils/test/testapi/opnfv_testapi/tests/unit/handlers/test_base.py (renamed from utils/test/testapi/opnfv_testapi/tests/unit/resources/test_base.py) | 6 | ||||
-rw-r--r-- | utils/test/testapi/opnfv_testapi/tests/unit/handlers/test_pod.py (renamed from utils/test/testapi/opnfv_testapi/tests/unit/resources/test_pod.py) | 4 | ||||
-rw-r--r-- | utils/test/testapi/opnfv_testapi/tests/unit/handlers/test_project.py (renamed from utils/test/testapi/opnfv_testapi/tests/unit/resources/test_project.py) | 4 | ||||
-rw-r--r-- | utils/test/testapi/opnfv_testapi/tests/unit/handlers/test_result.py (renamed from utils/test/testapi/opnfv_testapi/tests/unit/resources/test_result.py) | 17 | ||||
-rw-r--r-- | utils/test/testapi/opnfv_testapi/tests/unit/handlers/test_scenario.py (renamed from utils/test/testapi/opnfv_testapi/tests/unit/resources/test_scenario.py) | 4 | ||||
-rw-r--r-- | utils/test/testapi/opnfv_testapi/tests/unit/handlers/test_testcase.py (renamed from utils/test/testapi/opnfv_testapi/tests/unit/resources/test_testcase.py) | 6 | ||||
-rw-r--r-- | utils/test/testapi/opnfv_testapi/tests/unit/handlers/test_token.py (renamed from utils/test/testapi/opnfv_testapi/tests/unit/resources/test_token.py) | 2 | ||||
-rw-r--r-- | utils/test/testapi/opnfv_testapi/tests/unit/handlers/test_version.py (renamed from utils/test/testapi/opnfv_testapi/tests/unit/resources/test_version.py) | 6 | ||||
-rw-r--r-- | utils/test/testapi/opnfv_testapi/tests/unit/resources/test_fake_pymongo.py | 123 | ||||
-rw-r--r-- | utils/test/testapi/opnfv_testapi/tornado_swagger/handlers.py | 2 | ||||
-rw-r--r-- | utils/test/testapi/opnfv_testapi/ui/about/about.html (renamed from utils/test/testapi/3rd_party/static/testapi-ui/components/about/about.html) | 0 | ||||
-rw-r--r-- | utils/test/testapi/opnfv_testapi/ui/auth-failure/authFailureController.js (renamed from utils/test/testapi/3rd_party/static/testapi-ui/components/auth-failure/authFailureController.js) | 0 | ||||
-rw-r--r-- | utils/test/testapi/opnfv_testapi/ui/auth/__init__.py | 0 | ||||
-rw-r--r-- | utils/test/testapi/opnfv_testapi/ui/auth/user.py | 26 | ||||
-rw-r--r-- | utils/test/testapi/opnfv_testapi/ui/home/home.html (renamed from utils/test/testapi/3rd_party/static/testapi-ui/components/home/home.html) | 0 | ||||
-rw-r--r-- | utils/test/testapi/opnfv_testapi/ui/logout/logout.html (renamed from utils/test/testapi/3rd_party/static/testapi-ui/components/logout/logout.html) | 0 | ||||
-rw-r--r-- | utils/test/testapi/opnfv_testapi/ui/logout/logoutController.js (renamed from utils/test/testapi/3rd_party/static/testapi-ui/components/logout/logoutController.js) | 0 | ||||
-rw-r--r-- | utils/test/testapi/opnfv_testapi/ui/pods/pods.html (renamed from utils/test/testapi/3rd_party/static/testapi-ui/components/pods/pods.html) | 0 | ||||
-rw-r--r-- | utils/test/testapi/opnfv_testapi/ui/pods/podsController.js (renamed from utils/test/testapi/3rd_party/static/testapi-ui/components/pods/podsController.js) | 0 | ||||
-rw-r--r-- | utils/test/testapi/opnfv_testapi/ui/profile/importPubKeyModal.html (renamed from utils/test/testapi/3rd_party/static/testapi-ui/components/profile/importPubKeyModal.html) | 0 | ||||
-rw-r--r-- | utils/test/testapi/opnfv_testapi/ui/profile/profile.html (renamed from utils/test/testapi/3rd_party/static/testapi-ui/components/profile/profile.html) | 0 | ||||
-rw-r--r-- | utils/test/testapi/opnfv_testapi/ui/profile/profileController.js (renamed from utils/test/testapi/3rd_party/static/testapi-ui/components/profile/profileController.js) | 0 | ||||
-rw-r--r-- | utils/test/testapi/opnfv_testapi/ui/profile/showPubKeyModal.html (renamed from utils/test/testapi/3rd_party/static/testapi-ui/components/profile/showPubKeyModal.html) | 0 | ||||
-rw-r--r-- | utils/test/testapi/opnfv_testapi/ui/results-report/partials/editTestModal.html (renamed from utils/test/testapi/3rd_party/static/testapi-ui/components/results-report/partials/editTestModal.html) | 0 | ||||
-rw-r--r-- | utils/test/testapi/opnfv_testapi/ui/results-report/partials/fullTestListModal.html (renamed from utils/test/testapi/3rd_party/static/testapi-ui/components/results-report/partials/fullTestListModal.html) | 0 | ||||
-rw-r--r-- | utils/test/testapi/opnfv_testapi/ui/results-report/partials/reportDetails.html (renamed from utils/test/testapi/3rd_party/static/testapi-ui/components/results-report/partials/reportDetails.html) | 0 | ||||
-rw-r--r-- | utils/test/testapi/opnfv_testapi/ui/results-report/resultsReport.html (renamed from utils/test/testapi/3rd_party/static/testapi-ui/components/results-report/resultsReport.html) | 0 | ||||
-rw-r--r-- | utils/test/testapi/opnfv_testapi/ui/results-report/resultsReportController.js (renamed from utils/test/testapi/3rd_party/static/testapi-ui/components/results-report/resultsReportController.js) | 0 | ||||
-rw-r--r-- | utils/test/testapi/opnfv_testapi/ui/results/results.html (renamed from utils/test/testapi/3rd_party/static/testapi-ui/components/results/results.html) | 0 | ||||
-rw-r--r-- | utils/test/testapi/opnfv_testapi/ui/results/resultsController.js (renamed from utils/test/testapi/3rd_party/static/testapi-ui/components/results/resultsController.js) | 0 | ||||
-rw-r--r-- | utils/test/testapi/setup.cfg | 3 | ||||
-rw-r--r-- | utils/test/testapi/tox.ini | 4 |
80 files changed, 1007 insertions, 265 deletions
diff --git a/utils/test/reporting/reporting/functest/reporting-status.py b/utils/test/reporting/reporting/functest/reporting-status.py index c71e00f3b..592f92996 100755 --- a/utils/test/reporting/reporting/functest/reporting-status.py +++ b/utils/test/reporting/reporting/functest/reporting-status.py @@ -172,8 +172,13 @@ for version in versions: nb_test_runnable_for_this_scenario += 1 LOGGER.info(" Searching results for case %s ", displayName) - result = rp_utils.getResult(name, installer, - s, version) + if "fuel" in installer: + result = rp_utils.getCaseScoreFromBuildTag( + name, + s_result) + else: + result = rp_utils.getCaseScore(name, installer, + s, version) # if no result set the value to 0 if result < 0: result = 0 @@ -204,8 +209,13 @@ for version in versions: project = test_case.getProject() LOGGER.info(" Searching results for case %s ", displayName) - result = rp_utils.getResult(name, installer, - s, version) + if "fuel" in installer: + result = rp_utils.getCaseScoreFromBuildTag( + name, + s_result) + else: + result = rp_utils.getCaseScore(name, installer, + s, version) # at least 1 result for the test if result > -1: test_case.setCriteria(result) @@ -240,6 +250,8 @@ for version in versions: # 2 iterations : max score = 20 (10x2) # 3 iterations : max score = 20 # 4 or more iterations : max score = 30 (1x30) + LOGGER.info("Number of iterations for this scenario: %s", + len(s_result)) if len(s_result) > 3: k_score = 3 elif len(s_result) < 2: diff --git a/utils/test/reporting/reporting/reporting.yaml b/utils/test/reporting/reporting/reporting.yaml index 1e2e9a476..8123d0135 100644 --- a/utils/test/reporting/reporting/reporting.yaml +++ b/utils/test/reporting/reporting/reporting.yaml @@ -10,7 +10,6 @@ general: versions: - master - euphrates - - danube log: log_file: reporting.log @@ -38,6 +37,8 @@ functest: blacklist: - odl_netvirt - juju_epc + - tempest_full_parallel + - rally_full max_scenario_criteria: 50 test_conf: https://git.opnfv.org/cgit/functest/plain/functest/ci/testcases.yaml log_level: ERROR diff --git a/utils/test/reporting/reporting/utils/reporting_utils.py b/utils/test/reporting/reporting/utils/reporting_utils.py index 65267ca11..58a0c6233 100644 --- a/utils/test/reporting/reporting/utils/reporting_utils.py +++ b/utils/test/reporting/reporting/utils/reporting_utils.py @@ -6,7 +6,6 @@ # # http://www.apache.org/licenses/LICENSE-2.0 # -from urllib2 import Request, urlopen, URLError import logging import json import os @@ -14,6 +13,8 @@ import requests import pdfkit import yaml +from urllib2 import Request, urlopen, URLError + # ---------------------------------------------------------- # @@ -113,7 +114,8 @@ def getScenarios(project, case, installer, version): """ Get the list of Scenarios """ - + test_results = None + scenario_results = None period = get_config('general.period') url_base = get_config('testapi.url') @@ -284,7 +286,7 @@ def getNbtestOk(results): return nb_test_ok -def getResult(testCase, installer, scenario, version): +def getCaseScore(testCase, installer, scenario, version): """ Get Result for a given Functest Testcase """ @@ -343,6 +345,41 @@ def getResult(testCase, installer, scenario, version): return test_result_indicator +def getCaseScoreFromBuildTag(testCase, s_results): + """ + Get Results for a given Functest Testcase with arch filtering + """ + url_base = get_config('testapi.url') + nb_tests = get_config('general.nb_iteration_tests_success_criteria') + test_result_indicator = 0 + # architecture is not a result field...so we cannot use getResult as it is + res_matrix = [] + try: + for s_result in s_results: + build_tag = s_result['build_tag'] + d = s_result['start_date'] + res_matrix.append({'date': d, + 'build_tag': build_tag}) + # sort res_matrix + filter_res_matrix = sorted(res_matrix, key=lambda k: k['date'], + reverse=True)[:nb_tests] + for my_res in filter_res_matrix: + url = ("http://" + url_base + "?case=" + testCase + + "&build_tag=" + my_res['build_tag']) + request = Request(url) + response = urlopen(request) + k = response.read() + results = json.loads(k) + if "PASS" in results['results'][0]['criteria']: + test_result_indicator += 1 + except: + print "No results found for this case" + if test_result_indicator > 2: + test_result_indicator = test_result_indicator - 1 + + return test_result_indicator + + def getJenkinsUrl(build_tag): """ Get Jenkins url_base corespoding to the last test CI run diff --git a/utils/test/testapi/.gitignore b/utils/test/testapi/.gitignore index a3d6e01ec..e34365e60 100644 --- a/utils/test/testapi/.gitignore +++ b/utils/test/testapi/.gitignore @@ -6,3 +6,10 @@ build *.egg-info 3rd_party/static/static *.pyc +.cache +.eggs +.tox +.ven +docs/_build +opnfv_testapi/tests/UI/coverage +3rd_party/static/testapi-ui/testapi-ui
\ No newline at end of file diff --git a/utils/test/testapi/3rd_party/static/testapi-ui/Gruntfile.js b/utils/test/testapi/3rd_party/static/testapi-ui/Gruntfile.js new file mode 100644 index 000000000..8ff280278 --- /dev/null +++ b/utils/test/testapi/3rd_party/static/testapi-ui/Gruntfile.js @@ -0,0 +1,155 @@ + +module.exports = function (grunt) { + require('load-grunt-tasks')(grunt); + require('grunt-protractor-coverage')(grunt); + grunt.loadNpmTasks('grunt-shell-spawn'); + grunt.loadNpmTasks('grunt-wait'); + grunt.loadNpmTasks('grunt-contrib-copy'); + grunt.loadNpmTasks('grunt-contrib-connect'); + grunt.initConfig({ + connect: { + server: { + options: { + port: 8000, + base: './', + middleware: function(connect, options, middlewares) { + middlewares.unshift(function(req, res, next) { + if (req.method.toUpperCase() == 'POST') req.method='GET'; + return next(); + }); + return middlewares; + } + } + } + }, + copy: { + assets: { + expand: true, + cwd: 'assets', + src: '**', + dest: 'testapi-ui/assets', + }, + components: { + expand: true, + cwd: 'components', + src: '**', + dest: 'testapi-ui/components', + }, + shared: { + expand: true, + cwd: 'shared', + src: '**', + dest: 'testapi-ui/shared', + }, + filesPng: { + expand: true, + src: '*.png', + dest: 'testapi-ui/', + }, + filesIco: { + expand: true, + src: '*.ico', + dest: 'testapi-ui/', + }, + filesJs: { + expand: true, + src: 'app.js', + dest: 'testapi-ui/', + }, + filesJson: { + expand: true, + src: 'config.json', + dest: 'testapi-ui/', + } + }, + wait: { + default: { + options: { + delay: 3000 + } + } + }, + shell: { + updateSelenium: { + command: 'node_modules/protractor/bin/webdriver-manager update', + options: { + async: false + } + }, + startSelenium: { + command: 'node_modules/protractor/bin/webdriver-manager start', + options: { + async: true + } + }, + options: { + stdout: false, + stderr: false + } + }, + instrument: { + files: ['components/**/*.js'], + options: { + lazy: false, + basePath: "./testapi-ui/" + } + }, + karma: { + unit: { + configFile: '../../../opnfv_testapi/tests/UI/karma.conf.js' + } + }, + protractor_coverage: { + options: { + keepAlive: true, + noColor: false, + coverageDir: '../../../opnfv_testapi/tests/UI/coverage', + args: { + specs: ['../../../opnfv_testapi/tests/UI/e2e/podsControllerSpec.js'] + } + }, + local: { + options: { + configFile: '../../../opnfv_testapi/tests/UI/protractor-conf.js' + } + } + }, + makeReport: { + src: '../../../opnfv_testapi/tests/UI/coverage/*.json', + options: { + print: 'detail' + } + }, + protractor: { + e2e: { + options: { + args: { + specs: ['../../../opnfv_testapi/tests/UI/e2e/podsControllerSpec.js'] + }, + configFile: '../../../opnfv_testapi/tests/UI/protractor-conf.js', + keepAlive: true + } + } + } + }); + grunt.registerTask('test', [ + 'karma:unit' + ]); + grunt.registerTask('e2e', [ + 'copy:assets', + 'copy:components', + 'copy:shared', + 'copy:filesPng', + 'copy:filesIco', + 'copy:filesJs', + 'copy:filesJson', + 'instrument', + 'connect', + 'shell:updateSelenium', + 'shell:startSelenium', + 'wait:default', + 'protractor_coverage', + 'makeReport' + // 'protractor' + ]); +} diff --git a/utils/test/testapi/3rd_party/static/testapi-ui/package.json b/utils/test/testapi/3rd_party/static/testapi-ui/package.json new file mode 100644 index 000000000..dc992390d --- /dev/null +++ b/utils/test/testapi/3rd_party/static/testapi-ui/package.json @@ -0,0 +1,18 @@ +{ + "devDependencies": { + "grunt": "~1.0.1", + "grunt-contrib-connect": "^1.0.2", + "grunt-contrib-copy": "^1.0.0", + "grunt-karma": "~2.0.0", + "grunt-protractor-coverage": "^0.2.18", + "grunt-protractor-runner": "~5.0.0", + "grunt-shell-spawn": "~0.3.10", + "grunt-wait": "~0.1.0", + "karma": "~1.7.1", + "karma-chrome-launcher": "~2.2.0", + "karma-coverage": "~1.1.1", + "karma-jasmine": "~1.1.0", + "load-grunt-tasks": "~3.5.2", + "protractor-http-mock": "^0.10.0" + } +} diff --git a/utils/test/testapi/docs/Makefile b/utils/test/testapi/docs/Makefile new file mode 100644 index 000000000..11e9eb6d8 --- /dev/null +++ b/utils/test/testapi/docs/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +SPHINXPROJ = OPNFVTestAPI +SOURCEDIR = . +BUILDDIR = _build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
\ No newline at end of file diff --git a/utils/test/testapi/docs/conf.py b/utils/test/testapi/docs/conf.py new file mode 100644 index 000000000..eaf15017d --- /dev/null +++ b/utils/test/testapi/docs/conf.py @@ -0,0 +1,165 @@ +# -*- coding: utf-8 -*- +# +# OPNFV TestAPI documentation build configuration file, created by +# sphinx-quickstart on Thu Oct 26 10:23:57 2017. +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +# import os +# import sys +# sys.path.insert(0, os.path.abspath('.')) + + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +# +# needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +# source_suffix = ['.rst', '.md'] +source_suffix = '.rst' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'OPNFV TestAPI' +copyright = u'2017, SerenaFeng' +author = u'SerenaFeng' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = u'v1.0' +# The full version, including alpha/beta/rc tags. +release = u'v1.0' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This patterns also effect to html_static_path and html_extra_path +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = False + + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'alabaster' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +# +# html_theme_options = {} + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +# html_static_path = ['_static'] + +# Custom sidebar templates, must be a dictionary that maps document names +# to template names. +# +# This is required for the alabaster theme +# refs: http://alabaster.readthedocs.io/en/latest/installation.html#sidebars +html_sidebars = { + '**': [ + 'relations.html', # needs 'show_related': True theme option to display + 'searchbox.html', + ] +} + + +# -- Options for HTMLHelp output ------------------------------------------ + +# Output file base name for HTML help builder. +htmlhelp_basename = 'OPNFVTestAPIdoc' + + +# -- Options for LaTeX output --------------------------------------------- + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', + + # Latex figure (float) alignment + # + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + (master_doc, 'OPNFVTestAPI.tex', u'OPNFV TestAPI Documentation', + u'SerenaFeng', 'manual'), +] + + +# -- Options for manual page output --------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + (master_doc, 'opnfvtestapi', u'OPNFV TestAPI Documentation', + [author], 1) +] + + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + (master_doc, 'OPNFVTestAPI', u'OPNFV TestAPI Documentation', + author, 'OPNFVTestAPI', 'One line description of project.', + 'Miscellaneous'), +] diff --git a/utils/test/testapi/docs/developer/devguide/api.rst b/utils/test/testapi/docs/developer/devguide/api.rst new file mode 100644 index 000000000..cd2ca27cf --- /dev/null +++ b/utils/test/testapi/docs/developer/devguide/api.rst @@ -0,0 +1,10 @@ +.. This work is licensed under a Creative Commons Attribution 4.0 International License. +.. http://creativecommons.org/licenses/by/4.0 +.. (c) 2017 ZTE Corp. + +============ +Restful APIs +============ + +.. toctree:: + :maxdepth: 2 diff --git a/utils/test/testapi/README.rst b/utils/test/testapi/docs/developer/devguide/framework.rst index 0d18b7e93..f7a760531 100644 --- a/utils/test/testapi/README.rst +++ b/utils/test/testapi/docs/developer/devguide/framework.rst @@ -1,6 +1,14 @@ -============= -opnfv-testapi -============= +.. This work is licensed under a Creative Commons Attribution 4.0 International License. +.. http://creativecommons.org/licenses/by/4.0 +.. (c) 2017 ZTE Corp. + + +.. toctree:: + :maxdepth: 2 + +========= +Framework +========= **Test Results Collector of OPNFV Test Projects**: diff --git a/utils/test/testapi/docs/developer/devguide/index.rst b/utils/test/testapi/docs/developer/devguide/index.rst new file mode 100644 index 000000000..7afcd96fe --- /dev/null +++ b/utils/test/testapi/docs/developer/devguide/index.rst @@ -0,0 +1,18 @@ +.. This work is licensed under a Creative Commons Attribution 4.0 International License. +.. http://creativecommons.org/licenses/by/4.0 +.. (c) 2017 ZTE Corp. + + +*********************** +TestAPI Developer Guide +*********************** + +.. toctree:: + :maxdepth: 2 + + overview.rst + framework.rst + api.rst + swagger-ui.rst + web-portal.rst + testapi-client.rst diff --git a/utils/test/testapi/docs/developer/devguide/overview.rst b/utils/test/testapi/docs/developer/devguide/overview.rst new file mode 100644 index 000000000..b6475f30e --- /dev/null +++ b/utils/test/testapi/docs/developer/devguide/overview.rst @@ -0,0 +1,98 @@ +.. This work is licensed under a Creative Commons Attribution 4.0 International License. +.. http://creativecommons.org/licenses/by/4.0 +.. (c) 2017 ZTE Corporation + + +******** +Overview +******** + +TestAPI uses Python as primary programming language and build the framework from the following packages + +======== =============================================================================================================== +Module Package +======== =============================================================================================================== +api `Tornado-Motor`_ - API applications using Motor with tornado +swagger `tornado-swagger`_ - a wrapper for tornado which enables swagger-ui-v1.2 support +web `angular`_ - a superheroic JavaScript MVW framework, the version is AngularJS v1.3.15 +docs `sphinx`_ - a tool that makes it easy to create intelligent and beautiful documentation +testing `pytest`_ - a mature full-featured Python testing tool that helps you write better programs +======== =============================================================================================================== + + +Source Code +=========== + +The structure of repository is based on the recommended sample in `The Hitchhiker's Guide to Python`_ + +========================== ==================================================================================================== +Path Content +========================== ==================================================================================================== +``./3rd_party/`` third part included in TestAPI project +``./docker/`` configuration for building Docker image for TestAPI deployment +``./docs/`` user and developer documentation, design proposals +``./etc/`` configuration files used to install opnfv-testapi +``./opnfv_testapi/`` the actual package +``./opnfv_testapi/tests/`` package functional and unit tests +``./opts/`` optional components, e.g. one click deployment script +========================== ==================================================================================================== + + +Coding Style +============ + +TestAPI follows `OpenStack Style Guidelines`_ for source code and commit message. + +Specially, it is recommended to link each patch set with a JIRA issue. Put:: + + JIRA: RELENG-n + +in commit message to create an automatic link. + + +Testing +======= + +All testing related code are stored in ``./opnfv_testapi/tests/`` + +================== ==================================================================================================== +Path Content +================== ==================================================================================================== +``./tests/unit/`` unit test for each module, follow the same layout as ./opnfv_testapi/ +``./conftest.py`` pytest configuration in project scope +================== ==================================================================================================== + +`tox`_ is used to automate the testing tasks + +.. code-block:: shell + + cd <project_root> + pip install tox + tox + +The test cases are written in `pytest`_. You may run it selectively with + +.. code-block:: shell + + pytest opnfv_testapi/tests/unit/common/test_config.py + + +Branching +========= + +Currently, no branching for TestAPI, only master branch + + +Releasing +========= + +Currently, TestAPI does not follow community's milestones and releases + +.. _Tornado-Motor: https://motor.readthedocs.io/en/stable/tutorial-tornado.html +.. _tornado-swagger: https://github.com/SerenaFeng/tornado-swagger +.. _angular: https://code.angularjs.org/1.3.15/docs/guide +.. _sphinx: http://www.sphinx-doc.org/en/stable/ +.. _pytest: http://doc.pytest.org/ +.. _OpenStack Style Guidelines: http://docs.openstack.org/developer/hacking/ +.. _The Hitchhiker's Guide to Python: http://python-guide-pt-br.readthedocs.io/en/latest/writing/structure/ +.. _tox: https://tox.readthedocs.io/ diff --git a/utils/test/testapi/docs/developer/devguide/swagger-ui.rst b/utils/test/testapi/docs/developer/devguide/swagger-ui.rst new file mode 100644 index 000000000..7f53047e5 --- /dev/null +++ b/utils/test/testapi/docs/developer/devguide/swagger-ui.rst @@ -0,0 +1,10 @@ +.. This work is licensed under a Creative Commons Attribution 4.0 International License. +.. http://creativecommons.org/licenses/by/4.0 +.. (c) 2017 ZTE Corp. + +============ +Swagger page +============ + +.. toctree:: + :maxdepth: 2 diff --git a/utils/test/testapi/docs/developer/devguide/testapi-client.rst b/utils/test/testapi/docs/developer/devguide/testapi-client.rst new file mode 100644 index 000000000..ab4c8e802 --- /dev/null +++ b/utils/test/testapi/docs/developer/devguide/testapi-client.rst @@ -0,0 +1,10 @@ +.. This work is licensed under a Creative Commons Attribution 4.0 International License. +.. http://creativecommons.org/licenses/by/4.0 +.. (c) 2017 ZTE Corp. + +============== +TestAPI client +============== + +.. toctree:: + :maxdepth: 2 diff --git a/utils/test/testapi/docs/developer/devguide/web-portal.rst b/utils/test/testapi/docs/developer/devguide/web-portal.rst new file mode 100644 index 000000000..62b2f1794 --- /dev/null +++ b/utils/test/testapi/docs/developer/devguide/web-portal.rst @@ -0,0 +1,10 @@ +.. This work is licensed under a Creative Commons Attribution 4.0 International License. +.. http://creativecommons.org/licenses/by/4.0 +.. (c) 2017 ZTE Corp. + +========== +Web portal +========== + +.. toctree:: + :maxdepth: 2 diff --git a/utils/test/testapi/docs/index.rst b/utils/test/testapi/docs/index.rst new file mode 100644 index 000000000..017282a74 --- /dev/null +++ b/utils/test/testapi/docs/index.rst @@ -0,0 +1,20 @@ +.. OPNFV TestAPI documentation master file, created by + sphinx-quickstart on Thu Oct 26 10:23:57 2017. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to OPNFV TestAPI's documentation! +========================================= + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + +Developer Guide +=============== + +.. toctree:: + :maxdepth: 2 + + developer/devguide/index.rst diff --git a/utils/test/testapi/etc/config.ini b/utils/test/testapi/etc/config.ini index 8d0bde20b..86cb0caa7 100644 --- a/utils/test/testapi/etc/config.ini +++ b/utils/test/testapi/etc/config.ini @@ -16,7 +16,8 @@ results_per_page = 20 # With debug_on set to true, error traces will be shown in HTTP responses debug = True -authenticate = False +token_check = False +authenticate = True [ui] url = http://localhost:8000 diff --git a/utils/test/testapi/opnfv_testapi/cmd/server.py b/utils/test/testapi/opnfv_testapi/cmd/server.py index b7d3caa20..011a6cd6e 100644 --- a/utils/test/testapi/opnfv_testapi/cmd/server.py +++ b/utils/test/testapi/opnfv_testapi/cmd/server.py @@ -42,7 +42,7 @@ def make_app(): return swagger.Application( url_mappings.mappings, debug=CONF.api_debug, - auth=CONF.api_authenticate, + auth=CONF.api_token_check, cookie_secret='opnfv-testapi', ) diff --git a/utils/test/testapi/opnfv_testapi/common/check.py b/utils/test/testapi/opnfv_testapi/common/check.py index e80b1c6b7..667578fed 100644 --- a/utils/test/testapi/opnfv_testapi/common/check.py +++ b/utils/test/testapi/opnfv_testapi/common/check.py @@ -14,13 +14,14 @@ from tornado import gen from opnfv_testapi.common import constants from opnfv_testapi.common import message from opnfv_testapi.common import raises +from opnfv_testapi.common.config import CONF from opnfv_testapi.db import api as dbapi def is_authorized(method): @functools.wraps(method) def wrapper(self, *args, **kwargs): - if self.table in ['pods']: + if CONF.api_authenticate and self.table in ['pods']: testapi_id = self.get_secure_cookie(constants.TESTAPI_ID) if not testapi_id: raises.Unauthorized(message.not_login()) @@ -102,6 +103,19 @@ def carriers_exist(xstep): return wrap +def values_check(xstep): + @functools.wraps(xstep) + def wrap(self, *args, **kwargs): + checks = kwargs.pop('values_check', {}) + if checks: + for field, check, options in checks: + if not check(field, options): + raises.BadRequest(message.invalid_value(field, options)) + ret = yield gen.coroutine(xstep)(self, *args, **kwargs) + raise gen.Return(ret) + return wrap + + def new_not_exists(xstep): @functools.wraps(xstep) def wrap(self, *args, **kwargs): diff --git a/utils/test/testapi/opnfv_testapi/common/config.py b/utils/test/testapi/opnfv_testapi/common/config.py index 140e49283..f888b07be 100644 --- a/utils/test/testapi/opnfv_testapi/common/config.py +++ b/utils/test/testapi/opnfv_testapi/common/config.py @@ -44,7 +44,7 @@ class Config(object): def _parse_value(value): try: value = int(value) - except: + except Exception: if str(value).lower() == 'true': value = True elif str(value).lower() == 'false': diff --git a/utils/test/testapi/opnfv_testapi/common/message.py b/utils/test/testapi/opnfv_testapi/common/message.py index 8b5c3fb7a..3e14f7258 100644 --- a/utils/test/testapi/opnfv_testapi/common/message.py +++ b/utils/test/testapi/opnfv_testapi/common/message.py @@ -26,6 +26,10 @@ def missing(name): return '{} Missing'.format(name) +def invalid_value(name, options): + return '{} must be in {}'.format(name, options) + + def exist(key, value): return '{} [{}] {}'.format(key, value, exist_base) diff --git a/utils/test/testapi/opnfv_testapi/tests/unit/resources/__init__.py b/utils/test/testapi/opnfv_testapi/handlers/__init__.py index e69de29bb..e69de29bb 100644 --- a/utils/test/testapi/opnfv_testapi/tests/unit/resources/__init__.py +++ b/utils/test/testapi/opnfv_testapi/handlers/__init__.py diff --git a/utils/test/testapi/opnfv_testapi/resources/handlers.py b/utils/test/testapi/opnfv_testapi/handlers/base_handlers.py index 8e5dab235..a8ee3db2b 100644 --- a/utils/test/testapi/opnfv_testapi/resources/handlers.py +++ b/utils/test/testapi/opnfv_testapi/handlers/base_handlers.py @@ -20,8 +20,8 @@ # feng.xiaowei@zte.com.cn remove DashboardHandler 5-30-2016 ############################################################################## -import json from datetime import datetime +import json from tornado import gen from tornado import web @@ -30,7 +30,7 @@ from opnfv_testapi.common import check from opnfv_testapi.common import message from opnfv_testapi.common import raises from opnfv_testapi.db import api as dbapi -from opnfv_testapi.resources import models +from opnfv_testapi.models import base_models from opnfv_testapi.tornado_swagger import swagger DEFAULT_REPRESENTATION = "application/json" @@ -67,7 +67,7 @@ class GenericApiHandler(web.RequestHandler): def _create_response(self, resource): href = self.request.full_url() + '/' + str(resource) - return models.CreateResponse(href=href).format() + return base_models.CreateResponse(href=href).format() def format_data(self, data): cls_data = self.table_cls.from_dict(data) @@ -79,6 +79,7 @@ class GenericApiHandler(web.RequestHandler): @check.valid_token @check.no_body @check.miss_fields + @check.values_check @check.carriers_exist @check.new_not_exists def _create(self, **kwargs): diff --git a/utils/test/testapi/opnfv_testapi/resources/pod_handlers.py b/utils/test/testapi/opnfv_testapi/handlers/pod_handlers.py index 502988752..abf5bf9f1 100644 --- a/utils/test/testapi/opnfv_testapi/resources/pod_handlers.py +++ b/utils/test/testapi/opnfv_testapi/handlers/pod_handlers.py @@ -6,12 +6,12 @@ # which accompanies this distribution, and is available at # http://www.apache.org/licenses/LICENSE-2.0 ############################################################################## -import handlers -from opnfv_testapi.resources import pod_models +from opnfv_testapi.handlers import base_handlers +from opnfv_testapi.models import pod_models from opnfv_testapi.tornado_swagger import swagger -class GenericPodHandler(handlers.GenericApiHandler): +class GenericPodHandler(base_handlers.GenericApiHandler): def __init__(self, application, request, **kwargs): super(GenericPodHandler, self).__init__(application, request, **kwargs) self.table = 'pods' diff --git a/utils/test/testapi/opnfv_testapi/resources/project_handlers.py b/utils/test/testapi/opnfv_testapi/handlers/project_handlers.py index be2950705..30d9ab34a 100644 --- a/utils/test/testapi/opnfv_testapi/resources/project_handlers.py +++ b/utils/test/testapi/opnfv_testapi/handlers/project_handlers.py @@ -7,12 +7,12 @@ # http://www.apache.org/licenses/LICENSE-2.0 ############################################################################## -from opnfv_testapi.resources import handlers -from opnfv_testapi.resources import project_models +from opnfv_testapi.handlers import base_handlers +from opnfv_testapi.models import project_models from opnfv_testapi.tornado_swagger import swagger -class GenericProjectHandler(handlers.GenericApiHandler): +class GenericProjectHandler(base_handlers.GenericApiHandler): def __init__(self, application, request, **kwargs): super(GenericProjectHandler, self).__init__(application, request, diff --git a/utils/test/testapi/opnfv_testapi/resources/result_handlers.py b/utils/test/testapi/opnfv_testapi/handlers/result_handlers.py index e202f5c2c..c4b61ff22 100644 --- a/utils/test/testapi/opnfv_testapi/resources/result_handlers.py +++ b/utils/test/testapi/opnfv_testapi/handlers/result_handlers.py @@ -6,23 +6,23 @@ # which accompanies this distribution, and is available at # http://www.apache.org/licenses/LICENSE-2.0 ############################################################################## +from datetime import datetime +from datetime import timedelta import json import logging from bson import objectid -from datetime import datetime -from datetime import timedelta from opnfv_testapi.common import constants from opnfv_testapi.common import message from opnfv_testapi.common import raises from opnfv_testapi.common.config import CONF -from opnfv_testapi.resources import handlers -from opnfv_testapi.resources import result_models +from opnfv_testapi.handlers import base_handlers +from opnfv_testapi.models import result_models from opnfv_testapi.tornado_swagger import swagger -class GenericResultHandler(handlers.GenericApiHandler): +class GenericResultHandler(base_handlers.GenericApiHandler): def __init__(self, application, request, **kwargs): super(GenericResultHandler, self).__init__(application, request, @@ -33,7 +33,7 @@ class GenericResultHandler(handlers.GenericApiHandler): def get_int(self, key, value): try: value = int(value) - except: + except Exception: raises.BadRequest(message.must_int(key)) return value @@ -215,12 +215,18 @@ class ResultsCLHandler(GenericResultHandler): return {'project_name': self.json_args.get('project_name'), 'name': self.json_args.get('case_name')} + def options_check(field, options): + return self.json_args.get(field).upper() in options + miss_fields = ['pod_name', 'project_name', 'case_name'] carriers = [('pods', pod_query), ('projects', project_query), ('testcases', testcase_query)] + values_check = [('criteria', options_check, ['PASS', 'FAIL'])] - self._create(miss_fields=miss_fields, carriers=carriers) + self._create(miss_fields=miss_fields, + carriers=carriers, + values_check=values_check) class ResultsUploadHandler(ResultsCLHandler): diff --git a/utils/test/testapi/opnfv_testapi/ui/root.py b/utils/test/testapi/opnfv_testapi/handlers/root_handlers.py index 286a6b097..92920fa85 100644 --- a/utils/test/testapi/opnfv_testapi/ui/root.py +++ b/utils/test/testapi/opnfv_testapi/handlers/root_handlers.py @@ -1,8 +1,8 @@ from opnfv_testapi.common.config import CONF -from opnfv_testapi.resources import handlers +from opnfv_testapi.handlers import base_handlers -class RootHandler(handlers.GenericApiHandler): +class RootHandler(base_handlers.GenericApiHandler): def get_template_path(self): return CONF.ui_static_path diff --git a/utils/test/testapi/opnfv_testapi/resources/scenario_handlers.py b/utils/test/testapi/opnfv_testapi/handlers/scenario_handlers.py index e9c19a7a4..67abcfff6 100644 --- a/utils/test/testapi/opnfv_testapi/resources/scenario_handlers.py +++ b/utils/test/testapi/opnfv_testapi/handlers/scenario_handlers.py @@ -2,12 +2,12 @@ import functools from opnfv_testapi.common import message from opnfv_testapi.common import raises -from opnfv_testapi.resources import handlers -import opnfv_testapi.resources.scenario_models as models +from opnfv_testapi.handlers import base_handlers +import opnfv_testapi.models.scenario_models as models from opnfv_testapi.tornado_swagger import swagger -class GenericScenarioHandler(handlers.GenericApiHandler): +class GenericScenarioHandler(base_handlers.GenericApiHandler): def __init__(self, application, request, **kwargs): super(GenericScenarioHandler, self).__init__(application, request, diff --git a/utils/test/testapi/opnfv_testapi/ui/auth/sign.py b/utils/test/testapi/opnfv_testapi/handlers/sign_handlers.py index 318473ea2..754066256 100644 --- a/utils/test/testapi/opnfv_testapi/ui/auth/sign.py +++ b/utils/test/testapi/opnfv_testapi/handlers/sign_handlers.py @@ -5,10 +5,10 @@ from tornado import web from opnfv_testapi.common import constants from opnfv_testapi.common.config import CONF from opnfv_testapi.db import api as dbapi -from opnfv_testapi.resources import handlers +from opnfv_testapi.handlers import base_handlers -class SignBaseHandler(handlers.GenericApiHandler): +class SignBaseHandler(base_handlers.GenericApiHandler): def __init__(self, application, request, **kwargs): super(SignBaseHandler, self).__init__(application, request, **kwargs) self.table = 'users' diff --git a/utils/test/testapi/opnfv_testapi/resources/testcase_handlers.py b/utils/test/testapi/opnfv_testapi/handlers/testcase_handlers.py index 9399326f0..c4c3c21f5 100644 --- a/utils/test/testapi/opnfv_testapi/resources/testcase_handlers.py +++ b/utils/test/testapi/opnfv_testapi/handlers/testcase_handlers.py @@ -7,12 +7,12 @@ # http://www.apache.org/licenses/LICENSE-2.0 ############################################################################## -from opnfv_testapi.resources import handlers -from opnfv_testapi.resources import testcase_models +from opnfv_testapi.handlers import base_handlers +from opnfv_testapi.models import testcase_models from opnfv_testapi.tornado_swagger import swagger -class GenericTestcaseHandler(handlers.GenericApiHandler): +class GenericTestcaseHandler(base_handlers.GenericApiHandler): def __init__(self, application, request, **kwargs): super(GenericTestcaseHandler, self).__init__(application, request, diff --git a/utils/test/testapi/opnfv_testapi/handlers/user_handlers.py b/utils/test/testapi/opnfv_testapi/handlers/user_handlers.py new file mode 100644 index 000000000..5067e358b --- /dev/null +++ b/utils/test/testapi/opnfv_testapi/handlers/user_handlers.py @@ -0,0 +1,25 @@ +from opnfv_testapi.common import constants +from opnfv_testapi.common import raises +from opnfv_testapi.common.config import CONF +from opnfv_testapi.handlers import base_handlers +from opnfv_testapi.models.user_models import User + + +class UserHandler(base_handlers.GenericApiHandler): + def __init__(self, application, request, **kwargs): + super(UserHandler, self).__init__(application, request, **kwargs) + self.table = 'users' + self.table_cls = User + + def get(self): + if CONF.api_authenticate: + username = self.get_secure_cookie(constants.TESTAPI_ID) + if username: + self._get_one(query={'user': username}) + else: + raises.Unauthorized('Unauthorized') + else: + self.finish_request(User('anonymous', + 'anonymous@linuxfoundation.com', + 'anonymous lf', + constants.TESTAPI_USERS).format()) diff --git a/utils/test/testapi/opnfv_testapi/resources/__init__.py b/utils/test/testapi/opnfv_testapi/models/__init__.py index 05c0c9392..05c0c9392 100644 --- a/utils/test/testapi/opnfv_testapi/resources/__init__.py +++ b/utils/test/testapi/opnfv_testapi/models/__init__.py diff --git a/utils/test/testapi/opnfv_testapi/resources/models.py b/utils/test/testapi/opnfv_testapi/models/base_models.py index e70a6ed23..27396d116 100644 --- a/utils/test/testapi/opnfv_testapi/resources/models.py +++ b/utils/test/testapi/opnfv_testapi/models/base_models.py @@ -91,10 +91,10 @@ class ModelBase(object): elif isinstance(obj, unicode): try: obj = self._obj_format(ast.literal_eval(obj)) - except: + except Exception: try: obj = str(obj) - except: + except Exception: obj = obj elif isinstance(obj, list): hs = list() diff --git a/utils/test/testapi/opnfv_testapi/resources/pod_models.py b/utils/test/testapi/opnfv_testapi/models/pod_models.py index 415d3d66b..15c283374 100644 --- a/utils/test/testapi/opnfv_testapi/resources/pod_models.py +++ b/utils/test/testapi/opnfv_testapi/models/pod_models.py @@ -6,7 +6,7 @@ # which accompanies this distribution, and is available at # http://www.apache.org/licenses/LICENSE-2.0 ############################################################################## -from opnfv_testapi.resources import models +from opnfv_testapi.models import base_models from opnfv_testapi.tornado_swagger import swagger @@ -17,7 +17,7 @@ from opnfv_testapi.tornado_swagger import swagger @swagger.model() -class PodCreateRequest(models.ModelBase): +class PodCreateRequest(base_models.ModelBase): def __init__(self, name, mode='', details='', role=""): self.name = name self.mode = mode @@ -26,7 +26,7 @@ class PodCreateRequest(models.ModelBase): @swagger.model() -class Pod(models.ModelBase): +class Pod(base_models.ModelBase): def __init__(self, name='', mode='', details='', role="", _id='', create_date='', owner=''): @@ -40,7 +40,7 @@ class Pod(models.ModelBase): @swagger.model() -class Pods(models.ModelBase): +class Pods(base_models.ModelBase): """ @property pods: @ptype pods: C{list} of L{Pod} diff --git a/utils/test/testapi/opnfv_testapi/resources/project_models.py b/utils/test/testapi/opnfv_testapi/models/project_models.py index 3243882bd..5f280f192 100644 --- a/utils/test/testapi/opnfv_testapi/resources/project_models.py +++ b/utils/test/testapi/opnfv_testapi/models/project_models.py @@ -6,26 +6,26 @@ # which accompanies this distribution, and is available at # http://www.apache.org/licenses/LICENSE-2.0 ############################################################################## -from opnfv_testapi.resources import models +from opnfv_testapi.models import base_models from opnfv_testapi.tornado_swagger import swagger @swagger.model() -class ProjectCreateRequest(models.ModelBase): +class ProjectCreateRequest(base_models.ModelBase): def __init__(self, name, description=''): self.name = name self.description = description @swagger.model() -class ProjectUpdateRequest(models.ModelBase): +class ProjectUpdateRequest(base_models.ModelBase): def __init__(self, name='', description=''): self.name = name self.description = description @swagger.model() -class Project(models.ModelBase): +class Project(base_models.ModelBase): def __init__(self, name=None, _id=None, description=None, create_date=None): self._id = _id @@ -35,7 +35,7 @@ class Project(models.ModelBase): @swagger.model() -class Projects(models.ModelBase): +class Projects(base_models.ModelBase): """ @property projects: @ptype projects: C{list} of L{Project} diff --git a/utils/test/testapi/opnfv_testapi/resources/result_models.py b/utils/test/testapi/opnfv_testapi/models/result_models.py index 890bf8220..97fda08b4 100644 --- a/utils/test/testapi/opnfv_testapi/resources/result_models.py +++ b/utils/test/testapi/opnfv_testapi/models/result_models.py @@ -6,12 +6,12 @@ # which accompanies this distribution, and is available at # http://www.apache.org/licenses/LICENSE-2.0 ############################################################################## -from opnfv_testapi.resources import models +from opnfv_testapi.models import base_models from opnfv_testapi.tornado_swagger import swagger @swagger.model() -class TIHistory(models.ModelBase): +class TIHistory(base_models.ModelBase): """ @ptype step: L{float} """ @@ -21,7 +21,7 @@ class TIHistory(models.ModelBase): @swagger.model() -class TI(models.ModelBase): +class TI(base_models.ModelBase): """ @property histories: trust_indicator update histories @ptype histories: C{list} of L{TIHistory} @@ -37,7 +37,7 @@ class TI(models.ModelBase): @swagger.model() -class ResultCreateRequest(models.ModelBase): +class ResultCreateRequest(base_models.ModelBase): """ @property trust_indicator: @ptype trust_indicator: L{TI} @@ -74,7 +74,7 @@ class ResultCreateRequest(models.ModelBase): @swagger.model() -class ResultUpdateRequest(models.ModelBase): +class ResultUpdateRequest(base_models.ModelBase): """ @property trust_indicator: @ptype trust_indicator: L{TI} @@ -84,7 +84,7 @@ class ResultUpdateRequest(models.ModelBase): @swagger.model() -class TestResult(models.ModelBase): +class TestResult(base_models.ModelBase): """ @property trust_indicator: used for long duration test case @ptype trust_indicator: L{TI} @@ -116,7 +116,7 @@ class TestResult(models.ModelBase): @swagger.model() -class TestResults(models.ModelBase): +class TestResults(base_models.ModelBase): """ @property results: @ptype results: C{list} of L{TestResult} diff --git a/utils/test/testapi/opnfv_testapi/resources/scenario_models.py b/utils/test/testapi/opnfv_testapi/models/scenario_models.py index d950ed1d7..0610c6b4c 100644 --- a/utils/test/testapi/opnfv_testapi/resources/scenario_models.py +++ b/utils/test/testapi/opnfv_testapi/models/scenario_models.py @@ -1,4 +1,4 @@ -from opnfv_testapi.resources import models +from opnfv_testapi.models import base_models from opnfv_testapi.tornado_swagger import swagger @@ -11,7 +11,7 @@ def dict_default(value): @swagger.model() -class ScenarioTI(models.ModelBase): +class ScenarioTI(base_models.ModelBase): def __init__(self, date=None, status='silver'): self.date = date self.status = status @@ -25,7 +25,7 @@ class ScenarioTI(models.ModelBase): @swagger.model() -class ScenarioScore(models.ModelBase): +class ScenarioScore(base_models.ModelBase): def __init__(self, date=None, score='0'): self.date = date self.score = score @@ -39,7 +39,7 @@ class ScenarioScore(models.ModelBase): @swagger.model() -class ScenarioProject(models.ModelBase): +class ScenarioProject(base_models.ModelBase): """ @property customs: @ptype customs: C{list} of L{string} @@ -83,7 +83,7 @@ class ScenarioProject(models.ModelBase): @swagger.model() -class ScenarioVersion(models.ModelBase): +class ScenarioVersion(base_models.ModelBase): """ @property projects: @ptype projects: C{list} of L{ScenarioProject} @@ -116,7 +116,7 @@ class ScenarioVersion(models.ModelBase): @swagger.model() -class ScenarioInstaller(models.ModelBase): +class ScenarioInstaller(base_models.ModelBase): """ @property versions: @ptype versions: C{list} of L{ScenarioVersion} @@ -146,7 +146,7 @@ class ScenarioInstaller(models.ModelBase): @swagger.model() -class ScenarioCreateRequest(models.ModelBase): +class ScenarioCreateRequest(base_models.ModelBase): """ @property installers: @ptype installers: C{list} of L{ScenarioInstaller} @@ -161,19 +161,19 @@ class ScenarioCreateRequest(models.ModelBase): @swagger.model() -class ScenarioChangeOwnerRequest(models.ModelBase): +class ScenarioChangeOwnerRequest(base_models.ModelBase): def __init__(self, owner=None): self.owner = owner @swagger.model() -class ScenarioUpdateRequest(models.ModelBase): +class ScenarioUpdateRequest(base_models.ModelBase): def __init__(self, name=None): self.name = name @swagger.model() -class Scenario(models.ModelBase): +class Scenario(base_models.ModelBase): """ @property installers: @ptype installers: C{list} of L{ScenarioInstaller} @@ -205,7 +205,7 @@ class Scenario(models.ModelBase): @swagger.model() -class Scenarios(models.ModelBase): +class Scenarios(base_models.ModelBase): """ @property scenarios: @ptype scenarios: C{list} of L{Scenario} diff --git a/utils/test/testapi/opnfv_testapi/resources/testcase_models.py b/utils/test/testapi/opnfv_testapi/models/testcase_models.py index 2379dfc4c..d1b8877f7 100644 --- a/utils/test/testapi/opnfv_testapi/resources/testcase_models.py +++ b/utils/test/testapi/opnfv_testapi/models/testcase_models.py @@ -6,12 +6,12 @@ # which accompanies this distribution, and is available at # http://www.apache.org/licenses/LICENSE-2.0 ############################################################################## -from opnfv_testapi.resources import models +from opnfv_testapi.models import base_models from opnfv_testapi.tornado_swagger import swagger @swagger.model() -class TestcaseCreateRequest(models.ModelBase): +class TestcaseCreateRequest(base_models.ModelBase): def __init__(self, name, url=None, description=None, catalog_description=None, tier=None, ci_loop=None, criteria=None, blocking=None, dependencies=None, run=None, @@ -33,7 +33,7 @@ class TestcaseCreateRequest(models.ModelBase): @swagger.model() -class TestcaseUpdateRequest(models.ModelBase): +class TestcaseUpdateRequest(base_models.ModelBase): def __init__(self, name=None, description=None, project_name=None, catalog_description=None, tier=None, ci_loop=None, criteria=None, blocking=None, dependencies=None, run=None, @@ -55,7 +55,7 @@ class TestcaseUpdateRequest(models.ModelBase): @swagger.model() -class Testcase(models.ModelBase): +class Testcase(base_models.ModelBase): def __init__(self, _id=None, name=None, project_name=None, description=None, url=None, creation_date=None, catalog_description=None, tier=None, ci_loop=None, @@ -82,7 +82,7 @@ class Testcase(models.ModelBase): @swagger.model() -class Testcases(models.ModelBase): +class Testcases(base_models.ModelBase): """ @property testcases: @ptype testcases: C{list} of L{Testcase} diff --git a/utils/test/testapi/opnfv_testapi/models/user_models.py b/utils/test/testapi/opnfv_testapi/models/user_models.py new file mode 100644 index 000000000..90fbadcd4 --- /dev/null +++ b/utils/test/testapi/opnfv_testapi/models/user_models.py @@ -0,0 +1,9 @@ +from opnfv_testapi.models import base_models + + +class User(base_models.ModelBase): + def __init__(self, user=None, email=None, fullname=None, groups=None): + self.user = user + self.email = email + self.fullname = fullname + self.groups = groups diff --git a/utils/test/testapi/opnfv_testapi/router/url_mappings.py b/utils/test/testapi/opnfv_testapi/router/url_mappings.py index ce0a3eeb3..349d55771 100644 --- a/utils/test/testapi/opnfv_testapi/router/url_mappings.py +++ b/utils/test/testapi/opnfv_testapi/router/url_mappings.py @@ -9,19 +9,19 @@ import tornado.web from opnfv_testapi.common.config import CONF -from opnfv_testapi.resources import handlers -from opnfv_testapi.resources import pod_handlers -from opnfv_testapi.resources import project_handlers -from opnfv_testapi.resources import result_handlers -from opnfv_testapi.resources import scenario_handlers -from opnfv_testapi.resources import testcase_handlers -from opnfv_testapi.ui import root -from opnfv_testapi.ui.auth import sign -from opnfv_testapi.ui.auth import user +from opnfv_testapi.handlers import base_handlers +from opnfv_testapi.handlers import pod_handlers +from opnfv_testapi.handlers import project_handlers +from opnfv_testapi.handlers import result_handlers +from opnfv_testapi.handlers import root_handlers +from opnfv_testapi.handlers import scenario_handlers +from opnfv_testapi.handlers import sign_handlers +from opnfv_testapi.handlers import testcase_handlers +from opnfv_testapi.handlers import user_handlers mappings = [ # GET /versions => GET API version - (r"/versions", handlers.VersionHandler), + (r"/versions", base_handlers.VersionHandler), # few examples: # GET /api/v1/pods => Get all pods @@ -74,10 +74,11 @@ mappings = [ tornado.web.StaticFileHandler, {'path': CONF.ui_static_path}), - (r'/', root.RootHandler), - (r'/api/v1/auth/signin', sign.SigninHandler), - (r'/{}'.format(CONF.lfid_signin_return), sign.SigninReturnHandler), - (r'/api/v1/auth/signout', sign.SignoutHandler), - (r'/api/v1/profile', user.UserHandler), + (r'/', root_handlers.RootHandler), + (r'/api/v1/auth/signin', sign_handlers.SigninHandler), + (r'/{}'.format(CONF.lfid_signin_return), + sign_handlers.SigninReturnHandler), + (r'/api/v1/auth/signout', sign_handlers.SignoutHandler), + (r'/api/v1/profile', user_handlers.UserHandler), ] diff --git a/utils/test/testapi/opnfv_testapi/tests/UI/e2e/podsControllerSpec.js b/utils/test/testapi/opnfv_testapi/tests/UI/e2e/podsControllerSpec.js new file mode 100644 index 000000000..66a57f2f2 --- /dev/null +++ b/utils/test/testapi/opnfv_testapi/tests/UI/e2e/podsControllerSpec.js @@ -0,0 +1,188 @@ +'use strict'; + +var mock = require('protractor-http-mock'); +var baseURL = "http://localhost:8000" +describe('testing the Pods page for anonymous user', function () { + + beforeEach(function(){ + mock([{ + request: { + path: '/api/v1/pods', + method: 'GET' + }, + response: { + data: { + pods: [{role: "community-ci", name: "test", owner: "testUser", details: "DemoDetails", mode: "metal", _id: "59f02f099a07c84bfc5c7aed", creation_date: "2017-10-25 11:58:25.926168"}] + } + } + }]); + }); + + it( 'should navigate to pods link ', function() { + browser.get(baseURL); + var podslink = element(by.linkText('Pods')).click(); + var EC = browser.ExpectedConditions; + browser.wait(EC.urlContains(baseURL+ '/#/pods'), 10000); + }); + + it('create button is not visible for anonymous user', function () { + browser.get(baseURL+'#/pods'); + var buttonCreate = element(by.buttonText('Create')); + expect(buttonCreate.isDisplayed()).toBeFalsy(); + }); + + it('filter button is visible for anonymous user', function () { + var buttonFilter = element(by.buttonText('Filter')); + expect(buttonFilter.isDisplayed()).toBe(true) + }); + + it('clear button is visible for anonymous user', function () { + var buttonClear = element(by.buttonText('Clear')); + expect(buttonClear.isDisplayed()).toBe(true) + }); + + it('Show results when click filter button', function () { + var buttonFilter = element(by.buttonText('Filter')); + buttonFilter.click(); + var pod = element(by.css('.show-pod')); + expect(pod.isPresent()).toBe(true); + }); + + it('Show results when click clear button', function () { + browser.get(baseURL+'#/pods'); + var buttonClear = element(by.buttonText('Clear')); + buttonClear.click(); + var pod = element(by.css('.show-pod')); + expect(pod.isPresent()).toBe(true); + }); + + it('If details is not shown then show details when click the link',function() { + expect(element(by.css('.show-pod.hidden')).isPresent()).toBe(true); + var podslink = element(by.linkText('test')).click(); + expect(element(by.css('.show-pod.hidden')).isPresent()).toBe(false); + }); + + it('If details is shown then hide details when click the link',function() { + expect(element(by.css('.show-pod.hidden')).isPresent()).toBe(false); + var podslink = element(by.linkText('test')).click(); + expect(element(by.css('.show-pod.hidden')).isPresent()).toBe(true); + }); + + it('If backend is not responding then show error when click filter button', function () { + browser.get(baseURL + '/#/pods'); + mock.teardown(); + var buttonFilter = element(by.buttonText('Filter')); + buttonFilter.click().then(function(){ + expect(element(by.css('.alert.alert-danger.ng-binding.ng-scope')).isDisplayed()).toBe(true); + }); + }); + +}); + +describe('testing the Pods page for authorized user', function () { + + beforeEach(function(){ + mock([ + { + request: { + path: '/api/v1/pods', + method: 'POST' + }, + response: { + data: { + href: baseURL+"/api/v1/pods/test" + } + } + }, + { + request: { + path: '/api/v1/pods', + method: 'POST', + data: { + name: 'test1', + details : 'DemoDetails', + role : 'community-ci', + mode : 'metal' + } + }, + response: { + status : 403 + } + }, + { + request: { + path: '/api/v1/profile', + method: 'GET' + }, + response: { + data: { + "fullname": "Test User", "_id": "79f82eey9a00c84bfhc7aed", "user": "testUser", "groups": ["opnfv-testapi-users"], "email": "testuser@test.com" + } + } + } + ]); + }); + + it('create button is visible for authorized user', function () { + browser.get(baseURL + '/#/pods'); + var buttonCreate = element(by.buttonText('Create')); + expect(buttonCreate.isDisplayed()).toBe(true); + }); + + it('Do not show error if input is acceptable', function () { + var name = element(by.model('ctrl.name')); + var details = element(by.model('ctrl.details')); + name.sendKeys('test'); + details.sendKeys('DemoDetails'); + var buttonCreate = element(by.buttonText('Create')); + buttonCreate.click().then(function(){ + expect(element(by.css('.alert.alert-danger.ng-binding.ng-scope')).isDisplayed()).toBe(false); + }); + }); + + it('Show error when user click the create button with a empty name', function () { + browser.get(baseURL+ '/#/pods'); + var details = element(by.model('ctrl.details')); + details.sendKeys('DemoDetails'); + var buttonCreate = element(by.buttonText('Create')); + buttonCreate.click(); + expect(element(by.cssContainingText(".alert","Name is missing.")).isDisplayed()).toBe(true); + }); + + it('Show error when user click the create button with an already existing name', function () { + browser.get(baseURL+ '/#/pods'); + var name = element(by.model('ctrl.name')); + var details = element(by.model('ctrl.details')); + name.sendKeys('test1'); + details.sendKeys('DemoDetails'); + var buttonCreate = element(by.buttonText('Create')); + buttonCreate.click(); + expect(element(by.cssContainingText(".alert","Error creating the new pod from server: Pod's name already exists")).isDisplayed()).toBe(true); + }); + + it('If backend is not responding then show error when user click the create button',function(){ + mock.teardown(); + mock([ + { + request: { + path: '/api/v1/profile', + method: 'GET' + }, + response: { + data: { + "fullname": "Test User", "_id": "79f82eey9a00c84bfhc7aed", "user": "testUser", "groups": ["opnfv-testapi-users"], "email": "testuser@test.com" + } + } + } + ]); + browser.get(baseURL+ '/#/pods'); + var name = element(by.model('ctrl.name')); + var details = element(by.model('ctrl.details')); + name.sendKeys('test'); + details.sendKeys('DemoDetails'); + var buttonCreate = element(by.buttonText('Create')); + buttonCreate.click().then(function(){ + expect(element(by.css('.alert.alert-danger.ng-binding.ng-scope')).isDisplayed()).toBe(true); + }); + }) +});
\ No newline at end of file diff --git a/utils/test/testapi/opnfv_testapi/tests/UI/karma.conf.js b/utils/test/testapi/opnfv_testapi/tests/UI/karma.conf.js new file mode 100644 index 000000000..eaded5a1d --- /dev/null +++ b/utils/test/testapi/opnfv_testapi/tests/UI/karma.conf.js @@ -0,0 +1,14 @@ +module.exports = function (config) { + config.set({ + frameworks: ['jasmine'], + files: [ + "assets/lib/angular/angular.js", + "assets/lib/angular-mocks/angular-mocks.js", + ], + autoWatch: true, + browsers: ['Chrome'], + singleRun: true, + reporters: ['progress', 'coverage'], + preprocessors: { 'src/*.js': ['coverage'] } + }); +}; diff --git a/utils/test/testapi/opnfv_testapi/tests/UI/protractor-conf.js b/utils/test/testapi/opnfv_testapi/tests/UI/protractor-conf.js new file mode 100644 index 000000000..affbe5d26 --- /dev/null +++ b/utils/test/testapi/opnfv_testapi/tests/UI/protractor-conf.js @@ -0,0 +1,18 @@ +exports.config = { + seleniumAddress: 'http://localhost:4444/wd/hub', + capabilities: { + 'browserName': 'chrome', + 'chromeOptions': { + 'args': ['show-fps-counter=true', '--disable-web-security', "no-sandbox", "--headless", "--disable-gpu"] + } + }, + jasmineNodeOpts: { + showColors: true, + defaultTimeoutInterval: 30000 + }, + onPrepare: function(){ + require('protractor-http-mock').config = { + rootDirectory: __dirname + }; + } +}; diff --git a/utils/test/testapi/opnfv_testapi/tests/unit/common/test_config.py b/utils/test/testapi/opnfv_testapi/tests/unit/common/test_config.py index ea2297275..6d160ce1d 100644 --- a/utils/test/testapi/opnfv_testapi/tests/unit/common/test_config.py +++ b/utils/test/testapi/opnfv_testapi/tests/unit/common/test_config.py @@ -12,7 +12,8 @@ def test_config_normal(mocker, config_normal): assert CONF.mongo_dbname == 'test_results_collection' assert CONF.api_port == 8000 assert CONF.api_debug is True - assert CONF.api_authenticate is False + assert CONF.api_token_check is False + assert CONF.api_authenticate is True assert CONF.ui_url == 'http://localhost:8000' diff --git a/utils/test/testapi/opnfv_testapi/tests/unit/executor.py b/utils/test/testapi/opnfv_testapi/tests/unit/executor.py index aa99b9086..743c07615 100644 --- a/utils/test/testapi/opnfv_testapi/tests/unit/executor.py +++ b/utils/test/testapi/opnfv_testapi/tests/unit/executor.py @@ -14,7 +14,7 @@ import mock O_get_secure_cookie = ( - 'opnfv_testapi.resources.handlers.GenericApiHandler.get_secure_cookie') + 'opnfv_testapi.handlers.base_handlers.GenericApiHandler.get_secure_cookie') def thread_execute(method, *args, **kwargs): diff --git a/utils/test/testapi/opnfv_testapi/ui/__init__.py b/utils/test/testapi/opnfv_testapi/tests/unit/handlers/__init__.py index e69de29bb..e69de29bb 100644 --- a/utils/test/testapi/opnfv_testapi/ui/__init__.py +++ b/utils/test/testapi/opnfv_testapi/tests/unit/handlers/__init__.py diff --git a/utils/test/testapi/opnfv_testapi/tests/unit/resources/scenario-c1.json b/utils/test/testapi/opnfv_testapi/tests/unit/handlers/scenario-c1.json index 187802215..187802215 100644 --- a/utils/test/testapi/opnfv_testapi/tests/unit/resources/scenario-c1.json +++ b/utils/test/testapi/opnfv_testapi/tests/unit/handlers/scenario-c1.json diff --git a/utils/test/testapi/opnfv_testapi/tests/unit/resources/scenario-c2.json b/utils/test/testapi/opnfv_testapi/tests/unit/handlers/scenario-c2.json index 980051c4f..980051c4f 100644 --- a/utils/test/testapi/opnfv_testapi/tests/unit/resources/scenario-c2.json +++ b/utils/test/testapi/opnfv_testapi/tests/unit/handlers/scenario-c2.json diff --git a/utils/test/testapi/opnfv_testapi/tests/unit/resources/test_base.py b/utils/test/testapi/opnfv_testapi/tests/unit/handlers/test_base.py index 89cd7e8ed..b7fabb994 100644 --- a/utils/test/testapi/opnfv_testapi/tests/unit/resources/test_base.py +++ b/utils/test/testapi/opnfv_testapi/tests/unit/handlers/test_base.py @@ -14,8 +14,8 @@ from bson.objectid import ObjectId import mock from tornado import testing -from opnfv_testapi.resources import models -from opnfv_testapi.resources import pod_models +from opnfv_testapi.models import base_models +from opnfv_testapi.models import pod_models from opnfv_testapi.tests.unit import fake_pymongo @@ -25,7 +25,7 @@ class TestBase(testing.AsyncHTTPTestCase): def setUp(self): self._patch_server() self.basePath = '' - self.create_res = models.CreateResponse + self.create_res = base_models.CreateResponse self.get_res = None self.list_res = None self.update_res = None diff --git a/utils/test/testapi/opnfv_testapi/tests/unit/resources/test_pod.py b/utils/test/testapi/opnfv_testapi/tests/unit/handlers/test_pod.py index 5d9da3a86..95ed8bac1 100644 --- a/utils/test/testapi/opnfv_testapi/tests/unit/resources/test_pod.py +++ b/utils/test/testapi/opnfv_testapi/tests/unit/handlers/test_pod.py @@ -10,10 +10,10 @@ import httplib import unittest from opnfv_testapi.common import message -from opnfv_testapi.resources import pod_models +from opnfv_testapi.models import pod_models from opnfv_testapi.tests.unit import executor from opnfv_testapi.tests.unit import fake_pymongo -from opnfv_testapi.tests.unit.resources import test_base as base +from opnfv_testapi.tests.unit.handlers import test_base as base class TestPodBase(base.TestBase): diff --git a/utils/test/testapi/opnfv_testapi/tests/unit/resources/test_project.py b/utils/test/testapi/opnfv_testapi/tests/unit/handlers/test_project.py index 0622ba8d4..939cc0d07 100644 --- a/utils/test/testapi/opnfv_testapi/tests/unit/resources/test_project.py +++ b/utils/test/testapi/opnfv_testapi/tests/unit/handlers/test_project.py @@ -2,9 +2,9 @@ import httplib import unittest from opnfv_testapi.common import message -from opnfv_testapi.resources import project_models +from opnfv_testapi.models import project_models from opnfv_testapi.tests.unit import executor -from opnfv_testapi.tests.unit.resources import test_base as base +from opnfv_testapi.tests.unit.handlers import test_base as base class TestProjectBase(base.TestBase): diff --git a/utils/test/testapi/opnfv_testapi/tests/unit/resources/test_result.py b/utils/test/testapi/opnfv_testapi/tests/unit/handlers/test_result.py index 1df31f36c..b9f9ede26 100644 --- a/utils/test/testapi/opnfv_testapi/tests/unit/resources/test_result.py +++ b/utils/test/testapi/opnfv_testapi/tests/unit/handlers/test_result.py @@ -15,12 +15,12 @@ import urllib import unittest from opnfv_testapi.common import message -from opnfv_testapi.resources import project_models -from opnfv_testapi.resources import result_models -from opnfv_testapi.resources import testcase_models +from opnfv_testapi.models import project_models +from opnfv_testapi.models import result_models +from opnfv_testapi.models import testcase_models from opnfv_testapi.tests.unit import executor from opnfv_testapi.tests.unit import fake_pymongo -from opnfv_testapi.tests.unit.resources import test_base as base +from opnfv_testapi.tests.unit.handlers import test_base as base class Details(object): @@ -62,7 +62,7 @@ class TestResultBase(base.TestBase): self.version = 'C' self.build_tag = 'v3.0' self.scenario = 'odl-l2' - self.criteria = 'passed' + self.criteria = 'PASS' self.trust_indicator = result_models.TI(0.7) self.start_date = str(datetime.now()) self.stop_date = str(datetime.now() + timedelta(minutes=1)) @@ -170,6 +170,13 @@ class TestResultCreate(TestResultBase): req.case_name = None return req + @executor.create(httplib.BAD_REQUEST, + message.invalid_value('criteria', ['PASS', 'FAIL'])) + def test_invalid_criteria(self): + req = self.req_d + req.criteria = 'invalid' + return req + @executor.create(httplib.FORBIDDEN, message.not_found_base) def test_noPod(self): req = self.req_d diff --git a/utils/test/testapi/opnfv_testapi/tests/unit/resources/test_scenario.py b/utils/test/testapi/opnfv_testapi/tests/unit/handlers/test_scenario.py index 1367fc669..de7777a83 100644 --- a/utils/test/testapi/opnfv_testapi/tests/unit/resources/test_scenario.py +++ b/utils/test/testapi/opnfv_testapi/tests/unit/handlers/test_scenario.py @@ -6,8 +6,8 @@ import os from datetime import datetime from opnfv_testapi.common import message -import opnfv_testapi.resources.scenario_models as models -from opnfv_testapi.tests.unit.resources import test_base as base +import opnfv_testapi.models.scenario_models as models +from opnfv_testapi.tests.unit.handlers import test_base as base def _none_default(check, default): diff --git a/utils/test/testapi/opnfv_testapi/tests/unit/resources/test_testcase.py b/utils/test/testapi/opnfv_testapi/tests/unit/handlers/test_testcase.py index 4f2bc2ad1..e4c668e7a 100644 --- a/utils/test/testapi/opnfv_testapi/tests/unit/resources/test_testcase.py +++ b/utils/test/testapi/opnfv_testapi/tests/unit/handlers/test_testcase.py @@ -11,10 +11,10 @@ import httplib import unittest from opnfv_testapi.common import message -from opnfv_testapi.resources import project_models -from opnfv_testapi.resources import testcase_models +from opnfv_testapi.models import project_models +from opnfv_testapi.models import testcase_models from opnfv_testapi.tests.unit import executor -from opnfv_testapi.tests.unit.resources import test_base as base +from opnfv_testapi.tests.unit.handlers import test_base as base class TestCaseBase(base.TestBase): diff --git a/utils/test/testapi/opnfv_testapi/tests/unit/resources/test_token.py b/utils/test/testapi/opnfv_testapi/tests/unit/handlers/test_token.py index bd64723be..e8b746dfc 100644 --- a/utils/test/testapi/opnfv_testapi/tests/unit/resources/test_token.py +++ b/utils/test/testapi/opnfv_testapi/tests/unit/handlers/test_token.py @@ -11,7 +11,7 @@ from tornado import web from opnfv_testapi.common import message from opnfv_testapi.tests.unit import executor from opnfv_testapi.tests.unit import fake_pymongo -from opnfv_testapi.tests.unit.resources import test_result +from opnfv_testapi.tests.unit.handlers import test_result class TestTokenCreateResult(test_result.TestResultBase): diff --git a/utils/test/testapi/opnfv_testapi/tests/unit/resources/test_version.py b/utils/test/testapi/opnfv_testapi/tests/unit/handlers/test_version.py index 51fed11ea..6ef810f0e 100644 --- a/utils/test/testapi/opnfv_testapi/tests/unit/resources/test_version.py +++ b/utils/test/testapi/opnfv_testapi/tests/unit/handlers/test_version.py @@ -9,15 +9,15 @@ import httplib import unittest -from opnfv_testapi.resources import models +from opnfv_testapi.models import base_models from opnfv_testapi.tests.unit import executor -from opnfv_testapi.tests.unit.resources import test_base as base +from opnfv_testapi.tests.unit.handlers import test_base as base class TestVersionBase(base.TestBase): def setUp(self): super(TestVersionBase, self).setUp() - self.list_res = models.Versions + self.list_res = base_models.Versions self.basePath = '/versions' diff --git a/utils/test/testapi/opnfv_testapi/tests/unit/resources/test_fake_pymongo.py b/utils/test/testapi/opnfv_testapi/tests/unit/resources/test_fake_pymongo.py deleted file mode 100644 index 1ebc96f3b..000000000 --- a/utils/test/testapi/opnfv_testapi/tests/unit/resources/test_fake_pymongo.py +++ /dev/null @@ -1,123 +0,0 @@ -############################################################################## -# Copyright (c) 2016 ZTE Corporation -# feng.xiaowei@zte.com.cn -# 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 unittest - -from tornado import gen -from tornado import testing -from tornado import web - -from opnfv_testapi.tests.unit import fake_pymongo - - -class MyTest(testing.AsyncHTTPTestCase): - def setUp(self): - super(MyTest, self).setUp() - self.db = fake_pymongo - self.addCleanup(self._clear) - self.io_loop.run_sync(self.fixture_setup) - - def get_app(self): - return web.Application() - - @gen.coroutine - def fixture_setup(self): - self.test1 = {'_id': '1', 'name': 'test1'} - self.test2 = {'name': 'test2'} - yield self.db.pods.insert({'_id': '1', 'name': 'test1'}) - yield self.db.pods.insert({'name': 'test2'}) - - @testing.gen_test - def test_find_one(self): - user = yield self.db.pods.find_one({'name': 'test1'}) - self.assertEqual(user, self.test1) - self.db.pods.remove() - - @testing.gen_test - def test_find(self): - cursor = self.db.pods.find() - names = [] - while (yield cursor.fetch_next): - ob = cursor.next_object() - names.append(ob.get('name')) - self.assertItemsEqual(names, ['test1', 'test2']) - - @testing.gen_test - def test_update(self): - yield self.db.pods.update({'_id': '1'}, {'name': 'new_test1'}) - user = yield self.db.pods.find_one({'_id': '1'}) - self.assertEqual(user.get('name', None), 'new_test1') - - def test_update_dot_error(self): - self._update_assert({'_id': '1', 'name': {'1. name': 'test1'}}, - 'key 1. name must not contain .') - - def test_update_dot_no_error(self): - self._update_assert({'_id': '1', 'name': {'1. name': 'test1'}}, - None, - check_keys=False) - - def test_update_dollar_error(self): - self._update_assert({'_id': '1', 'name': {'$name': 'test1'}}, - 'key $name must not start with $') - - def test_update_dollar_no_error(self): - self._update_assert({'_id': '1', 'name': {'$name': 'test1'}}, - None, - check_keys=False) - - @testing.gen_test - def test_remove(self): - yield self.db.pods.remove({'_id': '1'}) - user = yield self.db.pods.find_one({'_id': '1'}) - self.assertIsNone(user) - - def test_insert_dot_error(self): - self._insert_assert({'_id': '1', '2. name': 'test1'}, - 'key 2. name must not contain .') - - def test_insert_dot_no_error(self): - self._insert_assert({'_id': '1', '2. name': 'test1'}, - None, - check_keys=False) - - def test_insert_dollar_error(self): - self._insert_assert({'_id': '1', '$name': 'test1'}, - 'key $name must not start with $') - - def test_insert_dollar_no_error(self): - self._insert_assert({'_id': '1', '$name': 'test1'}, - None, - check_keys=False) - - def _clear(self): - self.db.pods.clear() - - def _update_assert(self, docs, error=None, **kwargs): - self._db_assert('update', error, {'_id': '1'}, docs, **kwargs) - - def _insert_assert(self, docs, error=None, **kwargs): - self._db_assert('insert', error, docs, **kwargs) - - @testing.gen_test - def _db_assert(self, method, error, *args, **kwargs): - name_error = None - try: - yield self._eval_pods_db(method, *args, **kwargs) - except NameError as err: - name_error = err.args[0] - finally: - self.assertEqual(name_error, error) - - def _eval_pods_db(self, method, *args, **kwargs): - table_obj = vars(self.db)['pods'] - return table_obj.__getattribute__(method)(*args, **kwargs) - - -if __name__ == '__main__': - unittest.main() diff --git a/utils/test/testapi/opnfv_testapi/tornado_swagger/handlers.py b/utils/test/testapi/opnfv_testapi/tornado_swagger/handlers.py index e39a9f639..a04de07f7 100644 --- a/utils/test/testapi/opnfv_testapi/tornado_swagger/handlers.py +++ b/utils/test/testapi/opnfv_testapi/tornado_swagger/handlers.py @@ -26,7 +26,7 @@ def swagger_handlers(): settings.docs_settings, name=settings.API_DOCS_NAME), tornado.web.URLSpec( - _path(r'resources.json$'), + _path(r'models.json$'), views.SwaggerResourcesHandler, settings.docs_settings, name=settings.RESOURCE_LISTING_NAME), diff --git a/utils/test/testapi/3rd_party/static/testapi-ui/components/about/about.html b/utils/test/testapi/opnfv_testapi/ui/about/about.html index 65860a8cc..65860a8cc 100644 --- a/utils/test/testapi/3rd_party/static/testapi-ui/components/about/about.html +++ b/utils/test/testapi/opnfv_testapi/ui/about/about.html diff --git a/utils/test/testapi/3rd_party/static/testapi-ui/components/auth-failure/authFailureController.js b/utils/test/testapi/opnfv_testapi/ui/auth-failure/authFailureController.js index 29d1d70fa..29d1d70fa 100644 --- a/utils/test/testapi/3rd_party/static/testapi-ui/components/auth-failure/authFailureController.js +++ b/utils/test/testapi/opnfv_testapi/ui/auth-failure/authFailureController.js diff --git a/utils/test/testapi/opnfv_testapi/ui/auth/__init__.py b/utils/test/testapi/opnfv_testapi/ui/auth/__init__.py deleted file mode 100644 index e69de29bb..000000000 --- a/utils/test/testapi/opnfv_testapi/ui/auth/__init__.py +++ /dev/null diff --git a/utils/test/testapi/opnfv_testapi/ui/auth/user.py b/utils/test/testapi/opnfv_testapi/ui/auth/user.py deleted file mode 100644 index ab86007f1..000000000 --- a/utils/test/testapi/opnfv_testapi/ui/auth/user.py +++ /dev/null @@ -1,26 +0,0 @@ -from opnfv_testapi.common import constants -from opnfv_testapi.common import raises -from opnfv_testapi.resources import handlers -from opnfv_testapi.resources import models - - -class User(models.ModelBase): - def __init__(self, user=None, email=None, fullname=None, groups=None): - self.user = user - self.email = email - self.fullname = fullname - self.groups = groups - - -class UserHandler(handlers.GenericApiHandler): - def __init__(self, application, request, **kwargs): - super(UserHandler, self).__init__(application, request, **kwargs) - self.table = 'users' - self.table_cls = User - - def get(self): - username = self.get_secure_cookie(constants.TESTAPI_ID) - if username: - self._get_one(query={'user': username}) - else: - raises.Unauthorized('Unauthorized') diff --git a/utils/test/testapi/3rd_party/static/testapi-ui/components/home/home.html b/utils/test/testapi/opnfv_testapi/ui/home/home.html index 47d747fd8..47d747fd8 100644 --- a/utils/test/testapi/3rd_party/static/testapi-ui/components/home/home.html +++ b/utils/test/testapi/opnfv_testapi/ui/home/home.html diff --git a/utils/test/testapi/3rd_party/static/testapi-ui/components/logout/logout.html b/utils/test/testapi/opnfv_testapi/ui/logout/logout.html index 38a5c3698..38a5c3698 100644 --- a/utils/test/testapi/3rd_party/static/testapi-ui/components/logout/logout.html +++ b/utils/test/testapi/opnfv_testapi/ui/logout/logout.html diff --git a/utils/test/testapi/3rd_party/static/testapi-ui/components/logout/logoutController.js b/utils/test/testapi/opnfv_testapi/ui/logout/logoutController.js index 1b6d78c63..1b6d78c63 100644 --- a/utils/test/testapi/3rd_party/static/testapi-ui/components/logout/logoutController.js +++ b/utils/test/testapi/opnfv_testapi/ui/logout/logoutController.js diff --git a/utils/test/testapi/3rd_party/static/testapi-ui/components/pods/pods.html b/utils/test/testapi/opnfv_testapi/ui/pods/pods.html index 22f29347b..22f29347b 100644 --- a/utils/test/testapi/3rd_party/static/testapi-ui/components/pods/pods.html +++ b/utils/test/testapi/opnfv_testapi/ui/pods/pods.html diff --git a/utils/test/testapi/3rd_party/static/testapi-ui/components/pods/podsController.js b/utils/test/testapi/opnfv_testapi/ui/pods/podsController.js index 489fa8a8d..489fa8a8d 100644 --- a/utils/test/testapi/3rd_party/static/testapi-ui/components/pods/podsController.js +++ b/utils/test/testapi/opnfv_testapi/ui/pods/podsController.js diff --git a/utils/test/testapi/3rd_party/static/testapi-ui/components/profile/importPubKeyModal.html b/utils/test/testapi/opnfv_testapi/ui/profile/importPubKeyModal.html index 0f55c27fd..0f55c27fd 100644 --- a/utils/test/testapi/3rd_party/static/testapi-ui/components/profile/importPubKeyModal.html +++ b/utils/test/testapi/opnfv_testapi/ui/profile/importPubKeyModal.html diff --git a/utils/test/testapi/3rd_party/static/testapi-ui/components/profile/profile.html b/utils/test/testapi/opnfv_testapi/ui/profile/profile.html index 763f5d120..763f5d120 100644 --- a/utils/test/testapi/3rd_party/static/testapi-ui/components/profile/profile.html +++ b/utils/test/testapi/opnfv_testapi/ui/profile/profile.html diff --git a/utils/test/testapi/3rd_party/static/testapi-ui/components/profile/profileController.js b/utils/test/testapi/opnfv_testapi/ui/profile/profileController.js index 5dbdf7b1a..5dbdf7b1a 100644 --- a/utils/test/testapi/3rd_party/static/testapi-ui/components/profile/profileController.js +++ b/utils/test/testapi/opnfv_testapi/ui/profile/profileController.js diff --git a/utils/test/testapi/3rd_party/static/testapi-ui/components/profile/showPubKeyModal.html b/utils/test/testapi/opnfv_testapi/ui/profile/showPubKeyModal.html index 5f63a5ef6..5f63a5ef6 100644 --- a/utils/test/testapi/3rd_party/static/testapi-ui/components/profile/showPubKeyModal.html +++ b/utils/test/testapi/opnfv_testapi/ui/profile/showPubKeyModal.html diff --git a/utils/test/testapi/3rd_party/static/testapi-ui/components/results-report/partials/editTestModal.html b/utils/test/testapi/opnfv_testapi/ui/results-report/partials/editTestModal.html index 583c9b92b..583c9b92b 100644 --- a/utils/test/testapi/3rd_party/static/testapi-ui/components/results-report/partials/editTestModal.html +++ b/utils/test/testapi/opnfv_testapi/ui/results-report/partials/editTestModal.html diff --git a/utils/test/testapi/3rd_party/static/testapi-ui/components/results-report/partials/fullTestListModal.html b/utils/test/testapi/opnfv_testapi/ui/results-report/partials/fullTestListModal.html index 6db198b02..6db198b02 100644 --- a/utils/test/testapi/3rd_party/static/testapi-ui/components/results-report/partials/fullTestListModal.html +++ b/utils/test/testapi/opnfv_testapi/ui/results-report/partials/fullTestListModal.html diff --git a/utils/test/testapi/3rd_party/static/testapi-ui/components/results-report/partials/reportDetails.html b/utils/test/testapi/opnfv_testapi/ui/results-report/partials/reportDetails.html index 517e569c7..517e569c7 100644 --- a/utils/test/testapi/3rd_party/static/testapi-ui/components/results-report/partials/reportDetails.html +++ b/utils/test/testapi/opnfv_testapi/ui/results-report/partials/reportDetails.html diff --git a/utils/test/testapi/3rd_party/static/testapi-ui/components/results-report/resultsReport.html b/utils/test/testapi/opnfv_testapi/ui/results-report/resultsReport.html index 5527121ba..5527121ba 100644 --- a/utils/test/testapi/3rd_party/static/testapi-ui/components/results-report/resultsReport.html +++ b/utils/test/testapi/opnfv_testapi/ui/results-report/resultsReport.html diff --git a/utils/test/testapi/3rd_party/static/testapi-ui/components/results-report/resultsReportController.js b/utils/test/testapi/opnfv_testapi/ui/results-report/resultsReportController.js index 591ad402b..591ad402b 100644 --- a/utils/test/testapi/3rd_party/static/testapi-ui/components/results-report/resultsReportController.js +++ b/utils/test/testapi/opnfv_testapi/ui/results-report/resultsReportController.js diff --git a/utils/test/testapi/3rd_party/static/testapi-ui/components/results/results.html b/utils/test/testapi/opnfv_testapi/ui/results/results.html index 2ae5339a0..2ae5339a0 100644 --- a/utils/test/testapi/3rd_party/static/testapi-ui/components/results/results.html +++ b/utils/test/testapi/opnfv_testapi/ui/results/results.html diff --git a/utils/test/testapi/3rd_party/static/testapi-ui/components/results/resultsController.js b/utils/test/testapi/opnfv_testapi/ui/results/resultsController.js index cc6cc0b6e..cc6cc0b6e 100644 --- a/utils/test/testapi/3rd_party/static/testapi-ui/components/results/resultsController.js +++ b/utils/test/testapi/opnfv_testapi/ui/results/resultsController.js diff --git a/utils/test/testapi/setup.cfg b/utils/test/testapi/setup.cfg index 23341e4b4..b3394d44f 100644 --- a/utils/test/testapi/setup.cfg +++ b/utils/test/testapi/setup.cfg @@ -1,8 +1,6 @@ [metadata] name = opnfv_testapi summary = Test Result Collector -description-file = - README.rst author = SerenaFeng author-email = feng.xiaowei@zte.com.cn #home-page = http://www.opnfv.org/ @@ -28,6 +26,7 @@ packages = data_files = /etc/opnfv_testapi = etc/config.ini /usr/local/share/opnfv_testapi = 3rd_party/static/* + /usr/local/share/opnfv_testapi/testapi-ui/components = opnfv_testapi/ui/* [entry_points] console_scripts = diff --git a/utils/test/testapi/tox.ini b/utils/test/testapi/tox.ini index d300f1a61..13b197c63 100644 --- a/utils/test/testapi/tox.ini +++ b/utils/test/testapi/tox.ini @@ -25,6 +25,10 @@ setenv= HOME = {envtmpdir} PYTHONPATH = {toxinidir} +[testenv:docs] +basepython=python2.7 +commands = sphinx-build -W -b html docs/ docs/_build + [testenv:pep8] deps = flake8 commands = flake8 {toxinidir} |