Merge "Docker: VSPERF Results Container."
authorSridhar Rao <sridhar.rao@spirent.com>
Wed, 7 Aug 2019 08:39:04 +0000 (08:39 +0000)
committerGerrit Code Review <gerrit@opnfv.org>
Wed, 7 Aug 2019 08:39:04 +0000 (08:39 +0000)
12 files changed:
docs/testing/user/configguide/tools.rst
tools/docker/results/README.md [new file with mode: 0644]
tools/docker/results/docker-compose.yml [new file with mode: 0644]
tools/docker/results/jupyter/Dockerfile [new file with mode: 0644]
tools/docker/results/logstash/pipeline/02-beats-input.conf [new file with mode: 0644]
tools/docker/results/logstash/pipeline/20-collectd-input.conf [new file with mode: 0644]
tools/docker/results/logstash/pipeline/30-output.conf [new file with mode: 0644]
tools/docker/results/notebooks/testresult-analysis.ipynb [new file with mode: 0644]
tools/docker/results/resultsdb/cases.json [new file with mode: 0644]
tools/docker/results/resultsdb/init_db.py [new file with mode: 0644]
tools/docker/results/resultsdb/pods.json [new file with mode: 0644]
tools/docker/results/resultsdb/projects.json [new file with mode: 0644]

index fbc0c71..362bfca 100644 (file)
@@ -185,3 +185,43 @@ VSPERF provides following configuration options, for user to define and enforce
 * ``VNF_CA`` - [min-cache-value, max-cache-value] for VNF
 * ``PMD_CA`` - [min-cache-value, max-cache-value] for PMD
 * ``NOISEVM_CA`` - [min-cache-value, max-cache-value] for Noisy VM
+
+VSPERF Containers
+-----------------
+
+VSPERF containers are found in tools/docker folder.
+
+RESULTS CONTAINER
+^^^^^^^^^^^^^^^^^
+
+The results container includes multiple services - ELK Stack, Barometer-Grafana, OPNFV-TestAPI & Jupyter.
+
+Pre-Deployment Configuration
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+1. Set the limit on mmap counts equal to 262144 or more.
+   You can do this by the command - ``sysctl -w vm.max_map_count = 262144``.
+   Or to set it permanently, update the ``vm.max_map_count`` field in ``/etc/sysctl.conf``.
+
+2. You may want to modify the IP address from 0.0.0.0 to appropriate host-ip in ``docker-compose.yml``
+
+3. Please add dashboards folder from OPNFV-Barometer-Grafana into the grafana folder. It can be found in `Barometer Grafana <https://github.com/opnfv/barometer/tree/master/docker/barometer-grafana`
+
+Build
+~~~~~
+
+Run ``docker-compose build`` command to build the container.
+
+Run
+~~~
+
+Run the container with ``docker-compose up`` command.
+
+Post-Deployment Configuration
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The directory ``resultsdb`` contains the source from Dovetail/Dovetail-webportal project.
+Once the results container is deployed, please run the python script as follows, to ensure that results can be
+pushed and queried correctly - ``python init_db.py host_ip_address testapi_port``.
+For example, if the host on which the container is running is 10.10.120.22, and container is exposing 8000 as the port,
+the command should be: ``python init_db.py 10.10.120.22 8000``
diff --git a/tools/docker/results/README.md b/tools/docker/results/README.md
new file mode 100644 (file)
index 0000000..15d28b1
--- /dev/null
@@ -0,0 +1,48 @@
+## Please set the limit on mmap counts equal to 262144 or more.
+
+There are two options. Run this command:
+```sh
+
+sysctl -w vm.max_map_count = 262144
+
+```
+or, to set it permanently, update the
+```sh
+
+vm.max_map_count
+
+```
+setting in
+
+```sh
+
+/etc/sysctl.conf
+
+```
+
+### Update the IP address.
+You may want to modify the IP address from 0.0.0.0 to appropriate host-ip in
+```sh
+docker-compose.yml
+
+```
+
+### Changes made to sebp/elk
+The vsperf/elk image is same as sebp/elk with a minor change - the inclusion of collectd codec to logstash.
+In the Dockerfile of sebp/elk, under logstash configuration, following lines are added:
+```sh
+ WORKDIR ${LOGSTASH_HOME}
+ RUN gosu logstash bin/logstash-plugin install logstash-codec-collectd
+ WORKDIR /
+
+```
+
+The resultsdb directory contains the source from Dovetail/Dovetail-webportal project.
+Once the results container is deployed, please run the python script as follows, to ensure that results can be pushed and queried correctly.
+```sh
+python init_db.py host_ip_address testapi_port
+```
+For example, if the host on which the container is running is 10.10.120.22, and container is exposing 8000 as the port, the command should be:
+```sh
+python init_db.py 10.10.120.22 8000
+```
diff --git a/tools/docker/results/docker-compose.yml b/tools/docker/results/docker-compose.yml
new file mode 100644 (file)
index 0000000..5c3ab1d
--- /dev/null
@@ -0,0 +1,79 @@
+version: '3'
+volumes:
+    elk-data:
+    influx-data:
+    grafana-data:
+    mongo-data:
+    testapi-logs:
+services:
+  influxdb:
+    image: influxdb:latest
+    ports:
+      - "25826:25826/udp"
+      - "25826:25826"
+      - "8083:8083"
+      - "8086:8086"
+    expose:
+      - "25826"
+      - "8086"
+      - "8083"
+    volumes:
+      - influx-data:/var/lib/influxdb
+  grafana:
+    image: opnfv/barometer-grafana
+    volumes:
+      - grafana-data:/var/lib/grafana
+      - ./grafana/dashboards:/opt/grafana/dashboards
+    ports:
+      - "3000:3000"
+  elk:
+    image: vsperf/elk
+    ports:
+      - "5601:5601"
+      - "9200:9200"
+      - "5044:5044"
+    volumes:
+      - elk-data:/var/lib/elasticsearch
+      - ./logstash/pipeline/30-output.conf:/etc/logstash/conf.d/30-output.conf
+      - ./logstash/pipeline/02-beats-input.conf:/etc/logstash/conf.d/02-beats-input.conf
+      - ./logstash/pipeline/20-collectd-input.conf:/etc/logstash/conf.d/20-collectd-input.conf
+    environment:
+      - discovery.type=single-node
+  mongo:
+    image: mongo:3.2.1
+    ports:
+      - "27017:27017"
+    volumes:
+      - mongo-data:/data/db
+    container_name: opnfv-mongo
+  testapi:
+    image: opnfv/testapi:latest
+    container_name: opnfv-testapi
+    volumes:
+      - testapi-logs:/home/testapi/logs
+    environment:
+      - mongodb_url=mongodb://opnfv-mongo:27017/
+      - base_url=http://0.0.0.0:8000
+    ports:
+      - "8000:8000"
+      - "8001:8001"
+    links:
+      - mongo
+  jupyter:
+    build:
+      context: ./jupyter
+    ports:
+      - "8888:8888"
+    links:
+      - postgres
+    volumes:
+      - ./notebooks:/notebooks
+      - ./notebooks/testresult-analysis.ipynb:/notebooks/testresult-analysis.ipynb
+      - ./data:/data
+  postgres:
+    image: postgres
+    restart: always
+    environment:
+      POSTGRES_USER: data
+      POSTGRES_PASSWORD: data
+      POSTGRES_DB: data
diff --git a/tools/docker/results/jupyter/Dockerfile b/tools/docker/results/jupyter/Dockerfile
new file mode 100644 (file)
index 0000000..d281695
--- /dev/null
@@ -0,0 +1,13 @@
+FROM jupyter/scipy-notebook
+
+RUN python --version
+
+RUN conda install --quiet --yes -c \
+    conda-forge osmnx dask
+
+RUN pip install -U graphviz paramiko
+
+RUN echo "c.NotebookApp.token=''" >> $HOME/.jupyter/jupyter_notebook_config.py 
+
+VOLUME /notebooks
+WORKDIR /notebooks
diff --git a/tools/docker/results/logstash/pipeline/02-beats-input.conf b/tools/docker/results/logstash/pipeline/02-beats-input.conf
new file mode 100644 (file)
index 0000000..a00d3f5
--- /dev/null
@@ -0,0 +1,6 @@
+input {
+  beats {
+    port => 5044
+    ssl => false
+  }
+}
diff --git a/tools/docker/results/logstash/pipeline/20-collectd-input.conf b/tools/docker/results/logstash/pipeline/20-collectd-input.conf
new file mode 100644 (file)
index 0000000..990903f
--- /dev/null
@@ -0,0 +1,14 @@
+input {
+  udp {
+    port => 25826
+    buffer_size => 1452
+    type => collectd
+    codec => collectd { }
+  }
+}
+
+filter {
+  mutate {
+      remove_field => [ "host" ]
+  }
+}
diff --git a/tools/docker/results/logstash/pipeline/30-output.conf b/tools/docker/results/logstash/pipeline/30-output.conf
new file mode 100644 (file)
index 0000000..0e3161a
--- /dev/null
@@ -0,0 +1,7 @@
+output {
+  elasticsearch {
+    hosts => "http://localhost:9200"
+    manage_template => false
+    codec => collectd { }
+  }
+}
diff --git a/tools/docker/results/notebooks/testresult-analysis.ipynb b/tools/docker/results/notebooks/testresult-analysis.ipynb
new file mode 100644 (file)
index 0000000..a7e9335
--- /dev/null
@@ -0,0 +1,784 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "hide_input": true
+   },
+   "source": [
+    "# OPNFV VSPERF\n",
+    "# Beyond Performance Metrics: Towards Causation Analysis"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### sridhar.rao@spirent.com and acm@research.att.com"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# Import packages\n",
+    "import numpy as np\n",
+    "import pandas as pd\n",
+    "import matplotlib.pyplot as plt\n",
+    "import seaborn as sns\n",
+    "from graphviz import Digraph\n",
+    "import collections\n",
+    "import glob\n",
+    "import os"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Get the results to analyze: \n",
+    "Getting Latest one, if ``directory_to_download`` is empty"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "hide_input": true
+   },
+   "outputs": [],
+   "source": [
+    "import paramiko\n",
+    "import tarfile\n",
+    "import os\n",
+    "from stat import S_ISDIR\n",
+    "RECV_BYTES = 4096\n",
+    "hostname = '10.10.120.24'\n",
+    "port = 22\n",
+    "uname='opnfv'\n",
+    "pwd='opnfv' \n",
+    "stdout_data = []\n",
+    "stderr_data = []\n",
+    "client = paramiko.Transport((hostname, port))\n",
+    "client.connect(username=uname, password=pwd)\n",
+    "session = client.open_channel(kind='session')\n",
+    "directory_to_download = ''\n",
+    "\n",
+    "session.exec_command('ls /tmp | grep results')\n",
+    "if not directory_to_download:\n",
+    "    while True:\n",
+    "        if session.recv_ready():\n",
+    "            stdout_data.append(session.recv(RECV_BYTES))\n",
+    "        if session.recv_stderr_ready():\n",
+    "            stderr_data.append(session.recv_stderr(RECV_BYTES))\n",
+    "        if session.exit_status_ready():\n",
+    "            break\n",
+    "    if stdout_data:\n",
+    "        line = stdout_data[0]\n",
+    "        filenames = line.decode(\"utf-8\").rstrip('\\n').split('\\n')\n",
+    "        filenames = sorted(filenames)\n",
+    "        latest = filenames[-1]\n",
+    "        directory_to_download = os.path.join('/tmp', latest).replace(\"\\\\\",\"/\")\n",
+    "        print(directory_to_download)\n",
+    "stdout_data = []\n",
+    "stderr_data = []\n",
+    "if directory_to_download:\n",
+    "    # zip the collectd results to make the download faster\n",
+    "    zip_command = 'sudo -S tar -czvf '+ directory_to_download + '/collectd.tar.gz -C ' + directory_to_download + '/csv .'\n",
+    "    session = client.open_channel(kind='session')\n",
+    "    session.get_pty()\n",
+    "    session.exec_command(zip_command)\n",
+    "    while True:\n",
+    "        if session.recv_ready():\n",
+    "            stdout_data.append(session.recv(RECV_BYTES))\n",
+    "        if session.recv_stderr_ready():\n",
+    "            stderr_data.append(session.recv_stderr(RECV_BYTES))\n",
+    "        if session.exit_status_ready():\n",
+    "            break\n",
+    "    if stderr_data:\n",
+    "        print(stderr_data[0])\n",
+    "    if stdout_data:\n",
+    "        print(stdout_data[0])\n",
+    "\n",
+    "    # Begin the actual downlaod\n",
+    "    sftp = paramiko.SFTPClient.from_transport(client)\n",
+    "    def sftp_walk(remotepath):\n",
+    "        path=remotepath\n",
+    "        files=[]\n",
+    "        folders=[]\n",
+    "        for f in sftp.listdir_attr(remotepath):\n",
+    "            if S_ISDIR(f.st_mode):\n",
+    "                folders.append(f.filename)\n",
+    "            else:\n",
+    "                files.append(f.filename)\n",
+    "        if files:\n",
+    "            yield path, files\n",
+    "    # Filewise download happens here\n",
+    "    for path,files  in sftp_walk(directory_to_download):\n",
+    "        for file in files:\n",
+    "            remote = os.path.join(path,file).replace(\"\\\\\",\"/\")\n",
+    "            local = os.path.join('./results', file).replace(\"\\/\",\"/\")\n",
+    "            sftp.get(remote, local)\n",
+    "# Untar the collectd results if we got it.\n",
+    "path = os.path.join('./results', 'collectd.tar.gz')\n",
+    "if os.path.exists(path):\n",
+    "    tar = tarfile.open(path)\n",
+    "    tar.extractall()\n",
+    "    tar.close()\n",
+    "# Ready to work with downloaded data, close the session and client.\n",
+    "session.close()\n",
+    "client.close()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "hide_input": true
+   },
+   "outputs": [],
+   "source": [
+    "strings = ('* OS:', '* Kernel Version:', '* Board:', '* CPU:', '* CPU cores:',\n",
+    "           '* Memory:', '* Virtual Switch Set-up:',\n",
+    "           '* Traffic Generator:','* vSwitch:', '* DPDK Version:', '* VNF:')\n",
+    "filename = os.path.basename(glob.glob('./results/result*.rst')[0])\n",
+    "info_dict = {}\n",
+    "with open(os.path.join('./results', filename), 'r') as file:\n",
+    "    for line in file:\n",
+    "        if any(s in line for s in strings):\n",
+    "            info_dict[line.split(':', 1)[0]] = line.split(':', 1)[1].rstrip()\n",
+    "df = pd.DataFrame.from_dict(info_dict, orient='index', columns=['Value'])\n",
+    "df"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Understand the configuration used for the test."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "filename = os.path.basename(glob.glob('./results/vsperf*.conf')[0])\n",
+    "file = os.path.join('./results', filename)\n",
+    "with open(file, 'r') as f:\n",
+    "    for line in f:\n",
+    "        if line.startswith('TRAFFICGEN_DURATION'):\n",
+    "            value = line.split('=')[1]\n",
+    "            value = value.rstrip()\n",
+    "            value = value.lstrip()\n",
+    "            traffic_duration = int(value)\n",
+    "        elif line.startswith('VSWITCH_PMD_CPU_MASK'):\n",
+    "            value = line.split('=')[1]\n",
+    "            value = value.rstrip()\n",
+    "            pmd_cores_mask = value.lstrip()\n",
+    "        elif line.startswith('GUEST_CORE_BINDING'):\n",
+    "            value = line.split('=')[1]\n",
+    "            value = value.rstrip()\n",
+    "            value = value.lstrip()\n",
+    "            guest_cores = value[1:-2]\n",
+    "\n",
+    "print(traffic_duration)\n",
+    "print(pmd_cores_mask)\n",
+    "print(guest_cores)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## OVS-Ports and Cores"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "hide_input": true
+   },
+   "outputs": [],
+   "source": [
+    "import collections\n",
+    "portcores = collections.OrderedDict()\n",
+    "chunks = []\n",
+    "current_chunk = []\n",
+    "file = os.path.join('./results', 'ovs-cores.log')\n",
+    "with open(file, 'r') as f:\n",
+    "    for line in f:\n",
+    "        if line.startswith('pmd') and current_chunk:\n",
+    "            # if line starts with token and the current chunk is not empty\n",
+    "            chunks.append(current_chunk[:]) #  add not empty chunk to chunks\n",
+    "            current_chunk = [] #  make current chunk blank\n",
+    "        # just append a line to the current chunk on each iteration\n",
+    "        if \"port:\" in line or 'pmd' in line:\n",
+    "            current_chunk.append(line)\n",
+    "    chunks.append(current_chunk)  #  append the last chunk outside the loop\n",
+    "\n",
+    "core_ids = []\n",
+    "for ch in chunks:\n",
+    "    port_id = ''\n",
+    "    core_id = ''\n",
+    "    for line in ch:\n",
+    "        if 'pmd' in line:\n",
+    "            core_id = line.split()[-1][:-1]\n",
+    "            if core_id not in core_ids:\n",
+    "                core_ids.append(core_id)\n",
+    "        elif 'port:' in line:\n",
+    "            port_id = line.split()[1]\n",
+    "        if port_id and core_id:\n",
+    "            if port_id not in portcores:\n",
+    "                portcores[port_id] = core_id\n",
+    "\n",
+    "# import graphviz\n",
+    "from graphviz import Digraph\n",
+    "ps = Digraph(name='ovs-ports-cores', node_attr={'shape': 'box'}, edge_attr={'arrowhead':\"none\"})\n",
+    "with ps.subgraph(name=\"cluster_0\") as c:\n",
+    "    c.node_attr.update(style='filled', color='green')\n",
+    "    c.node('t0', 'TGen-Port-0')\n",
+    "    c.node('t1', 'TGen-Port-1')\n",
+    "    c.attr(label='TGEN')\n",
+    "    c.attr(color='blue')\n",
+    "with ps.subgraph(name=\"cluster_1\") as c:\n",
+    "    c.node_attr.update(style='filled', color='yellow')\n",
+    "    c.node('v0', 'VNF-Port-0')\n",
+    "    c.node('v1', 'VNF-Port-1')\n",
+    "    c.attr(label='VNF')\n",
+    "    c.attr(color='blue')\n",
+    "    \n",
+    "with ps.subgraph(name='cluster_2') as c: \n",
+    "    c.attr(label='OVS-DPDK')\n",
+    "    c.attr(color='blue')\n",
+    "    count = 0\n",
+    "    for port, core in portcores.items():\n",
+    "        id = 'o'+str(count)\n",
+    "        c.node(id, port+'\\nCore-ID:'+ core)\n",
+    "        count += 1\n",
+    "        num = port[-1]\n",
+    "        if 'dpdkvhost' in port:\n",
+    "            ps.edge(id, 'v'+num)\n",
+    "        else:\n",
+    "            ps.edge(id, 't'+num)\n",
+    "\n",
+    "ps"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Dropped Packets"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "hide_input": true
+   },
+   "outputs": [],
+   "source": [
+    "portcores = collections.OrderedDict()\n",
+    "chunks = []\n",
+    "current_chunk = []\n",
+    "file = os.path.join('./results', 'ovs-cores.log')\n",
+    "with open(file, 'r') as f:\n",
+    "    for line in f:\n",
+    "        if line.startswith('pmd') and current_chunk:\n",
+    "            # if line starts with token and the current chunk is not empty\n",
+    "            chunks.append(current_chunk[:]) #  add not empty chunk to chunks\n",
+    "            current_chunk = [] #  make current chunk blank\n",
+    "        # just append a line to the current chunk on each iteration\n",
+    "        if \"port:\" in line or 'pmd' in line:\n",
+    "            current_chunk.append(line)\n",
+    "    chunks.append(current_chunk)  #  append the last chunk outside the loop\n",
+    "\n",
+    "core_ids = []\n",
+    "for ch in chunks:\n",
+    "    port_id = ''\n",
+    "    core_id = ''\n",
+    "    for line in ch:\n",
+    "        if 'pmd' in line:\n",
+    "            core_id = line.split()[-1][:-1]\n",
+    "            if core_id not in core_ids:\n",
+    "                core_ids.append(core_id)\n",
+    "        elif 'port:' in line:\n",
+    "            port_id = line.split()[1]\n",
+    "        if port_id and core_id:\n",
+    "            if port_id not in portcores:\n",
+    "                portcores[port_id] = core_id\n",
+    "\n",
+    "ps = Digraph(name='ovs-dropped', node_attr={'shape': 'box'}, edge_attr={'arrowhead':\"none\"})\n",
+    "\n",
+    "def get_dropped(port_id):\n",
+    "    # port_id = 'dpdk0'\n",
+    "    if glob.glob('./pod12-node4/*'+port_id):\n",
+    "        dirname = os.path.basename(glob.glob('./pod12-node4/*'+port_id)[0])\n",
+    "        if dirname:\n",
+    "            if glob.glob('./pod12-node4/'+dirname+ '/*dropped*'):\n",
+    "                filename = os.path.basename(glob.glob('./pod12-node4/'+dirname+ '/*dropped*')[0])\n",
+    "                if filename:\n",
+    "                    with open(os.path.join('./pod12-node4', dirname, filename), 'r') as f:\n",
+    "                        line = f.readlines()[-1]\n",
+    "                        fields = line.split(',')\n",
+    "                        return fields[1], fields[2]\n",
+    "    return 'NA','NA'\n",
+    "\n",
+    "with ps.subgraph(name=\"cluster_0\") as c:\n",
+    "    c.node_attr.update(style='filled', color='pink')\n",
+    "    c.attr(label='OVS-DPDK')\n",
+    "    c.attr(color='blue')\n",
+    "    count = 0\n",
+    "    for port, core in portcores.items():\n",
+    "        id = 'o'+str(count)\n",
+    "        rx,tx = get_dropped(port)\n",
+    "        c.node(id, port+'\\nRX-Dropped:'+ rx + '\\nTX-Dropped:' + tx)\n",
+    "        count += 1\n",
+    "        num = port[-1]\n",
+    "ps"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Plotting Live Results - T-Rex"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "hide_input": true
+   },
+   "outputs": [],
+   "source": [
+    "lines_seen = set() # holds lines already seen\n",
+    "outfile = open('./counts.dat', \"w\")\n",
+    "file = os.path.join('./results', 'trex-liveresults-counts.dat')\n",
+    "for line in open(file, \"r\"):\n",
+    "    if line not in lines_seen: # not a duplicate\n",
+    "        outfile.write(line)\n",
+    "        lines_seen.add(line)\n",
+    "outfile.close()\n",
+    "tdf = pd.read_csv('./counts.dat')\n",
+    "print(tdf.columns)\n",
+    "ax = tdf.loc[(tdf.rx_port == 1)].plot(y='rx_pkts')\n",
+    "def highlight(indices,ax):\n",
+    "    i=0\n",
+    "    while i<len(indices):\n",
+    "        ax.axvspan(indices[i][0], indices[i][1], facecolor='RED', edgecolor='BLUE', alpha=.2)\n",
+    "        i+=1\n",
+    "\n",
+    "ind = 0\n",
+    "indv = tdf.ts[0]\n",
+    "ax.set_xlabel(\"Index\")\n",
+    "ax.set_ylabel('Count')\n",
+    "for i in range(len(tdf.ts)):\n",
+    "    if tdf.ts[i] - indv > int(traffic_duration):\n",
+    "        highlight([(ind, i)], ax)\n",
+    "        ind = i\n",
+    "        indv = tdf.ts[i]\n",
+    "highlight([(ind,i)], ax)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## IRQ Latency Histogram"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "hide_input": true
+   },
+   "outputs": [],
+   "source": [
+    "file = os.path.join('./results', 'RUNirq.irq.log')\n",
+    "tdf = pd.read_csv(file)\n",
+    "tdf.columns\n",
+    "exclude = ['          <1', '         < 5', '        < 10','        < 50', '       < 100', '       < 500', '      < 1000']\n",
+    "ax = tdf.loc[:, tdf.columns.difference(exclude)].plot(x='      number', xticks=tdf['      number'], figsize=(20,10))\n",
+    "ax.set_xlabel('Core #')\n",
+    "ax.set_ylabel('Count')\n",
+    "#tdf.plot(x='number')"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Sample Collectd Metric Display - L3 Cache Occupancy in Bytes"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import math\n",
+    "def cpumask2coreids(mask):\n",
+    "    intmask = int(mask, 16)\n",
+    "    i = 1\n",
+    "    coreids = []\n",
+    "    while (i < intmask):\n",
+    "        if (i & intmask):\n",
+    "            coreids.append(str(math.frexp(i)[-1]-1))\n",
+    "        i = i << 1\n",
+    "    return (coreids)\n",
+    "\n",
+    "vswitch_cpus = \"['2']\"\n",
+    "ps = Digraph(name='cpu-map', node_attr={'shape': 'box'}, edge_attr={'arrowhead':\"none\"})\n",
+    "with ps.subgraph(name=\"cluster_0\") as c:\n",
+    "    c.node_attr.update(style='filled', color='pink')\n",
+    "    c.attr(label='CPU-MAPPINGS')\n",
+    "    c.attr(color='blue')\n",
+    "    c.node('vscpus', 'vSwitch: \\n' + vswitch_cpus)\n",
+    "    # vnf_cpus = cpumask2coreids(guest_cores)\n",
+    "    c.node('vncpus', 'VNF: \\n' + guest_cores)\n",
+    "    pmd_cpus = cpumask2coreids(pmd_cores_mask[1:-1])\n",
+    "    c.node('pmcpus', 'PMDs: \\n' + str(pmd_cpus))\n",
+    "\n",
+    "ps"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "hide_input": true
+   },
+   "outputs": [],
+   "source": [
+    "# Path where collectd results are stored.\n",
+    "mypath = \"./pod12-node4\"\n",
+    "file_count = 0\n",
+    "cpu_names = []\n",
+    "for level1 in os.listdir(mypath):\n",
+    "    if \"intel_rdt\" in level1:\n",
+    "        l2path = os.path.join(mypath, level1)\n",
+    "        for level2 in os.listdir(l2path):\n",
+    "            if \"bytes\" in level2:\n",
+    "                l3path = os.path.join(l2path, level2)\n",
+    "                if file_count == 0:\n",
+    "                    file_count += 1\n",
+    "                    df = pd.read_csv(l3path)\n",
+    "                    nn = 'cpu-'+ level1[len('intel_rdt-'):]\n",
+    "                    # nn = 'cpu-'+ level1.split('-')[1]\n",
+    "                    cpu_names.append(nn)\n",
+    "                    # print(nn)\n",
+    "                    df.rename(columns={'value': nn}, inplace=True)\n",
+    "                else:\n",
+    "                    file_count += 1\n",
+    "                    tdf = pd.read_csv(l3path)\n",
+    "                    nn = 'cpu-'+ level1[len('intel_rdt-'):]\n",
+    "                    cpu_names.append(nn)\n",
+    "                    tdf.rename(columns={'value': nn}, inplace=True)\n",
+    "                    df[nn] = tdf[nn]            \n",
+    "\n",
+    "ax = df.plot(x='epoch', y=cpu_names)\n",
+    "ax.set_ylabel(\"MBytes\")\n",
+    "ax.set_xlabel('Time')\n",
+    "\n",
+    "\n",
+    "        \n",
+    "#    df = pd.read_csv()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Events "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "hide_input": true
+   },
+   "outputs": [],
+   "source": [
+    "from datetime import datetime\n",
+    "filename = os.path.basename(glob.glob('./results/vsperf-overall*.log')[0])\n",
+    "logfile = os.path.join('./results', filename)\n",
+    "linecnt = 0\n",
+    "times = {}\n",
+    "with open(logfile) as f:\n",
+    "    for line in f:\n",
+    "        line = line.strip('\\n')\n",
+    "        if linecnt == 0:\n",
+    "            times['Start-Test'] = line.split(\" : \")[0]\n",
+    "            linecnt += 1\n",
+    "        if 'Binding NICs' in line:\n",
+    "            times['Binding-NICs'] = line.split(\" : \")[0]\n",
+    "        if 'Starting traffic at' in line:\n",
+    "            sline = line.split(\" : \")[1]\n",
+    "            time = line.split(\" : \")[0]\n",
+    "            speed = sline.split('at',1)[1]\n",
+    "            times[speed] = time \n",
+    "        elif 'Starting vswitchd' in line:\n",
+    "            times['vSwitch-Start'] = line.split(\" : \")[0]\n",
+    "        elif 'Starting ovs-vswitchd' in line:\n",
+    "            times['ovsvswitch-start'] = line.split(\" : \")[0]\n",
+    "        elif 'Adding Ports' in line:\n",
+    "            times['Ports-Added'] = line.split(\" : \")[0]\n",
+    "        elif 'Flows Added' in line:\n",
+    "            times['Flows-Added'] = line.split(\" : \")[0]\n",
+    "        elif 'send_traffic with' in line:\n",
+    "            times['Traffic Start']  = line.split(\" : \")[0]\n",
+    "        elif 'l2 framesize 1280' in line:\n",
+    "            times['Traffic-Start-1280'] = line.split(\" : \")[0]\n",
+    "        elif 'Starting qemu' in line:\n",
+    "            times['VNF-Start'] = line.split(\" : \")[0]\n",
+    "        elif 'l2 framesize 64' in line:\n",
+    "            times['Traffic-Start-64'] = line.split(\" : \")[0]\n",
+    "        elif 'l2 framesize 128' in line:\n",
+    "            times['Traffic-Start-128'] = line.split(\" : \")[0]\n",
+    "        elif 'l2 framesize 256' in line:\n",
+    "            times['Traffic-Start-256'] = line.split(\" : \")[0]\n",
+    "        elif 'l2 framesize 512' in line:\n",
+    "            times['Traffic-Start-512'] = line.split(\" : \")[0]\n",
+    "        elif 'l2 framesize 1024' in line:\n",
+    "            times['Traffic-Start-1024'] = line.split(\" : \")[0]\n",
+    "        elif 'l2 framesize 1518' in line:\n",
+    "            times['Traffic-Start-1518'] = line.split(\" : \")[0]\n",
+    "        elif 'dump flows' in line:\n",
+    "            times['Traffic-End'] = line.split(\" : \")[0]\n",
+    "        elif 'Wait for QEMU' in line:\n",
+    "            times['VNF-Stop'] = line.split(\" : \")[0]\n",
+    "        elif 'delete flow' in line:\n",
+    "            times['flow-removed'] = line.split(\" : \")[0]\n",
+    "        elif 'delete port' in line:\n",
+    "            times['port-removed'] = line.split(\" : \")[0]\n",
+    "        elif 'Killing ovs-vswitchd' in line:\n",
+    "            times['vSwitch-Stop'] = line.split(\" : \")[0]\n",
+    "\n",
+    "times['Test-Stop'] = line.split(\" : \")[0]\n",
+    "#print(times)\n",
+    "ddf = pd.DataFrame.from_dict(times, orient='index', columns=['timestamp'])\n",
+    "names = ddf.index.values\n",
+    "dates = ddf['timestamp'].tolist()\n",
+    "datefmt=\"%Y-%m-%d %H:%M:%S,%f\"\n",
+    "dates = [datetime.strptime(ii, datefmt) for ii in dates]\n",
+    "# print(names)\n",
+    "# print(dates)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "hide_input": true
+   },
+   "outputs": [],
+   "source": [
+    "import matplotlib.dates as mdates\n",
+    "from matplotlib import ticker\n",
+    "\n",
+    "levels = np.array([-5, 5, -3, 3, -1, 1])\n",
+    "fig, ax = plt.subplots(figsize=(40, 5))\n",
+    "\n",
+    "# Create the base line\n",
+    "start = min(dates)\n",
+    "stop = max(dates)\n",
+    "ax.plot((start, stop), (0, 0), 'k', alpha=.5)\n",
+    "\n",
+    "pos_list = np.arange(len(dates))\n",
+    "\n",
+    "# Iterate through releases annotating each one\n",
+    "for ii, (iname, idate) in enumerate(zip(names, dates)):\n",
+    "    level = levels[ii % 6]\n",
+    "    vert = 'top' if level < 0 else 'bottom'\n",
+    "    ax.scatter(idate, 0, s=100, facecolor='w', edgecolor='k', zorder=9999)\n",
+    "    # Plot a line up to the text\n",
+    "    ax.plot((idate, idate), (0, level), c='r', alpha=.7)\n",
+    "    # Give the text a faint background and align it properly\n",
+    "    ax.text(idate, level, iname,\n",
+    "            horizontalalignment='right', verticalalignment=vert, fontsize=14,\n",
+    "            backgroundcolor=(1., 1., 1., .3))\n",
+    "ax.set(title=\"VSPERF Main Events\")\n",
+    "# Set the xticks formatting\n",
+    "ax.get_xaxis().set_major_locator(mdates.SecondLocator(interval=30))\n",
+    "ax.get_xaxis().set_major_formatter(mdates.DateFormatter(\"%M %S\"))\n",
+    "fig.autofmt_xdate()\n",
+    "plt.setp((ax.get_yticklabels() + ax.get_yticklines() +\n",
+    "          list(ax.spines.values())), visible=False)\n",
+    "plt.show()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Current and old."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Current Result"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "hide_input": true
+   },
+   "outputs": [],
+   "source": [
+    "import glob\n",
+    "filename = os.path.basename(glob.glob('./results/result*.csv')[0])\n",
+    "filename\n",
+    "tdf = pd.read_csv(os.path.join('./results', filename))\n",
+    "pkts = ['tx_frames', 'rx_frames']\n",
+    "fps =  ['tx_rate_fps', 'throughput_rx_fps']\n",
+    "mbps = ['tx_rate_mbps', 'throughput_rx_mbps']\n",
+    "pcents = ['tx_rate_percent', 'throughput_rx_percent', 'frame_loss_percent']\n",
+    "fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(14, 12))\n",
+    "tdf.plot.bar(y= pkts,ax=axes[0,0])\n",
+    "tdf.plot.bar(y= fps,ax=axes[0,1])\n",
+    "tdf.plot.bar(y= mbps,ax=axes[1,0])\n",
+    "tdf.plot.bar(y= pcents,ax=axes[1,1])\n",
+    "current_pkt_size = str(tdf['packet_size'].iloc[-1])\n",
+    "current_rx_fps = str(tdf['throughput_rx_fps'].iloc[-1])\n",
+    "print(current_rx_fps)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## How Current Result compares to Previous ones?"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "hide_input": true
+   },
+   "outputs": [],
+   "source": [
+    "import urllib\n",
+    "import json\n",
+    "import requests\n",
+    "#json_data = requests.get('http://testresults.opnfv.org/test/api/v1/results?project=vsperf').json()\n",
+    "json_data = requests.get('http://10.10.120.22:8000/api/v1/results?project=vsperf').json()\n",
+    "res = json_data['results']\n",
+    "df1 = pd.DataFrame(res)\n",
+    "sort_by_date = df1.sort_values('start_date')\n",
+    "details = df1['details'].apply(pd.Series)\n",
+    "details[current_pkt_size] = pd.to_numeric(pd.Series(details[current_pkt_size]))\n",
+    "# details.plot.bar(y = current_pkt_size)\n",
+    "details_cur_pkt = details[[current_pkt_size]].copy()\n",
+    "details_cur_pkt.loc[-1]= float(current_rx_fps)\n",
+    "details_cur_pkt.index = details_cur_pkt.index + 1  # shifting index\n",
+    "details_cur_pkt.sort_index(inplace=True) \n",
+    "ax = details_cur_pkt.plot.bar()\n",
+    "ax.set_ylabel(\"Frames per sec\")\n",
+    "ax.set_xlabel(\"Run Number\")\n",
+    "def highlight(indices,ax):\n",
+    "    i=0\n",
+    "    while i<len(indices):\n",
+    "        ax.axvspan(indices[i]-0.5, indices[i]+0.5, facecolor='RED', edgecolor='none', alpha=.2)\n",
+    "        i+=1\n",
+    "highlight([0], ax)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Heatmaps"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "hide_input": true
+   },
+   "outputs": [],
+   "source": [
+    "array_of_dfs = []\n",
+    "for dirs in glob.glob('./pod12-node4/ovs_stats-vsperf*'):\n",
+    "    dirname = os.path.basename(dirs)\n",
+    "    if dirname:\n",
+    "        port = dirname.split('.')[1]\n",
+    "        if glob.glob('./pod12-node4/'+dirname+ '/*dropped*'):\n",
+    "            full_path = glob.glob('./pod12-node4/'+dirname+ '/*dropped*')[0]\n",
+    "            filename = os.path.basename(full_path)\n",
+    "            if filename:\n",
+    "                df = pd.read_csv(full_path)\n",
+    "                df.rename(index=str, columns={\"rx\": port+\"-rx\" , \"tx\": port+\"-tx\"}, inplace=True)\n",
+    "                df = df.drop(columns=['epoch'])\n",
+    "                array_of_dfs.append(df)\n",
+    "master_df = pd.concat(array_of_dfs, axis=1, sort=True)\n",
+    "master_df.columns\n",
+    "\n",
+    "# get the correlation coefficient between the different columns\n",
+    "corr = master_df.iloc[:, 0:].corr()\n",
+    "arr_corr = corr.values\n",
+    "# mask out the top triangle\n",
+    "arr_corr[np.triu_indices_from(arr_corr)] = np.nan\n",
+    "fig, ax = plt.subplots(figsize=(18, 12))\n",
+    "sns.set(font_scale=3.0)\n",
+    "hm = sns.heatmap(arr_corr, cbar=True, vmin=-0.5, vmax=0.5,\n",
+    "                 fmt='.2f', annot_kws={'size': 20}, annot=True, \n",
+    "                 square=True, cmap=plt.cm.Reds)\n",
+    "ticks = np.arange(corr.shape[0]) + 0.5\n",
+    "ax.set_xticks(ticks)\n",
+    "ax.set_xticklabels(corr.columns, rotation=90, fontsize=20)\n",
+    "ax.set_yticks(ticks)\n",
+    "ax.set_yticklabels(corr.index, rotation=360, fontsize=20)\n",
+    "\n",
+    "ax.set_title('Heatmap')\n",
+    "plt.tight_layout()\n",
+    "plt.show()"
+   ]
+  }
+ ],
+ "metadata": {
+  "author": {
+   "@type": "Person",
+   "name": "Sridhar K. N. Rao",
+   "worksFor": {
+    "@type": "Organization",
+    "name": "Spirent Communications"
+   }
+  },
+  "kernelspec": {
+   "display_name": "Python 3",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.7.1"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/tools/docker/results/resultsdb/cases.json b/tools/docker/results/resultsdb/cases.json
new file mode 100644 (file)
index 0000000..e7576db
--- /dev/null
@@ -0,0 +1 @@
+{"testcases": [{"project_name": "vsperf", "run": null, "description": "LTD.Throughput.RFC2544.PacketLossRatio for DPDK Ovs", "ci_loop": null, "tags": null, "url": "http://tput_ovsdpdk", "_id": "565feb6b514bc5087f3cfe2e", "catalog_description": "Packet Loss Ratio for DPDK OVS (RFC2544)", "creation_date": "2015-12-03 07:12:43.925943", "domains": null, "dependencies": null, "version": null, "criteria": null, "tier": null, "trust": null, "blocking": null, "name": "tput_ovsdpdk"}, {"project_name": "vsperf", "run": null, "description": "LTD.Throughput.RFC2544.PacketLossRatio for Vanilla Ovs", "ci_loop": null, "tags": null, "url": "http://tput_ovs", "_id": "566005d9514bc5087f3cfe30", "catalog_description": "Packet Loss Ratio for Vanilla Ovs (RFC2544)", "creation_date": "2015-12-03 09:05:29.686136", "domains": null, "dependencies": null, "version": null, "criteria": null, "tier": null, "trust": null, "blocking": null, "name": "tput_ovs"}, {"project_name": "vsperf", "run": null, "description": "LTD.Throughput.RFC2544.PacketLossRatio for Vanilla Ovs", "ci_loop": null, "tags": null, "url": "http://tput_ovs", "_id": "566005ed514bc5087f3cfe31", "catalog_description": "Packet Loss Ratio for Vanilla Ovs (RFC2544)", "creation_date": "2015-12-03 09:05:49.363961", "domains": null, "dependencies": null, "version": null, "criteria": null, "tier": null, "trust": null, "blocking": null, "name": "tput_ovs"}, {"project_name": "vsperf", "run": null, "description": "LTD.Throughput.RFC2544.BackToBackFrames for DPDK Ovs", "ci_loop": null, "tags": null, "url": "http://b2b_ovsdpdk", "_id": "566006c8514bc5087f3cfe32", "catalog_description": "Back To Back Frames for DPDK Ovs (RFC2544)", "creation_date": "2015-12-03 09:09:28.927130", "domains": null, "dependencies": null, "version": null, "criteria": null, "tier": null, "trust": null, "blocking": null, "name": "b2b_ovsdpdk"}, {"project_name": "vsperf", "run": null, "description": "LTD.Throughput.RFC2544.BackToBackFrames for Vanilla Ovs", "ci_loop": null, "tags": null, "url": "http://b2b_ovs", "_id": "5660071e514bc5087f3cfe33", "catalog_description": "Back To Back Frames for Vanilla Ovs (RFC2544)", "creation_date": "2015-12-03 09:10:54.473180", "domains": null, "dependencies": null, "version": null, "criteria": null, "tier": null, "trust": null, "blocking": null, "name": "b2b_ovs"}, {"project_name": "vsperf", "run": null, "description": "LTD.Throughput.RFC2544.PacketLossRatioFrameModification for DPDK Ovs", "ci_loop": null, "tags": null, "url": "http://tput_mod_vlan_ovsdpdk", "_id": "566007a9514bc5087f3cfe34", "catalog_description": "Packet Loss Ratio Frame Modification for DPDK Ovs (RFC2544)", "creation_date": "2015-12-03 09:13:13.600168", "domains": null, "dependencies": null, "version": null, "criteria": null, "tier": null, "trust": null, "blocking": null, "name": "tput_mod_vlan_ovsdpdk"}, {"project_name": "vsperf", "run": null, "description": "LTD.Throughput.RFC2544.PacketLossRatioFrameModification for Vanilla Ovs", "ci_loop": null, "tags": null, "url": "http://tput_mod_vlan_ovs", "_id": "566007ec514bc5087f3cfe35", "catalog_description": "Packet Loss Ratio Frame Modification for Vanilla Ovs (RFC2544)", "creation_date": "2015-12-03 09:14:20.594501", "domains": null, "dependencies": null, "version": null, "criteria": null, "tier": null, "trust": null, "blocking": null, "name": "tput_mod_vlan_ovs"}, {"project_name": "vsperf", "run": null, "description": "LTD.Scalability.RFC2544.0PacketLoss for DPDK Ovs", "ci_loop": null, "tags": null, "url": "http://scalability_ovsdpdk", "_id": "56600870514bc5087f3cfe36", "catalog_description": ".Scalability Packet Loss for DPDK Ovs", "creation_date": "2015-12-03 09:16:32.491960", "domains": null, "dependencies": null, "version": null, "criteria": null, "tier": null, "trust": null, "blocking": null, "name": "scalability_ovsdpdk"}, {"project_name": "vsperf", "run": null, "description": "LTD.Scalability.RFC2544.0PacketLoss for Vanilla Ovs", "ci_loop": null, "tags": null, "url": "http://scalability_ovs", "_id": "566008b3514bc5087f3cfe37", "catalog_description": "Scalability Packet Loss for Vanilla Ovs (RFC2544)", "creation_date": "2015-12-03 09:17:39.501079", "domains": null, "dependencies": null, "version": null, "criteria": null, "tier": null, "trust": null, "blocking": null, "name": "scalability_ovs"}, {"project_name": "vsperf", "run": null, "description": "PVP LTD.Throughput.RFC2544.PacketLossRatio for DPDK User Ovs", "ci_loop": null, "tags": null, "url": "http://pvp_tput_ovsdpdkuser", "_id": "5660095a514bc5087f3cfe38", "catalog_description": "PVP Packet Loss Ratio for DPDK User Ovs", "creation_date": "2015-12-03 09:20:26.244843", "domains": null, "dependencies": null, "version": null, "criteria": null, "tier": null, "trust": null, "blocking": null, "name": "pvp_tput_ovsdpdkuser"}, {"project_name": "vsperf", "run": null, "description": "PVP LTD.Throughput.RFC2544.PacketLossRatio for Vanilla Ovs", "ci_loop": null, "tags": null, "url": "http://pvp_tput_ovsvirtio", "_id": "566009ae514bc5087f3cfe39", "catalog_description": "PVP Packet Loss Ratio for Vanilla Ovs", "creation_date": "2015-12-03 09:21:50.251212", "domains": null, "dependencies": null, "version": null, "criteria": null, "tier": null, "trust": null, "blocking": null, "name": "pvp_tput_ovsvirtio"}, {"project_name": "vsperf", "run": null, "description": "PVP LTD.Throughput.RFC2544.BackToBackFrames for DPDK User Ovs", "ci_loop": null, "tags": null, "url": "http://pvp_b2b_ovsdpdkuser", "_id": "56600a1a514bc5087f3cfe3a", "catalog_description": "PVP Back To Back Frames for DPDK User Ovs", "creation_date": "2015-12-03 09:23:38.269821", "domains": null, "dependencies": null, "version": null, "criteria": null, "tier": null, "trust": null, "blocking": null, "name": "pvp_b2b_ovsdpdkuser"}, {"project_name": "vsperf", "run": null, "description": "PVP LTD.Throughput.RFC2544.BackToBackFrames for Vanilla Ovs", "ci_loop": null, "tags": null, "url": "http://pvp_b2b_ovsvirtio", "_id": "56600a5f514bc5087f3cfe3b", "catalog_description": "PVP Back To Back Frames for Vanilla Ovs", "creation_date": "2015-12-03 09:24:47.990062", "domains": null, "dependencies": null, "version": null, "criteria": null, "tier": null, "trust": null, "blocking": null, "name": "pvp_b2b_ovsvirtio"}, {"project_name": "vsperf", "run": null, "description": "PVVP LTD.Throughput.RFC2544.PacketLossRatio for DPDK User Ovs", "ci_loop": null, "tags": null, "url": "http://pvvp_tput_ovsdpdkuser", "_id": "56600ab3514bc5087f3cfe3c", "catalog_description": "PVVP Packet Loss Ratio for DPDK User Ovs", "creation_date": "2015-12-03 09:26:11.657515", "domains": null, "dependencies": null, "version": null, "criteria": null, "tier": null, "trust": null, "blocking": null, "name": "pvvp_tput_ovsdpdkuser"}, {"project_name": "vsperf", "run": null, "description": "PVVP LTD.Throughput.RFC2544.PacketLossRatio for Vanilla Ovs", "ci_loop": null, "tags": null, "url": "http://pvvp_tput_ovsvirtio", "_id": "56600ae9514bc5087f3cfe3d", "catalog_description": "PVVP Packet Loss Ratio for Vanilla Ovs", "creation_date": "2015-12-03 09:27:05.466374", "domains": null, "dependencies": null, "version": null, "criteria": null, "tier": null, "trust": null, "blocking": null, "name": "pvvp_tput_ovsvirtio"}, {"project_name": "vsperf", "run": null, "description": "PVVP LTD.Throughput.RFC2544.BackToBackFrames for DPDK User Ovs", "ci_loop": null, "tags": null, "url": "http://pvvp_b2b_ovsdpdkuser", "_id": "56600b2a514bc5087f3cfe3e", "catalog_description": "PVVP Back To Back Frames for DPDK User Ovs", "creation_date": "2015-12-03 09:28:10.150217", "domains": null, "dependencies": null, "version": null, "criteria": null, "tier": null, "trust": null, "blocking": null, "name": "pvvp_b2b_ovsdpdkuser"}, {"project_name": "vsperf", "run": null, "description": "PVVP LTD.Throughput.RFC2544.BackToBackFrames for Vanilla Ovs", "ci_loop": null, "tags": null, "url": "http://pvvp_b2b_ovsvirtio", "_id": "56600b4f514bc5087f3cfe3f", "catalog_description": "PVVP Back To Back Frames for Vanilla Ovs", "creation_date": "2015-12-03 09:28:47.108529", "domains": null, "dependencies": null, "version": null, "criteria": null, "tier": null, "trust": null, "blocking": null, "name": "pvvp_b2b_ovsvirtio"}, {"project_name": "vsperf", "run": "", "description": "", "ci_loop": "", "tags": "ovs,dpdk", "url": "", "_id": "591e8a8f41b755000a68c831", "catalog_description": "Phy2Phy Continuous Stream DPDK", "creation_date": "2017-05-19 06:02:55.177254", "domains": "compute", "dependencies": "", "version": ">euphrates", "criteria": "", "tier": "performance", "trust": null, "blocking": "", "name": "cont_ovsdpdk"}, {"project_name": "vsperf", "run": "", "description": "", "ci_loop": "", "tags": "ovs", "url": "", "_id": "5980d1b073ce050010c339ca", "catalog_description": "Phy2Phy Continuous Stream", "creation_date": "2017-08-01 19:08:32.518983", "domains": "compute", "dependencies": "", "version": "euphrates", "criteria": "", "tier": null, "trust": null, "blocking": "", "name": "cont_ovs"}, {"project_name": "vsperf", "run": null, "description": "LTD.Throughput.RFC2544.PacketLossRatio for DPDK Ovs", "ci_loop": null, "tags": null, "url": "http://tput_ovsdpdk", "_id": "565feb6b514bc5087f3cfe2e", "catalog_description": "Packet Loss Ratio for DPDK OVS (RFC2544)", "creation_date": "2015-12-03 07:12:43.925943", "domains": null, "dependencies": null, "version": null, "criteria": null, "tier": null, "trust": "Silver", "blocking": null, "name": "phy2phy_tput_ovsdpdkvhost"}, {"project_name": "vsperf", "run": null, "description": "LTD.Throughput.RFC2544.PacketLossRatio for Vanilla Ovs", "ci_loop": null, "tags": null, "url": "http://tput_ovs", "_id": "566005d9514bc5087f3cfe30", "catalog_description": "Packet Loss Ratio for Vanilla Ovs (RFC2544)", "creation_date": "2015-12-03 09:05:29.686136", "domains": null, "dependencies": null, "version": null, "criteria": null, "tier": null, "trust": "Silver", "blocking": null, "name": "phy2phy_tput_ovsvanilla"}, {"project_name": "vsperf", "run": null, "description": "LTD.Throughput.RFC2544.BackToBackFrames for DPDK Ovs", "ci_loop": null, "tags": null, "url": "http://b2b_ovsdpdk", "_id": "566006c8514bc5087f3cfe32", "catalog_description": "Back To Back Frames for DPDK Ovs (RFC2544)", "creation_date": "2015-12-03 09:09:28.927130", "domains": null, "dependencies": null, "version": null, "criteria": null, "tier": null, "trust": "Silver", "blocking": null, "name": "back2back_ovsdpdkvhost"}, {"project_name": "vsperf", "run": null, "description": "LTD.Throughput.RFC2544.BackToBackFrames for Vanilla Ovs", "ci_loop": null, "tags": null, "url": "http://b2b_ovs", "_id": "5660071e514bc5087f3cfe33", "catalog_description": "Back To Back Frames for Vanilla Ovs (RFC2544)", "creation_date": "2015-12-03 09:10:54.473180", "domains": null, "dependencies": null, "version": null, "criteria": null, "tier": null, "trust": "Silver", "blocking": null, "name": "back2back_ovsvanilla"}, {"project_name": "vsperf", "run": null, "description": "LTD.Throughput.RFC2544.PacketLossRatioFrameModification for DPDK Ovs", "ci_loop": null, "tags": null, "url": "http://tput_mod_vlan_ovsdpdk", "_id": "566007a9514bc5087f3cfe34", "catalog_description": "Packet Loss Ratio Frame Modification for DPDK Ovs (RFC2544)", "creation_date": "2015-12-03 09:13:13.600168", "domains": null, "dependencies": null, "version": null, "criteria": null, "tier": null, "trust": "Silver", "blocking": null, "name": "phy2phy_tput_mod_vlan_ovsdpdkvhost"}, {"project_name": "vsperf", "run": null, "description": "LTD.Throughput.RFC2544.PacketLossRatioFrameModification for Vanilla Ovs", "ci_loop": null, "tags": null, "url": "http://tput_mod_vlan_ovs", "_id": "566007ec514bc5087f3cfe35", "catalog_description": "Packet Loss Ratio Frame Modification for Vanilla Ovs (RFC2544)", "creation_date": "2015-12-03 09:14:20.594501", "domains": null, "dependencies": null, "version": null, "criteria": null, "tier": null, "trust": "Silver", "blocking": null, "name": "phy2phy_tput_mod_vlan_ovsvanilla"}, {"project_name": "vsperf", "run": null, "description": "LTD.Scalability.RFC2544.0PacketLoss for DPDK Ovs", "ci_loop": null, "tags": null, "url": "http://scalability_ovsdpdk", "_id": "56600870514bc5087f3cfe36", "catalog_description": ".Scalability Packet Loss for DPDK Ovs", "creation_date": "2015-12-03 09:16:32.491960", "domains": null, "dependencies": null, "version": null, "criteria": null, "tier": null, "trust": "Silver", "blocking": null, "name": "phy2phy_scalability_ovsdpdkvhost"}, {"project_name": "vsperf", "run": null, "description": "LTD.Scalability.RFC2544.0PacketLoss for Vanilla Ovs", "ci_loop": null, "tags": null, "url": "http://scalability_ovs", "_id": "566008b3514bc5087f3cfe37", "catalog_description": "Scalability Packet Loss for Vanilla Ovs (RFC2544)", "creation_date": "2015-12-03 09:17:39.501079", "domains": null, "dependencies": null, "version": null, "criteria": null, "tier": null, "trust": "Silver", "blocking": null, "name": "phy2phy_scalability_ovsvanilla"}, {"project_name": "vsperf", "run": null, "description": "PVP LTD.Throughput.RFC2544.PacketLossRatio for DPDK User Ovs", "ci_loop": null, "tags": null, "url": "http://pvp_tput_ovsdpdkuser", "_id": "5660095a514bc5087f3cfe38", "catalog_description": "PVP Packet Loss Ratio for DPDK User Ovs", "creation_date": "2015-12-03 09:20:26.244843", "domains": null, "dependencies": null, "version": null, "criteria": null, "tier": null, "trust": "Silver", "blocking": null, "name": "pvp_tput_ovsdpdkvhost"}, {"project_name": "vsperf", "run": null, "description": "PVP LTD.Throughput.RFC2544.PacketLossRatio for Vanilla Ovs", "ci_loop": null, "tags": null, "url": "http://pvp_tput_ovsvirtio", "_id": "566009ae514bc5087f3cfe39", "catalog_description": "PVP Packet Loss Ratio for Vanilla Ovs", "creation_date": "2015-12-03 09:21:50.251212", "domains": null, "dependencies": null, "version": null, "criteria": null, "tier": null, "trust": "Silver", "blocking": null, "name": "pvp_tput_ovsvanilla"}, {"project_name": "vsperf", "run": null, "description": "PVP LTD.Throughput.RFC2544.BackToBackFrames for DPDK User Ovs", "ci_loop": null, "tags": null, "url": "http://pvp_b2b_ovsdpdkuser", "_id": "56600a1a514bc5087f3cfe3a", "catalog_description": "PVP Back To Back Frames for DPDK User Ovs", "creation_date": "2015-12-03 09:23:38.269821", "domains": null, "dependencies": null, "version": null, "criteria": null, "tier": null, "trust": "Silver", "blocking": null, "name": "pvp_back2back_ovsdpdkvhost"}, {"project_name": "vsperf", "run": null, "description": "PVP LTD.Throughput.RFC2544.BackToBackFrames for Vanilla Ovs", "ci_loop": null, "tags": null, "url": "http://pvp_b2b_ovsvirtio", "_id": "56600a5f514bc5087f3cfe3b", "catalog_description": "PVP Back To Back Frames for Vanilla Ovs", "creation_date": "2015-12-03 09:24:47.990062", "domains": null, "dependencies": null, "version": null, "criteria": null, "tier": null, "trust": "Silver", "blocking": null, "name": "pvp_back2back_ovsvanilla"}, {"project_name": "vsperf", "run": null, "description": "PVVP LTD.Throughput.RFC2544.PacketLossRatio for DPDK User Ovs", "ci_loop": null, "tags": null, "url": "http://pvvp_tput_ovsdpdkuser", "_id": "56600ab3514bc5087f3cfe3c", "catalog_description": "PVVP Packet Loss Ratio for DPDK User Ovs", "creation_date": "2015-12-03 09:26:11.657515", "domains": null, "dependencies": null, "version": null, "criteria": null, "tier": null, "trust": "Silver", "blocking": null, "name": "pvvp_tput_ovsdpdkvhost"}, {"project_name": "vsperf", "run": null, "description": "PVVP LTD.Throughput.RFC2544.PacketLossRatio for Vanilla Ovs", "ci_loop": null, "tags": null, "url": "http://pvvp_tput_ovsvirtio", "_id": "56600ae9514bc5087f3cfe3d", "catalog_description": "PVVP Packet Loss Ratio for Vanilla Ovs", "creation_date": "2015-12-03 09:27:05.466374", "domains": null, "dependencies": null, "version": null, "criteria": null, "tier": null, "trust": "Silver", "blocking": null, "name": "pvvp_tput_ovsvanilla"}, {"project_name": "vsperf", "run": null, "description": "PVVP LTD.Throughput.RFC2544.BackToBackFrames for DPDK User Ovs", "ci_loop": null, "tags": null, "url": "http://pvvp_b2b_ovsdpdkuser", "_id": "56600b2a514bc5087f3cfe3e", "catalog_description": "PVVP Back To Back Frames for DPDK User Ovs", "creation_date": "2015-12-03 09:28:10.150217", "domains": null, "dependencies": null, "version": null, "criteria": null, "tier": null, "trust": "Silver", "blocking": null, "name": "pvvp_back2back_ovsdpdkvhost"}, {"project_name": "vsperf", "run": null, "description": "PVVP LTD.Throughput.RFC2544.BackToBackFrames for Vanilla Ovs", "ci_loop": null, "tags": null, "url": "http://pvvp_b2b_ovsvirtio", "_id": "56600b4f514bc5087f3cfe3f", "catalog_description": "PVVP Back To Back Frames for Vanilla Ovs", "creation_date": "2015-12-03 09:28:47.108529", "domains": null, "dependencies": null, "version": null, "criteria": null, "tier": null, "trust": "Silver", "blocking": null, "name": "pvvp_back2back_ovsvanilla"}, {"project_name": "vsperf", "run": "", "description": "", "ci_loop": "", "tags": "ovs,dpdk", "url": "", "_id": "591e8a8f41b755000a68c831", "catalog_description": "Phy2Phy Continuous Stream DPDK", "creation_date": "2017-05-19 06:02:55.177254", "domains": "compute", "dependencies": "", "version": ">euphrates", "criteria": "", "tier": "performance", "trust": null, "blocking": "", "name": "phy2phy_cont_ovsdpdkvhost"}, {"project_name": "vsperf", "run": "", "description": "", "ci_loop": "", "tags": "ovs", "url": "", "_id": "5980d1b073ce050010c339ca", "catalog_description": "Phy2Phy Continuous Stream", "creation_date": "2017-08-01 19:08:32.518983", "domains": "compute", "dependencies": "", "version": "euphrates", "criteria": "", "tier": null, "trust": null, "blocking": "", "name": "phy2phy_cont_ovsvanilla"}, {"project_name": "vsperf", "run": "", "description": "", "ci_loop": "", "tags": "", "url": "", "_id": "59a48f18dc5815000e54a624", "catalog_description": "LTD.Throughput.RFC2544.PacketLossRatio VPP DPDK", "creation_date": "2017-08-28 21:46:00.448859", "domains": "compute", "dependencies": "", "version": "euphrates", "criteria": "", "tier": null, "trust": null, "blocking": "", "name": "phy2phy_tput_vpp_vppdpdkvhost"}, {"project_name": "vsperf", "run": "", "description": "", "ci_loop": "", "tags": "", "url": "", "_id": "59a493e7dc5815000e54a62e", "catalog_description": "LTD.Throughput.RFC2544.BackToBackFrames VPP DPDK", "creation_date": "2017-08-28 22:06:31.415776", "domains": "compute", "dependencies": "", "version": "euphrates", "criteria": "", "tier": null, "trust": null, "blocking": "", "name": "phy2phy_back2back_vpp_vppdpdkvhost"}, {"project_name": "vsperf", "run": "", "description": "", "ci_loop": "", "tags": "", "url": "", "_id": "59a4946ddc5815000e54a630", "catalog_description": "LTD.Throughput.RFC2544.PacketLossRatio VPP DPDK", "creation_date": "2017-08-28 22:08:45.830223", "domains": "compute", "dependencies": "", "version": "euphrates", "criteria": "", "tier": null, "trust": null, "blocking": "", "name": "pvp_tput_vpp_vppdpdkvhost"}, {"project_name": "vsperf", "run": "", "description": "", "ci_loop": "", "tags": "", "url": "", "_id": "59a494cbdc5815000e54a632", "catalog_description": "LTD.Throughput.RFC2544.BackToBackFrames VPP DPDK", "creation_date": "2017-08-28 22:10:19.882545", "domains": "compute", "dependencies": "", "version": "euphrates", "criteria": "", "tier": null, "trust": null, "blocking": "", "name": "pvp_back2back_vpp_vppdpdkvhost"}, {"project_name": "vsperf", "run": "", "description": "", "ci_loop": "", "tags": "", "url": "", "_id": "59a495cfdc5815000e54a635", "catalog_description": "LTD.Throughput.RFC2544.PacketLossRatio VPP DPDK", "creation_date": "2017-08-28 22:14:39.603143", "domains": "compute", "dependencies": "", "version": "euphrates", "criteria": "", "tier": null, "trust": null, "blocking": "", "name": "pvvp_tput_vpp_vppdpdkvhost"}, {"project_name": "vsperf", "run": "", "description": "", "ci_loop": "", "tags": "", "url": "", "_id": "59a4964edc5815000e54a637", "catalog_description": "LTD.Throughput.RFC2544.BackToBackFrames VPP DPDK", "creation_date": "2017-08-28 22:16:46.066477", "domains": "compute", "dependencies": "", "version": "euphrates", "criteria": "", "tier": null, "trust": null, "blocking": "", "name": "pvvp_back2back_vpp_vppdpdkvhost"}]}
diff --git a/tools/docker/results/resultsdb/init_db.py b/tools/docker/results/resultsdb/init_db.py
new file mode 100644 (file)
index 0000000..40bb4ee
--- /dev/null
@@ -0,0 +1,110 @@
+##############################################################################
+# Copyright (c) 2016 HUAWEI TECHNOLOGIES CO.,LTD 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
+##############################################################################
+"""
+Preload the results database with testcases.
+"""
+
+from __future__ import print_function
+import json
+import sys
+import requests
+
+DB_HOST_IP = sys.argv[1]
+TESTAPI_PORT = sys.argv[2]
+
+TARGET_URL = 'http://{}:{}/api/v1'.format(DB_HOST_IP, TESTAPI_PORT)
+
+
+def get(url):
+    """
+    Get the http response.
+    """
+    return requests.get(url).json()
+
+
+def post(url, data):
+    """
+    Post HTTP request.
+    """
+    headers = {'Content-Type': 'application/json'}
+    res = requests.post(url, data=json.dumps(data), headers=headers)
+    print(res.text)
+
+
+def pod():
+    """
+    Get the PODs.
+    """
+    target = '{}/pods'.format(TARGET_URL)
+
+    with open('pods.json', 'r') as podref:
+        pods = json.load(podref)
+    for apod in pods:
+        post(target, apod)
+
+    add_pod('master', 'metal')
+    add_pod('virtual_136_2', 'virtual')
+
+
+def project():
+    """
+    Get the Projects
+    """
+    target = '{}/projects'.format(TARGET_URL)
+    with open('projects.json', 'r') as projref:
+        projects = json.load(projref)
+    for proj in projects:
+        post(target, proj)
+
+
+def cases():
+    """
+    Get the Cases
+    """
+    with open('cases.json', 'r') as caseref:
+        for line in caseref:
+            subcases = json.loads(line)
+            for cas in subcases["testcases"]:
+                target = '{}/projects/{}/cases'.format(TARGET_URL,
+                                                       cas['project_name'])
+                post(target, cas)
+    add_case("functest", "tempest_custom")
+
+
+def add_pod(name, mode):
+    """
+    Add the Pods.
+    """
+    data = {
+        "role": "",
+        "name": name,
+        "details": '',
+        "mode": mode,
+        "creation_date": "2017-2-23 11:23:03.765581"
+    }
+    pod_url = '{}/pods'.format(TARGET_URL)
+    post(pod_url, data)
+
+
+def add_case(projectname, casename):
+    """
+    Add a testcase
+    """
+    data = {
+        "project_name": projectname,
+        "name": casename,
+    }
+    case_url = '{}/projects/{}/cases'.format(TARGET_URL, projectname)
+    post(case_url, data)
+
+
+if __name__ == '__main__':
+    pod()
+    project()
+    cases()
diff --git a/tools/docker/results/resultsdb/pods.json b/tools/docker/results/resultsdb/pods.json
new file mode 100644 (file)
index 0000000..3cd1dad
--- /dev/null
@@ -0,0 +1,382 @@
+[
+    {
+        "name": "lf-pod2", 
+        "creation_date": "2015-01-01 08:00:00.476549", 
+        "role": "production-ci", 
+        "mode": "metal", 
+        "_id": "5617f98e514bc5355b51f6b5", 
+        "details": ""
+    }, 
+    {
+        "name": "lf-pod1", 
+        "creation_date": "2015-01-01 08:00:00.476549", 
+        "role": "production-ci", 
+        "mode": "metal", 
+        "_id": "5617fa5a514bc5355b51f6b6", 
+        "details": ""
+    }, 
+    {
+        "name": "orange-pod2", 
+        "creation_date": "2015-10-27 15:27:30.312012", 
+        "role": "", 
+        "mode": "metal", 
+        "_id": "562f97e2514bc5174d053d38", 
+        "details": "https://wiki.opnfv.org/opnfv-orange"
+    }, 
+    {
+        "name": "unknown-pod", 
+        "creation_date": "2015-11-30 08:55:02.550465", 
+        "role": "", 
+        "mode": "undefined", 
+        "_id": "565c0ee6514bc5087f2ddcf7", 
+        "details": null
+    }, 
+    {
+        "name": "huawei-pod1", 
+        "creation_date": "", 
+        "role": "", 
+        "mode": "metal", 
+        "_id": "566fea58514bc5068a345d4b", 
+        "details": ""
+    }, 
+    {
+        "name": "intel-pod5", 
+        "creation_date": "2015-12-15 10:24:53.476549", 
+        "role": "", 
+        "mode": "metal", 
+        "_id": "566fea75514bc5068a345d4c", 
+        "details": null
+    }, 
+    {
+        "name": "intel-pod3", 
+        "creation_date": "2015-12-21 17:38:31.435593", 
+        "role": "", 
+        "mode": "metal", 
+        "_id": "56783917514bc5068a345d97", 
+        "details": null
+    }, 
+    {
+        "name": "ericsson-pod1", 
+        "creation_date": "2015-12-22 07:21:03.765581", 
+        "role": "", 
+        "mode": "metal", 
+        "_id": "5678f9df514bc5068a345d98", 
+        "details": null
+    }, 
+    {
+        "name": "ericsson-pod2", 
+        "creation_date": "2015-12-22 07:21:18.173966", 
+        "role": "", 
+        "mode": "metal", 
+        "_id": "5678f9ee514bc5068a345d99", 
+        "details": null
+    }, 
+    {
+        "name": "dell-us-testing-bm-1", 
+        "creation_date": "2016-01-08 12:41:54.097114", 
+        "role": "", 
+        "mode": "metal", 
+        "_id": "568fae92514bc5068a60e7d2", 
+        "details": null
+    }, 
+    {
+        "name": "dell-us-deploying-bm-3", 
+        "creation_date": "2016-01-08 14:13:16.740415", 
+        "role": "", 
+        "mode": null, 
+        "_id": "568fc3fc514bc5068a60e7d4", 
+        "details": null
+    }, 
+    {
+        "name": "dell-us-deploying-bm-2", 
+        "creation_date": "2016-01-08 14:15:54.037500", 
+        "role": "", 
+        "mode": null, 
+        "_id": "568fc49a514bc5068a60e7d5", 
+        "details": null
+    }, 
+    {
+        "name": "dell-us-deploying-bm3", 
+        "creation_date": "2016-01-15 12:14:20.956198", 
+        "role": "", 
+        "mode": "metal", 
+        "_id": "5698e29c514bc56e65a47bc8", 
+        "details": null
+    }, 
+    {
+        "name": "intel-pod6", 
+        "creation_date": "2016-01-22 13:32:18.767326", 
+        "role": "", 
+        "mode": "metal", 
+        "_id": "56a22f62514bc541f885b2c0", 
+        "details": null
+    }, 
+    {
+        "name": "huawei-virtual2", 
+        "creation_date": "", 
+        "role": "", 
+        "mode": "virtual", 
+        "_id": "56a9d7ac851d7e6a0f74930d", 
+        "details": ""
+    }, 
+    {
+        "name": "huawei-virtual1", 
+        "creation_date": "", 
+        "role": "", 
+        "mode": "virtual", 
+        "_id": "56a9f411851d7e6a0f749313", 
+        "details": ""
+    }, 
+    {
+        "name": "huawei-virtual3", 
+        "creation_date": "", 
+        "role": "", 
+        "mode": "virtual", 
+        "_id": "56e67ba6851d7e4b188676bc", 
+        "details": ""
+    }, 
+    {
+        "name": "huawei-virtual4", 
+        "creation_date": "", 
+        "role": "", 
+        "mode": "virtual", 
+        "_id": "56e67bb6851d7e4b188676bd", 
+        "details": ""
+    }, 
+    {
+        "name": "intel-pod8", 
+        "creation_date": "2016-03-14 08:52:47.576623", 
+        "role": "", 
+        "mode": "metal", 
+        "_id": "56e67bdf851d7e4b188676be", 
+        "details": null
+    }, 
+    {
+        "name": "intel-pod7", 
+        "creation_date": "2016-03-14 08:53:00.757525", 
+        "role": "", 
+        "mode": "metal", 
+        "_id": "56e67bec851d7e4b188676c0", 
+        "details": null
+    }, 
+    {
+        "name": "huawei-pod2", 
+        "creation_date": "", 
+        "role": "", 
+        "mode": "metal", 
+        "_id": "56e67c35851d7e4b188676c1", 
+        "details": ""
+    }, 
+    {
+        "name": "ericsson-virtual1", 
+        "creation_date": "2016-03-14 08:58:06.432105", 
+        "role": "", 
+        "mode": "virtual", 
+        "_id": "56e67d1e851d7e4b188676c2", 
+        "details": null
+    }, 
+    {
+        "name": "arm-pod1", 
+        "creation_date": "2016-05-05 09:18:54.879497", 
+        "role": "", 
+        "mode": "metal", 
+        "_id": "572b0ffe9377c51472b7878f", 
+        "details": null
+    }, 
+    {
+        "name": "zte-pod1", 
+        "creation_date": "2016-05-12 03:36:56.091397", 
+        "role": "", 
+        "mode": "metal", 
+        "_id": "5733fa589377c548e8df3834", 
+        "details": null
+    }, 
+    {
+        "name": "intel-virtual1", 
+        "creation_date": "2016-08-23 17:22:30.901081", 
+        "role": null, 
+        "mode": "virtual", 
+        "_id": "57bc86561d2c6e000ab19d93", 
+        "details": null
+    }, 
+    {
+        "name": "intel-virtual2", 
+        "creation_date": "2016-08-23 17:24:23.143681", 
+        "role": null, 
+        "mode": "virtual", 
+        "_id": "57bc86c71d2c6e000ab19d94", 
+        "details": null
+    }, 
+    {
+        "name": "zte-pod2", 
+        "creation_date": "2016-09-06 09:49:20.228736", 
+        "role": "", 
+        "mode": "metal", 
+        "_id": "57ce91201d2c6e000ab1c261", 
+        "details": ""
+    }, 
+    {
+        "name": "zte-pod3", 
+        "creation_date": "2016-09-06 09:49:26.019816", 
+        "role": "", 
+        "mode": "metal", 
+        "_id": "57ce91261d2c6e000ab1c263", 
+        "details": ""
+    }, 
+    {
+        "name": "arm-pod3", 
+        "creation_date": "2016-09-12 09:47:50.791351", 
+        "role": "", 
+        "mode": "metal", 
+        "_id": "57d679c61d2c6e000ab1d6bd", 
+        "details": "ARM POD3"
+    }, 
+    {
+        "name": "cisco-pod1", 
+        "creation_date": "2016-09-13 13:01:21.906958", 
+        "role": "Community lab", 
+        "mode": "metal", 
+        "_id": "57d7f8a11d2c6e000ab1db88", 
+        "details": "not yet declared in CI but needed to validate vpp scenarios for Colorado"
+    }, 
+    {
+        "name": "ool-virtual1", 
+        "creation_date": "2016-09-19 12:43:50.313032", 
+        "role": "", 
+        "mode": "virtual", 
+        "_id": "57dfdd861d2c6e000ab1f37b", 
+        "details": "Okinawa lab"
+    }, 
+    {
+        "name": "ericsson-pod3", 
+        "creation_date": "2016-09-26 09:45:40.565795", 
+        "role": "", 
+        "mode": "metal", 
+        "_id": "57e8ee441d2c6e000ab20fa9", 
+        "details": ""
+    }, 
+    {
+        "name": "ericsson-pod4", 
+        "creation_date": "2016-09-26 09:45:48.980198", 
+        "role": "", 
+        "mode": "metal", 
+        "_id": "57e8ee4c1d2c6e000ab20faa", 
+        "details": ""
+    }, 
+    {
+        "name": "ericsson-virtual2", 
+        "creation_date": "2016-09-26 09:46:05.508776", 
+        "role": "", 
+        "mode": "virtual", 
+        "_id": "57e8ee5d1d2c6e000ab20fac", 
+        "details": ""
+    }, 
+    {
+        "name": "ericsson-virtual3", 
+        "creation_date": "2016-09-26 09:46:10.244443", 
+        "role": "", 
+        "mode": "virtual", 
+        "_id": "57e8ee621d2c6e000ab20fad", 
+        "details": ""
+    }, 
+    {
+        "name": "ericsson-virtual4", 
+        "creation_date": "2016-09-26 09:46:14.734383", 
+        "role": "", 
+        "mode": "virtual", 
+        "_id": "57e8ee661d2c6e000ab20fae", 
+        "details": ""
+    }, 
+    {
+        "name": "ericsson-virtual5", 
+        "creation_date": "2016-09-26 09:46:19.477110", 
+        "role": "", 
+        "mode": "virtual", 
+        "_id": "57e8ee6b1d2c6e000ab20faf", 
+        "details": ""
+    }, 
+    {
+        "name": "intel-pod9", 
+        "creation_date": "2016-11-23 14:07:35.963037", 
+        "role": "", 
+        "mode": "metal", 
+        "_id": "5835a2a71d2c6e000ab2bb4b", 
+        "details": "https://wiki.opnfv.org/display/pharos/Intel+Pod9"
+    }, 
+    {
+        "name": "huawei-pod3", 
+        "creation_date": "2017-01-17 13:36:03.908341", 
+        "role": "production-ci", 
+        "mode": "metal", 
+        "_id": "587e1dc38cf551000c780eda", 
+        "details": ""
+    }, 
+    {
+        "name": "huawei-pod4", 
+        "creation_date": "2017-01-17 13:36:10.759860", 
+        "role": "production-ci", 
+        "mode": "metal", 
+        "_id": "587e1dca8cf551000c780edb", 
+        "details": ""
+    }, 
+    {
+        "name": "huawei-pod5", 
+        "creation_date": "2017-01-17 13:36:15.447849", 
+        "role": "production-ci", 
+        "mode": "metal", 
+        "_id": "587e1dcf8cf551000c780edc", 
+        "details": ""
+    }, 
+    {
+        "name": "huawei-pod6", 
+        "creation_date": "2017-01-18 10:53:10.586724", 
+        "role": "production-ci", 
+        "mode": "metal", 
+        "_id": "587f49168cf551000c780f5e", 
+        "details": ""
+    }, 
+    {
+        "name": "huawei-pod7", 
+        "creation_date": "2017-01-18 10:53:15.373953", 
+        "role": "production-ci", 
+        "mode": "metal", 
+        "_id": "587f491b8cf551000c780f5f", 
+        "details": ""
+    }, 
+    {
+        "name": "huawei-pod12", 
+        "creation_date": "2017-02-09 07:22:46.425836", 
+        "role": "production-ci", 
+        "mode": "metal", 
+        "_id": "589c18c68cf551000c7820e8", 
+        "details": ""
+    }, 
+    {
+        "name": "intel-pod12", 
+        "creation_date": "2017-05-17 14:11:18.852731", 
+        "role": "production-ci", 
+        "details": "performance", 
+        "query": "<function query at 0x7f574c29c500>", 
+        "mode": "metal", 
+        "_id": "591c5a06ee2e3f000a50f0b4", 
+        "miss_fields": [
+            "name"
+        ]
+    }, 
+    {
+        "name": "cisco-vina-pod10", 
+        "creation_date": "2017-05-29 09:13:20.818497", 
+        "role": "production-ci", 
+        "mode": "metal", 
+        "_id": "592be63078a2ad000ae6aad7", 
+        "details": ""
+    }, 
+    {
+        "name": "zte-virtual1", 
+        "creation_date": "2017-05-30 14:11:04.264967", 
+        "role": "", 
+        "mode": "baremetal", 
+        "_id": "592d7d7878a2ad000ae6ac49", 
+        "details": ""
+    }
+]
\ No newline at end of file
diff --git a/tools/docker/results/resultsdb/projects.json b/tools/docker/results/resultsdb/projects.json
new file mode 100644 (file)
index 0000000..81c3d77
--- /dev/null
@@ -0,0 +1,8 @@
+[
+    {
+        "_id": "5641e12d514bc5174df3d77e", 
+        "description": "OPNFV vsperf project", 
+        "name": "vsperf", 
+        "creation_date": "2015-11-10 12:21:01.464979"
+    }
+]