diff --git a/dockerfiles/aws/nodejs/Dockerfile.buid2023 b/dockerfiles/aws/nodejs/Dockerfile.buid2023 new file mode 100644 index 00000000..f9654dc5 --- /dev/null +++ b/dockerfiles/aws/nodejs/Dockerfile.buid2023 @@ -0,0 +1,22 @@ +ARG BASE_IMAGE +FROM ${BASE_IMAGE} + +# shadow-utils +RUN dnf install -y shadow-utils && dnf clean all + +ENV GOSU_VERSION 1.14 +# https://github.com/tianon/gosu/releases/tag/1.14 +# key https://keys.openpgp.org/search?q=tianon%40debian.org +RUN curl -o /usr/local/bin/gosu -SL "https://github.com/tianon/gosu/releases/download/${GOSU_VERSION}/gosu-amd64" \ + && chmod +x /usr/local/bin/gosu + +RUN mkdir -p /sebs/ +COPY dockerfiles/nodejs_installer.sh /sebs/installer.sh +COPY dockerfiles/entrypoint.sh /sebs/entrypoint.sh +RUN chmod +x /sebs/entrypoint.sh + +# useradd and groupmod is installed in /usr/sbin which is not in PATH +ENV PATH=/usr/sbin:$PATH +ENV SCRIPT_FILE=/mnt/function/package.sh +CMD /bin/bash /sebs/installer.sh +ENTRYPOINT ["/sebs/entrypoint.sh"] diff --git a/dockerfiles/aws/python/Dockerfile.build2023 b/dockerfiles/aws/python/Dockerfile.build2023 new file mode 100644 index 00000000..ff1524aa --- /dev/null +++ b/dockerfiles/aws/python/Dockerfile.build2023 @@ -0,0 +1,24 @@ +ARG BASE_IMAGE +FROM ${BASE_IMAGE} +ARG VERSION +ENV PYTHON_VERSION=${VERSION} + +# shadow-utils, zip +RUN dnf install -y shadow-utils zip && dnf clean all + +ENV GOSU_VERSION 1.14 +# https://github.com/tianon/gosu/releases/tag/1.14 +# key https://keys.openpgp.org/search?q=tianon%40debian.org +RUN curl -o /usr/local/bin/gosu -SL "https://github.com/tianon/gosu/releases/download/${GOSU_VERSION}/gosu-amd64" \ + && chmod +x /usr/local/bin/gosu + +RUN mkdir -p /sebs/ +COPY dockerfiles/python_installer.sh /sebs/installer.sh +COPY dockerfiles/entrypoint.sh /sebs/entrypoint.sh +RUN chmod +x /sebs/entrypoint.sh + +# useradd and groupmod is installed in /usr/sbin which is not in PATH +ENV PATH=/usr/sbin:$PATH +ENV SCRIPT_FILE=/mnt/function/package.sh +CMD /bin/bash /sebs/installer.sh +ENTRYPOINT ["/sebs/entrypoint.sh"] diff --git a/load_generator/artillery_generator.py b/load_generator/artillery_generator.py new file mode 100644 index 00000000..44e6cbac --- /dev/null +++ b/load_generator/artillery_generator.py @@ -0,0 +1,77 @@ +import yaml +import sys +import argparse +import math + +def create_yaml_config(max_users, frequency, cycles): + """ + Create a YAML configuration for load testing with a sinusoidal pattern. + + :param max_users: Maximum number of concurrent users + :param frequency: Duration of each cycle in seconds + :param cycles: Number of cycles to run + :return: Dictionary containing the YAML configuration + """ + # Define the initial configuration dictionary + config = { + 'config': { + 'target': 'http://172.17.0.2:9000', # Target URL for the load test + 'phases': [], # List to store the different phases of the load test + 'ensure': { + 'p95': 2000 # Ensure 95% of responses are under 2000ms + } + }, + 'scenarios': [ + { + 'flow': [ + { + 'post': { + 'url': '/post', + 'json': '{{ payload }}' # JSON payload for the POST request + } + } + ] + } + ], + 'payload': '{{ $processEnvironment.PAYLOAD_FILE }}' # Reference to the environment variable for payload file + } + + # Generate phases for each cycle + for i in range(cycles): + for j in range(10): # 10 phases per cycle for a smoother sinusoidal pattern + phase_duration = max(1, int(frequency / 10)) # Ensure phase duration is at least 1 second + t = j / 10 # Time variable from 0 to 1 + users = int(max_users * (math.sin(2 * math.pi * t) + 1) / 2) # Calculate users using sine function + + # Append the phase configuration to the phases list + config['config']['phases'].append({ + 'duration': phase_duration, + 'arrivalRate': users, + 'name': f'Cycle {i+1}, Phase {j+1}' + }) + + return config + +def main(): + """ + Main function to parse command-line arguments and generate the YAML configuration file. + """ + # Set up command-line argument parser + parser = argparse.ArgumentParser(description='Generate YAML config for load testing') + parser.add_argument('max_users', type=int, help='Maximum number of users (1-1000)') + parser.add_argument('frequency', type=int, help='Duration of each cycle in seconds (1-50)') + parser.add_argument('cycles', type=int, help='Number of cycles (1-50)') + + args = parser.parse_args() + + # Generate YAML configuration using the input parameters + config = create_yaml_config(args.max_users, args.frequency, args.cycles) + + # Write YAML configuration to file + with open('load_test_config.yaml', 'w') as f: + yaml.dump(config, f, default_flow_style=False) + + print("YAML configuration file 'load_test_config.yaml' has been created.") + +if __name__ == '__main__': + main() diff --git a/load_generator/payloads/210_payload.json b/load_generator/payloads/210_payload.json new file mode 100644 index 00000000..0f75c77e --- /dev/null +++ b/load_generator/payloads/210_payload.json @@ -0,0 +1,50 @@ +{ + "functions": [ + { + "benchmark": "210.thumbnailer", + "config": { + "architecture": "x86", + "memory": 256, + "runtime": { + "language": "python", + "version": "3.7" + }, + "timeout": 60 + }, + "hash": "442f3e4db7130c83a19c23ecd82efb70", + "instance_id": "67f07668974637517d711c11b9d1c761f7dd571af6ad2173019aec143dcf7a2a", + "name": "210.thumbnailer-python-3.7", + "port": 9000, + "triggers": [], + "url": "172.17.0.3:9000" + } + ], + "inputs": [ + { + "bucket": { + "bucket": "sebs-benchmarks-local-0cf48662", + "input": "210.thumbnailer-0-input", + "output": "210.thumbnailer-0-output" + }, + "object": { + "height": 200, + "key": "6_astronomy-desktop-wallpaper-evening-1624438.jpg", + "width": 200 + } + } + ], + "storage": { + "access_key": "GNAZaCZQiH0sd-cZfpXN-2DextknZwjN5JezJ2wiciw", + "address": "172.17.0.2:9000", + "input_buckets": [ + "210.thumbnailer-0-input" + ], + "instance_id": "69161516e1cd11774ba54925d1828a14b6e43ca389468897bc7fa3bedb339f54", + "mapped_port": 9011, + "output_buckets": [ + "210.thumbnailer-0-output" + ], + "secret_key": "ae8704512eda16b6b5aa0cc267192b0fbdc931eb78acd8dba417c27c2badb735", + "type": "minio" + } +} diff --git a/load_generator/readme.md b/load_generator/readme.md new file mode 100644 index 00000000..d143fc48 --- /dev/null +++ b/load_generator/readme.md @@ -0,0 +1,27 @@ +# SeBS Load Generator + +## Overview + +This tool allows the user to specify parameters for entry into a docker container. + +## New Prerequisites +- Artillery +- Pyyaml + +## Setup + +### 1. Install Dependencies + +`pip install artillery pyyaml` + +### 2. Build Config File + +`python artillery_generator ` + +### 3. Run the File + +`export PAYLOAD_FILE=/payloads/_payload.json` + +`artillery run load_test_config.yml` + +### 4. Enjoy!