aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--examples/compute-qpi-report/qpi.json250
-rw-r--r--examples/compute-qpi-report/report.ipynb71
-rw-r--r--qtip/web/bench/__init__.py0
-rw-r--r--qtip/web/bench/admin.py22
-rw-r--r--qtip/web/bench/apps.py8
-rw-r--r--qtip/web/bench/migrations/0001_initial.py36
-rw-r--r--qtip/web/bench/migrations/0002_auto_20170713_0210.py20
-rw-r--r--qtip/web/bench/migrations/0003_auto_20170713_0225.py20
-rw-r--r--qtip/web/bench/migrations/__init__.py0
-rw-r--r--qtip/web/bench/models.py28
-rw-r--r--qtip/web/bench/tests.py6
-rw-r--r--qtip/web/bench/views.py6
-rwxr-xr-xqtip/web/manage.py22
-rw-r--r--qtip/web/web/__init__.py0
-rw-r--r--qtip/web/web/settings.py121
-rw-r--r--qtip/web/web/urls.py21
-rw-r--r--qtip/web/web/wsgi.py16
-rw-r--r--requirements.txt3
-rw-r--r--tests/ci/run_ci.sh6
20 files changed, 655 insertions, 2 deletions
diff --git a/.gitignore b/.gitignore
index f2849f1e..9df6dccd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -54,6 +54,7 @@ data/my_key.pem
# Django stuff:
*.log
+*.sqlite3
# Sphinx documentation
docs/_build/
diff --git a/examples/compute-qpi-report/qpi.json b/examples/compute-qpi-report/qpi.json
new file mode 100644
index 00000000..313b0ed5
--- /dev/null
+++ b/examples/compute-qpi-report/qpi.json
@@ -0,0 +1,250 @@
+{
+ "score": 1789,
+ "nodes": [
+ {
+ "name": "node-9",
+ "description": "QTIP Performance Index of compute",
+ "system_info": {
+ "product": [
+ "KVM"
+ ],
+ "disk": [
+ "53.7GB (5.9% used)"
+ ],
+ "os": [
+ "Ubuntu 14.04 trusty"
+ ],
+ "memory": [
+ "799.5/3945.4MB"
+ ]
+ },
+ "score": 1789,
+ "sections": [
+ {
+ "metrics": [
+ {
+ "score": 0.8011997053326527,
+ "workloads": [
+ {
+ "description": "workload",
+ "score": 0.906301071363719,
+ "result": "14973.3",
+ "name": "rsa_sign_512"
+ },
+ {
+ "description": "workload",
+ "score": 0.9057407614156525,
+ "result": "202818.2",
+ "name": "rsa_verify_512"
+ },
+ {
+ "description": "workload",
+ "score": 0.9153740089624267,
+ "result": "5311.7",
+ "name": "rsa_sign_1024"
+ },
+ {
+ "description": "workload",
+ "score": 0.8537774532382183,
+ "result": "75999.7",
+ "name": "rsa_verify_1024"
+ },
+ {
+ "description": "workload",
+ "score": 0.5396440129449838,
+ "result": "667.9",
+ "name": "rsa_sign_2048"
+ },
+ {
+ "description": "workload",
+ "score": 0.8264622658404671,
+ "result": "23074.2",
+ "name": "rsa_verify_2048"
+ },
+ {
+ "description": "workload",
+ "score": 0.7456140350877193,
+ "result": "85.0",
+ "name": "rsa_sign_4096"
+ },
+ {
+ "description": "workload",
+ "score": 0.7166840338080352,
+ "result": "6190.5",
+ "name": "rsa_verify_4096"
+ }
+ ],
+ "name": "ssl_rsa",
+ "description": "metric"
+ },
+ {
+ "score": 0.8825181751154869,
+ "workloads": [
+ {
+ "description": "workload",
+ "score": 0.8370586428196568,
+ "result": "455386.11k",
+ "name": "aes_128_cbc_16_bytes"
+ },
+ {
+ "description": "workload",
+ "score": 0.88480457910821,
+ "result": "508865.58k",
+ "name": "aes_128_cbc_64_bytes"
+ },
+ {
+ "description": "workload",
+ "score": 0.8915887914399657,
+ "result": "523945.47k",
+ "name": "aes_128_cbc_256_bytes"
+ },
+ {
+ "description": "workload",
+ "score": 0.9128156148324568,
+ "result": "543212.20k",
+ "name": "aes_128_cbc_1024_bytes"
+ },
+ {
+ "description": "workload",
+ "score": 0.8863232473771453,
+ "result": "523026.43k",
+ "name": "aes_128_cbc_8192_bytes"
+ }
+ ],
+ "name": "ssl_aes",
+ "description": "metric"
+ }
+ ],
+ "score": 0.8418589402240698,
+ "name": "SSL",
+ "description": "cryptography and SSL/TLS performance"
+ },
+ {
+ "metrics": [
+ {
+ "score": 0.44965595077729636,
+ "workloads": [
+ {
+ "description": "workload",
+ "score": 0.45041322314049587,
+ "result": "1.09 M",
+ "name": "dpi_pps"
+ },
+ {
+ "description": "workload",
+ "score": 0.4488986784140969,
+ "result": "10.19 G",
+ "name": "dpi_bps"
+ }
+ ],
+ "name": "dpi_throughput",
+ "description": "metric"
+ }
+ ],
+ "score": 0.44965595077729636,
+ "name": "DPI",
+ "description": "deep packet inspection"
+ },
+ {
+ "metrics": [
+ {
+ "score": 0.8277109922623959,
+ "workloads": [
+ {
+ "description": "workload",
+ "score": 0.8159569260890847,
+ "result": "8335.43",
+ "name": "triad"
+ },
+ {
+ "description": "workload",
+ "score": 0.8046851833547495,
+ "result": "8141.71",
+ "name": "add"
+ },
+ {
+ "description": "workload",
+ "score": 0.8622673849167483,
+ "result": "7043.29",
+ "name": "copy"
+ },
+ {
+ "description": "workload",
+ "score": 0.827934474689001,
+ "result": "6722.34",
+ "name": "scale"
+ }
+ ],
+ "name": "floatmem",
+ "description": "metric"
+ },
+ {
+ "score": 0.6916571989516922,
+ "workloads": [
+ {
+ "description": "workload",
+ "score": 0.7023780136591788,
+ "result": "8536.47",
+ "name": "triad"
+ },
+ {
+ "description": "workload",
+ "score": 0.6702975125995773,
+ "result": "8246.31",
+ "name": "add"
+ },
+ {
+ "description": "workload",
+ "score": 0.6987862883385272,
+ "result": "8521.74",
+ "name": "copy"
+ },
+ {
+ "description": "workload",
+ "score": 0.6951669812094855,
+ "result": "8472.50",
+ "name": "scale"
+ }
+ ],
+ "name": "intmem",
+ "description": "metric"
+ }
+ ],
+ "score": 0.7596840956070441,
+ "name": "memory",
+ "description": "cache and memory performance"
+ },
+ {
+ "metrics": [
+ {
+ "score": 1.4439459760636688,
+ "workloads": [
+ {
+ "description": "workload",
+ "score": 0.9324691580096908,
+ "result": "27044320.8",
+ "name": "dhrystone_lps"
+ },
+ {
+ "description": "workload",
+ "score": 1.955422794117647,
+ "result": "4255.2",
+ "name": "whetstone_MWIPS"
+ }
+ ],
+ "name": "arithmetic",
+ "description": "metric"
+ }
+ ],
+ "score": 1.4439459760636688,
+ "name": "arithmetic",
+ "description": "arithmetic computing speed"
+ }
+ ],
+ "spec": "https://git.opnfv.org/qtip/tree/resources/QPI/compute.yaml",
+ "baseline": "https://git.opnfv.org/qtip/tree/resources/QPI/compute-baseline.json"
+ }
+ ],
+ "name": "compute",
+ "description": "POD Compute QPI"
+}
diff --git a/examples/compute-qpi-report/report.ipynb b/examples/compute-qpi-report/report.ipynb
new file mode 100644
index 00000000..b4068a37
--- /dev/null
+++ b/examples/compute-qpi-report/report.ipynb
@@ -0,0 +1,71 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {
+ "scrolled": true
+ },
+ "outputs": [
+ {
+ "data": {
+ "image/png": "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\nEQa+JDXi/wPL3cFfQ6ukQgAAAABJRU5ErkJggg==\n",
+ "text/plain": [
+ "<matplotlib.figure.Figure at 0x7f5982b410d0>"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "import matplotlib.pyplot as plt\n",
+ "from asq.initiators import query\n",
+ "import json\n",
+ "\n",
+ "workload_name = []\n",
+ "workload_score = []\n",
+ "project_name = 'workspace'\n",
+ "\n",
+ "with open(\"qpi.json\".format(project_name)) as result:\n",
+ " final = json.load(result)\n",
+ "\n",
+ "qpi = query(final['nodes']).where(lambda child: child['name'] == 'node-9') \\\n",
+ " .select_many(lambda child: child['sections']) \\\n",
+ " .where(lambda child: child['name'] == 'SSL') \\\n",
+ " .select_many(lambda child: child['metrics']).to_list()\n",
+ "\n",
+ "for wl in qpi[0]['workloads']:\n",
+ " workload_name.append(wl['name'])\n",
+ " workload_score.append(wl['score'])\n",
+ "\n",
+ "x_axis = range(len(workload_name))\n",
+ "\n",
+ "plt.bar(x_axis, workload_score)\n",
+ "plt.xticks(x_axis, workload_name)\n",
+ "plt.show()"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 2",
+ "language": "python",
+ "name": "python2"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 2
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython2",
+ "version": "2.7.12"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 1
+}
diff --git a/qtip/web/bench/__init__.py b/qtip/web/bench/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/qtip/web/bench/__init__.py
diff --git a/qtip/web/bench/admin.py b/qtip/web/bench/admin.py
new file mode 100644
index 00000000..1e678ad5
--- /dev/null
+++ b/qtip/web/bench/admin.py
@@ -0,0 +1,22 @@
+##############################################################################
+# Copyright (c) 2017 akhil.batra@research.iiit.ac.in 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
+##############################################################################
+
+# -*- coding: utf-8 -*-
+
+from __future__ import unicode_literals
+
+from django.contrib import admin
+
+import models
+
+# Register your models here.
+
+
+admin.site.register(models.Repo)
+admin.site.register(models.Task)
diff --git a/qtip/web/bench/apps.py b/qtip/web/bench/apps.py
new file mode 100644
index 00000000..db50dfe0
--- /dev/null
+++ b/qtip/web/bench/apps.py
@@ -0,0 +1,8 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.apps import AppConfig
+
+
+class BenchConfig(AppConfig):
+ name = 'bench'
diff --git a/qtip/web/bench/migrations/0001_initial.py b/qtip/web/bench/migrations/0001_initial.py
new file mode 100644
index 00000000..04736679
--- /dev/null
+++ b/qtip/web/bench/migrations/0001_initial.py
@@ -0,0 +1,36 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.3 on 2017-07-13 01:36
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ initial = True
+
+ dependencies = [
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='Repo',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('name', models.CharField(max_length=200)),
+ ('github_link', models.URLField()),
+ ],
+ ),
+ migrations.CreateModel(
+ name='Task',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('start_time', models.DateTimeField(auto_now_add=True)),
+ ('end_time', models.DateTimeField()),
+ ('run_time', models.DurationField()),
+ ('log', models.TextField()),
+ ('repo', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to='bench.Repo')),
+ ],
+ ),
+ ]
diff --git a/qtip/web/bench/migrations/0002_auto_20170713_0210.py b/qtip/web/bench/migrations/0002_auto_20170713_0210.py
new file mode 100644
index 00000000..30c0cd63
--- /dev/null
+++ b/qtip/web/bench/migrations/0002_auto_20170713_0210.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.3 on 2017-07-13 02:10
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('bench', '0001_initial'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='repo',
+ name='github_link',
+ field=models.URLField(unique=True),
+ ),
+ ]
diff --git a/qtip/web/bench/migrations/0003_auto_20170713_0225.py b/qtip/web/bench/migrations/0003_auto_20170713_0225.py
new file mode 100644
index 00000000..fec4234a
--- /dev/null
+++ b/qtip/web/bench/migrations/0003_auto_20170713_0225.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.3 on 2017-07-13 02:25
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('bench', '0002_auto_20170713_0210'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='repo',
+ name='name',
+ field=models.CharField(max_length=20),
+ ),
+ ]
diff --git a/qtip/web/bench/migrations/__init__.py b/qtip/web/bench/migrations/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/qtip/web/bench/migrations/__init__.py
diff --git a/qtip/web/bench/models.py b/qtip/web/bench/models.py
new file mode 100644
index 00000000..0594dbd9
--- /dev/null
+++ b/qtip/web/bench/models.py
@@ -0,0 +1,28 @@
+##############################################################################
+# Copyright (c) 2017 akhil.batra@research.iiit.ac.in 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
+##############################################################################
+
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import models
+
+# Create your models here.
+
+
+class Repo(models.Model):
+ name = models.CharField(max_length=200, blank=False)
+ github_link = models.URLField(unique=True)
+
+
+class Task(models.Model):
+ start_time = models.DateTimeField(auto_now_add=True)
+ end_time = models.DateTimeField()
+ run_time = models.DurationField()
+ repo = models.ForeignKey('Repo', on_delete=models.DO_NOTHING)
+ log = models.TextField()
diff --git a/qtip/web/bench/tests.py b/qtip/web/bench/tests.py
new file mode 100644
index 00000000..c2de5b3a
--- /dev/null
+++ b/qtip/web/bench/tests.py
@@ -0,0 +1,6 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+# from django.test import TestCase
+
+# Create your tests here.
diff --git a/qtip/web/bench/views.py b/qtip/web/bench/views.py
new file mode 100644
index 00000000..da5c56c3
--- /dev/null
+++ b/qtip/web/bench/views.py
@@ -0,0 +1,6 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+# from django.shortcuts import render
+
+# Create your views here.
diff --git a/qtip/web/manage.py b/qtip/web/manage.py
new file mode 100755
index 00000000..f33e87a0
--- /dev/null
+++ b/qtip/web/manage.py
@@ -0,0 +1,22 @@
+#!/usr/bin/env python
+import os
+import sys
+
+if __name__ == "__main__":
+ os.environ.setdefault("DJANGO_SETTINGS_MODULE", "web.settings")
+ try:
+ from django.core.management import execute_from_command_line
+ except ImportError:
+ # The above import may fail for some other reason. Ensure that the
+ # issue is really that Django is missing to avoid masking other
+ # exceptions on Python 2.
+ try:
+ import django # noqa
+ except ImportError:
+ raise ImportError(
+ "Couldn't import Django. Are you sure it's installed and "
+ "available on your PYTHONPATH environment variable? Did you "
+ "forget to activate a virtual environment?"
+ )
+ raise
+ execute_from_command_line(sys.argv)
diff --git a/qtip/web/web/__init__.py b/qtip/web/web/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/qtip/web/web/__init__.py
diff --git a/qtip/web/web/settings.py b/qtip/web/web/settings.py
new file mode 100644
index 00000000..30bb6e38
--- /dev/null
+++ b/qtip/web/web/settings.py
@@ -0,0 +1,121 @@
+"""
+Django settings for web project.
+
+Generated by 'django-admin startproject' using Django 1.11.3.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/1.11/topics/settings/
+
+For the full list of settings and their values, see
+https://docs.djangoproject.com/en/1.11/ref/settings/
+"""
+
+import os
+
+# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
+BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+
+
+# Quick-start development settings - unsuitable for production
+# See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/
+
+# SECURITY WARNING: keep the secret key used in production secret!
+SECRET_KEY = '9=rwv)cv6&sao=xnl%b)-jrl(tnid$l(4n7i96@44+3-cog$)$'
+
+# SECURITY WARNING: don't run with debug turned on in production!
+DEBUG = True
+
+ALLOWED_HOSTS = []
+
+
+# Application definition
+
+INSTALLED_APPS = [
+ 'django.contrib.admin',
+ 'django.contrib.auth',
+ 'django.contrib.contenttypes',
+ 'django.contrib.sessions',
+ 'django.contrib.messages',
+ 'django.contrib.staticfiles',
+ 'bench.apps.BenchConfig',
+]
+
+MIDDLEWARE = [
+ 'django.middleware.security.SecurityMiddleware',
+ 'django.contrib.sessions.middleware.SessionMiddleware',
+ 'django.middleware.common.CommonMiddleware',
+ 'django.middleware.csrf.CsrfViewMiddleware',
+ 'django.contrib.auth.middleware.AuthenticationMiddleware',
+ 'django.contrib.messages.middleware.MessageMiddleware',
+ 'django.middleware.clickjacking.XFrameOptionsMiddleware',
+]
+
+ROOT_URLCONF = 'web.urls'
+
+TEMPLATES = [
+ {
+ 'BACKEND': 'django.template.backends.django.DjangoTemplates',
+ 'DIRS': [],
+ 'APP_DIRS': True,
+ 'OPTIONS': {
+ 'context_processors': [
+ 'django.template.context_processors.debug',
+ 'django.template.context_processors.request',
+ 'django.contrib.auth.context_processors.auth',
+ 'django.contrib.messages.context_processors.messages',
+ ],
+ },
+ },
+]
+
+WSGI_APPLICATION = 'web.wsgi.application'
+
+
+# Database
+# https://docs.djangoproject.com/en/1.11/ref/settings/#databases
+
+DATABASES = {
+ 'default': {
+ 'ENGINE': 'django.db.backends.sqlite3',
+ 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
+ }
+}
+
+
+# Password validation
+# https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators
+
+AUTH_PASSWORD_VALIDATORS = [
+ {
+ 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
+ },
+ {
+ 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
+ },
+ {
+ 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
+ },
+ {
+ 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
+ },
+]
+
+
+# Internationalization
+# https://docs.djangoproject.com/en/1.11/topics/i18n/
+
+LANGUAGE_CODE = 'en-us'
+
+TIME_ZONE = 'UTC'
+
+USE_I18N = True
+
+USE_L10N = True
+
+USE_TZ = True
+
+
+# Static files (CSS, JavaScript, Images)
+# https://docs.djangoproject.com/en/1.11/howto/static-files/
+
+STATIC_URL = '/static/'
diff --git a/qtip/web/web/urls.py b/qtip/web/web/urls.py
new file mode 100644
index 00000000..b0de5fe2
--- /dev/null
+++ b/qtip/web/web/urls.py
@@ -0,0 +1,21 @@
+"""web URL Configuration
+
+The `urlpatterns` list routes URLs to views. For more information please see:
+ https://docs.djangoproject.com/en/1.11/topics/http/urls/
+Examples:
+Function views
+ 1. Add an import: from my_app import views
+ 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home')
+Class-based views
+ 1. Add an import: from other_app.views import Home
+ 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home')
+Including another URLconf
+ 1. Import the include() function: from django.conf.urls import url, include
+ 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls'))
+"""
+from django.conf.urls import url
+from django.contrib import admin
+
+urlpatterns = [
+ url(r'^admin/', admin.site.urls),
+]
diff --git a/qtip/web/web/wsgi.py b/qtip/web/web/wsgi.py
new file mode 100644
index 00000000..23d62e95
--- /dev/null
+++ b/qtip/web/web/wsgi.py
@@ -0,0 +1,16 @@
+"""
+WSGI config for web project.
+
+It exposes the WSGI callable as a module-level variable named ``application``.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/1.11/howto/deployment/wsgi/
+"""
+
+import os
+
+from django.core.wsgi import get_wsgi_application
+
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "web.settings")
+
+application = get_wsgi_application()
diff --git a/requirements.txt b/requirements.txt
index b9d0e881..adcc1fd4 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -10,4 +10,5 @@ prettytable
six
PyYAML
humanfriendly
-asq \ No newline at end of file
+asq
+Django
diff --git a/tests/ci/run_ci.sh b/tests/ci/run_ci.sh
index 5c62644b..02dfca09 100644
--- a/tests/ci/run_ci.sh
+++ b/tests/ci/run_ci.sh
@@ -76,7 +76,11 @@ cd /home/opnfv/workspace/
qtip setup
eval `ssh-agent`
-qtip run --extra-vars "testapi_url=$testapi_url"
+if [[ -z $testapi_url ]];then
+ qtip run
+else
+ qtip run --extra-vars "testapi_url=$testapi_url"
+fi
qtip teardown
# Remove ssh public key from installer