dissertation-3-evaluation/evaluation.ipynb
2020-11-16 11:47:22 +00:00

596 lines
15 KiB
Plaintext

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Project Evaluation\n",
"\n",
"This file interfaces with a Proxmox server to automatically generate VM structures and graphs for testing the\n",
"success criteria of my project."
]
},
{
"cell_type": "markdown",
"metadata": {
"pycharm": {
"name": "#%% md\n"
}
},
"source": [
"## Setup\n",
"This section sets up the required variables for the Proxmox server."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import os\n",
"import ipaddress\n",
"from typing import Dict\n",
"\n",
"import runners\n",
"from structure import StandardEnvironment, StandardTest, StandardIperfResult\n",
"from structure.structure import DirectEnvironment, DirectTest\n",
"\n",
"%load_ext dotenv\n",
"%dotenv"
]
},
{
"cell_type": "markdown",
"metadata": {
"pycharm": {
"name": "#%% md\n"
}
},
"source": [
"## Testing\n",
"This section gathers the required data from the different structures for later graphs."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"runner = runners.ProxmoxRunner(\n",
" host=os.getenv('PROXMOX_HOST'),\n",
" node=os.getenv('PROXMOX_NODE'),\n",
" user=os.getenv('PROXMOX_USER'),\n",
" token_name=os.getenv('PROXMOX_TOKEN_NAME'),\n",
" token_value=os.getenv('PROXMOX_TOKEN_VALUE'),\n",
"\n",
" template_id=9000,\n",
" initial_vm_id=21002,\n",
"\n",
" internet_bridge=os.getenv('INTERNET_BRIDGE'),\n",
"\n",
" management_bridge=os.getenv('MANAGEMENT_BRIDGE'),\n",
" management_initial_ip=ipaddress.ip_address(os.getenv('MANAGEMENT_INITIAL_IP')),\n",
")\n",
"\n",
"setup_params = {\n",
" 'access_key': os.getenv('S3_ACCESS_KEY'),\n",
" 'secret_key': os.getenv('S3_SECRET_KEY'),\n",
" 'branch': os.getenv('TARGET_BRANCH'),\n",
"}\n",
"\n",
"directionInbound: Dict[str, StandardIperfResult] = {}\n",
"directionOutbound: Dict[str, StandardIperfResult] = {}\n",
"\n",
"def run_and_save_test(env: StandardEnvironment, test: StandardTest):\n",
" (directionInbound[test.name()], directionOutbound[test.name()]) = env.test(test)\n",
"\n",
"def attempt_n_times(foo, n=3):\n",
" i = 0\n",
" while True:\n",
" try:\n",
" return foo()\n",
" except Exception as e:\n",
" if i == n:\n",
" raise e\n",
" finally:\n",
" i += 1\n",
"\n",
"\n",
"fast_tests = True"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false,
"pycharm": {
"name": "#%% md\n"
}
},
"source": [
"### Direct Server to Server Testing"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"def direct_tests():\n",
" with DirectEnvironment(runner) as env:\n",
" run_and_save_test(env, DirectTest(1, variation_target=0.4 if fast_tests else 0.2))\n",
" run_and_save_test(env, DirectTest(2, variation_target=0.4 if fast_tests else 0.2))\n",
" run_and_save_test(env, DirectTest(3, variation_target=0.4 if fast_tests else 0.2))\n",
" run_and_save_test(env, DirectTest(4, variation_target=0.4 if fast_tests else 0.2))"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false,
"pycharm": {
"name": "#%% md\n"
}
},
"source": [
"### Local Portal with 2 Interfaces"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"def two_interface_tests():\n",
" with StandardEnvironment(2, runner, setup_params) as env:\n",
" run_and_save_test(env, StandardTest([1,1], variation_target=0.4 if fast_tests else 0.2))\n",
" run_and_save_test(env, StandardTest([1,2], variation_target=0.4 if fast_tests else 0.2))\n",
" run_and_save_test(env, StandardTest([2,2], variation_target=0.4 if fast_tests else 0.2))\n",
" run_and_save_test(env, StandardTest(\n",
" [2,2],\n",
" events={10: (0,1), 15: (0,2)},\n",
" duration=30,\n",
" variation_target=0.8 if fast_tests else 0.5,\n",
" ))\n",
"\n",
"attempt_n_times(two_interface_tests)"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false
},
"source": [
"### Local Portal with 3 Interfaces"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"def three_interface_tests():\n",
" with StandardEnvironment(3, runner, setup_params) as env:\n",
" run_and_save_test(env, StandardTest([1,1,1], variation_target=0.4 if fast_tests else 0.2))\n",
" run_and_save_test(env, StandardTest([2,2,2], variation_target=0.4 if fast_tests else 0.2))\n",
"\n",
"attempt_n_times(three_interface_tests)"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false
},
"source": [
"### Local Portal with 4 Interfaces"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"def four_interface_tests():\n",
" with StandardEnvironment(4, runner, setup_params) as env:\n",
" run_and_save_test(env, StandardTest([1,1,1,1], variation_target=0.4 if fast_tests else 0.2))\n",
" run_and_save_test(env, StandardTest([2,2,2,2], variation_target=0.4 if fast_tests else 0.2))\n",
"\n",
"attempt_n_times(four_interface_tests)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Graphs\n",
"This section produces graphs from the collected data."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"from itertools import cycle\n",
"import matplotlib.pyplot as plt\n",
"\n",
"def plot_iperf_results(\n",
" series: Dict[str, StandardTest],\n",
" title: str = None,\n",
" direction = 'both',\n",
" error_bars_x=False,\n",
" error_bars_y=True,\n",
" filename=None,\n",
" start_at_zero=True,\n",
"):\n",
" if direction == 'both':\n",
" plot_iperf_results(series, title, 'outbound', error_bars_x, error_bars_y, filename, start_at_zero)\n",
" plot_iperf_results(series, title, 'inbound', error_bars_x, error_bars_y, filename, start_at_zero)\n",
" return\n",
"\n",
" if filename in ['png', 'eps']:\n",
" filename = 'graphs/{}{}{}{}.{}'.format(\n",
" 'I' if direction == 'inbound' else 'O',\n",
" 'Ex' if error_bars_x else '',\n",
" 'Ey' if error_bars_y else '',\n",
" ''.join(['S{}-{}'.format(i,x.name()) for (i, x) in enumerate(series.values())]),\n",
" filename,\n",
" )\n",
"\n",
" series = {\n",
" k: (directionInbound if direction == 'inbound' else directionOutbound)[v.name()] for (k, v) in series.items()\n",
" }\n",
"\n",
" cycol = cycle('brgy')\n",
"\n",
" fig = plt.figure()\n",
" axes = fig.add_axes([0,0,1,1])\n",
"\n",
" if title is not None:\n",
" axes.set_title(title, pad=20.0 if True in [len(x.test.events) > 0 for x in series.values()] else None)\n",
"\n",
" axes.set_xlabel('Time (s)')\n",
" axes.set_ylabel('Throughput (Mbps)')\n",
"\n",
" for k, v in series.items():\n",
" data = v.summarise()\n",
"\n",
" axes.errorbar(\n",
" data.keys(),\n",
" [x/1e6 for x in data.values()],\n",
" xerr=([x[0] for x in v.time_range().values()], [x[1] for x in v.time_range().values()]) if error_bars_x else None,\n",
" yerr=[x*1.5/1e6 for x in v.standard_deviation().values()] if error_bars_y else None,\n",
" capsize=3,\n",
" ecolor='grey',\n",
" color=next(cycol),\n",
" label=k,\n",
" )\n",
"\n",
" legend = axes.legend()\n",
"\n",
" if start_at_zero:\n",
" axes.set_ylim(bottom=0)\n",
" axes.set_xlim(left=0)\n",
"\n",
" if False:\n",
" for k, v in events.items():\n",
" axes.axvline(k, linestyle='--', color='grey')\n",
" axes.annotate(v, (k, 1.02), xycoords=axes.get_xaxis_transform(), ha='center')\n",
"\n",
" if fast_tests:\n",
" fig.text(0.95, 0.05, 'Draft', fontsize=50, color='gray', ha='right', va='bottom', alpha=0.5)\n",
"\n",
" if filename is not None:\n",
" fig.savefig(filename, bbox_extra_artists=(legend,), bbox_inches='tight', pad_inches=0.3)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"if not os.path.exists('graphs/'):\n",
" os.makedirs('graphs/')\n",
"\n",
"for filename in os.listdir('graphs'):\n",
" file_path = os.path.join('graphs/', filename)\n",
" os.unlink(file_path)"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false,
"pycharm": {
"name": "#%% md\n"
}
},
"source": [
"### Error Bar Evaluation"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"plot_iperf_results(\n",
" {\n",
" '4x1MB Connections (proxied)': StandardTest([1,1,1,1]),\n",
" '3x1MB Connections (proxied)': StandardTest([1,1,1]),\n",
" '2x1MB Connections (proxied)': StandardTest([1,1]),\n",
" },\n",
" error_bars_x=False,\n",
" error_bars_y=False,\n",
" filename='png',\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"plot_iperf_results(\n",
" {\n",
" '4x1MB Connections (proxied)': StandardTest([1,1,1,1]),\n",
" '3x1MB Connections (proxied)': StandardTest([1,1,1]),\n",
" '2x1MB Connections (proxied)': StandardTest([1,1]),\n",
" },\n",
" error_bars_x=True,\n",
" error_bars_y=False,\n",
" filename='png',\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false,
"pycharm": {
"name": "#%% md\n"
}
},
"source": [
"### More than 2 connections evaluation"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"plot_iperf_results(\n",
" {\n",
" '4x1MB Connections (proxied)': StandardTest([1,1,1,1]),\n",
" '3x1MB Connections (proxied)': StandardTest([1,1,1]),\n",
" '2x1MB Connections (proxied)': StandardTest([1,1]),\n",
" },\n",
" filename='png',\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"plot_iperf_results(\n",
" {\n",
" '4x2MB Connections (proxied)': StandardTest([2,2,2,2]),\n",
" '3x2MB Connections (proxied)': StandardTest([2,2,2]),\n",
" '2x2MB Connections (proxied)': StandardTest([2,2]),\n",
" },\n",
" filename='png',\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false,
"pycharm": {
"name": "#%% md\n"
}
},
"source": [
"### Mixed Performance Evaluation"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"plot_iperf_results(\n",
" {\n",
" '2x2MB Connections (proxied)': StandardTest([2,2]),\n",
" '1x1MB + 1x2MB Connections (proxied)': StandardTest([1,2]),\n",
" '2x1MB Connections (proxied)': StandardTest([1,1]),\n",
" },\n",
" filename='png',\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false,
"pycharm": {
"name": "#%% md\n"
}
},
"source": [
"### Eventful Evaluation"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"plot_iperf_results(\n",
" {\n",
" 'Varied Connection': StandardTest([2,2], events={10: (0,1), 15: (0,2)}, duration=30),\n",
" },\n",
" filename='png',\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": false,
"pycharm": {
"name": "#%% md\n"
}
},
"source": [
"### Comparisons to a Direct Connection"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"plot_iperf_results(\n",
" {\n",
" '1x2MB Connection (not proxied)': DirectTest(2),\n",
" '2x1MB Connections (proxied)': StandardTest([1,1]),\n",
" '1x1MB Connection (not proxied)': DirectTest(1),\n",
"\n",
" },\n",
" filename='png',\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"plot_iperf_results(\n",
" {\n",
" '1x4MB Connection (not proxied)': DirectTest(4),\n",
" '2x2MB Connections (proxied)': StandardTest([2,2]),\n",
" '1x2MB Connection (not proxied)': DirectTest(2),\n",
"\n",
" },\n",
" filename='png',\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [],
"source": []
}
],
"metadata": {
"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.8.6"
}
},
"nbformat": 4,
"nbformat_minor": 1
}