diff --git a/Makefile b/Makefile
index 44c456f..193a7de 100644
@@ -72,6 +72,7 @@ k6:
docker compose run --rm k6 run -u $$(nproc) -d ${DURATION} \
-e FORMAT="${FORMAT}" \
+ -e OUT_FORMAT="${OUT_FORMAT}" \
-e TOOL="${TOOL}" \
-e WIDTH=${WIDTH} \
-e HEIGHT=${HEIGHT} \
diff --git a/docker-compose.yml b/docker-compose.yml
index 2e9bdba..082c1ec 100644
@@ -2,6 +2,7 @@ version: "3"
services:
nginx:
+ cpuset: "0-1"
container_name: nginx_benchmark
image: nginx:latest
restart: unless-stopped
@@ -18,12 +19,14 @@ services:
k6:
image: grafana/k6:latest
+ cpuset: "0-1"
container_name: k6
volumes:
- ${PWD}:/bench:ro
working_dir: /bench
imgproxy:
+ cpuset: "0-1"
container_name: imgproxy_benchmark
image: darthsim/imgproxy:latest
restart: unless-stopped
@@ -45,6 +48,7 @@ services:
start_period: 10s
thumbor:
+ cpuset: "0-1"
container_name: thumbor_benchmark
build: ${PWD}/thumbor
restart: unless-stopped
@@ -63,6 +67,7 @@ services:
start_period: 10s
imagor:
+ cpuset: "0-1"
container_name: imagor_benchmark
image: ghcr.io/cshum/imagor:latest
restart: unless-stopped
@@ -83,3 +88,23 @@ services:
timeout: 5s
start_period: 10s
+
+ oximg:
+ cpuset: "0-1"
+ container_name: oximg_benchmark
+ image: oximg:bench
+ restart: unless-stopped
+ tty: true
+ ports:
+ - 9005:80
+ environment:
+ PORT: "80"
+ OXIMG_SOURCE_BASE_URL: "http://nginx"
+ depends_on:
+ nginx:
+ condition: service_healthy
+ healthcheck:
+ test: ["CMD-SHELL", "timeout 5s bash -c ':> /dev/tcp/127.0.0.1/80' || exit 1"]
+ interval: 5s
+ timeout: 5s
+ start_period: 10s
diff --git a/k6.js b/k6.js
index 73e99d5..1191412 100644
@@ -33,6 +33,37 @@ switch (scenario.format) {
throw `Unknown format ${scenario.format}`;
}
+// Cross-format cells (oximg extension): OUT_FORMAT overrides the output
+// format while FORMAT keeps selecting the source files. Quality follows
+// the output format, matching the same-format mapping above; unknown
+// values fail fast like FORMAT does (a typo must not silently benchmark
+// a different workload per server).
+let outFormat = (__ENV.OUT_FORMAT || '').toLowerCase();
+switch (outFormat) {
+ case '':
+ break;
+
+ case 'jpg':
+ case 'jpeg':
+ outFormat = 'jpg';
+ scenario.quality = 80;
+ break;
+
+ case 'png':
+ break;
+
+ case 'webp':
+ scenario.quality = 75;
+ break;
+
+ case 'avif':
+ scenario.quality = 65;
+ break;
+
+ default:
+ throw `Unknown output format ${outFormat}`;
+}
+
const getFilesList = (format) => {
const datasetDir = (__ENV.DATASET_DIR || './dataset');
const files = open(datasetDir+"/list.txt").split(/\r?\n/);
@@ -47,12 +78,15 @@ const getFormat = (filename) => {
const formatUrl = (format, quality, filename) => {
switch (scenario.tool) {
+ case 'oximg':
+ return `http://${scenario.tool}/resize/${scenario.width}/${scenario.height}/${filename}${outFormat && `@${outFormat}`}`;
+
case 'imgproxy':
- return `http://${scenario.tool}/unsafe/rs:fit:${scenario.width}:${scenario.height}/f:${format}/q:${quality}/plain/http://nginx/${filename}`;
+ return `http://${scenario.tool}/unsafe/rs:fit:${scenario.width}:${scenario.height}/f:${outFormat || format}/q:${quality}/plain/http://nginx/${filename}`;
case 'thumbor':
case 'imagor':
- return `http://${scenario.tool}/unsafe/fit-in/${scenario.width}x${scenario.height}/filters:format(${format}):quality(${quality})/http://nginx/${filename}`;
+ return `http://${scenario.tool}/unsafe/fit-in/${scenario.width}x${scenario.height}/filters:format(${outFormat || format}):quality(${quality})/http://nginx/${filename}`;
default:
throw `Unknown tool ${tool}`;