From e9b7320d1ce0b21170741c1c7fc3143bf0d5b824 Mon Sep 17 00:00:00 2001 From: Will Miles Date: Sun, 14 Jul 2024 11:38:29 -0400 Subject: [PATCH 1/8] Add preliminary web stress test script --- tools/stress_test.sh | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 tools/stress_test.sh diff --git a/tools/stress_test.sh b/tools/stress_test.sh new file mode 100644 index 000000000..c107f789a --- /dev/null +++ b/tools/stress_test.sh @@ -0,0 +1,24 @@ +#!/bin/bash +# Some web server stress tests +# +# Perform a large number of parallel requests, stress testing the web server +# TODO: some kind of performance metrics + + +TARGET=$1 + +JSON_TARGETS=('json/state' 'json/info' 'json/si', 'json/palettes' 'json/fxdata' 'settings/s.js?p=2') +FILE_TARGETS=('' 'iro.js' 'rangetouch.js' 'settings' 'settings/wifi') +CURL_ARGS="--compressed --parallel --parallel-immediate --parallel-max 2" + +# TODO: argument parsing + +# Test static file targets +TARGETS=(${JSON_TARGETS[@]}) +#TARGETS=(${FILE_TARGETS[@]}) + +# Expand target URLS to full arguments for curl +FULL_OPTIONS=$(printf "http://${TARGET}/%s -o /dev/null " "${TARGETS[@]}") + +#echo ${FULL_OPTIONS} +time curl ${CURL_ARGS} ${FULL_OPTIONS} From 91efcb910bc3d648044b655241ec094b19cb175e Mon Sep 17 00:00:00 2001 From: Will Miles Date: Sun, 14 Jul 2024 11:38:29 -0400 Subject: [PATCH 2/8] stress_test: Add a larger JSON target --- tools/stress_test.sh | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/tools/stress_test.sh b/tools/stress_test.sh index c107f789a..c3bdfd14d 100644 --- a/tools/stress_test.sh +++ b/tools/stress_test.sh @@ -7,15 +7,24 @@ TARGET=$1 +CURL_ARGS="--compressed --parallel --parallel-immediate --parallel-max 50" + JSON_TARGETS=('json/state' 'json/info' 'json/si', 'json/palettes' 'json/fxdata' 'settings/s.js?p=2') FILE_TARGETS=('' 'iro.js' 'rangetouch.js' 'settings' 'settings/wifi') -CURL_ARGS="--compressed --parallel --parallel-immediate --parallel-max 2" + +# Replicate one target many times +function replicate() { + printf "${1}?%d " {1..8} +} +read -a JSON_LARGE_TARGETS <<< $(replicate "json/si") +read -a JSON_LARGER_TARGETS <<< $(replicate "json/fxdata") # TODO: argument parsing # Test static file targets -TARGETS=(${JSON_TARGETS[@]}) +#TARGETS=(${JSON_TARGETS[@]}) #TARGETS=(${FILE_TARGETS[@]}) +TARGETS=(${JSON_LARGER_TARGETS[@]}) # Expand target URLS to full arguments for curl FULL_OPTIONS=$(printf "http://${TARGET}/%s -o /dev/null " "${TARGETS[@]}") From abcd2a2d01146c84ceb5ffd485d4d0cd80d41543 Mon Sep 17 00:00:00 2001 From: Will Miles Date: Sun, 14 Jul 2024 11:38:29 -0400 Subject: [PATCH 3/8] tools/stress_test: Allow command line target spec --- tools/stress_test.sh | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/tools/stress_test.sh b/tools/stress_test.sh index c3bdfd14d..31a0469f9 100644 --- a/tools/stress_test.sh +++ b/tools/stress_test.sh @@ -4,14 +4,16 @@ # Perform a large number of parallel requests, stress testing the web server # TODO: some kind of performance metrics - -TARGET=$1 +# Accepts two command line arguments: +# - first argument - mandatory - IP or hostname of target server +# - second argument - targert type +HOST=$1 +declare -n TARGET_STR="${2:-JSON_LARGER}_TARGETS" CURL_ARGS="--compressed --parallel --parallel-immediate --parallel-max 50" JSON_TARGETS=('json/state' 'json/info' 'json/si', 'json/palettes' 'json/fxdata' 'settings/s.js?p=2') FILE_TARGETS=('' 'iro.js' 'rangetouch.js' 'settings' 'settings/wifi') - # Replicate one target many times function replicate() { printf "${1}?%d " {1..8} @@ -19,15 +21,10 @@ function replicate() { read -a JSON_LARGE_TARGETS <<< $(replicate "json/si") read -a JSON_LARGER_TARGETS <<< $(replicate "json/fxdata") -# TODO: argument parsing - -# Test static file targets -#TARGETS=(${JSON_TARGETS[@]}) -#TARGETS=(${FILE_TARGETS[@]}) -TARGETS=(${JSON_LARGER_TARGETS[@]}) - # Expand target URLS to full arguments for curl -FULL_OPTIONS=$(printf "http://${TARGET}/%s -o /dev/null " "${TARGETS[@]}") +TARGETS=(${TARGET_STR[@]}) +#echo "${TARGETS[@]}" +FULL_TGT_OPTIONS=$(printf "http://${HOST}/%s -o /dev/null " "${TARGETS[@]}") +#echo ${FULL_TGT_OPTIONS} -#echo ${FULL_OPTIONS} -time curl ${CURL_ARGS} ${FULL_OPTIONS} +time curl ${CURL_ARGS} ${FULL_TGT_OPTIONS} From 0191af412bf1fa1f827646665d9bee33530f34c6 Mon Sep 17 00:00:00 2001 From: Will Miles Date: Sun, 14 Jul 2024 11:38:29 -0400 Subject: [PATCH 4/8] stress_test: Add small JSON target Good for measuring quick response performance --- tools/stress_test.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/stress_test.sh b/tools/stress_test.sh index 31a0469f9..4ea672405 100644 --- a/tools/stress_test.sh +++ b/tools/stress_test.sh @@ -10,7 +10,9 @@ HOST=$1 declare -n TARGET_STR="${2:-JSON_LARGER}_TARGETS" -CURL_ARGS="--compressed --parallel --parallel-immediate --parallel-max 50" +PARALLEL_MAX=${PARALLEL_MAX:-50} + +CURL_ARGS="--compressed --parallel --parallel-immediate --parallel-max ${PARALLEL_MAX}" JSON_TARGETS=('json/state' 'json/info' 'json/si', 'json/palettes' 'json/fxdata' 'settings/s.js?p=2') FILE_TARGETS=('' 'iro.js' 'rangetouch.js' 'settings' 'settings/wifi') @@ -18,6 +20,7 @@ FILE_TARGETS=('' 'iro.js' 'rangetouch.js' 'settings' 'settings/wifi') function replicate() { printf "${1}?%d " {1..8} } +read -a JSON_SMALL_TARGETS <<< $(replicate "json/info") read -a JSON_LARGE_TARGETS <<< $(replicate "json/si") read -a JSON_LARGER_TARGETS <<< $(replicate "json/fxdata") From 541d3f286afab91b21c1468f82471883f45315ac Mon Sep 17 00:00:00 2001 From: Will Miles Date: Sun, 14 Jul 2024 11:38:29 -0400 Subject: [PATCH 5/8] stress_test: Make it worse Read 40 copies! --- tools/stress_test.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/stress_test.sh b/tools/stress_test.sh index 4ea672405..0a11c4332 100644 --- a/tools/stress_test.sh +++ b/tools/stress_test.sh @@ -18,8 +18,9 @@ JSON_TARGETS=('json/state' 'json/info' 'json/si', 'json/palettes' 'json/fxdata' FILE_TARGETS=('' 'iro.js' 'rangetouch.js' 'settings' 'settings/wifi') # Replicate one target many times function replicate() { - printf "${1}?%d " {1..8} + printf "${1}?%d " {1..40} } +read -a JSON_TINY_TARGETS <<< $(replicate "json/nodes") read -a JSON_SMALL_TARGETS <<< $(replicate "json/info") read -a JSON_LARGE_TARGETS <<< $(replicate "json/si") read -a JSON_LARGER_TARGETS <<< $(replicate "json/fxdata") From 5a6ebd665787b66e94719dacf2e82d07f2c0ce6e Mon Sep 17 00:00:00 2001 From: Will Miles Date: Sun, 14 Jul 2024 11:38:29 -0400 Subject: [PATCH 6/8] stress_test: Allow replication argument --- tools/stress_test.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tools/stress_test.sh b/tools/stress_test.sh index 0a11c4332..fe25f3b4e 100644 --- a/tools/stress_test.sh +++ b/tools/stress_test.sh @@ -4,11 +4,13 @@ # Perform a large number of parallel requests, stress testing the web server # TODO: some kind of performance metrics -# Accepts two command line arguments: +# Accepts three command line arguments: # - first argument - mandatory - IP or hostname of target server -# - second argument - targert type +# - second argument - target type (optional) +# - third argument - xfer count (for replicated targets) (optional) HOST=$1 declare -n TARGET_STR="${2:-JSON_LARGER}_TARGETS" +REPLICATE_COUNT=$(("${3:-10}")) PARALLEL_MAX=${PARALLEL_MAX:-50} @@ -18,7 +20,7 @@ JSON_TARGETS=('json/state' 'json/info' 'json/si', 'json/palettes' 'json/fxdata' FILE_TARGETS=('' 'iro.js' 'rangetouch.js' 'settings' 'settings/wifi') # Replicate one target many times function replicate() { - printf "${1}?%d " {1..40} + printf "${1}?%d " $(seq 1 ${REPLICATE_COUNT}) } read -a JSON_TINY_TARGETS <<< $(replicate "json/nodes") read -a JSON_SMALL_TARGETS <<< $(replicate "json/info") From 509cbdf476c258aa2eb5900310ea899f886ce025 Mon Sep 17 00:00:00 2001 From: Will Miles Date: Sun, 14 Jul 2024 11:38:29 -0400 Subject: [PATCH 7/8] Add UDP test code Courtesy of @_tvk_ on Discord --- tools/udp_test.py | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 tools/udp_test.py diff --git a/tools/udp_test.py b/tools/udp_test.py new file mode 100644 index 000000000..c4c9129cf --- /dev/null +++ b/tools/udp_test.py @@ -0,0 +1,46 @@ +import numpy as np +import socket + +class WledRealtimeClient: + def __init__(self, wled_controller_ip, num_pixels, udp_port=21324, max_pixels_per_packet=126): + self.wled_controller_ip = wled_controller_ip + self.num_pixels = num_pixels + self.udp_port = udp_port + self.max_pixels_per_packet = max_pixels_per_packet + self._sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + self._prev_pixels = np.full((3, self.num_pixels), 253, dtype=np.uint8) + self.pixels = np.full((3, self.num_pixels), 1, dtype=np.uint8) + + def update(self): + # Truncate values and cast to integer + self.pixels = np.clip(self.pixels, 0, 255).astype(np.uint8) + p = np.copy(self.pixels) + + idx = np.where(~np.all(p == self._prev_pixels, axis=0))[0] + num_pixels = len(idx) + n_packets = (num_pixels + self.max_pixels_per_packet - 1) // self.max_pixels_per_packet + idx_split = np.array_split(idx, n_packets) + + header = bytes([1, 2]) # WARLS protocol header + for packet_indices in idx_split: + data = bytearray(header) + for i in packet_indices: + data.extend([i, *p[:, i]]) # Index and RGB values + self._sock.sendto(bytes(data), (self.wled_controller_ip, self.udp_port)) + + self._prev_pixels = np.copy(p) + + + +################################## LED blink test ################################## +if __name__ == "__main__": + WLED_CONTROLLER_IP = "192.168.1.153" + NUM_PIXELS = 255 # Amount of LEDs on your strip + import time + wled = WledRealtimeClient(WLED_CONTROLLER_IP, NUM_PIXELS) + print('Starting LED blink test') + while True: + for i in range(NUM_PIXELS): + wled.pixels[1, i] = 255 if wled.pixels[1, i] == 0 else 0 + wled.update() + time.sleep(.01) From 5582bbac6068b03d6ec68c94c6e7035a6a35f72c Mon Sep 17 00:00:00 2001 From: Will Miles Date: Sun, 14 Jul 2024 11:38:29 -0400 Subject: [PATCH 8/8] stress_test: Add code for logging responses --- tools/stress_test.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/stress_test.sh b/tools/stress_test.sh index fe25f3b4e..d7c344c58 100644 --- a/tools/stress_test.sh +++ b/tools/stress_test.sh @@ -15,6 +15,7 @@ REPLICATE_COUNT=$(("${3:-10}")) PARALLEL_MAX=${PARALLEL_MAX:-50} CURL_ARGS="--compressed --parallel --parallel-immediate --parallel-max ${PARALLEL_MAX}" +CURL_PRINT_RESPONSE_ARGS="-w %{http_code}\n" JSON_TARGETS=('json/state' 'json/info' 'json/si', 'json/palettes' 'json/fxdata' 'settings/s.js?p=2') FILE_TARGETS=('' 'iro.js' 'rangetouch.js' 'settings' 'settings/wifi')