add k6 benchmark script
This commit is contained in:
parent
deb8c49354
commit
0e871aeffa
4 changed files with 12239 additions and 0 deletions
41
bench-fuzzy.js
Normal file
41
bench-fuzzy.js
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
import http from "k6/http";
|
||||
import { check } from "k6";
|
||||
import { SharedArray } from "k6/data";
|
||||
|
||||
export const options = {
|
||||
discardResponseBodies: true,
|
||||
scenarios: {
|
||||
concurrent_test: {
|
||||
executor: "per-vu-iterations",
|
||||
vus: 1,
|
||||
iterations: 1,
|
||||
maxDuration: "30m",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const testData = new SharedArray("test requests", function () {
|
||||
return JSON.parse(open("fuzzy.json"));
|
||||
});
|
||||
|
||||
export default function () {
|
||||
console.log(`Starting run with ${testData.length} requests.`);
|
||||
for (const requestBody of testData) {
|
||||
const url = "http://localhost:7007/api/image/generate";
|
||||
const payload = JSON.stringify(requestBody);
|
||||
const params = {
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Accept: "image/png",
|
||||
},
|
||||
timeout: "200s",
|
||||
};
|
||||
|
||||
const res = http.post(url, payload, params);
|
||||
check(res, {
|
||||
[`status is 200 (OK)`]: (r) => r.status === 200,
|
||||
[`content-type is image/png`]: (r) =>
|
||||
r.headers["Content-Type"] === "image/png",
|
||||
});
|
||||
}
|
||||
}
|
||||
52
bench.js
Normal file
52
bench.js
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
import http from "k6/http";
|
||||
import { check } from "k6";
|
||||
import { SharedArray } from "k6/data";
|
||||
|
||||
export const options = {
|
||||
discardResponseBodies: true,
|
||||
scenarios: {
|
||||
sequential_test: {
|
||||
executor: "per-vu-iterations",
|
||||
vus: 1,
|
||||
iterations: 1,
|
||||
maxDuration: "30m",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const testData = new SharedArray("test requests", function () {
|
||||
return JSON.parse(open("answer.json")).tests;
|
||||
});
|
||||
|
||||
export default function () {
|
||||
console.log(`Starting sequential test run with ${testData.length} requests.`);
|
||||
|
||||
for (const testCase of testData) {
|
||||
const requestBody = testCase.request;
|
||||
const testName = testCase.name;
|
||||
|
||||
const url = "http://localhost:7007/api/image/generate";
|
||||
const payload = JSON.stringify(requestBody);
|
||||
const params = {
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Accept: "image/png",
|
||||
},
|
||||
tags: {
|
||||
name: testName,
|
||||
},
|
||||
timeout: "200s",
|
||||
};
|
||||
|
||||
console.log(`'${testName}'`);
|
||||
const res = http.post(url, payload, params);
|
||||
console.log(`'${testName}' duration=${res.timings.duration}ms`);
|
||||
check(res, {
|
||||
"status is 200 (OK)": (r) => r.status === 200,
|
||||
"content-type is image/png": (r) =>
|
||||
r.headers["Content-Type"] === "image/png",
|
||||
});
|
||||
}
|
||||
|
||||
console.log("Sequential test run finished.");
|
||||
}
|
||||
144
fuzz.py
Normal file
144
fuzz.py
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
#!/usr/bin/env python3
|
||||
import argparse
|
||||
import json
|
||||
import random
|
||||
import sys
|
||||
|
||||
# --- Configuration for Crop Fuzzing ---
|
||||
MAX_SUM = 0.99
|
||||
MIN_CROP_SIZE = 0.05
|
||||
PRECISION = 4
|
||||
|
||||
# --- Configuration for Canvas Fuzzing ---
|
||||
# The desired size of the fuzzed rectangle.
|
||||
FUZZED_RECT_WIDTH = 12
|
||||
FUZZED_RECT_HEIGHT = 8
|
||||
|
||||
# The boundaries of the entire canvas.
|
||||
# A=1, B=2, ..., Z=26, AA=27, ..., AE=31
|
||||
CANVAS_MIN_COL = 1 # 'A'
|
||||
CANVAS_MIN_ROW = 1
|
||||
CANVAS_MAX_COL = 31 # 'AE'
|
||||
CANVAS_MAX_ROW = 55
|
||||
|
||||
|
||||
def num_to_col_str(n):
|
||||
"""Converts a 1-indexed column number to its spreadsheet-style string.
|
||||
e.g., 1 -> 'A', 27 -> 'AA'
|
||||
"""
|
||||
string = ""
|
||||
while n > 0:
|
||||
n, remainder = divmod(n - 1, 26)
|
||||
string = chr(65 + remainder) + string
|
||||
return string
|
||||
|
||||
|
||||
def generate_fuzzed_crop_values():
|
||||
"""
|
||||
Generates a random offset and size that adhere to the constraint:
|
||||
offset + size <= MAX_SUM
|
||||
"""
|
||||
offset = random.uniform(0.0, MAX_SUM - MIN_CROP_SIZE)
|
||||
max_size_allowed = MAX_SUM - offset
|
||||
size = random.uniform(MIN_CROP_SIZE, max_size_allowed)
|
||||
return round(offset, PRECISION), round(size, PRECISION)
|
||||
|
||||
|
||||
def generate_fuzzed_canvas_rect():
|
||||
"""
|
||||
Generates a random canvas_rect of a fixed size (12x8) within the
|
||||
overall canvas boundary (A1:AE55).
|
||||
"""
|
||||
# 1. Determine the valid range for the top-left corner.
|
||||
# To fit a 12-wide rect inside a 31-wide canvas, the top-left
|
||||
# column can start at 1 and must end early enough.
|
||||
# Last possible start col = 31 - 12 + 1 = 20
|
||||
max_start_col = CANVAS_MAX_COL - FUZZED_RECT_WIDTH + 1
|
||||
|
||||
# Same logic for rows.
|
||||
# Last possible start row = 55 - 8 + 1 = 48
|
||||
max_start_row = CANVAS_MAX_ROW - FUZZED_RECT_HEIGHT + 1
|
||||
|
||||
# 2. Pick a random top-left corner from the valid range.
|
||||
start_col = random.randint(CANVAS_MIN_COL, max_start_col)
|
||||
start_row = random.randint(CANVAS_MIN_ROW, max_start_row)
|
||||
|
||||
# 3. Calculate the bottom-right corner based on the fuzzed size.
|
||||
end_col = start_col + FUZZED_RECT_WIDTH - 1
|
||||
end_row = start_row + FUZZED_RECT_HEIGHT - 1
|
||||
|
||||
# 4. Convert numerical columns back to string representation.
|
||||
start_col_str = num_to_col_str(start_col)
|
||||
end_col_str = num_to_col_str(end_col)
|
||||
|
||||
# 5. Format the final string.
|
||||
return f"{start_col_str}{start_row}:{end_col_str}{end_row}"
|
||||
|
||||
|
||||
def main():
|
||||
"""
|
||||
Main function to read a JSON file, process the data, and either print
|
||||
to the console or write to an output file.
|
||||
"""
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Fuzzes 'canvas_rect', 'crop_offset', and 'crop_size' in a JSON file.",
|
||||
formatter_class=argparse.RawTextHelpFormatter,
|
||||
)
|
||||
parser.add_argument(
|
||||
"input_file", help="Path to the input JSON file to be processed."
|
||||
)
|
||||
parser.add_argument(
|
||||
"-o",
|
||||
"--output_file",
|
||||
help="Path to the output JSON file. If not provided, the result is printed to the console.",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
try:
|
||||
with open(args.input_file, "r") as f:
|
||||
print(f"Reading data from '{args.input_file}'...")
|
||||
data = json.load(f)
|
||||
except FileNotFoundError:
|
||||
print(f"Error: The file '{args.input_file}' was not found.", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
except json.JSONDecodeError:
|
||||
print(
|
||||
f"Error: The file '{args.input_file}' is not a valid JSON file.",
|
||||
file=sys.stderr,
|
||||
)
|
||||
sys.exit(1)
|
||||
except Exception as e:
|
||||
print(f"An unexpected error occurred: {e}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
# Iterate through each item and update it with fuzzed values
|
||||
for item in data:
|
||||
# Fuzz crop offset and size
|
||||
x_offset, x_size = generate_fuzzed_crop_values()
|
||||
y_offset, y_size = generate_fuzzed_crop_values()
|
||||
|
||||
item["crop_offset"] = [x_offset, y_offset]
|
||||
item["crop_size"] = [x_size, y_size]
|
||||
|
||||
# Fuzz the canvas rect
|
||||
item["canvas_rect"] = generate_fuzzed_canvas_rect()
|
||||
|
||||
# Handle the output
|
||||
if args.output_file:
|
||||
try:
|
||||
with open(args.output_file, "w") as f:
|
||||
json.dump(data, f, indent=2)
|
||||
print(f"Successfully wrote fuzzed data to '{args.output_file}'.")
|
||||
except IOError as e:
|
||||
print(
|
||||
f"Error: Could not write to file '{args.output_file}': {e}",
|
||||
file=sys.stderr,
|
||||
)
|
||||
sys.exit(1)
|
||||
else:
|
||||
print("\n--- Fuzzed JSON ---")
|
||||
print(json.dumps(data, indent=2))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
12002
fuzzy.json
Normal file
12002
fuzzy.json
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue