1 from kubernetes import client, config
2 from utils.k8s_setup import k8s_utils
8 import utils.logger as log
12 LOG = log.Logger(__name__).getLogger()
14 parser = argparse.ArgumentParser(description='kubestone (k8s stress) tests')
15 parser.add_argument("-c", "--TEST_CASE",
16 help="The path of test case in form of yaml")
17 args = parser.parse_args()
18 TEST_CASE = args.TEST_CASE
19 TEST_CASE_NAME, TEST_CASE_FORMAT = os.path.splitext(
20 os.path.basename(TEST_CASE))
21 OUT_FILE = ("/tmp/bottlenecks_kubestone_" +
22 TEST_CASE_NAME + "_" + str(uuid.uuid4()) + ".out")
25 def test_step_result(num, success_num, during_seconds, result):
28 test_result["number_of_deployments"] = float(num)
29 test_result["success_deployments"] = success_num
30 test_result["success_rate"] = success_num / num
31 test_result["duration_time"] = during_seconds
32 test_result["result"] = result
33 testdata["data_body"] = test_result
34 testdata["testcase"] = TEST_CASE_NAME
39 INSTALLER_TYPE = os.getenv("INSTALLER_TYPE")
40 K8S_CONFIG_PATH = os.getenv("K8S_CONFIG_PATH")
41 K8S_APPS_API_VERSION = os.getenv("K8S_APPS_API_VERSION")
42 K8S_CORE_API_VERSION = os.getenv("K8S_CORE_API_VERSION")
43 # Get k8s config. If provided in the path indicated by
44 # K8S_CONFIG_PATH, only return the path.
46 k8s_utils.get_config_path(
47 K8S_CONFIG_PATH=K8S_CONFIG_PATH)
50 K8S_CONFIG_PATH = k8s_utils.get_config_path(
51 INSTALLER_TYPE=INSTALLER_TYPE)
53 k8s_utils.get_config_path()
55 config.load_kube_config(K8S_CONFIG_PATH)
57 # Initiate api clients
58 if K8S_APPS_API_VERSION:
59 apps_api = k8s_utils.get_apps_api(K8S_APPS_API_VERSION)
61 apps_api = k8s_utils.get_apps_api()
63 if K8S_CORE_API_VERSION:
64 core_api = k8s_utils.get_core_api(K8S_CORE_API_VERSION)
66 core_api = k8s_utils.get_core_api()
68 # Read test case in the form of yaml
69 with open(TEST_CASE) as test_case_file:
70 test_case_yaml = yaml.load(test_case_file)
71 if test_case_yaml['template']:
72 if test_case_yaml['template'].lower() == 'none':
73 deployment_yaml = test_case_yaml
75 with open(test_case_yaml['template']) as deployment_file:
76 deployment_yaml = yaml.load(deployment_file)
78 deployment_yaml = test_case_yaml
80 name = deployment_yaml['metadata']['name']
81 namespace = deployment_yaml['namespace']
82 body = client.V1Deployment()
83 body.api_version = deployment_yaml['apiVersion']
84 body.kind = deployment_yaml['kind']
85 body.metadata = deployment_yaml['metadata']
86 body.spec = deployment_yaml['spec']
90 namespace_existed = k8s_utils.get_namespace_status(namespace)
91 if namespace_existed[0] == 0 and \
92 'exception' not in namespace_existed[1].lower():
93 namespace_read = core_api.read_namespace(namespace, pretty=pretty)
94 LOG.info('Namespace {} already exist: \n{}'.format(
95 namespace, namespace_read))
97 namespace_body = client.V1Namespace()
98 namespace_body.metadata = {'name': namespace}
99 namespace_created = core_api.create_namespace(
100 namespace_body, pretty=pretty)
101 LOG.info('Namespace has been created:\n{}'.format(
105 deployment_existed = k8s_utils.get_deployment_status(name, namespace)
106 if deployment_existed[0] == 0 and \
107 'exception' not in deployment_existed[1].lower():
108 deployment_read = apps_api.read_namespaced_deployment(
109 name, namespace, pretty=pretty)
110 LOG.info('Deployment {}@{} already exist.'.format(name, namespace))
111 LOG.info('Discription of this deployment is:\n{}'.format(
114 deployment_created = apps_api.create_namespaced_deployment(
115 namespace, body, pretty=pretty)
116 LOG.info('Deployment has been created:\n{}'.format(
119 # Scale the deployment
120 scaling_steps = deployment_yaml['scaling_steps'].split(',')
121 for step in scaling_steps:
122 start_time = datetime.datetime.now()
125 body.spec['replicas'] = step
126 api_response = apps_api.patch_namespaced_deployment_scale(
127 name, namespace, body, pretty=pretty)
128 LOG.info("Deployment replicas is to be scaled to: %s" % step)
129 pods_number = k8s_utils.get_available_pods(name, namespace)
130 while pods_number != step:
131 pods_number = k8s_utils.get_available_pods(name, namespace)
132 LOG.info("Number of available pods are {} out of {}".format(
134 api_response = apps_api.read_namespaced_deployment_scale(
135 name, namespace, pretty=pretty)
137 "Deployment {}-scaling finished:\n{}".format(
140 end_time = datetime.datetime.now()
141 duration_seconds = (start_time - end_time).seconds
142 if pods_number == step:
146 test_result_body = test_step_result(
147 step, pods_number, duration_seconds, criteria)
148 k8s_utils.write_json(test_result_body, OUT_FILE)
150 LOG.info("Deployment scaling test has been successfuly executed.")
151 LOG.info("Testing results written in: {}".format(OUT_FILE))
155 if __name__ == '__main__':