def experiment(host, yaml_path, target): """ Runs the chosen YAML for 30 minutes, running regular load tests against it, capturing replica counts and latency over time """ print("Creating k8s objects") subprocess.run(["kubectl", "apply", "-f", yaml_path], check=True) # Wait to let pods start time.sleep(30) result = {"latency": [], "replicas": []} start_time = time.time() for i in range(int(RUN_TIME / PROBE_INTERVAL)): print("Running probe") # Build config in loop as otherwise auth will expire config.load_kube_config() client_v1 = client.AppsV1Api() num_clients = 5 hatch_rate = 5 if (i - INTERVAL_OFFSET_BEFORE_LOAD) % INTERVALS_BEFORE_LOAD == 0: print("Setting up increased load") num_clients = 100 hatch_rate = 100 locust_settings = invokust.create_settings( locustfile=LOCUST_FILE, host= f"http://{host}/api/v1/namespaces/default/services/{target}/proxy/", num_clients=num_clients, hatch_rate=hatch_rate, run_time=LOCUST_RUN_TIME) test = invokust.LocustLoadTest(locust_settings) print(f"Running load for {LOCUST_RUN_TIME}") test.run() print("Finish running load") result["latency"].append(test.stats()) # Log number of replicas deployment_resp = client_v1.list_namespaced_deployment( "default", pretty=True, label_selector=f"run={target}") replica_count = deployment_resp.items[0].status.replicas print("Replicas: ", replica_count) result["replicas"].append(replica_count) time.sleep(PROBE_INTERVAL - ((time.time() - start_time) % PROBE_INTERVAL)) print("Deleting K8s objects") subprocess.run(["kubectl", "delete", "-f", yaml_path], check=True) return result
def load(): killer = GracefulKiller() while not killer.kill_now: print("Running load") now = datetime.utcnow() print("Current time:", now.strftime("%H:%M")) num_clients = LOW_NUM_CLIENTS hatch_rate = LOW_HATCH_RATE if MEDIUM_LOAD[0] <= now.hour < MEDIUM_LOAD[1]: print( f"Hour between {MEDIUM_LOAD[0]} and {MEDIUM_LOAD[1]}, running medium load" ) num_clients = MEDIUM_NUM_CLIENTS hatch_rate = MEDIUM_HATCH_RATE elif HIGH_LOAD[0] <= now.hour < HIGH_LOAD[1]: print( f"Hour between {HIGH_LOAD[0]} and {HIGH_LOAD[1]}, running high load" ) num_clients = HIGH_NUM_CLIENTS hatch_rate = HIGH_HATCH_RATE else: print(f"Running low load") settings = invokust.create_settings(locustfile=LOCUST_FILE, host=HOST, num_clients=num_clients, hatch_rate=hatch_rate, run_time=RUN_TIME) load_test = invokust.LocustLoadTest(settings) load_test.run() results = load_test.stats() requests = results.get("requests") request = requests.get("GET_/") avg_response_time = request.get("avg_response_time") min_response_time = request.get("min_response_time") max_response_time = request.get("max_response_time") num_requests = results.get("num_requests") num_requests_fail = results.get("num_requests_fail") timestamp = now.timestamp() with open(LOAD_RESULTS_FILE, "a") as file: file.write( f"{timestamp},{num_requests},{num_requests_fail},{avg_response_time},{min_response_time},{max_response_time}\n" ) print("Shutting down...")
import invokust settings = invokust.create_settings(locustfile='websocket_locust_v2.py', host='https://www.websocket.org', num_clients=1, hatch_rate=1, run_time='3m') loadtest = invokust.LocustLoadTest(settings) loadtest.run() print(loadtest.stats())
def start(event, context): print('Processing SQS trigger for notify.') client = boto3.client('sqs') print('Get the current Queue URL.') currentQueueArn = str(event["Records"][0]["eventSourceARN"]) response = client.get_queue_url( QueueName=currentQueueArn.split(":")[5], QueueOwnerAWSAccountId=currentQueueArn.split(":")[4] ) queueUrl = response["QueueUrl"] print('Managed to fetch the current queue url -> {}'.format(queueUrl)) message = json.loads(event["Records"][0]["body"]) url = str(message["url"]) numClients = int(message["numClients"]) hatchRate = int(message["hatchRate"]) runTime = str(message["runTime"]) requestId = str(message["requestId"]) maxThreads = int(message["maxThreads"]) threadCount = str(message["threadCount"]) method = str(message["method"]) global path global body global headers global request_name path = str(message["path"]) body = str(message["body"]) headers = str(message["headers"]) request_name = "{}_{}".format(method, path) print('Removing message from queue.') try: client.delete_message( QueueUrl=queueUrl, ReceiptHandle=event['Records'][0]['receiptHandle'] ) except Exception as e: print("Message was already deleted or \"receiptHandle\" is invalid.") pass print('Starting shell subprocess for loadtest with threadCount {}.'.format(threadCount)) # Set up the load test settings if method == "POST": if body == "{}" and headers == "{}": settings = invokust.create_settings( classes=[TestLogicPost], host=url, num_clients=numClients, hatch_rate=hatchRate, run_time=runTime ) if body == "{}" and headers != "{}": settings = invokust.create_settings( classes=[TestLogicPostWithHeaders], host=url, num_clients=numClients, hatch_rate=hatchRate, run_time=runTime ) if body != "{}" and headers == "{}": settings = invokust.create_settings( classes=[TestLogicPostWithBody], host=url, num_clients=numClients, hatch_rate=hatchRate, run_time=runTime ) if body != "{}" and headers != "{}": settings = invokust.create_settings( classes=[TestLogicPostWithBodyAndHeaders], host=url, num_clients=numClients, hatch_rate=hatchRate, run_time=runTime ) if method == "GET": if body == "{}" and headers == "{}": settings = invokust.create_settings( classes=[TestLogicGet], host=url, num_clients=numClients, hatch_rate=hatchRate, run_time=runTime ) if body == "{}" and headers != "{}": settings = invokust.create_settings( classes=[TestLogicGetWithHeaders], host=url, num_clients=numClients, hatch_rate=hatchRate, run_time=runTime ) if body != "{}" and headers == "{}": settings = invokust.create_settings( classes=[TestLogicGetWithBody], host=url, num_clients=numClients, hatch_rate=hatchRate, run_time=runTime ) if body != "{}" and headers != "{}": settings = invokust.create_settings( classes=[TestLogicGetWithBodyAndHeaders], host=url, num_clients=numClients, hatch_rate=hatchRate, run_time=runTime ) # Start the load test try: loadtest = invokust.LocustLoadTest(settings) loadtest.run() except Exception as e: print('Encountered error when running loadtest with threadCount {}. Error = {}'.format( threadCount, str(e))) stats = loadtest.stats() print("Finished tests.") responseValue={ "input": { "url": url, "numClients": numClients, "hatchRate": hatchRate, "runTime": runTime, "maxThreads": maxThreads, "requestId": requestId, "threadCount": threadCount, "method": method, "path": path }, "stats": stats } queue = os.environ.get("PostResultSqsUrl") client.send_message_batch( QueueUrl=queue, Entries=[{ "Id": threadCount, "MessageBody": json.dumps(responseValue), "DelaySeconds": 0 }] ) return "Done"