Add requests templates for performance testing
Add script wich can be used in CLI to generate 'bullets' for yandex-tank, which will be used for perfomance testing. Change-Id: I31dea6a8aa490b5f23c5cba6e1ac1c1e5ecd95ad Implements: blueprint anonymous-statistics-performance-testing
This commit is contained in:
parent
93d5a2986a
commit
874bc3e934
|
@ -0,0 +1,158 @@
|
|||
# Copyright 2014 Mirantis, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from __future__ import print_function
|
||||
import getopt
|
||||
import os
|
||||
import sys
|
||||
|
||||
from requests import ActionLogRequestTemplate
|
||||
from requests import InstallationRequestTemplate
|
||||
|
||||
|
||||
class Settings(object):
|
||||
def __init__(self):
|
||||
self.config_file = "ammo.txt"
|
||||
self.bullets_count = 5
|
||||
self.bullets_types = ['installation', 'action-log']
|
||||
self.host_address = '127.0.0.1'
|
||||
self.max_clusters_count = 10
|
||||
self.max_cluster_size = 100
|
||||
self.max_logs_count = 30
|
||||
|
||||
|
||||
def parse_args(argv, settings):
|
||||
try:
|
||||
opts, args = getopt.getopt(argv, "ha:c:t:f:", ["help",
|
||||
"host-address=",
|
||||
"bullets-count=",
|
||||
"bullets-type=",
|
||||
"output-file=",
|
||||
"max_clusters_count=",
|
||||
"max_cluster_size=",
|
||||
"max_logs_count="])
|
||||
except getopt.GetoptError as err:
|
||||
print(str(err))
|
||||
return usage()
|
||||
|
||||
for opt, arg in opts:
|
||||
if opt in ("-h", "--help"):
|
||||
usage()
|
||||
elif opt in ("-a", "host-address="):
|
||||
settings.host_address = arg
|
||||
elif opt in ("-c", "--bullets-count"):
|
||||
settings.bullets_count = int(arg)
|
||||
elif opt in ("-t", "--bullets-type"):
|
||||
types = []
|
||||
for type in arg.split(','):
|
||||
if type in settings.bullets_types:
|
||||
types.append(type)
|
||||
else:
|
||||
usage("ERROR! Unsupported bullet type '{0}'".format(type))
|
||||
settings.bullets_types = types
|
||||
elif opt in ("-f", "--output-file"):
|
||||
settings.config_file = arg
|
||||
elif opt == "--max_clusters_count":
|
||||
settings.max_clusters_count = int(arg)
|
||||
elif opt == "--max_cluster_size":
|
||||
settings.max_cluster_size = int(arg)
|
||||
elif opt == "--max_logs_count":
|
||||
settings.max_logs_count = int(arg)
|
||||
|
||||
return settings
|
||||
|
||||
|
||||
def usage(message=None):
|
||||
usage_text = """
|
||||
Usage: {name} [OPTIONS]
|
||||
Example: {name} --bullets-count 10 --bullets-type "installation"
|
||||
|
||||
Options:
|
||||
-a, --host-address set IP address or hostname/domain of
|
||||
Collector; default - {host}
|
||||
|
||||
-c, --bullets-count set number of each bullets type to
|
||||
generate; default value is {count}
|
||||
|
||||
-t, --bullets-type set bullets types; supported types are:
|
||||
{types}; by default all types are used
|
||||
|
||||
-f, --output-file set output file to save bullets;
|
||||
default file name is "{file}"
|
||||
|
||||
-h, --help print this help message
|
||||
|
||||
Additional options:
|
||||
--max_clusters_count set maximum clusters number in each
|
||||
installation request; default - 10
|
||||
--max_cluster_size set maximum nodes number assigned to each
|
||||
environment; default - 100
|
||||
--max_logs_count set maximum count of action logs which will
|
||||
in one request; default - 30
|
||||
""".format(name=sys.argv[0],
|
||||
host=Settings().host_address,
|
||||
count=Settings().bullets_count,
|
||||
types=', '.join(Settings().bullets_types),
|
||||
file=Settings().config_file)
|
||||
if message:
|
||||
print('{0}'.format(message))
|
||||
print(usage_text)
|
||||
sys.exit(2)
|
||||
|
||||
|
||||
def save_bullets(bullets, file):
|
||||
data_to_save = ''
|
||||
|
||||
for bullet in bullets:
|
||||
data_to_save += '\r\n'.join(bullet['headers']) + '\r\n'
|
||||
data_to_save += '{size} {url}\r\n'.format(size=len(bullet['body']),
|
||||
url=bullet['url'])
|
||||
data_to_save += '{body}\r\n\n'.format(body=bullet['body'])
|
||||
|
||||
with open(file, 'w+') as _file:
|
||||
_file.write(data_to_save)
|
||||
|
||||
file_size = os.stat(file).st_size / 1024
|
||||
print("\n\tBullets were saved to '{0}' ({1}K) file\n".format(file,
|
||||
file_size))
|
||||
|
||||
|
||||
def main(args):
|
||||
settings = parse_args(args, Settings())
|
||||
req_template = None
|
||||
bullets = []
|
||||
for type in settings.bullets_types:
|
||||
if type == "installation":
|
||||
req_template = InstallationRequestTemplate(
|
||||
max_clusters_count=settings.max_clusters_count,
|
||||
max_cluster_size=settings.max_cluster_size)
|
||||
elif type == "action-log":
|
||||
req_template = ActionLogRequestTemplate(
|
||||
max_logs_count=settings.max_logs_count)
|
||||
for _ in xrange(settings.bullets_count):
|
||||
bullet_url = req_template.url
|
||||
bullet_headers = ['[Host: {0}]'.format(settings.host_address)]
|
||||
bullet_headers.extend(req_template.headers)
|
||||
bullet_body = req_template.get_request_body()
|
||||
bullet = {
|
||||
'url': bullet_url,
|
||||
'headers': bullet_headers,
|
||||
'body': bullet_body
|
||||
}
|
||||
bullets.append(bullet)
|
||||
save_bullets(bullets, settings.config_file)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main(sys.argv[1:])
|
|
@ -0,0 +1,214 @@
|
|||
# Copyright 2014 Mirantis, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import datetime
|
||||
import json
|
||||
import random
|
||||
|
||||
|
||||
class BaseRequestTemplate(object):
|
||||
|
||||
def __init__(self):
|
||||
|
||||
self.headers = [
|
||||
'[Content-Type: application/json]',
|
||||
'[Connection: close]',
|
||||
'[User-Agent: Tank]'
|
||||
]
|
||||
|
||||
self.fuel_releases = {
|
||||
'6.0': [
|
||||
{
|
||||
'version': '2014.2-6.0',
|
||||
'os': 'Ubuntu',
|
||||
'name': 'Juno on Ubuntu 12.04.04'
|
||||
},
|
||||
{
|
||||
'version': '2014.2-6.0',
|
||||
'os': 'CentOS',
|
||||
'name': 'Juno on CentOS 6.5'
|
||||
}
|
||||
],
|
||||
'6.0.1': [
|
||||
{
|
||||
'version': '2014.2-6.0.1',
|
||||
'os': 'Ubuntu',
|
||||
'name': 'Juno on Ubuntu 12.04.05'
|
||||
},
|
||||
{
|
||||
'version': '2014.2-6.0.1',
|
||||
'os': 'CentOS',
|
||||
'name': 'Juno on CentOS 6.6'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
self.cluster_statuses = ['new',
|
||||
'operational',
|
||||
'error']
|
||||
|
||||
self.nodes_roles = ['controller',
|
||||
'compute',
|
||||
'mongodb',
|
||||
'ceph-osd',
|
||||
'cinder',
|
||||
'zabbix']
|
||||
|
||||
self.nodes_statuses = ['ready',
|
||||
'discovered',
|
||||
'provisioned',
|
||||
'provisioning',
|
||||
'deploying',
|
||||
'deployed',
|
||||
'error']
|
||||
|
||||
self.api_versions = ['v1', 'v2']
|
||||
self.feature_groups = ['mirantis', 'experimental']
|
||||
|
||||
@property
|
||||
def random_sha(self):
|
||||
return ''.join(random.choice('abcdef0123456789') for _ in xrange(40))
|
||||
|
||||
@property
|
||||
def fuel_release(self):
|
||||
return {
|
||||
"ostf_sha": self.random_sha,
|
||||
"nailgun_sha": self.random_sha,
|
||||
"astute_sha": self.random_sha,
|
||||
"fuellib_sha": self.random_sha,
|
||||
"api": random.choice(self.api_versions),
|
||||
"release": random.choice(self.fuel_releases.keys()),
|
||||
"feature_groups": random.sample(
|
||||
self.feature_groups,
|
||||
random.randint(1, len(self.feature_groups)))
|
||||
}
|
||||
|
||||
|
||||
class InstallationRequestTemplate(BaseRequestTemplate):
|
||||
|
||||
def __init__(self, max_clusters_count=10, max_cluster_size=100):
|
||||
BaseRequestTemplate.__init__(self)
|
||||
self.max_clusters_count = max_clusters_count
|
||||
self.max_cluster_size = max_cluster_size
|
||||
self.url = "/api/v1/installation_structure/"
|
||||
|
||||
@property
|
||||
def clusters_number(self):
|
||||
return random.randint(1, self.max_clusters_count)
|
||||
|
||||
@property
|
||||
def nodes_number(self):
|
||||
return random.randint(1, self.max_cluster_size)
|
||||
|
||||
def get_request_body(self):
|
||||
release = self.fuel_release
|
||||
clusters_number = self.clusters_number
|
||||
allocated_nodes = 0
|
||||
unallocated_nodes = self.nodes_number
|
||||
|
||||
clusters = []
|
||||
for cluster_id in xrange(1, clusters_number):
|
||||
nodes = []
|
||||
nodes_number = self.nodes_number
|
||||
allocated_nodes += nodes_number
|
||||
for node_id in xrange(1, nodes_number):
|
||||
node = {
|
||||
'status': random.choice(self.nodes_statuses),
|
||||
'id': node_id,
|
||||
'roles': random.sample(
|
||||
self.nodes_roles,
|
||||
random.randint(1, len(self.nodes_roles)))
|
||||
}
|
||||
nodes.append(node)
|
||||
|
||||
controllers = [n for n in nodes if 'controller' in n['roles']]
|
||||
|
||||
cluster = {
|
||||
'release': random.choice(
|
||||
self.fuel_releases.get(release["release"])),
|
||||
'nodes': nodes,
|
||||
'id': cluster_id,
|
||||
'mode': 'ha_full' if len(controllers) > 1 else 'multinode',
|
||||
'nodes_num': len(nodes),
|
||||
'status': random.choice(self.cluster_statuses),
|
||||
'attributes': {},
|
||||
}
|
||||
clusters.append(cluster)
|
||||
|
||||
data = {
|
||||
"installation_structure": {
|
||||
"master_node_uid": self.random_sha,
|
||||
"clusters_num": clusters_number,
|
||||
"allocated_nodes_num": allocated_nodes,
|
||||
"unallocated_nodes_num": unallocated_nodes,
|
||||
"fuel_release": release,
|
||||
"clusters": clusters
|
||||
}
|
||||
}
|
||||
|
||||
return json.dumps(data)
|
||||
|
||||
|
||||
class ActionLogRequestTemplate(BaseRequestTemplate):
|
||||
|
||||
def __init__(self, max_logs_count=30):
|
||||
BaseRequestTemplate.__init__(self)
|
||||
self.max_logs_count = max_logs_count
|
||||
self.url = "/api/v1/action_logs/"
|
||||
self.actions = {
|
||||
'action_group-1': {
|
||||
"type": "nailgun_task",
|
||||
"name": "action_name-1"
|
||||
},
|
||||
'action_group-2': {
|
||||
"type": "nailgun_task",
|
||||
"name": "action_name-2"
|
||||
},
|
||||
'action_group-3': {
|
||||
"type": "http_request",
|
||||
"name": "action_name-3"
|
||||
},
|
||||
'action_group-4': {
|
||||
"type": "http_request",
|
||||
"name": "action_name-4"
|
||||
}
|
||||
}
|
||||
|
||||
def get_request_body(self):
|
||||
actor_id = random.randint(1, 999)
|
||||
master_node_uid = self.random_sha
|
||||
data = {'action_logs': []}
|
||||
|
||||
for id in xrange(0, self.max_logs_count):
|
||||
action_group = random.choice(self.actions.keys())
|
||||
action_log = {
|
||||
'master_node_uid': master_node_uid,
|
||||
'external_id': random.randint(1, 999999),
|
||||
'body': {
|
||||
"id": id,
|
||||
"actor_id": str(actor_id),
|
||||
"action_group": action_group,
|
||||
"action_name": self.actions[action_group]['name'],
|
||||
"action_type": self.actions[action_group]['type'],
|
||||
"start_timestamp": str(datetime.datetime.now()),
|
||||
"end_timestamp": str(datetime.datetime.now()),
|
||||
"additional_info": {},
|
||||
"is_sent": False,
|
||||
"cluster_id": random.randint(1, 999),
|
||||
"task_uuid": self.random_sha
|
||||
}
|
||||
}
|
||||
data['action_logs'].append(action_log)
|
||||
|
||||
return json.dumps(data)
|
Loading…
Reference in New Issue