Sat, 03 Dec 2022 18:00:35 +0100
improve http listener migration / shutdown of old listener
/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright 2022 Olaf Wintermann. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include "object.h" #include "../util/object.h" #include <cx/linked_list.h> #include <cx/compare.h> #include "object.h" UCX_TEST(test_expr_parse_expr_value) { pool_handle_t *pool = pool_create(); CxList *tokens = cxLinkedListCreate(pool_allocator(pool), cx_cmp_ptr, sizeof(cxstring)); cxstring token = cx_str("123"); cxListAdd(tokens, &token); UCX_TEST_BEGIN; size_t pos = 0; NSAPIExpression *expr = expr_parse_logical_expr(pool, tokens, &pos); UCX_TEST_ASSERT(pos == 1, "wrong token pos"); UCX_TEST_ASSERT(expr, "expression is null"); UCX_TEST_ASSERT(expr->type == NSAPI_EXPRESSION_INT, "wrong type"); UCX_TEST_END; pool_destroy(pool); } UCX_TEST(test_expr_parse_expr_neg_value) { pool_handle_t *pool = pool_create(); CxList *tokens = cxLinkedListCreate(pool_allocator(pool), cx_cmp_ptr, sizeof(cxstring)); cxstring token = cx_str("-123"); cxListAdd(tokens, &token); UCX_TEST_BEGIN; size_t pos = 0; NSAPIExpression *expr = expr_parse_logical_expr(pool, tokens, &pos); UCX_TEST_ASSERT(pos == 1, "wrong token pos"); UCX_TEST_ASSERT(expr, "expression is null"); UCX_TEST_ASSERT(expr->type == NSAPI_EXPRESSION_INT, "wrong type"); UCX_TEST_ASSERT(expr->value.i == -123, "wrong value"); UCX_TEST_END; pool_destroy(pool); } UCX_TEST(test_expr_parse_expr_value_str) { pool_handle_t *pool = pool_create(); CxList *tokens = cxLinkedListCreate(pool_allocator(pool), cx_cmp_ptr, sizeof(cxstring)); cxstring token = cx_str("\"hello world\""); cxListAdd(tokens, &token); UCX_TEST_BEGIN; size_t pos = 0; NSAPIExpression *expr = expr_parse_logical_expr(pool, tokens, &pos); UCX_TEST_ASSERT(pos == 1, "wrong token pos"); UCX_TEST_ASSERT(expr, "expression is null"); UCX_TEST_ASSERT(expr->type == NSAPI_EXPRESSION_STRING, "wrong type"); UCX_TEST_ASSERT(!cx_strcmp(expr->value.str, cx_str("hello world")), "wrong value"); UCX_TEST_END; pool_destroy(pool); } UCX_TEST(test_expr_parse_expr_value_bool) { pool_handle_t *pool = pool_create(); CxList *tokens = cxLinkedListCreate(pool_allocator(pool), cx_cmp_ptr, sizeof(cxstring)); cxstring token = cx_str("true"); cxListAdd(tokens, &token); UCX_TEST_BEGIN; size_t pos = 0; NSAPIExpression *expr = expr_parse_logical_expr(pool, tokens, &pos); UCX_TEST_ASSERT(pos == 1, "wrong token pos"); UCX_TEST_ASSERT(expr, "expression is null"); UCX_TEST_ASSERT(expr->type == NSAPI_EXPRESSION_BOOL, "wrong type"); UCX_TEST_ASSERT(expr->value.b == 1, "wrong value"); UCX_TEST_END; pool_destroy(pool); } UCX_TEST(test_expr_parse_expr_value_var) { pool_handle_t *pool = pool_create(); CxList *tokens = cxLinkedListCreate(pool_allocator(pool), cx_cmp_ptr, sizeof(cxstring)); cxstring token = cx_str("$test"); cxListAdd(tokens, &token); UCX_TEST_BEGIN; size_t pos = 0; NSAPIExpression *expr = expr_parse_logical_expr(pool, tokens, &pos); UCX_TEST_ASSERT(pos == 1, "wrong token pos"); UCX_TEST_ASSERT(expr, "expression is null"); UCX_TEST_ASSERT(expr->type == NSAPI_EXPRESSION_VARIABLE, "wrong type"); UCX_TEST_ASSERT(!cx_strcmp(expr->value.var, cx_str("test")), "wrong var name"); UCX_TEST_END; pool_destroy(pool); } UCX_TEST(test_expr_parse_expr_not_value) { pool_handle_t *pool = pool_create(); CxList *tokens = cxLinkedListCreate(pool_allocator(pool), cx_cmp_ptr, sizeof(cxstring)); cxstring token = cx_str("not"); cxListAdd(tokens, &token); token = cx_str("true"); cxListAdd(tokens, &token); UCX_TEST_BEGIN; size_t pos = 0; NSAPIExpression *expr = expr_parse_logical_expr(pool, tokens, &pos); UCX_TEST_ASSERT(pos == 2, "wrong token pos"); UCX_TEST_ASSERT(expr, "expression is null"); UCX_TEST_ASSERT(expr->type == NSAPI_EXPRESSION_UNARY, "wrong root expression type"); UCX_TEST_ASSERT(expr->left, "missing left expression"); UCX_TEST_ASSERT(!expr->right, "right expression should be null"); UCX_TEST_ASSERT(expr->left->type == NSAPI_EXPRESSION_BOOL, "left expression has wrong type"); UCX_TEST_ASSERT(expr->left->value.b == 1, "left expression has wrong value"); UCX_TEST_END; pool_destroy(pool); } UCX_TEST(test_expr_parse_expr_sign_value) { pool_handle_t *pool = pool_create(); CxList *tokens1 = cxLinkedListCreate(pool_allocator(pool), cx_cmp_ptr, sizeof(cxstring)); cxstring token = cx_str("+"); cxListAdd(tokens1, &token); token = cx_str("123"); cxListAdd(tokens1, &token); CxList *tokens2 = cxLinkedListCreate(pool_allocator(pool), cx_cmp_ptr, sizeof(cxstring)); token = cx_str("-"); cxListAdd(tokens2, &token); token = cx_str("123"); cxListAdd(tokens2, &token); UCX_TEST_BEGIN; size_t pos = 0; NSAPIExpression *expr = expr_parse_logical_expr(pool, tokens1, &pos); UCX_TEST_ASSERT(pos == 2, "test1: wrong token pos"); UCX_TEST_ASSERT(expr, "test1: expression is null"); pos = 0; expr = expr_parse_logical_expr(pool, tokens2, &pos); UCX_TEST_ASSERT(pos == 2, "test2: wrong token pos"); UCX_TEST_ASSERT(expr, "test2: expression is null"); UCX_TEST_ASSERT(expr->type == NSAPI_EXPRESSION_UNARY, "wrong expression type"); UCX_TEST_ASSERT(expr->operator == NSAPI_EXPRESSION_SUB, "wrong expression operator"); UCX_TEST_ASSERT(expr->left, "missing left expresion"); UCX_TEST_ASSERT(expr->left->type == NSAPI_EXPRESSION_INT, "left expression has wrong type"); UCX_TEST_ASSERT(expr->left->value.i == 123, "left expression has wrong value"); UCX_TEST_END; pool_destroy(pool); } UCX_TEST(test_expr_parse_expr_compare2values) { pool_handle_t *pool = pool_create(); CxList *tokens = cxLinkedListCreate(pool_allocator(pool), cx_cmp_ptr, sizeof(cxstring)); cxstring token = cx_str("2"); cxListAdd(tokens, &token); token = cx_str("=="); cxListAdd(tokens, &token); token = cx_str("2"); cxListAdd(tokens, &token); UCX_TEST_BEGIN; size_t pos = 0; NSAPIExpression *expr = expr_parse_logical_expr(pool, tokens, &pos); UCX_TEST_ASSERT(pos == 3, "wrong token pos"); UCX_TEST_ASSERT(expr, "expression is null"); UCX_TEST_ASSERT(expr->type == NSAPI_EXPRESSION_BINARY, "wrong expression type"); UCX_TEST_ASSERT(expr->left, "left expression is null"); UCX_TEST_ASSERT(expr->right, "right expression is null"); UCX_TEST_ASSERT(expr->left->operator == NSAPI_EXPRESSION_NOOP, "left should be a literal with no operator"); UCX_TEST_ASSERT(expr->right->operator == NSAPI_EXPRESSION_NOOP, "right should be a literal with no operator"); UCX_TEST_END; pool_destroy(pool); } UCX_TEST(test_expr_parse_expr_compare2value_expr) { pool_handle_t *pool = pool_create(); CxList *tokens = cxLinkedListCreate(pool_allocator(pool), cx_cmp_ptr, sizeof(cxstring)); cxstring token = cx_str("2"); cxListAdd(tokens, &token); token = cx_str("=="); cxListAdd(tokens, &token); token = cx_str("1"); cxListAdd(tokens, &token); token = cx_str("+"); cxListAdd(tokens, &token); token = cx_str("1"); cxListAdd(tokens, &token); UCX_TEST_BEGIN; size_t pos = 0; NSAPIExpression *expr = expr_parse_logical_expr(pool, tokens, &pos); UCX_TEST_ASSERT(pos == 5, "wrong token pos"); UCX_TEST_ASSERT(expr, "expression is null"); UCX_TEST_ASSERT(expr->type == NSAPI_EXPRESSION_BINARY, "wrong expression type"); UCX_TEST_ASSERT(expr->left, "left expression is null"); UCX_TEST_ASSERT(expr->right, "right expression is null"); UCX_TEST_ASSERT(expr->left->operator == NSAPI_EXPRESSION_NOOP, "left should be a literal with no operator"); UCX_TEST_ASSERT(expr->right->operator == NSAPI_EXPRESSION_ADD, "right should be a binary expression"); UCX_TEST_END; pool_destroy(pool); } UCX_TEST(test_expr_parse_expr_compare2expr_value) { pool_handle_t *pool = pool_create(); CxList *tokens = cxLinkedListCreate(pool_allocator(pool), cx_cmp_ptr, sizeof(cxstring)); cxstring token = cx_str("1"); cxListAdd(tokens, &token); token = cx_str("+"); cxListAdd(tokens, &token); token = cx_str("1"); cxListAdd(tokens, &token); token = cx_str("=="); cxListAdd(tokens, &token); token = cx_str("2"); cxListAdd(tokens, &token); UCX_TEST_BEGIN; size_t pos = 0; NSAPIExpression *expr = expr_parse_logical_expr(pool, tokens, &pos); UCX_TEST_ASSERT(pos == 5, "wrong token pos"); UCX_TEST_ASSERT(expr, "expression is null"); UCX_TEST_ASSERT(expr->type == NSAPI_EXPRESSION_BINARY, "wrong expression type"); UCX_TEST_ASSERT(expr->left, "left expression is null"); UCX_TEST_ASSERT(expr->right, "right expression is null"); UCX_TEST_ASSERT(expr->right->value.i == 2, "right wrong value"); UCX_TEST_ASSERT(expr->left->operator == NSAPI_EXPRESSION_ADD, "left should be a binary operation"); UCX_TEST_ASSERT(expr->right->operator == NSAPI_EXPRESSION_NOOP, "right should be NOOP"); UCX_TEST_ASSERT(expr->left->left, "ADD-op missing left"); UCX_TEST_ASSERT(expr->left->right, "ADD-op missing right"); UCX_TEST_ASSERT(expr->left->left->value.i == 1, "ADD-op: wrong left value"); UCX_TEST_ASSERT(expr->left->right->value.i == 1, "ADD-op: wrong right value"); UCX_TEST_END; pool_destroy(pool); } UCX_TEST(test_expr_parse_expr_bracket) { pool_handle_t *pool = pool_create(); // expression: 2 * (1 + 2) == 6 CxList *tokens = cxLinkedListCreate(pool_allocator(pool), cx_cmp_ptr, sizeof(cxstring)); cxstring token = cx_str("2"); cxListAdd(tokens, &token); token = cx_str("*"); cxListAdd(tokens, &token); token = cx_str("("); cxListAdd(tokens, &token); token = cx_str("1"); cxListAdd(tokens, &token); token = cx_str("+"); cxListAdd(tokens, &token); token = cx_str("2"); cxListAdd(tokens, &token); token = cx_str(")"); cxListAdd(tokens, &token); token = cx_str("=="); cxListAdd(tokens, &token); token = cx_str("6"); cxListAdd(tokens, &token); UCX_TEST_BEGIN; size_t pos = 0; NSAPIExpression *expr = expr_parse_logical_expr(pool, tokens, &pos); UCX_TEST_ASSERT(pos == 9, "wrong token pos"); UCX_TEST_ASSERT(expr, "expression is null"); UCX_TEST_ASSERT(expr->operator == NSAPI_EXPRESSION_EQ, "root: wrong operator"); UCX_TEST_ASSERT(expr->left, "missing left expression"); UCX_TEST_ASSERT(expr->right, "missing right expression"); UCX_TEST_ASSERT(expr->right->type == NSAPI_EXPRESSION_INT, "right expression has wrong type"); UCX_TEST_ASSERT(expr->left->operator == NSAPI_EXPRESSION_MUL, "left expression has wrong operator"); UCX_TEST_ASSERT(expr->left->left, "mul: missing left"); UCX_TEST_ASSERT(expr->left->right, "mul: missing right"); UCX_TEST_ASSERT(expr->left->right->operator == NSAPI_EXPRESSION_ADD, "missing add operator"); UCX_TEST_ASSERT(expr->left->right->left, "add: missing left"); UCX_TEST_ASSERT(expr->left->right->left, "add: missing right"); UCX_TEST_END; pool_destroy(pool); } UCX_TEST(test_expr_parse_expr_func_arg0) { pool_handle_t *pool = pool_create(); CxList *tokens = cxLinkedListCreate(pool_allocator(pool), cx_cmp_ptr, sizeof(cxstring)); cxstring token = cx_str("test"); cxListAdd(tokens, &token); token = cx_str("("); cxListAdd(tokens, &token); token = cx_str(")"); cxListAdd(tokens, &token); UCX_TEST_BEGIN; size_t pos = 0; NSAPIExpression *expr = expr_parse_logical_expr(pool, tokens, &pos); UCX_TEST_ASSERT(pos == 3, "wrong token pos"); UCX_TEST_ASSERT(expr, "expression is null"); UCX_TEST_ASSERT(expr->type == NSAPI_EXPRESSION_IDENTIFIER, "wrong expression type"); UCX_TEST_ASSERT(expr->operator == NSAPI_EXPRESSION_CALL, "wrong expression operator"); UCX_TEST_ASSERT(!expr->left, "left is not null"); UCX_TEST_ASSERT(!expr->right, "right is not null"); UCX_TEST_END; pool_destroy(pool); } int test_get_args(NSAPIExpression *arglist, size_t maxArgs, size_t *numArgs, NSAPIExpression *arg) { if(!arg) { return 0; } if(arg->operator == NSAPI_EXPRESSION_ARG) { if(arg->left) { if(test_get_args(arglist, maxArgs, numArgs, arg->left)) { return 1; } } if(arg->right) { if(test_get_args(arglist, maxArgs, numArgs, arg->right)) { return 1; } } } else { if(*numArgs >= maxArgs) { return 1; } arglist[*numArgs] = *arg; (*numArgs)++; } return 0; } UCX_TEST(test_expr_parse_expr_func_arg1) { pool_handle_t *pool = pool_create(); CxList *tokens = cxLinkedListCreate(pool_allocator(pool), cx_cmp_ptr, sizeof(cxstring)); cxstring token = cx_str("test"); cxListAdd(tokens, &token); token = cx_str("("); cxListAdd(tokens, &token); token = cx_str("1"); cxListAdd(tokens, &token); token = cx_str(")"); cxListAdd(tokens, &token); UCX_TEST_BEGIN; size_t pos = 0; NSAPIExpression *expr = expr_parse_logical_expr(pool, tokens, &pos); UCX_TEST_ASSERT(pos == tokens->size, "wrong token pos"); UCX_TEST_ASSERT(expr, "expression is null"); UCX_TEST_ASSERT(expr->type == NSAPI_EXPRESSION_IDENTIFIER, "wrong expression type"); UCX_TEST_ASSERT(expr->operator == NSAPI_EXPRESSION_CALL, "wrong expression operator"); size_t numArgs = 0; NSAPIExpression args[8]; int err = test_get_args(args, 8, &numArgs, expr->left); UCX_TEST_ASSERT(err == 0, "too much args"); UCX_TEST_ASSERT(numArgs == 1, "wrong arg count"); UCX_TEST_ASSERT(args[0].value.i == 1, "wrong arg value"); UCX_TEST_END; pool_destroy(pool); } UCX_TEST(test_expr_parse_expr_func_arg3) { pool_handle_t *pool = pool_create(); CxList *tokens = cxLinkedListCreate(pool_allocator(pool), cx_cmp_ptr, sizeof(cxstring)); cxstring token = cx_str("test"); cxListAdd(tokens, &token); token = cx_str("("); cxListAdd(tokens, &token); token = cx_str("1"); cxListAdd(tokens, &token); token = cx_str(","); cxListAdd(tokens, &token); token = cx_str("2"); cxListAdd(tokens, &token); token = cx_str(","); cxListAdd(tokens, &token); token = cx_str("3"); cxListAdd(tokens, &token); token = cx_str(")"); cxListAdd(tokens, &token); UCX_TEST_BEGIN; size_t pos = 0; NSAPIExpression *expr = expr_parse_logical_expr(pool, tokens, &pos); UCX_TEST_ASSERT(pos == tokens->size, "wrong token pos"); UCX_TEST_ASSERT(expr, "expression is null"); UCX_TEST_ASSERT(expr->type == NSAPI_EXPRESSION_IDENTIFIER, "wrong expression type"); UCX_TEST_ASSERT(expr->operator == NSAPI_EXPRESSION_CALL, "wrong expression operator"); size_t numArgs = 0; NSAPIExpression args[8]; int err = test_get_args(args, 8, &numArgs, expr->left); UCX_TEST_ASSERT(err == 0, "too much args"); UCX_TEST_ASSERT(numArgs == 3, "wrong arg count"); UCX_TEST_ASSERT(args[0].value.i == 1, "arg0: wrong value"); UCX_TEST_ASSERT(args[1].value.i == 2, "arg1: wrong value"); UCX_TEST_ASSERT(args[2].value.i == 3, "arg2: wrong value"); UCX_TEST_END; pool_destroy(pool); } UCX_TEST(test_expr_parse_expr_func_expr1) { pool_handle_t *pool = pool_create(); CxList *tokens = cxLinkedListCreate(pool_allocator(pool), cx_cmp_ptr, sizeof(cxstring)); cxstring token = cx_str("test"); cxListAdd(tokens, &token); token = cx_str("("); cxListAdd(tokens, &token); token = cx_str("1"); cxListAdd(tokens, &token); token = cx_str(","); cxListAdd(tokens, &token); token = cx_str("2"); cxListAdd(tokens, &token); token = cx_str("+"); cxListAdd(tokens, &token); token = cx_str("3"); cxListAdd(tokens, &token); token = cx_str(")"); cxListAdd(tokens, &token); UCX_TEST_BEGIN; size_t pos = 0; NSAPIExpression *expr = expr_parse_logical_expr(pool, tokens, &pos); UCX_TEST_ASSERT(pos == tokens->size, "wrong token pos"); UCX_TEST_ASSERT(expr, "expression is null"); UCX_TEST_ASSERT(expr->type == NSAPI_EXPRESSION_IDENTIFIER, "wrong expression type"); UCX_TEST_ASSERT(expr->operator == NSAPI_EXPRESSION_CALL, "wrong expression operator"); size_t numArgs = 0; NSAPIExpression args[8]; int err = test_get_args(args, 8, &numArgs, expr->left); UCX_TEST_ASSERT(err == 0, "too much args"); UCX_TEST_ASSERT(numArgs == 2, "wrong arg count"); UCX_TEST_ASSERT(args[0].value.i == 1, "arg0: wrong value"); UCX_TEST_ASSERT(args[1].operator == NSAPI_EXPRESSION_ADD, "arg1: wrong operator"); UCX_TEST_ASSERT(args[1].left && args[1].right, "arg1: missing operator values"); UCX_TEST_ASSERT(args[1].left->value.i == 2 && args[1].right->value.i == 3, "arg1: wrong operator values"); UCX_TEST_END; pool_destroy(pool); } UCX_TEST(test_expr_parse_expr_func_expr2) { pool_handle_t *pool = pool_create(); CxList *tokens = cxLinkedListCreate(pool_allocator(pool), cx_cmp_ptr, sizeof(cxstring)); cxstring token = cx_str("test"); cxListAdd(tokens, &token); token = cx_str("("); cxListAdd(tokens, &token); token = cx_str("2"); cxListAdd(tokens, &token); token = cx_str("+"); cxListAdd(tokens, &token); token = cx_str("3"); cxListAdd(tokens, &token); token = cx_str(","); cxListAdd(tokens, &token); token = cx_str("sub"); cxListAdd(tokens, &token); token = cx_str("("); cxListAdd(tokens, &token); token = cx_str("4"); cxListAdd(tokens, &token); token = cx_str(")"); cxListAdd(tokens, &token); token = cx_str(","); cxListAdd(tokens, &token); token = cx_str("6"); cxListAdd(tokens, &token); token = cx_str(")"); cxListAdd(tokens, &token); UCX_TEST_BEGIN; size_t pos = 0; NSAPIExpression *expr = expr_parse_logical_expr(pool, tokens, &pos); UCX_TEST_ASSERT(pos == tokens->size, "wrong token pos"); UCX_TEST_ASSERT(expr, "expression is null"); UCX_TEST_ASSERT(expr->type == NSAPI_EXPRESSION_IDENTIFIER, "wrong expression type"); UCX_TEST_ASSERT(expr->operator == NSAPI_EXPRESSION_CALL, "wrong expression operator"); size_t numArgs = 0; NSAPIExpression args[8]; int err = test_get_args(args, 8, &numArgs, expr->left); UCX_TEST_ASSERT(err == 0, "too much args"); UCX_TEST_ASSERT(numArgs == 3, "wrong arg count"); UCX_TEST_ASSERT(args[0].operator == NSAPI_EXPRESSION_ADD, "arg0: wrong operator"); UCX_TEST_ASSERT(args[0].left && args[0].right, "arg0: missing operator values"); UCX_TEST_ASSERT(args[1].operator == NSAPI_EXPRESSION_CALL, "arg1: wrong operator"); UCX_TEST_ASSERT(args[1].left, "arg1: missing args"); UCX_TEST_ASSERT(args[2].type == NSAPI_EXPRESSION_INT, "arg2: wrong type"); UCX_TEST_ASSERT(args[2].value.i == 6, "arg2: wrong value"); UCX_TEST_END; pool_destroy(pool); }