summaryrefslogtreecommitdiffstats
path: root/clover/test/validate_success.py
diff options
context:
space:
mode:
Diffstat (limited to 'clover/test/validate_success.py')
-rw-r--r--clover/test/validate_success.py131
1 files changed, 131 insertions, 0 deletions
diff --git a/clover/test/validate_success.py b/clover/test/validate_success.py
new file mode 100644
index 0000000..65cd579
--- /dev/null
+++ b/clover/test/validate_success.py
@@ -0,0 +1,131 @@
+#!/usr/bin/env python
+
+# Copyright (c) Authors of Clover
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+from clover.orchestration import kube_client
+from clover.tracing.tracing import Tracing
+
+def _get_svc_pods(svc_name, namespace):
+ k8s_client = kube_client.KubeClient()
+ svc = k8s_client.find_svc_by_namespace(svc_name=svc_name,
+ namespace=namespace)
+ if not svc:
+ err_msg = 'Failed to locate service %s in %s namespace' \
+ % (svc_name, namespace)
+ print err_msg
+ return False, [err_msg]
+ pods = k8s_client.find_pod_by_namespace()
+ if not pods:
+ err_msg = 'No pod found in namespace %s' % namespace
+ return False, [err_msg]
+ svc_pods = {}
+ for p,l in pods.items():
+ pod_labels = l.get('labels')
+ svc_selector_dict = svc[service_name].get('selector')
+ for svc_select_key in svc_selector_dict:
+ if svc_select_key in pod_labels:
+ if svc_selector_dict[svc_select_key] == pod_labels[svc_select_key]:
+ svc_pods[p] = l
+ return svc_pods
+
+def validate_perf(tracing, test_id, svc_name, control_svc, variant_svc):
+ ret_dict = {}
+ ret_dict[control_svc] = {}
+ ret_dict[control_svc]['in'] = {}
+ ret_dict[control_svc]['in']['total'] = 0
+ ret_dict[control_svc]['in']['average'] = 0
+ ret_dict[control_svc]['out'] = {}
+ ret_dict[control_svc]['out']['total'] = 0
+ ret_dict[control_svc]['out']['average'] = 0
+
+ ret_dict[variant_svc] = {}
+ ret_dict[variant_svc]['in'] = {}
+ ret_dict[variant_svc]['in']['total'] = 0
+ ret_dict[variant_svc]['in']['average'] = 0
+ ret_dict[variant_svc]['out'] = {}
+ ret_dict[variant_svc]['out']['total'] = 0
+ ret_dict[variant_svc]['out']['average'] = 0
+
+ req_id_dict = {}
+ def _fill_up_ret_dict(direction, svc, duration, out_svc=None):
+ sum = ret_dict[svc][direction]['average'] * \
+ ret_dict[svc][direction]['total'] + \
+ int(duration)
+ ret_dict[svc][direction]['total'] += 1
+ ret_dict[svc][direction]['average'] = \
+ float(sum) / float(ret_dict[svc][direction]['total'])
+ if direction == 'out' and out_svc:
+ # tracking the out service from svc
+ # TODO(s3wong): this assumes only ONE direction from
+ # service to another service, which may not be true
+ # in essence, the data structure should track (srv, out)
+ # pairs and calculate average that way
+ ret_dict[svc][direction]['out_svc'] = out_svc
+
+
+ def _check_req_id(req_id, svc=None, node_id=None,
+ duration=None, direction=None,
+ out_svc=None):
+ if req_id not in req_id_dict:
+ req_id_dict[req_id] = {}
+
+ if svc:
+ req_id_dict[req_id]['svc'] = svc
+ else:
+ req_id_dict[req_id]['node_id'] = node_id
+ req_id_dict[req_id]['duration'] = int(duration)
+ req_id_dict[req_id]['direction'] = direction
+ if direction == 'out' and out_svc:
+ req_id_dict[req_id]['out_svc'] = out_svc
+
+ trace_ids = tracing.getRedisTraceids(test_id)
+ for trace_id in trace_ids:
+ span_ids = tracing.getRedisSpanids(trace_id)
+ for span in span_ids:
+ out_svc = None
+ duration = tracing.getRedisSpanValue(span, trace_id, 'duration')
+ node_id = tracing.getRedisTagsValue(span, trace_id, 'node_id')
+ upstream_cluster = tracing.getRedisTagsValue(span, trace_id, 'upstream_cluster')
+ req_id = tracing.getRedisTagsValue(span, trace_id, 'guid:x-request-id')
+ if upstream_cluster.startswith('in.'):
+ direction = 'in'
+ else:
+ direction = 'out'
+ out_svc = upstream_cluster.split('.')[1]
+ if control_svc in node_id:
+ _fill_up_ret_dict(direction, control_svc, duration, out_svc=out_svc)
+ _check_req_id(req_id, svc=control_svc)
+ elif variant_svc in node_id:
+ _fill_up_ret_dict(direction, variant_svc, duration, out_svc=out_svc)
+ _check_req_id(req_id, svc=variant_svc)
+ else:
+ # client to svc or server from svc as client
+ if out_svc and out_svc == svc_name:
+ _check_req_id(req_id, node_id=node_id, direction=direction,
+ duration=duration, out_svc=out_svc)
+
+ for req_id, svc_dict in req_id_dict.items():
+ node_id = svc_dict.get('node_id')
+ if not node_id:
+ continue
+ pod_name = node_id.split('~')[2]
+ svc = svc_dict.get('svc')
+ if pod_name not in ret_dict.get(svc):
+ ret_dict[svc][pod_name] = {}
+ ret_dict[svc][pod_name]['total'] = 0
+ ret_dict[svc][pod_name]['direction'] = svc_dict.get('direction')
+ if svc_dict.get('out_svc'):
+ ret_dict[svc][pod_name]['out_svc'] = svc_dict.get('out_svc')
+ ret_dict[svc][pod_name]['average'] = 0
+ sum = ret_dict[svc][pod_name]['average'] * \
+ ret_dict[svc][pod_name]['total'] + \
+ svc_dict.get('duration')
+ ret_dict[svc][pod_name]['total'] += 1
+ ret_dict[svc][pod_name]['average'] = \
+ float(sum) / float(ret_dict[svc][pod_name]['total'])
+
+ return ret_dict