dissertation-3-evaluation/evaluation.ipynb

331 lines
117 KiB
Plaintext
Raw Normal View History

{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"import os\n",
"import ipaddress\n",
"\n",
"import runners\n",
"from structure import Bridge\n",
"from structure import SpeedTestServer, RemoteServer, LocalServer\n",
"from structure import Interface, IpMethod\n",
"\n",
"%load_ext dotenv\n",
"%dotenv"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
2020-11-01 18:35:10 +00:00
"outputs": [
{
"ename": "NameError",
"evalue": "name 'runners' is not defined",
"output_type": "error",
"traceback": [
"\u001B[0;31m---------------------------------------------------------------------------\u001B[0m",
"\u001B[0;31mNameError\u001B[0m Traceback (most recent call last)",
"\u001B[0;32m<ipython-input-2-5781debf60ce>\u001B[0m in \u001B[0;36m<module>\u001B[0;34m\u001B[0m\n\u001B[0;32m----> 1\u001B[0;31m runner = runners.ProxmoxRunner(\n\u001B[0m\u001B[1;32m 2\u001B[0m \u001B[0mhost\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0mos\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mgetenv\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0;34m'PROXMOX_HOST'\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 3\u001B[0m \u001B[0mnode\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0mos\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mgetenv\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0;34m'PROXMOX_NODE'\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 4\u001B[0m \u001B[0muser\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0mos\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mgetenv\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0;34m'PROXMOX_USER'\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 5\u001B[0m \u001B[0mtoken_name\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0mos\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mgetenv\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0;34m'PROXMOX_TOKEN_NAME'\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n",
"\u001B[0;31mNameError\u001B[0m: name 'runners' is not defined"
]
}
],
"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='vmbr2',\n",
"\n",
" management_bridge='vmbr4',\n",
" management_initial_ip=ipaddress.ip_address('10.21.12.2'),\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"g_st = SpeedTestServer([Interface(IpMethod.Auto4)])\n",
"l_st = SpeedTestServer([Interface(IpMethod.Dhcp4)])\n",
"\n",
"rs = RemoteServer([Interface(IpMethod.Auto4)])\n",
"ls = LocalServer([\n",
" Interface(IpMethod.Auto4, limit=1),\n",
" Interface(IpMethod.Auto4, limit=1),\n",
"], l_st)\n",
"\n",
"top_level_bridge = Bridge(*[\n",
" g_st.get_interfaces()[0],\n",
" rs.get_interfaces()[0],\n",
" *ls.get_interfaces()[0:2],\n",
"])\n",
"runner.build(top_level_bridge)\n",
"\n",
"# Test from the client to the global network via the proxy\n",
"g_st.server()\n",
"l_st.client(rs.get_interfaces()[0])\n",
"\n",
"# Test from the global network to the client via the proxy\n",
"g_st.server()\n",
"l_st.client(rs.get_interfaces()[0])\n",
"\n",
"# Clean up\n",
"runner.teardown()"
]
},
{
"cell_type": "code",
"execution_count": 60,
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
2020-11-01 18:35:10 +00:00
"outputs": [],
"source": [
"from itertools import cycle\n",
"import matplotlib.pyplot as plt\n",
"\n",
"def plot_iperf_results(data, title, events=None, filename=None, start_at_zero=True):\n",
" cycol = cycle('brgy')\n",
2020-11-01 18:35:10 +00:00
"\n",
" fig = plt.figure()\n",
" axes = fig.add_axes([0,0,1,1])\n",
"\n",
" axes.set_title(title, pad=20.0)\n",
2020-11-01 18:35:10 +00:00
" axes.set_xlabel('Time (s)')\n",
" axes.set_ylabel('Throughput (Mbps)')\n",
"\n",
" for k, v in data.items():\n",
" intervals = [x['sum'] for x in v['intervals'] if not x['sum']['omitted']]\n",
"\n",
" x_axis = [((x['start'] + x['end'])/2) for x in intervals]\n",
" y_axis = [x['bits_per_second']/1e6 for x in intervals]\n",
2020-11-01 18:35:10 +00:00
" axes.plot(x_axis, y_axis, next(cycol), label=k)\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",
2020-11-01 18:35:10 +00:00
" if events is not None:\n",
" for k, v in events.items():\n",
" axes.axvline(k, linestyle='--', color='grey', ymax=0.92)\n",
" axes.annotate(v, (k, 1.02), xycoords=axes.get_xaxis_transform(), ha='center')\n",
2020-11-01 18:35:10 +00:00
"\n",
" if filename is not None:\n",
" fig.savefig(filename, bbox_extra_artists=(legend,), bbox_inches='tight', pad_inches=0.3)"
]
},
{
"cell_type": "code",
2020-11-02 17:23:42 +00:00
"execution_count": 71,
2020-11-01 18:35:10 +00:00
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"# Manual results\n",
"# sudo iperf3 -c X.X.X.X -t 30 -O 5 -J\n",
"\n",
"import json\n",
"\n",
"def load_json_from_file(path):\n",
" with open(path, 'r') as f:\n",
" return json.loads(f.read())\n",
"\n",
"One1MBStraight = load_json_from_file('manual/One1MBStraight.json')\n",
"One2MBStraight = load_json_from_file('manual/One2MBStraight.json')\n",
"\n",
"Two1MBAggregate = load_json_from_file('manual/Two1MBAggregate.json')\n",
"Two2MBAggregate = load_json_from_file('manual/Two2MBAggregate.json')\n",
"\n",
"One1MBOne2MBAggregate = load_json_from_file('manual/One1MBOne2MBAggregate.json')\n",
"\n",
"Two2MBAggregateKillOneRecoverOne = load_json_from_file('manual/Two2MBAggregateKillOneRecoverOne.json')\n"
]
2020-11-01 18:35:10 +00:00
},
{
"cell_type": "code",
2020-11-02 17:23:42 +00:00
"execution_count": 72,
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
2020-11-01 18:35:10 +00:00
"outputs": [
{
"data": {
"text/plain": "<Figure size 432x288 with 1 Axes>",
"image/png": "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
2020-11-01 18:35:10 +00:00
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"plot_iperf_results(\n",
" {\n",
" '1x1MBps connection (not proxied)': One1MBStraight,\n",
" '2x1MBps connections (proxied)': Two1MBAggregate,\n",
" },\n",
" 'Proxying adds additional bandwidth',\n",
2020-11-01 18:35:10 +00:00
")"
]
},
{
"cell_type": "code",
2020-11-02 17:23:42 +00:00
"execution_count": 73,
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [
{
"data": {
"text/plain": "<Figure size 432x288 with 1 Axes>",
2020-11-02 17:23:42 +00:00
"image/png": "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
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"plot_iperf_results(\n",
" {\n",
" '1x1MBps connection (not proxied)': One1MBStraight,\n",
" '2x1MBps connections (proxied)': Two1MBAggregate,\n",
" '1x2MBps connection (not proxied)': One2MBStraight,\n",
" '2x2MBps connections (proxied)': Two2MBAggregate,\n",
" },\n",
" 'Proxing bandwidth scaling/overhead'\n",
")"
]
},
{
"cell_type": "code",
2020-11-02 17:23:42 +00:00
"execution_count": 74,
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [
{
"data": {
"text/plain": "<Figure size 432x288 with 1 Axes>",
2020-11-02 17:23:42 +00:00
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAeAAAAFrCAYAAAAJo1qOAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8vihELAAAACXBIWXMAAAsTAAALEwEAmpwYAABfW0lEQVR4nO3dd3gU1frA8e+bBBJ6TZAOKh0hAgIWEMUuilhRbNeK14LtqvdeC/izXnvD3kVQQRBBQQUVRRHpHaWETiihpZGy7++Ps5tGElK2JJv38zzz7OxOO7OzO++cM2fOEVXFGGOMMcEVEeoEGGOMMVWRBWBjjDEmBCwAG2OMMSFgAdgYY4wJAQvAxhhjTAhYADbGGGNCwAKwqRJE5AMReayMy44UkU/8nabyEJEEETkt1OkIBBFJFpEjQ52OoojITyJyQxHT2oiIikhUsNNlKh8LwKbSCOegU1UVFsxUtbaqrgtVmowJFgvAxhhjTAhYADaVkohcKyKzReQFEdkrIutE5ATv55tEZIeIXFNgscYi8r2IHBCRn0WkdZ71veRdbr+IzBeRfsVs+wsR2S4i+0Rkloh0yTPtAxF5TUSmerfzh4gclWd6F28akkQkUUT+4/08QkQeEJG1IrJbRD4XkYZ5lrtKRDZ4p/33MN9NDRF5zjv/PhH5VURqeKedLyLLvd/ZTyLSKc9yCSJyr4gs8S73mYjEeKcNEJHNInKP97vdJiL/yLNstIg8KyIbvfv1hm+b3umDRWSR9/tdKyJnicjjQD/gVW+x86veeVVEjvaO1xORj0Rkp3d/HhSRiDy/gV+9290jIutF5OwCv5F13uOwXkSGFfF99RaR373fyTYReVVEqueZfrqIrPJ+J68CkmdapHf7u0RkHXBuccfGmLwsAJvKrA+wBGgEfAqMA44DjgauxJ3Ya+eZfxjwf0BjYBEwJs+0P4F4oKF3XV/4gk8hvgXaAXHAggLrARgKjAIaAGuAxwFEpA7wAzANaOZN5wzvMrcDFwAne6ftAV7zLtcZeB24yjutEdCimO/lWaAncIJ3f+4DPCLSHhgL3AnEAt8AX+cNNsClwFlAW6AbcG2eaUcA9YDmwPXAayLSwDvtKaA97js82jvPw9709wY+Av4F1Af6Awmq+l/gF+A2b7HzbYXsyyvebR7p/W6uBv6RZ3ofYDXumP4PeFecWsDLwNmqWsf7XSwq4vvKBu7yruN4YCDwT2/aGwNfAg96p68FTsyz7I3AIOBYoBdwcRHbMOZQqmqDDZViABKA07zj1wJ/55l2DKBAkzyf7QbiveMfAOPyTKuNO/G2LGJbe4Du3vGRwCdFzFffu916ebbzTp7p5wCrvOOXAwuLWM9KYGCe902BTCAKF8jypr0WkOH7LgqsJwJI86W9wLSHgM8LzLsFGJDn+70yz/T/AW94xwd41xuVZ/oOoC8uR5gCHJVn2vHAeu/4m8ALRez3T8ANBT5TXBCP9O5n5zzTbgZ+yvMbWJNnWk3vskd4v6O9wEVAjVL+zu4EJnrHrwbm5JkmwGZfmoGZwPA808/wpiGqNNu0oWoOlgM2lVlinvE0AFUt+FneHPAm34iqJgNJuBwl3qLXld5ixr24XFfjghv0Fjk+5S1G3Y8LWhSYd3ue8dQ8aWiJy0EVpjUw0VsMuhcXkLOBJt405k17Cu7iojCNgZgittMM2JBnPR7vepuXIO0Au1U1q5DpsbjgNz9P+qd5P4fi97s4jYFqedPsHS80vaqa6h2t7f2OLgOGA9u8twQ6FrYREWkvIlPE3VbYDzxB7vEs+N1r3vcFpxdIqzHFsgBsqpKWvhFv0XRDYKu4+7334YpfG6hqfWAfee715XEFMBg4DRek2/hWWYLtb8IVpRY17WxVrZ9niFHVLcC2AmmviSuGLswuIB04qpBpW3GB3rce8a53SwnSXpxduIudLnnSXk9VfcF7UxHpAZdbLG69mXnTDLQqaXpVdbqqno4rTVgFvF3ErK97p7dT1brAf8g9ngW/e8n7vuB0b/qMKRELwKYqOUdETvLe8/w/XNHiJqAOkAXsBKJE5GGgbhHrqAMcxOVAa+JySyU1BWgqInd6Ky3VEZE+3mlvAI+Lt2KYiMSKyGDvtPHAoDxpf5Qi/rveXO17wPMi0sybYz9eRKKBz4FzRWSgiFQD7vHuy2+l2Ieitvk28IKIxHnT31xEzvTO8i7wD+92I7zTfLnRRIq4KFHVbG+aH/d+V62Bu4HDPpMtIk28Fb9qefcxGfAUMXsdYD+Q7E3XLXmmTQW6iMiF4p7tvQNXxO3zOXCHiLTw3g9/4HBpM8bHArCpSj4FHsEVPffEVdQCmI4rMv0LV4SYTv5ixbw+8s6zBVgBzCnpxlX1AHA6cB6u6PRv4BTv5JeAycB3InLAu94+3uWWA7d6078Nd396czGbuhdYiqtYlgQ8DUSo6mrvPr+Cy12eB5ynqhkl3Ydi3I+rcDbHW4z7A9DBm/65uIpTL+BKFn4mN1f7EnCxtxbzy4Ws93bc/eV1wK+47+C9EqQnAhest+K+g5PJH1jzuhdXsnEAdyHxmW+Cqu4CLsFVMtuNq3w3O8+yb+N+P4txFfK+LEHajAFA3C0NY4wxxgST5YCNMcaYELAAbIwxxoSABWBjjDEmBCwAG2OMMSFgAdgYY4wJAQvAxhhjTAhYADbGGGNCwAKwMcYYEwIWgI0xxpgQsABsjDHGhIAFYGOMMSYELAAbY4wxIWAB2BhjjAkBC8DGGGNMCFgANsYYY0LAArAxxhgTAhaAjTHGmBCwAGyMMcaEgAVgY4wxJgSiQp2AkmjcuLG2adMm1MkwxhhjSmX+/Pm7VDW2sGmVIgC3adOGefPmhToZxhhjTKmIyIaiplkRtDHGGBMCFoCNMcaYELAAbIwxxoSABWBjjDEmBCwAG2OMMSFgAdgYY4wJgUrxGJIJvZSMFBL2JuQMyRnJXNjpQto1ahfqpBljTKVkAdgAkJaZxoZ9G1i/Z31OkF2/N3d8Z+rOQ5Z5YMYDDGgzgJt63MSQTkOIiYoJQcpNKGV7stl/cD8NajQIdVJCyqMe9qXvY3fabnal7so3NK3dlGHdhoU6iaYCCusArKos2r6IccvGMXHVRBrVbMTQLkO5pMslNKvTLNTJqzBe/uNl7v3uXjI9mTmfVY+sTpv6bWhTvw3HHnEsbeq3oW2DtjmfedTDB4s+4J0F73DFl1fQsEZDru52NTf2vJHOsZ1DuDfGn/Yf3M/GfRtzhk37NrFxf+77zfs3k+XJ4h/x/+DNQW9SLbJaqJNcKhnZGfy4/keSM5I5mH2QjOyMIoeDWW56amYqu9N25wu2u1N3k63ZRW5nSKch1KxWM4h7ZioDUdVQp+GwevXqpaVpCWvVrlWMWzaOccvGsXr3aqIiohjYdiCJKYks2r4IQejfuj+XdbmMiztfTGytQlsJC3vZnmzu+e4eXvrjJc5rfx5Duw7NCbBH1D6CCDl8FQGPepi5fiZvL3ibiSsnkunJ5ISWJ3Bjjxu5tMulYXHSSclIIVuzqRtdN9RJCZhsTzaLExfzU8JP/LLxF9YmrWXjvo3sO7gv33xREVG0qNuCVvVa0bJuS1rVa8W+9H2Mnjeas44+iy8u+YLa1WuHaC9KZ9uBbVz8xcX8tum3w84bKZFUj6xO9cjqxETF0LhmYxrXbEyjmo1oXKNxzvucz7zjU/6awohpI0gYkUDr+q39vg8Z2Rls2reJ1vVbExVR+fJTG/dtpEFMA+pE1wl1UgJGROaraq9Cp4VLAE7Ym8Bnyz5j3PJxOUF2QJsBDO06lAs7XUjjmo0BF5x9863atYpIieTUtqcytOtQhnQcUmWK0lIzU7nyyyuZuGoid/W9i2dOf4bIiMhyrXNnyk4+WvwRby94m9W7V1M3ui5XHnMlN/a8kfgj4v2T8CDanbqbF+e8yMtzXyYzO5Nbj7uV+068Lywu2LI92SzavoifEn7ipw0/8cuGX3KC7dENj6ZLbJecAJt3OKL2EYX+Tt6e/zbDpw6nR9MeTL1iKnG14oK9S6Uyd8tchnw2hL3pexl9zmh6NuuZE2ALDtUiqpX
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
2020-11-01 18:35:10 +00:00
],
"source": [
"plot_iperf_results(\n",
" {\n",
" '2x1MBps connections (proxied)': Two1MBAggregate,\n",
" '1x1MBps+1x2MBps connections (proxied)': One1MBOne2MBAggregate,\n",
" '2x2MBps connections (proxied)': Two2MBAggregate,\n",
" },\n",
" 'Imbalanced connections add',\n",
")"
]
},
{
"cell_type": "code",
2020-11-02 17:23:42 +00:00
"execution_count": 75,
2020-11-01 18:35:10 +00:00
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [
{
"data": {
"text/plain": "<Figure size 432x288 with 1 Axes>",
"image/png": "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
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"plot_iperf_results(\n",
" {\n",
" '1x2MBps+1xYMBps connections (proxied)': Two2MBAggregateKillOneRecoverOne,\n",
" },\n",
" 'Killed connection',\n",
" events={15: 'Y = 0', 40: 'Y = 2'},\n",
")"
]
2020-11-01 18:35:10 +00:00
},
{
"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
}