summaryrefslogtreecommitdiffstats
path: root/clover/tools/validate_rr.py
blob: 0e7b9ede22da9a99a4bf89a2debf09b6e27cf5f7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#!/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
import sys

sys.path.insert(0, '..')

from orchestration import kube_client
import servicemesh.route_rules as rr
from tracing.tracing import Tracing

class ValidateWRR(object):

    def __init__(self, test_id, tracing_ip='localhost', tracing_port='31298'):
        self._k8s_client = kube_client.KubeClient()
        self._test_id = test_id
        self._tracing = Tracing(tracing_ip, tracing_port)

    def check_pods_up(self, pod_list, namespace='default'):
        for pod in pod_list:
            up, name = self._k8s_client.check_pod_up(pod, namespace)
            if not up:
                print('pod %s in namespace %s not up' % (pod, namespace))
                return False
        return True

    def set_test_id(self, test_id):
        self._test_id = test_id

    def validate(self, service_name):
        total = 0
        svc = self._k8s_client.find_svc_by_namespace(svc_name=service_name)
        if not svc:
            err_msg = 'Failed to locate service %s in default namespace' % service_name
            print err_msg
            return False, [err_msg]
        pods = self._k8s_client.find_pod_by_namespace()
        if not pods:
            err_msg = 'No pod found in default 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

        trace_ids = self._tracing.getRedisTraceids(self._test_id)
        rr_dict = {'service': service_name}
        ver_count_dict = {}
        for trace_id in trace_ids:
            span_ids = self._tracing.getRedisSpanids(trace_id)
            for span in span_ids:
                # count only the received side --- i.e., messages sent TO
                # service
                node_id = self._tracing.getRedisTagsValue(span, trace_id, 'node_id')
                direction = self._tracing.getRedisTagsValue(span, trace_id, 'upstream_cluster')
                if direction.startswith('in.'):
                    for pod_name in svc_pods:
                        if pod_name in node_id:
                            total += 1
                            labels = svc_pods[pod_name]['labels']
                            print('node %s pod %s labels %s' % (node_id, pod_name, labels))
                            if 'version' in labels:
                                version = labels.get('version')
                                if version in ver_count_dict:
                                    ver_count_dict[version] += 1
                                else:
                                    ver_count_dict[version] = 1

        print('total is %d, ver_count_dict is %s' % (total, ver_count_dict))
        if ver_count_dict and total > 0:
            for version in ver_count_dict:
                rr_dict[version] = float(ver_count_dict[version]) / float(total) * 100

            return(rr.validate_weighted_route_rules(rr_dict, self._test_id))
        else:
            err_msg = 'No version label found on any pod'
            print(err_msg)
            return False, [err_msg]