diff --git a/runtime/include/http_request.h b/runtime/include/http_request.h index 1e2793e..bc5b8eb 100644 --- a/runtime/include/http_request.h +++ b/runtime/include/http_request.h @@ -23,16 +23,21 @@ struct http_request { int header_count; struct http_query_param query_params[HTTP_MAX_QUERY_PARAM_COUNT]; int query_params_count; + int header_length; char *body; int body_length; - int body_read_length; /* How far we've read */ + int body_length_read; /* Amount read into buffer from socket */ /* additional members for http-parser */ + int length_parsed; /* Amount parsed */ bool last_was_value; /* http-parser flag used to help the http-parser callbacks differentiate between header fields and values to know when to allocate a new header */ bool header_end; /* boolean flag set when header processing is complete */ bool message_begin; /* boolean flag set when body processing begins */ bool message_end; /* boolean flag set when body processing is complete */ + + /* Runtime state used by WASI */ + int cursor; /* Sandbox cursor (offset from body pointer) */ }; void http_request_print(struct http_request *http_request); diff --git a/runtime/include/http_router.h b/runtime/include/http_router.h index 4a42f7c..f54f9cd 100644 --- a/runtime/include/http_router.h +++ b/runtime/include/http_router.h @@ -18,8 +18,7 @@ struct route { /* HTTP State */ uint32_t relative_deadline_us; uint64_t relative_deadline; /* cycles */ - size_t max_request_size; - size_t max_response_size; + size_t response_size; char *response_content_type; struct admissions_info admissions_info; }; @@ -51,8 +50,7 @@ http_router_add_route(struct http_router *router, struct route_config *config, s .module = module, .relative_deadline_us = config->relative_deadline_us, .relative_deadline = (uint64_t)config->relative_deadline_us * runtime_processor_speed_MHz, - .max_request_size = config->http_req_size, - .max_response_size = config->http_resp_size, + .response_size = config->http_resp_size, .response_content_type = config->http_resp_content_type }; diff --git a/runtime/include/http_session.h b/runtime/include/http_session.h index 76b8553..0a2cfa2 100644 --- a/runtime/include/http_session.h +++ b/runtime/include/http_session.h @@ -49,16 +49,30 @@ http_session_init(struct http_session *session, int socket_descriptor, const str /* Set the session as the data the http-parser has access to */ session->http_parser.data = &session->http_request; + memset(&session->http_request, 0, sizeof(struct http_parser)); + int rc; rc = vec_u8_init(&session->request, HTTP_SESSION_DEFAULT_REQUEST_RESPONSE_SIZE); if (rc < 0) return -1; - rc = vec_u8_init(&session->response, HTTP_SESSION_DEFAULT_REQUEST_RESPONSE_SIZE); + /* Defer allocating response until we've matched a route */ + session->response.buffer = NULL; + + return 0; +} + +static inline int +http_session_init_response_buffer(struct http_session *session, size_t capacity) +{ + assert(session != NULL); + assert(session->response.buffer == NULL); + assert(capacity > 0); + + int rc = vec_u8_init(&session->response, HTTP_SESSION_DEFAULT_REQUEST_RESPONSE_SIZE); if (rc < 0) { vec_u8_deinit(&session->request); return -1; } - return 0; } @@ -174,11 +188,50 @@ http_session_receive(struct http_session *session, void_cb on_eagain) http_parser *parser = &session->http_parser; const http_parser_settings *settings = http_parser_settings_get(); - if (request->length == request->capacity) { + /* If header parsing is complete, resize using content-length */ + if (session->http_request.header_end && session->http_request.body != NULL) { + int header_size = (uint8_t *)session->http_request.body - session->request.buffer; + assert(header_size > 0); + debuglog("Header Size: %d\n", header_size); + debuglog("Body Length (Content-Length): %d\n", session->http_request.body_length); + int required_size = header_size + session->http_request.body_length; + + assert(required_size > 0); + + if (required_size > request->capacity) { + debuglog("vec_u8_resize\n"); + + uint8_t *old_buffer = request->buffer; + if (vec_u8_resize(request, required_size) != 0) { + debuglog("Failed to resize request vector to %d bytes\n", required_size); + goto err_nobufs; + } + + if (old_buffer != request->buffer) { + /* buffer moved, so invalidate to reparse */ + memset(&session->http_request, 0, sizeof(struct http_request)); + http_parser_init(&session->http_parser, HTTP_REQUEST); + /* Set the session as the data the http-parser has access to */ + session->http_parser.data = &session->http_request; + } + } + } else if (request->length == request->capacity) { + /* Otherwise, we have a huge header and should just grow */ + debuglog("vec_u8_grow\n"); + uint8_t *old_buffer = request->buffer; + if (vec_u8_grow(request) != 0) { - debuglog("Ran out of Request Buffer before message end\n"); + debuglog("Failed to grow request buffer\n"); goto err_nobufs; } + + if (old_buffer != request->buffer) { + /* buffer moved, so invalidate to reparse */ + memset(&session->http_request, 0, sizeof(struct http_request)); + http_parser_init(&session->http_parser, HTTP_REQUEST); + /* Set the session as the data the http-parser has access to */ + session->http_parser.data = &session->http_request; + } } ssize_t bytes_received = recv(session->socket, &request->buffer[request->length], @@ -213,16 +266,18 @@ http_session_receive(struct http_session *session, void_cb on_eagain) } assert(bytes_received > 0); + request->length += bytes_received; #ifdef LOG_HTTP_PARSER debuglog("http_parser_execute(%p, %p, %p, %zu\n)", parser, settings, &session->request.buffer[session->request.length], bytes_received); #endif - size_t bytes_parsed = http_parser_execute(parser, settings, - (const char *)&request->buffer[request->length], - (size_t)bytes_received); + size_t bytes_parsed = + http_parser_execute(parser, settings, + (const char *)&request->buffer[session->http_request.length_parsed], + (size_t)request->length - session->http_request.length_parsed); - if (bytes_parsed != (size_t)bytes_received) { + if (bytes_parsed < (size_t)bytes_received) { debuglog("Error: %s, Description: %s\n", http_errno_name((enum http_errno)session->http_parser.http_errno), http_errno_description((enum http_errno)session->http_parser.http_errno)); @@ -231,7 +286,7 @@ http_session_receive(struct http_session *session, void_cb on_eagain) goto err; } - request->length += bytes_parsed; + session->http_request.length_parsed += bytes_parsed; } #ifdef LOG_HTTP_PARSER diff --git a/runtime/include/json_parse.h b/runtime/include/json_parse.h index 3a450ad..4398613 100644 --- a/runtime/include/json_parse.h +++ b/runtime/include/json_parse.h @@ -48,8 +48,7 @@ parse_json(const char *json_buf, ssize_t json_buf_size, struct tenant_config **t } i = tenant_config_vec_parse(tenant_config_vec, &tenant_config_vec_len, json_buf, tokens, i, total_tokens); - - assert(i == total_tokens - 1); + if (i != total_tokens - 1) goto json_parse_err; done: return tenant_config_vec_len; diff --git a/runtime/include/route_config.h b/runtime/include/route_config.h index b653f7e..4a390e0 100644 --- a/runtime/include/route_config.h +++ b/runtime/include/route_config.h @@ -10,7 +10,6 @@ struct route_config { uint8_t admissions_percentile; uint32_t expected_execution_us; uint32_t relative_deadline_us; - uint32_t http_req_size; uint32_t http_resp_size; char *http_resp_content_type; }; @@ -31,7 +30,6 @@ route_config_print(struct route_config *config) printf("[Route] Admissions Percentile: %hhu\n", config->admissions_percentile); printf("[Route] Expected Execution (us): %u\n", config->expected_execution_us); printf("[Route] Relative Deadline (us): %u\n", config->relative_deadline_us); - printf("[Route] HTTP Request Size: %u\n", config->http_req_size); printf("[Route] HTTP Response Size: %u\n", config->http_resp_size); printf("[Route] HTTP Response Content Type: %s\n", config->http_resp_content_type); } diff --git a/runtime/include/route_config_parse.h b/runtime/include/route_config_parse.h index 6109b8f..4b0b15a 100644 --- a/runtime/include/route_config_parse.h +++ b/runtime/include/route_config_parse.h @@ -13,16 +13,18 @@ enum route_config_json_key_admissions_percentile, route_config_json_key_expected_execution_us, route_config_json_key_relative_deadline_us, - route_config_json_key_http_req_size, route_config_json_key_http_resp_size, route_config_json_key_http_resp_content_type, route_config_json_key_len }; -static const char *route_config_json_keys[route_config_json_key_len] = { - "route", "path", "admissions-percentile", "expected-execution-us", "relative-deadline-us", - "http-req-size", "http-resp-size", "http-resp-content-type" -}; +static const char *route_config_json_keys[route_config_json_key_len] = { "route", + "path", + "admissions-percentile", + "expected-execution-us", + "relative-deadline-us", + "http-resp-size", + "http-resp-content-type" }; static inline int route_config_parse(struct route_config *config, const char *json_buf, jsmntok_t *tokens, size_t tokens_base, @@ -77,13 +79,6 @@ route_config_parse(struct route_config *config, const char *json_buf, jsmntok_t route_config_json_keys[route_config_json_key_relative_deadline_us], &config->relative_deadline_us); if (rc < 0) return -1; - } else if (strcmp(key, route_config_json_keys[route_config_json_key_http_req_size]) == 0) { - if (!has_valid_type(tokens[i], key, JSMN_PRIMITIVE, json_buf)) return -1; - - int rc = parse_uint32_t(tokens[i], json_buf, - route_config_json_keys[route_config_json_key_http_req_size], - &config->http_req_size); - if (rc < 0) return -1; } else if (strcmp(key, route_config_json_keys[route_config_json_key_http_resp_size]) == 0) { if (!has_valid_type(tokens[i], key, JSMN_PRIMITIVE, json_buf)) return -1; diff --git a/runtime/include/tenant_functions.h b/runtime/include/tenant_functions.h index f4302d7..4adf7b9 100644 --- a/runtime/include/tenant_functions.h +++ b/runtime/include/tenant_functions.h @@ -36,15 +36,6 @@ tenant_alloc(struct tenant_config *config) if (route_config->path == 0) panic("path field is required\n"); if (route_config->route == 0) panic("route field is required\n"); - - if (route_config->http_req_size > RUNTIME_HTTP_REQUEST_SIZE_MAX) - panic("request_size must be between 0 and %u, was %u\n", - (uint32_t)RUNTIME_HTTP_REQUEST_SIZE_MAX, route_config->http_req_size); - - if (route_config->http_resp_size > RUNTIME_HTTP_RESPONSE_SIZE_MAX) - panic("response-size must be between 0 and %u, was %u\n", - (uint32_t)RUNTIME_HTTP_RESPONSE_SIZE_MAX, route_config->http_resp_size); - if (route_config->relative_deadline_us > (uint32_t)RUNTIME_RELATIVE_DEADLINE_US_MAX) panic("Relative-deadline-us must be between 0 and %u, was %u\n", (uint32_t)RUNTIME_RELATIVE_DEADLINE_US_MAX, route_config->relative_deadline_us); diff --git a/runtime/src/http_parser_settings.c b/runtime/src/http_parser_settings.c index 94dc08e..2836873 100644 --- a/runtime/src/http_parser_settings.c +++ b/runtime/src/http_parser_settings.c @@ -1,3 +1,6 @@ +#include +#include + #include "debuglog.h" #include "http.h" #include "http_request.h" @@ -189,6 +192,23 @@ http_parser_settings_on_header_end(http_parser *parser) #endif http_request->header_end = true; + + /* Search header for content length */ + for (int i = 0; i < http_request->header_count; i++) { + if (strncasecmp(http_request->headers[i].key, "content-length", strlen("content-length")) == 0) { + intmax_t temp = strtoimax(http_request->headers[i].value, NULL, 10); + + if (temp < 0 || temp > INT_MAX) { + /* TODO: Improve error handling to not crash runtime */ + fprintf(stderr, "Unable to parse int for key %.*s\n", + http_request->headers[i].key_length, http_request->headers[i].key); + assert(0); + } else { + http_request->body_length = (int)temp; + } + } + } + return 0; } @@ -212,18 +232,20 @@ http_parser_settings_on_body(http_parser *parser, const char *at, size_t length) assert(http_request->header_end); assert(!http_request->message_end); - if (!http_request->body) { + if (http_request->body == NULL) { #ifdef LOG_HTTP_PARSER debuglog("Setting start of body!\n"); #endif /* If this is the first invocation of the callback, just set */ - http_request->body = (char *)at; - http_request->body_length = length; + http_request->body = (char *)at; + http_request->cursor = 0; + http_request->body_length_read = length; } else { #ifdef LOG_HTTP_PARSER debuglog("Appending to existing body!\n"); #endif - http_request->body_length += length; + assert(http_request->body_length > 0); + http_request->body_length_read += length; } #ifdef LOG_HTTP_PARSER diff --git a/runtime/src/http_request.c b/runtime/src/http_request.c index 8995c9a..e244df8 100644 --- a/runtime/src/http_request.c +++ b/runtime/src/http_request.c @@ -23,5 +23,5 @@ http_request_print(struct http_request *http_request) putchar('\n'); } printf("Body Length %d\n", http_request->body_length); - printf("Body Read Length %d\n", http_request->body_read_length); + printf("Body Length Read %d\n", http_request->body_length_read); } diff --git a/runtime/src/libc/wasi_impl_serverless.c b/runtime/src/libc/wasi_impl_serverless.c index 1d0d2e7..f4e5a7e 100644 --- a/runtime/src/libc/wasi_impl_serverless.c +++ b/runtime/src/libc/wasi_impl_serverless.c @@ -660,20 +660,20 @@ wasi_snapshot_preview1_backing_fd_read(wasi_context_t *context, __wasi_fd_t fd, if (fd == STDIN_FILENO) { struct sandbox *current_sandbox = current_sandbox_get(); struct http_request *current_request = ¤t_sandbox->http->http_request; - int old_read = current_request->body_read_length; + int old_read = current_request->cursor; int bytes_to_read = current_request->body_length - old_read; for (int i = 0; i < iovs_len; i++) { if (bytes_to_read == 0) goto done; int amount_to_copy = iovs[i].buf_len > bytes_to_read ? bytes_to_read : iovs[i].buf_len; - memcpy(iovs[i].buf, current_request->body + current_request->body_read_length, amount_to_copy); - current_request->body_read_length += amount_to_copy; - bytes_to_read = current_request->body_length - current_request->body_read_length; + memcpy(iovs[i].buf, current_request->body + current_request->cursor, amount_to_copy); + current_request->cursor += amount_to_copy; + bytes_to_read = current_request->body_length - current_request->cursor; } done: - *nwritten_retptr = current_request->body_read_length - old_read; + *nwritten_retptr = current_request->cursor - old_read; return __WASI_ERRNO_SUCCESS; } @@ -791,6 +791,12 @@ wasi_snapshot_preview1_backing_fd_write(wasi_context_t *context, __wasi_fd_t fd, for (size_t i = 0; i < iovs_len; i++) { buffer_remaining = s->http->response.capacity - s->http->response.length; + + if (buffer_remaining < iovs[i].buf_len) { + vec_u8_grow(&s->http->response); + buffer_remaining = s->http->response.capacity - s->http->response.length; + } + if (buffer_remaining == 0) { *nwritten_retptr = s->http->response.length - old_response_len; return __WASI_ERRNO_FBIG; diff --git a/runtime/src/listener_thread.c b/runtime/src/listener_thread.c index 198ac45..c4968d0 100644 --- a/runtime/src/listener_thread.c +++ b/runtime/src/listener_thread.c @@ -170,8 +170,10 @@ listener_thread_main(void *dummy) http_session_alloc(client_socket, (const struct sockaddr *)&client_address); /* Read HTTP request */ + /* TODO: Use epoll on block instead of busy looping */ int rc = 0; - while ((rc = http_session_receive(session, NULL)) == -3) debuglog("Loop\n"); + while ((rc = http_session_receive(session, NULL)) == -3) + ; if (rc == -2) { debuglog("Request size exceeded Buffer\n"); diff --git a/runtime/src/sandbox.c b/runtime/src/sandbox.c index 7434a43..0d6ae3b 100644 --- a/runtime/src/sandbox.c +++ b/runtime/src/sandbox.c @@ -94,6 +94,12 @@ sandbox_prepare_execution_environment(struct sandbox *sandbox) int rc; + rc = http_session_init_response_buffer(sandbox->http, sandbox->route->response_size); + if (rc < 0) { + error_message = "failed to response buffer"; + goto err_globals_allocation_failed; + } + rc = sandbox_allocate_globals(sandbox); if (rc < 0) { error_message = "failed to allocate globals"; diff --git a/tests/CMSIS_5_NN/imageclassification/Makefile b/tests/CMSIS_5_NN/imageclassification/Makefile index e24a8fa..203f1ea 100644 --- a/tests/CMSIS_5_NN/imageclassification/Makefile +++ b/tests/CMSIS_5_NN/imageclassification/Makefile @@ -14,13 +14,13 @@ debug: .PHONY: client client: - @curl -H 'Expect:' -H "Content-Type: text/plain" --data-binary "@../../../applications/wasm_apps/CMSIS_5_NN/images/bmp/airplane1.bmp" "localhost:10000/random" - @curl -H 'Expect:' -H "Content-Type: text/plain" --data-binary "@../../../applications/wasm_apps/CMSIS_5_NN/images/bmp/automobile1.bmp" "localhost:10000/random" - @curl -H 'Expect:' -H "Content-Type: text/plain" --data-binary "@../../../applications/wasm_apps/CMSIS_5_NN/images/bmp/bird1.bmp" "localhost:10000/random" - @curl -H 'Expect:' -H "Content-Type: text/plain" --data-binary "@../../../applications/wasm_apps/CMSIS_5_NN/images/bmp/cat1.bmp" "localhost:10000/random" - @curl -H 'Expect:' -H "Content-Type: text/plain" --data-binary "@../../../applications/wasm_apps/CMSIS_5_NN/images/bmp/deer1.bmp" "localhost:10000/random" - @curl -H 'Expect:' -H "Content-Type: text/plain" --data-binary "@../../../applications/wasm_apps/CMSIS_5_NN/images/bmp/dog1.bmp" "localhost:10000/random" - @curl -H 'Expect:' -H "Content-Type: text/plain" --data-binary "@../../../applications/wasm_apps/CMSIS_5_NN/images/bmp/frog1.bmp" "localhost:10000/random" - @curl -H 'Expect:' -H "Content-Type: text/plain" --data-binary "@../../../applications/wasm_apps/CMSIS_5_NN/images/bmp/horse1.bmp" "localhost:10000/random" - @curl -H 'Expect:' -H "Content-Type: text/plain" --data-binary "@../../../applications/wasm_apps/CMSIS_5_NN/images/bmp/ship1.bmp" "localhost:10000/random" - @curl -H 'Expect:' -H "Content-Type: text/plain" --data-binary "@../../../applications/wasm_apps/CMSIS_5_NN/images/bmp/truck1.bmp" "localhost:10000/random" + @curl -H 'Expect:' -H "Content-Type: text/plain" --data-binary "@../../../applications/wasm_apps/CMSIS_5_NN/images/bmp/airplane1.bmp" "localhost:10000/rand" + @curl -H 'Expect:' -H "Content-Type: text/plain" --data-binary "@../../../applications/wasm_apps/CMSIS_5_NN/images/bmp/automobile1.bmp" "localhost:10000/rand" + @curl -H 'Expect:' -H "Content-Type: text/plain" --data-binary "@../../../applications/wasm_apps/CMSIS_5_NN/images/bmp/bird1.bmp" "localhost:10000/rand" + @curl -H 'Expect:' -H "Content-Type: text/plain" --data-binary "@../../../applications/wasm_apps/CMSIS_5_NN/images/bmp/cat1.bmp" "localhost:10000/rand" + @curl -H 'Expect:' -H "Content-Type: text/plain" --data-binary "@../../../applications/wasm_apps/CMSIS_5_NN/images/bmp/deer1.bmp" "localhost:10000/rand" + @curl -H 'Expect:' -H "Content-Type: text/plain" --data-binary "@../../../applications/wasm_apps/CMSIS_5_NN/images/bmp/dog1.bmp" "localhost:10000/rand" + @curl -H 'Expect:' -H "Content-Type: text/plain" --data-binary "@../../../applications/wasm_apps/CMSIS_5_NN/images/bmp/frog1.bmp" "localhost:10000/rand" + @curl -H 'Expect:' -H "Content-Type: text/plain" --data-binary "@../../../applications/wasm_apps/CMSIS_5_NN/images/bmp/horse1.bmp" "localhost:10000/rand" + @curl -H 'Expect:' -H "Content-Type: text/plain" --data-binary "@../../../applications/wasm_apps/CMSIS_5_NN/images/bmp/ship1.bmp" "localhost:10000/rand" + @curl -H 'Expect:' -H "Content-Type: text/plain" --data-binary "@../../../applications/wasm_apps/CMSIS_5_NN/images/bmp/truck1.bmp" "localhost:10000/rand" diff --git a/tests/fibonacci/bimodal/spec.json b/tests/fibonacci/bimodal/spec.json index d99c75d..a841aae 100644 --- a/tests/fibonacci/bimodal/spec.json +++ b/tests/fibonacci/bimodal/spec.json @@ -9,7 +9,6 @@ "admissions-percentile": 70, "expected-execution-us": 6000, "relative-deadline-us": 20000, - "http-req-size": 1024, "http-resp-size": 1024, "http-resp-content-type": "text/plain" }, @@ -19,7 +18,6 @@ "expected-execution-us": 10000000, "admissions-percentile": 70, "relative-deadline-us": 20000000, - "http-req-size": 1024, "http-resp-size": 1024, "http-resp-content-type": "text/plain" } @@ -35,10 +33,9 @@ "admissions-percentile": 70, "expected-execution-us": 6000, "relative-deadline-us": 20000, - "http-req-size": 1024, "http-resp-size": 1024, "http-resp-content-type": "text/plain" } ] } -] +] \ No newline at end of file diff --git a/tests/sod/image_resize/by_resolution/Makefile b/tests/sod/image_resize/by_resolution/Makefile index a96ec0d..590e44b 100644 --- a/tests/sod/image_resize/by_resolution/Makefile +++ b/tests/sod/image_resize/by_resolution/Makefile @@ -15,3 +15,14 @@ debug: --eval-command="handle SIGPIPE noprint nostop" \ --eval-command="set pagination off" \ --eval-command="run spec.json" + +client-small: + cat shrinking_man_small.jpg | http --output res/small.jpg --download :10000/resize_small + +client-medium: + cat shrinking_man_medium.jpg | http --output res/medium.jpg --download :10000/resize_medium + +client-large: + cat shrinking_man_large.jpg | http --output res/large.jpg --download :10000/resize_large + +client: client-small client-medium client-large diff --git a/tests/sod/image_resize/by_resolution/run.sh b/tests/sod/image_resize/by_resolution/run.sh index b1b53f1..23367b4 100755 --- a/tests/sod/image_resize/by_resolution/run.sh +++ b/tests/sod/image_resize/by_resolution/run.sh @@ -26,7 +26,7 @@ run_functional_tests() { ext="$RANDOM" # Small - if curl -H 'Expect:' -H "Content-Type: image/jpg" --data-binary "@shrinking_man_small.jpg" --output "/tmp/result_${ext}_small.jpg" "${hostname}:10000" 2> /dev/null 1> /dev/null; then + if curl -H 'Expect:' -H "Content-Type: image/jpg" --data-binary "@shrinking_man_small.jpg" --output "/tmp/result_${ext}_small.jpg" "${hostname}:10000/resize_small" 2> /dev/null 1> /dev/null; then pixel_differences="$(compare -identify -metric AE "/tmp/result_${ext}_small.jpg" expected_result_small.jpg null: 2>&1 > /dev/null)" rm -f "/tmp/result_${ext}_small.jpg" if [[ "$pixel_differences" != "0" ]]; then @@ -40,7 +40,7 @@ run_functional_tests() { fi # Medium - if curl -H 'Expect:' -H "Content-Type: image/jpg" --data-binary "@shrinking_man_medium.jpg" --output "/tmp/result_${ext}_medium.jpg" "${hostname}:10001" 2> /dev/null 1> /dev/null; then + if curl -H 'Expect:' -H "Content-Type: image/jpg" --data-binary "@shrinking_man_medium.jpg" --output "/tmp/result_${ext}_medium.jpg" "${hostname}:10000/resize_medium" 2> /dev/null 1> /dev/null; then pixel_differences="$(compare -identify -metric AE "/tmp/result_${ext}_medium.jpg" expected_result_medium.jpg null: 2>&1 > /dev/null)" rm -f "/tmp/result_${ext}_medium.jpg" if [[ "$pixel_differences" != "0" ]]; then @@ -54,7 +54,7 @@ run_functional_tests() { fi # Large - if curl -H 'Expect:' -H "Content-Type: image/jpg" --data-binary "@shrinking_man_large.jpg" --output "/tmp/result_${ext}_large.jpg" "${hostname}:10002" 2> /dev/null 1> /dev/null; then + if curl -H 'Expect:' -H "Content-Type: image/jpg" --data-binary "@shrinking_man_large.jpg" --output "/tmp/result_${ext}_large.jpg" "${hostname}:10000/resize_large" 2> /dev/null 1> /dev/null; then pixel_differences="$(compare -identify -metric AE "/tmp/result_${ext}_large.jpg" expected_result_large.jpg null: 2>&1 > /dev/null)" rm -f "/tmp/result_${ext}_large.jpg" if [[ "$pixel_differences" != "0" ]]; then @@ -95,7 +95,7 @@ run_perf_tests() { done ((batch_id++)) - hey -disable-compression -disable-keepalive -disable-redirects -n $batch_size -c 1 -cpus 1 -t 0 -o csv -m GET -D "shrinking_man_${workload}.jpg" "http://${hostname}:${port[$workload]}" > "$results_directory/${workload}_${batch_id}.csv" 2> /dev/null & + hey -disable-compression -disable-keepalive -disable-redirects -n $batch_size -c 1 -cpus 1 -t 0 -o csv -m GET -D "shrinking_man_${workload}.jpg" "http://${hostname}:10000${route[$workload]}" > "$results_directory/${workload}_${batch_id}.csv" 2> /dev/null & done pids=$(pgrep hey | tr '\n' ' ') [[ -n $pids ]] && wait -f $pids @@ -160,10 +160,10 @@ experiment_client() { validate_dependencies curl declare -ar workloads=(small medium large) -declare -Ar port=( - [small]=10000 - [medium]=10001 - [large]=10002 +declare -Ar route=( + [small]=/resize_small + [medium]=/resize_medium + [large]=/resize_large ) framework_init "$@" diff --git a/tests/sod/image_resize/by_resolution/spec.json b/tests/sod/image_resize/by_resolution/spec.json index 5fc6f7f..1836c8a 100644 --- a/tests/sod/image_resize/by_resolution/spec.json +++ b/tests/sod/image_resize/by_resolution/spec.json @@ -1,32 +1,32 @@ [ { - "name": "resize_small", - "path": "resize_image.wasm.so", + "name": "gwu", "port": 10000, - "expected-execution-us": 5000, - "relative-deadline-us": 50000, - "http-req-size": 1024000, - "http-resp-size": 1024000, - "http-resp-content-type": "image/png" - }, - { - "name": "resize_medium", - "path": "resize_image.wasm.so", - "port": 10001, - "expected-execution-us": 5000, - "relative-deadline-us": 50000, - "http-req-size": 1024000, - "http-resp-size": 1024000, - "http-resp-content-type": "image/png" - }, - { - "name": "resize_large", - "path": "resize_image.wasm.so", - "port": 10002, - "expected-execution-us": 5000, - "relative-deadline-us": 50000, - "http-req-size": 1524000, - "http-resp-size": 1524000, - "http-resp-content-type": "image/png" + "routes": [ + { + "route": "/resize_small", + "path": "resize_image.wasm.so", + "expected-execution-us": 5000, + "relative-deadline-us": 50000, + "http-resp-size": 1024000, + "http-resp-content-type": "image/png" + }, + { + "route": "/resize_medium", + "path": "resize_image.wasm.so", + "expected-execution-us": 5000, + "relative-deadline-us": 50000, + "http-resp-size": 1024000, + "http-resp-content-type": "image/png" + }, + { + "route": "/resize_large", + "path": "resize_image.wasm.so", + "expected-execution-us": 5000, + "relative-deadline-us": 50000, + "http-resp-size": 1524000, + "http-resp-content-type": "image/png" + } + ] } -] +] \ No newline at end of file