Yang Xu | 5c53ab2 | 2018-04-15 18:07:13 +0000 | [diff] [blame] | 1 | import random |
| 2 | import string |
| 3 | import time |
| 4 | import datetime |
| 5 | import sys |
| 6 | import collections |
| 7 | import json |
| 8 | import tzlocal |
| 9 | import os |
| 10 | import fcntl |
| 11 | import logging |
| 12 | from locust import HttpLocust, TaskSet, task |
| 13 | from decimal import Decimal |
| 14 | |
| 15 | |
| 16 | class UserBehavior(TaskSet): |
| 17 | base = "/ecomp/mso/infra/e2eServiceInstances/v3" |
| 18 | headers = {"Accept":"application/json","Content-Type":"application/json","Authorization":"Basic SW5mcmFQb3J0YWxDbGllbnQ6cGFzc3dvcmQxJA=="} |
| 19 | service_creation_body = "{\"service\": {\"name\": \"E2E_volte_%s\", \"description\": \"E2E_volte_ONAP_deploy\", \"serviceDefId\": \"a16eb184-4a81-4c8c-89df-c287d390315a\", \"templateId\": \"012c3446-51db-4a2a-9e64-a936f10a5e3c\", \"parameters\": { \"globalSubscriberId\": \"Demonstration\", \"subscriberName\": \"Demonstration\", \"serviceType\": \"vIMS\", \"templateName\": \"VoLTE e2e Service:null\", \"resources\": [ { \"resourceName\": \"VL OVERLAYTUNNEL\", \"resourceDefId\": \"671d4757-b018-47ab-9df3-351c3bda0a98\", \"resourceId\": \"e859b0fd-d928-4cc8-969e-0fee7795d623\", \"nsParameters\": { \"locationConstraints\": [], \"additionalParamForNs\": { \"site2_vni\": \"5010\", \"site1_localNetworkAll\": \"false\", \"site1_vni\": \"5010\", \"site1_exportRT1\": \"11:1\", \"description\": \"overlay\", \"site2_localNetworkAll\": \"false\", \"site1_routerId\": \"9.9.9.9\", \"site1_fireWallEnable\": \"false\", \"site1_networkName\": \"network1\", \"site2_description\": \"overlay\", \"site1_importRT1\": \"11:1\", \"site1_description\": \"overlay\", \"site2_networkName\": \"network3\", \"name\": \"overlay\", \"site2_fireWallEnable\": \"false\", \"site2_id\": \"ZTE-DCI-Controller\", \"site2_routerId\": \"9.9.9.9\", \"site2_importRT1\": \"11:1\", \"site2_exportRT1\": \"11:1\", \"site2_fireWallId\": \"false\", \"site1_id\": \"DCI-Controller-1\", \"tunnelType\": \"L3-DCI\" } } },{\"resourceName\": \"VL UNDERLAYVPN\", \"resourceDefId\": \"4f5d692b-4022-43ab-b878-a93deb5b2061\", \"resourceId\": \"b977ec47-45b2-41f6-aa03-bf6554dc9620\", \"nsParameters\": { \"locationConstraints\": [], \"additionalParamForNs\": { \"topology\": \"full-mesh\", \"site2_name\": \"site2\", \"sna2_name\": \"site2_sna\", \"description\": \"underlay\", \"sna1_name\": \"site1_sna\", \"ac1_route\": \"3.3.3.12/30:dc84ce88-99f7\", \"ac2_peer_ip\": \"3.3.3.20/30\", \"technology\": \"mpls\", \"ac2_route\": \"3.3.3.20/30:98928302-3287\", \"ac2_id\": \"84d937a4-b227-375f-a744-2b778f36e04e\", \"ac1_protocol\": \"STATIC\", \"ac2_svlan\": \"4004\", \"serviceType\": \"l3vpn-ipwan\", \"ac2_ip\": \"3.3.3.21/30\", \"pe2_id\": \"4412d3f0-c296-314d-9284-b72fc5d485e8\", \"ac1_id\": \"b4f01ac0-c1e1-3e58-a8be-325e4372c960\", \"af_type\": \"ipv4\", \"ac1_svlan\": \"4002\", \"ac1_peer_ip\": \"3.3.3.12/30\", \"ac1_ip\": \"3.3.3.13/30\", \"version\": \"1.0\", \"name\": \"testunderlay\", \"id\": \"123124141\", \"pe1_id\": \"2ef788f0-407c-3070-b756-3a5cd71fde18\", \"ac2_protocol\": \"STATIC\", \"site1_name\": \"stie1\" } } } ] } } }" |
| 20 | # following class variables to make them unique across all users |
| 21 | transaction_file= open("transaction.log", "w+") |
| 22 | operation_file = open("operation.log", "w+") |
| 23 | |
| 24 | def on_start(self): |
| 25 | """ on_start is called when a Locust start before any task is scheduled """ |
| 26 | self.init() |
| 27 | |
| 28 | def init(self): |
| 29 | pass |
| 30 | |
| 31 | def myconverter(self, o): |
| 32 | if isinstance(o, datetime.datetime): |
| 33 | return o.__str__() |
| 34 | |
| 35 | @task(1) |
| 36 | def create_service(self): |
| 37 | # Post a E2E service instantiation request to SO |
| 38 | method = "POST" |
| 39 | url = self.base |
| 40 | service_instance_name = ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(10)) |
| 41 | data = self.service_creation_body % service_instance_name |
| 42 | |
| 43 | t1 = datetime.datetime.now(tzlocal.get_localzone()) |
| 44 | response = self.client.request(method, url, headers=self.headers, data=data) |
| 45 | t2 = datetime.datetime.now(tzlocal.get_localzone()) |
| 46 | delta = t2 - t1 |
| 47 | data = collections.OrderedDict() |
| 48 | data['datetime'] = datetime.datetime.now(tzlocal.get_localzone()).strftime("%Y-%m-%dT%H:%M:%S%Z") |
| 49 | data['method'] = method |
| 50 | data['url'] = url |
| 51 | data['status_code'] = response.status_code |
| 52 | data['transaction_time'] = (delta.seconds*10^6 + delta.microseconds)/1000 |
| 53 | fcntl.flock(self.transaction_file, fcntl.LOCK_EX) |
| 54 | self.transaction_file.write(json.dumps(data, default = self.myconverter) + "\n") |
| 55 | self.transaction_file.flush() |
| 56 | os.fsync(self.transaction_file) |
| 57 | fcntl.flock(self.transaction_file, fcntl.LOCK_UN) |
| 58 | serviceId = response.json()['service']['serviceId'] |
| 59 | operationId = response.json()['service']['operationId'] |
| 60 | |
| 61 | # Get the request status |
| 62 | method = "GET" |
| 63 | url = self.base + "/" + serviceId + "/operations/" + operationId |
| 64 | url1 = "/ecomp/mso/infra/e2eServiceInstances/v3/{serviceId}/operations/{operationId}" |
| 65 | count = 1 |
| 66 | while count < 50: |
| 67 | tt1 = datetime.datetime.now() |
| 68 | response = self.client.request(method, url, name=url1, headers=self.headers) |
| 69 | tt2 = datetime.datetime.now() |
| 70 | delta = tt2 - tt1 |
| 71 | result = response.json()['operationStatus']['result'] |
| 72 | progress = response.json()['operationStatus']['progress'] |
| 73 | data = collections.OrderedDict() |
| 74 | data['datetime'] = datetime.datetime.now(tzlocal.get_localzone()).strftime("%Y-%m-%dT%H:%M:%S%Z") |
| 75 | data['method'] = method |
| 76 | data['url'] = url1 |
| 77 | data['status_code'] = response.status_code |
| 78 | data['count'] = count |
| 79 | data['result'] = result |
| 80 | data['progress'] = progress |
| 81 | data['transaction_time'] = (delta.seconds*10^6 + delta.microseconds)/1000 |
| 82 | fcntl.flock(self.transaction_file, fcntl.LOCK_EX) |
| 83 | self.transaction_file.write(json.dumps(data, default = self.myconverter) + "\n") |
| 84 | self.transaction_file.flush() |
| 85 | os.fsync(self.transaction_file) |
| 86 | fcntl.flock(self.transaction_file, fcntl.LOCK_UN) |
| 87 | if result == "finished" or result == "error": |
| 88 | break |
| 89 | else: |
| 90 | time.sleep(1) |
| 91 | count = count + 1 |
| 92 | |
| 93 | if result == "finished": |
| 94 | result = "success" |
| 95 | else: |
| 96 | result = "failure" |
| 97 | t3 = datetime.datetime.now(tzlocal.get_localzone()) |
| 98 | delta = t3 - t1 |
| 99 | data = collections.OrderedDict() |
| 100 | data['datetime'] = t1.strftime("%Y-%m-%dT%H:%M:%S%Z") |
| 101 | data['operation'] = "volte_create" |
| 102 | data['result'] = result |
| 103 | data['duration'] = round(delta.seconds + Decimal(delta.microseconds/1000000.0), 3) |
| 104 | fcntl.flock(self.operation_file, fcntl.LOCK_EX) |
| 105 | self.operation_file.write(json.dumps(data, default = self.myconverter) + "\n") |
| 106 | self.operation_file.flush() |
| 107 | os.fsync(self.operation_file) |
| 108 | fcntl.flock(self.operation_file, fcntl.LOCK_UN) |
| 109 | |
| 110 | self.delete_service(serviceId) |
| 111 | |
| 112 | def delete_service(self, serviceId): |
| 113 | method = "DELETE" |
| 114 | url = self.base + "/" + serviceId |
| 115 | data = "{\"globalSubscriberId\":\"Demonstration\", \"serviceType\":\"vIMS\"}" |
| 116 | t1 = datetime.datetime.now(tzlocal.get_localzone()) |
| 117 | response = self.client.request(method, url, name=self.base, headers=self.headers, data=data) |
| 118 | t2 = datetime.datetime.now(tzlocal.get_localzone()) |
| 119 | delta = t2 - t1 |
| 120 | data = collections.OrderedDict() |
| 121 | data['datetime'] = datetime.datetime.now(tzlocal.get_localzone()).strftime("%Y-%m-%dT%H:%M:%S%Z") |
| 122 | data['method'] = method |
| 123 | data['url'] = self.base |
| 124 | data['status_code'] = response.status_code |
| 125 | data['transaction_time'] = (delta.seconds*10^6 + delta.microseconds)/1000 |
| 126 | fcntl.flock(self.transaction_file, fcntl.LOCK_EX) |
| 127 | self.transaction_file.write(json.dumps(data, default = self.myconverter) + "\n") |
| 128 | self.transaction_file.flush() |
| 129 | os.fsync(self.transaction_file) |
| 130 | fcntl.flock(self.transaction_file, fcntl.LOCK_UN) |
| 131 | operationId = response.json()['operationId'] |
| 132 | |
| 133 | # Get the request status |
| 134 | method = "GET" |
| 135 | url = self.base + "/" + serviceId + "/operations/" + operationId |
| 136 | url1 = "/ecomp/mso/infra/e2eServiceInstances/v3/{serviceId}/operations/{operationId}" |
| 137 | count = 1 |
| 138 | while count < 50: |
| 139 | tt1 = datetime.datetime.now(tzlocal.get_localzone()) |
| 140 | response = self.client.request(method, url, name=url1, headers=self.headers) |
| 141 | tt2 = datetime.datetime.now(tzlocal.get_localzone()) |
| 142 | delta = tt2 - tt1 |
| 143 | result = response.json()['operationStatus']['result'] |
| 144 | progress = response.json()['operationStatus']['progress'] |
| 145 | data = collections.OrderedDict() |
| 146 | data['datetime'] = datetime.datetime.now(tzlocal.get_localzone()).strftime("%Y-%m-%dT%H:%M:%S%Z") |
| 147 | data['method'] = method |
| 148 | data['url'] = url1 |
| 149 | data['status_code'] = response.status_code |
| 150 | data['count'] = count |
| 151 | data['result'] = result |
| 152 | data['progress'] = progress |
| 153 | data['transaction_time'] = (delta.seconds*10^6 + delta.microseconds)/1000 |
| 154 | fcntl.flock(self.transaction_file, fcntl.LOCK_EX) |
| 155 | self.transaction_file.write(json.dumps(data, default = self.myconverter) + "\n") |
| 156 | self.transaction_file.flush() |
| 157 | os.fsync(self.transaction_file) |
| 158 | fcntl.flock(self.transaction_file, fcntl.LOCK_UN) |
| 159 | if result == "finished" or result == "error": |
| 160 | break |
| 161 | else: |
| 162 | time.sleep(1) |
| 163 | count = count + 1 |
| 164 | |
| 165 | if result == "finished": |
| 166 | result = "success" |
| 167 | else: |
| 168 | result = "failure" |
| 169 | t3 = datetime.datetime.now(tzlocal.get_localzone()) |
| 170 | delta = t3 - t1 |
| 171 | data = collections.OrderedDict() |
| 172 | data['datetime'] = t1.strftime("%Y-%m-%dT%H:%M:%S%Z") |
| 173 | data['operation'] = "volte_delete" |
| 174 | data['result'] = result |
| 175 | data['duration'] = round(delta.seconds + Decimal(delta.microseconds/1000000.0), 3) |
| 176 | fcntl.flock(self.operation_file, fcntl.LOCK_EX) |
| 177 | self.operation_file.write(json.dumps(data, default = self.myconverter) + "\n") |
| 178 | self.operation_file.flush() |
| 179 | os.fsync(self.operation_file) |
| 180 | fcntl.flock(self.operation_file, fcntl.LOCK_UN) |
| 181 | |
| 182 | |
| 183 | class WebsiteUser(HttpLocust): |
| 184 | task_set = UserBehavior |
| 185 | min_wait = 1000 |
| 186 | max_wait = 3000 |