Lazy creation of VM pairs for soak throuputs tests
[bottlenecks.git] / testsuites / posca / testcase_script / posca_factor_soak_throughputs.py
1 #!/usr/bin/env python
2 ##############################################################################
3 # Copyright (c) 2017 Huawei Technologies Co.,Ltd and others.
4 #
5 # All rights reserved. This program and the accompanying materials
6 # are made available under the terms of the Apache License, Version 2.0
7 # which accompanies this distribution, and is available at
8 # http://www.apache.org/licenses/LICENSE-2.0
9 ##############################################################################
10 '''This file is to do data-plane baseline test for
11 VM pair life-cycle events using netperf.
12 Testing steps are summarized below:
13 1. run_test load testcase configuration
14 2. Bottlenecks eliminates the environments limits/constraints
15 3. Bottlenecks tells Yardstick to prepare environment
16 4. Bottlenecks tells Yardstick to run test
17    3.1 to create stack
18    3.2 to install netperf
19    3.3 to send/forward packets for t2 seconds
20    3.4 record results and detroy stack
21    3.4 after every t1 seconds goto 3.1 and repeat the workflow
22 5. Bottlenecks collects testing results from Yardstick
23 6. Bottlenecks tells Yardstick to stop when time ends
24    or system fails the test
25 7. Bottlenecks sends testing data to bottlenecks-elk'''
26
27 import utils.logger as log
28 import uuid
29 import json
30 import os
31 import time
32 import threading
33 import datetime
34 import Queue
35 from utils.parser import Parser as conf_parser
36 import utils.env_prepare.quota_prepare as quota_prepare
37 import utils.env_prepare.stack_prepare as stack_prepare
38 import utils.infra_setup.runner.yardstick as runner_yardstick
39 import utils.infra_setup.runner.docker_env as docker_env
40 import math
41
42 # --------------------------------------------------
43 # logging configuration
44 # --------------------------------------------------
45 LOG = log.Logger(__name__).getLogger()
46
47 test_dict = {
48     "action": "runTestCase",
49     "args": {
50         "opts": {
51             "task-args": {}
52         },
53         "testcase": "netperf_bottlenecks"
54     }
55 }
56 testfile = os.path.basename(__file__)
57 testcase, file_format = os.path.splitext(testfile)
58 cidr = "/home/opnfv/repos/yardstick/samples/netperf_soak.yaml"
59 runner_DEBUG = True
60
61 q = Queue.Queue()
62
63
64 def env_pre(test_config):
65     test_yardstick = False
66     if "yardstick" in test_config["contexts"].keys():
67         test_yardstick = True
68     stack_prepare._prepare_env_daemon(test_yardstick)
69     quota_prepare.quota_env_prepare()
70     LOG.info("yardstick environment prepare!")
71     if(test_config["contexts"]['yardstick_envpre']):
72         stdout = runner_yardstick.yardstick_image_prepare()
73         LOG.debug(stdout)
74
75
76 def do_test(con_dic):
77     out_file = ("/tmp/yardstick_" + str(uuid.uuid4()) + ".out")
78     parameter_info = dict(test_time=con_dic["scenarios"]["vim_pair_ttl"])
79     yardstick_container = docker_env.yardstick_info['container']
80     cmd = runner_yardstick.yardstick_command_parser(debug=runner_DEBUG,
81                                                     cidr=cidr,
82                                                     outfile=out_file,
83                                                     parameter=parameter_info)
84     stdout = docker_env.docker_exec_cmd(yardstick_container, cmd)
85     LOG.info(stdout)
86     out_value = 0
87     loop_value = 0
88     while loop_value < 60:
89         time.sleep(2)
90         loop_value = loop_value + 1
91         with open(out_file) as f:
92             data = json.load(f)
93             if data["result"]["criteria"] == "PASS":
94                 LOG.info("Success run yardstick netperf_soak test!")
95                 out_value = 1
96                 break
97             elif data["result"]["criteria"] == "FAIL":
98                 LOG.error("Failed run yardstick netperf_soak test!")
99                 out_value = 0
100                 break
101     q.put((out_value, data["result"]["testcases"]))
102     return out_value
103
104
105 def config_to_result(
106         test_duration, added_duration, vim_pair_ttl,
107         vim_pair_lazy_cre_delay,
108         vim_pair_num, vim_pair_success_num, result):
109     testdata = {}
110     test_result = {}
111     test_result["test_duration"] = test_duration
112     test_result["sum_duration"] = added_duration
113     test_result["vim_pair_ttl"] = vim_pair_ttl
114     test_result["vim_pair_cre_interval"] = vim_pair_lazy_cre_delay
115     test_result["vim_pair_num"] = vim_pair_num
116     test_result["vim_pair_success_num"] = vim_pair_success_num
117     test_result["result"] = result
118     testdata["data_body"] = test_result
119     testdata["testcase"] = testcase
120     return testdata
121
122
123 def func_run(con_dic):
124     test_date = do_test(con_dic)
125     return test_date
126
127
128 def run(test_config):
129     con_dic = test_config["load_manager"]
130
131     env_pre(test_config)
132     LOG.info("yardstick environment prepare done!")
133
134     test_duration = float(
135         con_dic["scenarios"]["test_duration_hours"]) * 3600
136     vim_pair_ttl = float(
137         con_dic["scenarios"]["vim_pair_ttl"])
138     vim_pair_lazy_cre_delay = float(
139         con_dic["scenarios"]["vim_pair_lazy_cre_delay"])
140     vim_pair_num = int(math.ceil(
141         (test_duration - vim_pair_ttl) / vim_pair_lazy_cre_delay
142     ) + 1)
143
144     threadings = []
145     result = []
146     vim_pair_success_num = 0
147
148     start_time = datetime.datetime.now()
149
150     LOG.info("Data-path test duration are %i seconds", test_duration)
151     LOG.info("TTL of each VM pair are %i seconds", vim_pair_ttl)
152     LOG.info("Creation delay between VM pairs are %i seconds",
153              vim_pair_lazy_cre_delay)
154     LOG.info("Number of VM pairs to be created are %i", vim_pair_num)
155
156     for vim_pair_index in xrange(0, vim_pair_num):
157         index_thread = threading.Thread(target=func_run,
158                                         args=(con_dic,))
159         threadings.append(index_thread)
160         index_thread.start()
161         vim_pair_error = False
162         for wait_time in xrange(0, int(vim_pair_lazy_cre_delay)):
163             time.sleep(1)
164             while not q.empty():
165                 result.append(q.get())
166             for one_result in result:
167                 if '0' == one_result[0]:
168                     vim_pair_error = True
169                 break
170         if vim_pair_error:
171             break
172     for one_thread in threadings:
173         one_thread.join()
174     while not q.empty():
175             result.append(q.get())
176     for item in result:
177         vim_pair_success_num += int(item[0])
178
179     end_time = datetime.datetime.now()
180     added_duration = (end_time - start_time).seconds
181     LOG.info("Number of success VM pairs/threads are %s out %s ",
182              vim_pair_success_num, vim_pair_num)
183
184     return_result = config_to_result(
185         test_duration, added_duration, vim_pair_ttl,
186         vim_pair_lazy_cre_delay,
187         vim_pair_num, vim_pair_success_num, result
188     )
189
190     conf_parser.result_to_file(return_result, test_config["out_file"])
191
192     return vim_pair_error