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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
|
from kubernetes import client, config
from utils.k8s_setup import k8s_utils
import os
import datetime
import uuid
import utils.logger as log
import yaml
import argparse
LOG = log.Logger(__name__).getLogger()
parser = argparse.ArgumentParser(description='kubestone (k8s stress) tests')
parser.add_argument("-c", "--TEST_CASE",
help="The path of test case in form of yaml")
args = parser.parse_args()
TEST_CASE = args.TEST_CASE
TEST_CASE_NAME, TEST_CASE_FORMAT = os.path.splitext(
os.path.basename(TEST_CASE))
OUT_FILE = ("/tmp/bottlenecks_kubestone_" +
TEST_CASE_NAME + "_" + str(uuid.uuid4()) + ".out")
def test_step_result(num, success_num, during_seconds, result):
testdata = {}
test_result = {}
test_result["number_of_deployments"] = float(num)
test_result["success_deployments"] = success_num
test_result["success_rate"] = success_num / num
test_result["duration_time"] = during_seconds
test_result["result"] = result
testdata["data_body"] = test_result
testdata["testcase"] = TEST_CASE_NAME
return testdata
def main():
INSTALLER_TYPE = os.getenv("INSTALLER_TYPE")
K8S_CONFIG_PATH = os.getenv("K8S_CONFIG_PATH")
K8S_APPS_API_VERSION = os.getenv("K8S_APPS_API_VERSION")
K8S_CORE_API_VERSION = os.getenv("K8S_CORE_API_VERSION")
# Get k8s config. If provided in the path indicated by
# K8S_CONFIG_PATH, only return the path.
if K8S_CONFIG_PATH:
k8s_utils.get_config_path(
K8S_CONFIG_PATH=K8S_CONFIG_PATH)
else:
if INSTALLER_TYPE:
K8S_CONFIG_PATH = k8s_utils.get_config_path(
INSTALLER_TYPE=INSTALLER_TYPE)
else:
k8s_utils.get_config_path()
config.load_kube_config(K8S_CONFIG_PATH)
# Initiate api clients
if K8S_APPS_API_VERSION:
apps_api = k8s_utils.get_apps_api(K8S_APPS_API_VERSION)
else:
apps_api = k8s_utils.get_apps_api()
if K8S_CORE_API_VERSION:
core_api = k8s_utils.get_core_api(K8S_CORE_API_VERSION)
else:
core_api = k8s_utils.get_core_api()
# Read test case in the form of yaml
with open(TEST_CASE) as test_case_file:
test_case_yaml = yaml.load(test_case_file)
if test_case_yaml['template']:
if test_case_yaml['template'].lower() == 'none':
deployment_yaml = test_case_yaml
else:
with open(test_case_yaml['template']) as deployment_file:
deployment_yaml = yaml.load(deployment_file)
else:
deployment_yaml = test_case_yaml
name = deployment_yaml['metadata']['name']
namespace = deployment_yaml['namespace']
body = client.V1Deployment()
body.api_version = deployment_yaml['apiVersion']
body.kind = deployment_yaml['kind']
body.metadata = deployment_yaml['metadata']
body.spec = deployment_yaml['spec']
pretty = True
# Create namespace
namespace_existed = k8s_utils.get_namespace_status(namespace)
if namespace_existed[0] == 0 and \
'exception' not in namespace_existed[1].lower():
namespace_read = core_api.read_namespace(namespace, pretty=pretty)
LOG.info('Namespace {} already exist: \n{}'.format(
namespace, namespace_read))
else:
namespace_body = client.V1Namespace()
namespace_body.metadata = {'name': namespace}
namespace_created = core_api.create_namespace(
namespace_body, pretty=pretty)
LOG.info('Namespace has been created:\n{}'.format(
namespace_created))
# Create deployment
deployment_existed = k8s_utils.get_deployment_status(name, namespace)
if deployment_existed[0] == 0 and \
'exception' not in deployment_existed[1].lower():
deployment_read = apps_api.read_namespaced_deployment(
name, namespace, pretty=pretty)
LOG.info('Deployment {}@{} already exist.'.format(name, namespace))
LOG.info('Discription of this deployment is:\n{}'.format(
deployment_read))
else:
deployment_created = apps_api.create_namespaced_deployment(
namespace, body, pretty=pretty)
LOG.info('Deployment has been created:\n{}'.format(
deployment_created))
# Scale the deployment
scaling_steps = deployment_yaml['scaling_steps'].split(',')
for step in scaling_steps:
start_time = datetime.datetime.now()
step = int(step)
body.spec['replicas'] = step
api_response = apps_api.patch_namespaced_deployment_scale(
name, namespace, body, pretty=pretty)
LOG.info("Deployment replicas is to be scaled to: %s" % step)
pods_number = k8s_utils.get_available_pods(name, namespace)
while pods_number != step:
pods_number = k8s_utils.get_available_pods(name, namespace)
LOG.info("Number of available pods are {} out of {}".format(
pods_number, step))
api_response = apps_api.read_namespaced_deployment_scale(
name, namespace, pretty=pretty)
LOG.info(
"Deployment {}-scaling finished:\n{}".format(
step, api_response))
end_time = datetime.datetime.now()
duration_seconds = (start_time - end_time).seconds
if pods_number == step:
criteria = 'PASS'
else:
criteria = 'FAIL'
test_result_body = test_step_result(
step, pods_number, duration_seconds, criteria)
k8s_utils.write_json(test_result_body, OUT_FILE)
if api_response:
LOG.info("Deployment scaling test has been successfuly executed.")
LOG.info("Testing results written in: {}".format(OUT_FILE))
return
if __name__ == '__main__':
main()
|