@ -35,40 +35,73 @@ A test has two phases, the pre-execution phase and the execution phase. In the p
The execution phase contains the actual testing. A command can be executed and its results will be written to the Mininet console.
Additionally, failures can be introduced to the network. The key \textit{failures} contains a list of failures, defined by a type and a list of commands. The types of implemented failures are "intermediate" and "timer". Intermediate failures will be executed after a first run of the execute command, which will be repeated after the failure function was called. A failure that is of the type "timer" will start a timer in the beginning of the measurement, which will execute the defined command after a delay, which is provided through an attribute named "timing".
Additionally failures can be introduced to the network. The key \textit{failures} contains a list of failures, defined by a type and a list of commands. The types of implemented failures are "intermediate" and "timer". Intermediate failures will be executed after a first run of the execute command, which will be repeated after the failure function was called. A failure that is of the type "timer" will start a timer in the beginning of the measurement, which will execute the defined command after a delay, which is provided through an attribute named "timing".
\subsection{Implemented commands}
A command can either be a lambda which is only dependent on the net, which will be passed into the lambda by default, or a function definition which is a tuple of the name of the function and a second nested x-tuple, depending on the function to call, containing all arguments that need to be passed to the function.
The functions are defined in the \textit{mininet\_controller.py} and can't be called directly, because the topologies are loaded dynamically and will not know existing function definitions until they are loaded. Because of this the \textit{mininet\_controller.py} contains a dictionary called "functions" which has the function name as key and an attribute called "callable" containing a lambda with the function call using the provided arguments.
The functions are defined in the \textit{mininet\_controller} and can't be called directly, because the topologies are loaded dynamically and will not know existing function definitions until they are loaded. Because of this the \textit{mininet\_controller} contains a dictionary called "functions" which has the function name as key and an attribute called "callable" containing a lambda with the function call using the provided arguments. In the following we list the existing functions and explain their functionality, which files are created and which output can be used for further testing and evaluation.
\subsubsection{connection\_shutdown}
\subsubsection{connection\_shutdown}
This function will use a connection which is by definition a list with 2 elements, containing the names of the hosts/nodes which are linked together, a list with 2 elements containing the names of both components for printing and a list with 2 elements containing the interfaces which should be shut down. It will then access the components in the network and use the cmd function provided by Mininet to execute an "ifconfig down *interface*" on the component, which will cause the interface to be deactivated. This is done on both sides of the connection to make sure that each router will be able to recognize the missing connection instantly.
\subsubsection{measure\_ bandwidth}
This function will use a 2-element list of hosts, a 2-element list of ips, a length parameter that defines how long the test will run in seconds, an interval parameter defining the interval between each log entry of \textit{iperf}, a unique test name for naming a created graph or log entry, a graph title in case a graph should be created, a flag that defines whether \textit{iperf} should use tcp or udp as transfer protocol and a bandwidth to limit the transfer rate of \textit{iperf}.
\subsubsection{measure\_bandwidth}
\label{measure_bandwidth}
This function will use a 2-element list of hosts, a 2-element list of IPs, a length parameter that defines how long the test will run in seconds, an interval parameter defining the interval between each log entry of \textit{iperf}, a unique test name for naming a created graph or log entry, a graph title in case a graph should be created, a flag that defines whether \textit{iperf} should use tcp or udp as transfer protocol and a bandwidth to limit the transfer rate of \textit{iperf}.
The command starts an \textit{iperf} server and client on the defined devices and logs their output. It will then parse this output for \textit{gnuplot}, which will in turn create a plot in the "/tmp/" directory of the virtual machine.
The command starts an \textit{iperf} server. While experimenting we sometimes experienced unexpected behaviour causing tests to fail. There seemed to be an issue with the timing of the \textit{iperf} server and client commands which were executed on the corresponding devices. Because the \textit{iperf} server and client were started detached and the python script executed both commands directly one after another, the client seemed to try to connect to the server while the server was still in its startup process, denying the connection. This is why we added an additional delay between server and client command execution.
\subsubsection{measure\_ latency}
This function will use a sender element in the network, a destination ip, a length parameter that defines how many pings should be performed, an interval parameter defining the delay between each ping, a unique test name and a graph title.
Both the client and server log their output. The function will then parse the output of the server, as results from the server seemed to be more consistent, for \textit{gnuplot}, which will in turn create a plot in the "/tmp/" directory of the virtual machine as described in section \ref{plotting}.
\subsubsection{measure\_ packet\_ flow}
\subsubsection{measure\_link\_usage\_bandwidth}
This function will use an two \textit{iperf} server-client pairs to start two separate bandwidth tests. The second \textit{iperf} measurement will use the port 5202 instead of the default port 5201 in case two servers are started on the same device.
The function reuses the \textit{measure\_bandwidth} function described in section \ref{measure_bandwidth}. We call the measurement done by the \textit{measure\_bandwidth} function the "main" measurement, the additional transfer used to evaluate the influence of another file transfer on the network the "additional" measurement.
Because we reuse the \textit{measure\_bandwidth} function, the additional measurement is started with a delay. The \textit{measure\_bandwidth} functions introduces a sleep time of one second between the execution of the \textit{iperf} server command and the client command, which would cause the additional measurement to be executed a second early to the main measurement. This is why we considered this additional second in the execution and the parsing process of the \textit{iperf} output, executing the additional measurement for a longer period of time, omitting the entry for the first second and shifting all time values one second ahead. Doing this we create a log output that is nearly synced only adding the delay created by the Mininet and python overhead.
Both results are then passed to the \textit{multiplotting} function referenced in section \ref{plotting}, to create a plot containing both bandwidth measurements. The original graph created by the \textit{measure\_bandwidth} function is also saved. The combined graph receives the subtitle "\_combined".
\subsubsection{measure\_latency}
This function will use a sender element in the network, a destination IP, a length parameter that defines how many ping packets should be sent, an interval parameter defining the delay between each ping, a unique test name, a list containing the range for the y-axis of a created graph and a graph title which will be used in naming the files of tests.
After creating a test name out of the components of the measurement, including sender and destination, which latency measurement function was used (currently only ping is used), the defined unique test name, e.g. containing information whether the test was started before or after introducing a failure, as well as whether or not ShortCut was used.
It will then start a ping from the defined sender to the destination IP and log the results to a file in the "/tmp/" directory. The ping command is started in detached mode using the bash target "\&". Output is directly written to a file using the ">" operator in the bash command. The python script will then wait for the corresponding time, adding some seconds to make sure all executions were fully run. After that, the produced ping output is parsed using bash tools, including \textit{more}, \textit{head} and \textit{awk}, to create a single line command which will create a file with time-value pairs, separated by line.
The output file will then be extended by a zero value. All files created are saved in the "/tmp/" and can be used to further inspect results. They are named according to the test name. Files containing console output or parsed versions of said output use the file extension ".out".
After successfully parsing the output files the information about the test, including information about the test name is passed to the plotting function further explained in section \ref{plotting}, which will create a plot in the "/tmp/" directory under the same test name using the file type ".eps", which can be implemented directly in a LaTex document for documentation.
\subsubsection{measure\_packet\_flow}
This function will use a client and server parameter to start an \textit{iperf} transfer and will implement packet counters using the filtering capabilities of \textit{nftables} on all devices referenced in the flow measurement targets provided in the parameters of this function. Depending on the "flag" parameter they will count all packets entering the device which belong to the specified protocol. As \textit{nftables} is normally used to create firewall rulings and is used in many professional linux networks it is safe to assume that the counters will have a minimal impact on performance.
When the packet counters are created information about them will be stored in a global packet counter memory, which will later be used to access information about the counters. After initialization this status is saved in a global variable in case the script is run again during the lifetime of the network to avoid the multiple implementation of the same counter and thus errors that could occur. If this variable is already true during execution, the existing counters are reset to a value of zero instead.
There are python libraries for reading \textit{nftables} entries but an implementation would take additional time because of the usage of network namespaces of Mininet. Each device lives in its own network namespace, which would have to be specifically accessed by the python library. Because of this concern we decided to manually check and parse the output of the command line tool of \textit{nftables}.
After starting a bandwidth test using \textit{iperf} on the client device, the packet counters are started which will start a python thread for each of the measurement targets. In each of these threads the bash command for displaying counters is used to access the current count. The output is saved in python, parsed and then saved to a log file which is named after the device that is being logged, including the current time of execution in a fitting format for \textit{gnuplot}.
After stopping the \textit{iperf} server on the server device the created log files are passed as a dictionary with the corresponding label for the data to the \textit{multiplotting} function explained in section \ref{plotting}.
\subsubsection{Plotting}
Plotting results helps with visualizing differences. But performing many tests and creating graphs can become tedious and will take a lot of time. This is why we used \textit{gnuplot} to automatically create graphs. Each function that produces a log output containing results will parse its own results to only contain a time-value and a value, separated by a space, with additional values listed line-by-line. For parsing e.g. \textit{iperf} results we use a combination of grep to limit output to results with times, head to limit the count of lines read according to the length parameter of the function, \textit{tr} to remove hyphens and pass the by this created space separated table of values to \textit{awk} to print relevant data to a separate file.
This data is then passed to \textit{gnuplot}, which will produce an eps file containing a simple plot of our data. A test run with \textit{iperf} would look like seen in figure \ref{fig:s_to_d_iperf_tcp_pre_failure_graph}. We use the "with linespoints" option, as well as the passed graph title for additional information on the plot.
\label{plotting}
Plotting results helps with visualizing differences. But performing many tests and creating graphs can become tedious and will take a lot of time. This is why we used \textit{gnuplot} to automatically create graphs. Each function that produces a log output containing results will parse its own results to only contain a time-value and a value, separated by a space, with additional values listed line-by-line.
This data is then passed to \textit{gnuplot}, which will produce an eps file containing a simple plot of our data. A test run with \textit{iperf} would look like seen in figure \ref{fig:example_plotting}. We use the "with linespoints" option, as well as the passed graph title for additional information on the plot.
\caption{Exemplary latency test run with automatic plotting}
\label{fig:example_plotting}
\end{figure}
In addition to plotting a single line in a graph, we also implemented a function to plot multiple data files in \textit{gnuplot} automatically. The function will use a greyscale as line colors and different dash styles for differentiating plots. It will also add the monitored device to the legend.
In addition to plotting a single line in a graph, we also implemented a function to plot multiple data files in \textit{gnuplot} automatically. The function uses a greyscale as line colors and different dash styles for differentiating plots. It adds a defined label to each dataset. This can be used to e.g. plot the packet flow of multiple devices. A plot created with this method will look something like can be seen in figure \ref{fig:example_multiplotting}.