From 0b08f773da4b2e5305b5c8acef034fcbe90041a6 Mon Sep 17 00:00:00 2001
From: Florian Fischer <florian.fl.fischer@fau.de>
Date: Wed, 14 Apr 2021 16:41:15 +0200
Subject: [PATCH] [EchoClient] change the output format

Split output between two ini sections: global, clients.
The global section includes results like:
Arguments, total time spent in each phase, ...

The clients section contains a sigle key 'csv' containing the csv data
from each client inclufing the header:
iterations, latency, reconnects, unexpected echos

This leaves the post processing of the data to another program
and does not hide experiment behavior (e.g. starvation of single
clients) behind averages.

Remove support for appending to an output file, because we do not
use it in our emper-io-evaluation and it does not work anymore with the
new output format.
---
 apps/EchoClient.cpp | 50 ++++++++++++++++++++-------------------------
 1 file changed, 22 insertions(+), 28 deletions(-)

diff --git a/apps/EchoClient.cpp b/apps/EchoClient.cpp
index 830d23bb..ae9a8dcd 100644
--- a/apps/EchoClient.cpp
+++ b/apps/EchoClient.cpp
@@ -409,34 +409,18 @@ auto main(int argc, char* argv[]) -> int {
 
 		auto echo_end = high_resolution_clock::now();
 
-		RunningAverage avg_ns;
-		RunningAverage avg_iterations;
-		uint64_t total_iterations = 0;
-		uint64_t reconnects = 0;
-		uint64_t unexpectedEchos = 0;
-		for (size_t i = 0; i < nclients; ++i) {
-			avg_ns.update(clients[i]->avg_ns.getAverage());
-			avg_iterations.update(clients[i]->iteration);
-			total_iterations += clients[i]->iteration;
-			unexpectedEchos += clients[i]->unexpectedEchos;
-			reconnects += clients[i]->reconnects;
-		}
-
 		auto connect_duration = duration_cast<nanoseconds>(echo_start - connect_start).count();
 		auto echo_duration = duration_cast<nanoseconds>(echo_end - echo_start).count();
 		auto total_duration = duration_cast<nanoseconds>(echo_end - connect_start).count();
 
-		bool exists = true;
 		if (output_file) {
-			exists = access(output_file, W_OK) == 0;
-			int openflags;
-			int mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH;
-			if (!exists) {
-				openflags = O_CREAT | O_WRONLY;
-			} else {
-				openflags = O_APPEND;
+			if (access(output_file, W_OK) == 0) {
+				DIE_MSG("Output file: " << output_file << " already exists");
 			}
 
+			int openflags = O_CREAT | O_WRONLY;
+			int mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH;
+
 			out_fd = emper::io::openAndWait(output_file, openflags, mode);
 			if (out_fd < 0) {
 				DIE_MSG_ERRNO("opening output file failed");
@@ -444,14 +428,24 @@ auto main(int argc, char* argv[]) -> int {
 		}
 
 		std::stringstream sst;
-		if (!exists) {
-			sst << "clients,iterations,total_iterations,size,avg_ns,reconnects,unexpected_echos,connect,"
-						 "echo,total"
-					<< std::endl;
+		sst << "[global]" << std::endl;
+		sst << "clients = " << nclients << std::endl;
+		sst << "size = " << size << std::endl;
+		sst << "connect_duration = " << connect_duration << std::endl;
+		sst << "echo_duration = " << echo_duration << std::endl;
+		sst << "total_duration = " << total_duration << std::endl;
+		sst << std::endl;
+
+		sst << "[clients]" << std::endl;
+		sst << "csv =" << std::endl;
+		sst << " iterations,avg_ns,reconnects,unexpected_echos" << std::endl;
+		for (size_t i = 0; i < nclients; ++i) {
+			auto* client = clients[i];
+			sst << " " << client->iteration << ",";
+			sst << client->avg_ns.getAverage() << ",";
+			sst << client->reconnects << ",";
+			sst << client->unexpectedEchos << std::endl;
 		}
-		sst << nclients << "," << avg_iterations.getAverage() << "," << total_iterations << "," << size
-				<< "," << avg_ns.getAverage() << "," << reconnects << "," << unexpectedEchos << ","
-				<< connect_duration << "," << echo_duration << "," << total_duration << std::endl;
 
 		auto output = sst.str();
 		if (emper::io::writeFileAndWait(out_fd, output.c_str(), output.size()) < 0) {
-- 
GitLab