Skip to content

Commit

Permalink
Tc
Browse files Browse the repository at this point in the history
  • Loading branch information
msune committed Oct 19, 2024
1 parent c61539b commit f493f27
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 60 deletions.
8 changes: 2 additions & 6 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -174,12 +174,8 @@ jobs:
cd sfunnel/test/cni/
make VERBOSE=1 _check_perf
#Create the markdown report (TODO improve txt)
echo "# Performance report" >> $GITHUB_STEP_SUMMARY
echo "CNI: ${CNI}" >> $GITHUB_STEP_SUMMARY
echo "Number of nodes: ${NODES}" >> $GITHUB_STEP_SUMMARY
echo "## Results" >> $GITHUB_STEP_SUMMARY
cat .last_perf_report.txt >> $GITHUB_STEP_SUMMARY
#Create the markdown report
python3 perf/gen_report.py >> $GITHUB_STEP_SUMMARY
docker_build_test_publish:
needs: [check_unit, check_cni_example]
Expand Down
9 changes: 4 additions & 5 deletions test/cni/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -111,15 +111,14 @@ _check_perf: _wait_up _wait_running
while [[ "$$(minikube kubectl -- logs $$POD | grep 'Up and running...')" == "" ]]; do sleep 1; done; \
done;
$(QUIET) echo "Workaround lingering old conntrack (metallb/kubeproxy bug?)..."
$(QUIET) minikube ssh "sudo conntrack -F"
$(QUIET) sleep 10
$(QUIET) for NODE in $$(minikube node list | awk '{print $$1}'); do minikube ssh -n $${NODE} "sudo conntrack -F"; done;
$(QUIET) echo "Launching iperf tests..."
set -o pipefail; \
NETNS=client ./perf/check_perf.sh 2>&1 | tee .last_perf_report.txt; \
if [[ $${PIPESTATUS[0]} -ne 0 ]]; then echo "check_perf failed!"; exit 1; fi
DEBUG=1 NETNS=client python3 perf/check_perf.py
$(QUIET) echo "Unloading NDEBUG sfunnel in NS..."
$(QUIET) $(MAKE) _unload
$(QUIET) echo "Loading DEBUG sfunnel in NS..."
$(QUIET) $(MAKE) _load
$(QUIET) echo "Restoring nginx..."
$(QUIET) $(MAKE) _deploy
$(QUIET) echo "Print report..."
$(QUIET) python3 perf/gen_report.py
72 changes: 72 additions & 0 deletions test/cni/perf/check_perf.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import os
import subprocess
import sys
import re
import json

def get_lb_ip():
return sys.argv[1] if len(sys.argv) > 1 else subprocess.getoutput(
"minikube kubectl -- get service my-loadbalancer-service -o jsonpath='{.status.loadBalancer.ingress[0].ip}'"
)


def get_throughput(output):
for line in output.splitlines():
line = line.lower()
if not line.startswith("[") or "bits" not in line:
continue
if re.search(r'\d+\s+\S+', line):
return float(line.split()[6])

def check_perf(test_name, fqdn, results, target_ports, src_ips=[]):
N_WORKERS = int(os.getenv('N_WORKERS', 4))
debug = int(os.getenv('DEBUG', 0)) == 1
CMD = f"sudo ip netns exec {os.getenv('NETNS')} iperf -f m" if os.getenv('NETNS') else "iperf -f m"
total_throughput = 0
print(f"[{test_name}] Starting {N_WORKERS} workers against '{fqdn}' with target_ports='{target_ports}', src_ips='{src_ips}'")

# Start iperf workers in parallel
src_opt = ""
processes = []
for i in range(1, N_WORKERS + 1):
p = target_ports[i%len(target_ports)]
if len(src_ips):
src_opt = "-B " + src_ips[i%len(src_ips)]
cmd = f"{CMD} -c {fqdn} -p {p} {src_opt}"
if debug:
print(cmd)
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
processes.append({ 'id': i, 'process': p})

# Wait for all workers to finish
for p_ in processes:
p = p_["process"]
p.wait()
output = p.communicate()[0].decode('utf-8')
if debug:
print(f"Worker output {p_['id']}:\n{output}")
total_throughput += get_throughput(output)

avg_throughput = total_throughput / N_WORKERS
results[test_name] = {
'number_of_workers': N_WORKERS,
'total_throughput': total_throughput,
'average_throughput': avg_throughput
}

print(f"[{test_name}] Total throughput: {total_throughput:.2f} Mbit/s, Average throughput: {avg_throughput:.2f} Mbit/s")

def main():
LB_IP = get_lb_ip()

results = {}

check_perf("test_port_80 (calibration)", LB_IP, results, [80])
check_perf("test_port_8080", LB_IP, results, [8080])
check_perf("test_port_80_8080", LB_IP, results, [80, 8080])

with open('.last_perf_report.json', 'w') as json_file:
json.dump(results, json_file, indent=4)

if __name__ == "__main__":
main()
49 changes: 0 additions & 49 deletions test/cni/perf/check_perf.sh

This file was deleted.

37 changes: 37 additions & 0 deletions test/cni/perf/gen_report.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import re
import json
import platform
import os

with open('.last_perf_report.json', 'r') as file:
data = json.load(file)

md_report = "# Performance report\n"
md_report += f"\n"

md_report += f"## General information \n"
md_report += f"\n"
md_report += f"Number of K8s nodes: {os.getenv('NODES', 'unknown')}\n"
md_report += f"CNI: {os.getenv('CNI', 'unknown')}\n"
md_report += f"\n"

md_report += f"## Runner info\n"
md_report += f"\n"
md_report += f"Hostname: {platform.node()}\n"
md_report += f"OS: {platform.system()}\n"
md_report += f"Architecture: {platform.machine()}\n"
md_report += f"Kernel: {platform.release()} {platform.version()}\n"
md_report += f"\n"

md_report += f"## Results\n"
md_report += f"\n"
for key, elem in data.items():
md_report += f"### Fixture: {key}\n"
md_report += f"\n"
md_report += f"Number of workers: {elem['number_of_workers']}\n"
md_report += f"\n"
md_report += f"Average throughput per worker: {elem['average_throughput']:.2f} Mbit/s\n"
md_report += f"Total throughput: {elem['total_throughput']:.2f} Mbit/s\n"
md_report += f"\n"

print(md_report)

0 comments on commit f493f27

Please sign in to comment.