diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 6d92fcd..798120b 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -144,7 +144,7 @@ jobs: cat adaptived/tests/ftests/ftests-c-wrapper.sh.log - name: Archive test logs if: ${{ always() }} - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: Adaptived functional test logs path: adaptived/tests/*/*.log @@ -159,7 +159,7 @@ jobs: parallel: True - name: Archive code coverage results if: ${{ always() }} - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: Adaptived Functional Tests Code Coverage path: lcov.* @@ -187,7 +187,7 @@ jobs: cat adaptived/tests/ftests/ftests-c-wrapper.sh.log - name: Archive test logs if: ${{ always() }} - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: Adaptived functional test logs path: adaptived/tests/*/*.log @@ -202,7 +202,7 @@ jobs: parallel: True - name: Archive code coverage results if: ${{ always() }} - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: Adaptived Functional Tests Code Coverage path: lcov.* diff --git a/adaptived/src/main.c b/adaptived/src/main.c index 0b3f8e0..98bf0b2 100644 --- a/adaptived/src/main.c +++ b/adaptived/src/main.c @@ -443,6 +443,12 @@ API int adaptived_loop(struct adaptived_ctx * const ctx, bool parse) } pthread_mutex_lock(&ctx->ctx_mutex); + rule = ctx->rules; + while(rule) { + adaptived_dbg("Rule \"%s\" loaded\n", rule->name); + rule = rule->next; + } + if (ctx->daemon_mode) { adaptived_dbg("adaptived_loop: Try to run as daemon, nochdir = %d, noclose = %d\n", ctx->daemon_nochdir, ctx->daemon_noclose); @@ -456,9 +462,9 @@ API int adaptived_loop(struct adaptived_ctx * const ctx, bool parse) } else { adaptived_dbg("adaptived_loop: Debug mode. Skip running as daemon.\n"); } - pthread_mutex_unlock(&ctx->ctx_mutex); ctx->loop_cnt = 0; + pthread_mutex_unlock(&ctx->ctx_mutex); while (1) { pthread_mutex_lock(&ctx->ctx_mutex); diff --git a/adaptived/src/parse.c b/adaptived/src/parse.c index 94591e1..87e2035 100644 --- a/adaptived/src/parse.c +++ b/adaptived/src/parse.c @@ -600,10 +600,15 @@ int parse_rule(struct adaptived_ctx * const ctx, struct json_object * const rule * do not goto error after this point. we have added the rule * to the rules linked list */ - if (!ctx->rules) + if (!ctx->rules) { ctx->rules = rule; - else - ctx->rules->next = rule; + } else { + tmp_rule = ctx->rules; + + while (tmp_rule->next) + tmp_rule = tmp_rule->next; + tmp_rule->next = rule; + } return ret; diff --git a/adaptived/tests/ftests/070-rule-multiple_rules.c b/adaptived/tests/ftests/070-rule-multiple_rules.c new file mode 100644 index 0000000..de648c7 --- /dev/null +++ b/adaptived/tests/ftests/070-rule-multiple_rules.c @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +/** + * Test to verify all rules are properly loaded + * + */ + +#include +#include +#include +#include + +#include + +#include "ftests.h" + +static void *adaptived_wrapper(void *arg) +{ + struct adaptived_ctx *ctx = arg; + uintptr_t ret; + + ret = adaptived_loop(ctx, true); + + return (void *)ret; +} + +int main(int argc, char *argv[]) +{ + char config_path[FILENAME_MAX]; + pthread_t adaptived_thread; + struct adaptived_ctx *ctx; + uint32_t rule_cnt = 0; + void *tret; + int ret; + + snprintf(config_path, FILENAME_MAX - 1, "%s/070-rule-multiple_rules.json", argv[1]); + config_path[FILENAME_MAX - 1] = '\0'; + + ctx = adaptived_init(config_path); + if (!ctx) + return AUTOMAKE_HARD_ERROR; + + ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_LOG_LEVEL, LOG_DEBUG); + if (ret) + goto err; + ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_INTERVAL, 1500); + if (ret) + goto err; + ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_MAX_LOOPS, 2); + if (ret) + goto err; + + ret = pthread_create(&adaptived_thread, NULL, &adaptived_wrapper, ctx); + if (ret) + goto err; + + /* wait for the adaptived loop to get up and running */ + sleep(1); + + ret = adaptived_get_attr(ctx, ADAPTIVED_ATTR_RULE_CNT, &rule_cnt); + if (ret) + goto err; + if (rule_cnt != 5) + goto err; + + pthread_join(adaptived_thread, &tret); + + if (tret != (void *)-ETIME) + goto err; + + adaptived_release(&ctx); + + return AUTOMAKE_PASSED; + +err: + adaptived_release(&ctx); + + return AUTOMAKE_HARD_ERROR; +} diff --git a/adaptived/tests/ftests/070-rule-multiple_rules.json b/adaptived/tests/ftests/070-rule-multiple_rules.json new file mode 100644 index 0000000..bc9dec4 --- /dev/null +++ b/adaptived/tests/ftests/070-rule-multiple_rules.json @@ -0,0 +1,99 @@ +{ + "rules": [ + { + "name": "1", + "causes": [ + { + "name": "always", + "args": { + } + } + ], + "effects": [ + { + "name": "print", + "args": { + "file": "stdout", + "message": "Rule 1\n" + } + } + ] + }, + { + "name": "2", + "causes": [ + { + "name": "always", + "args": { + } + } + ], + "effects": [ + { + "name": "print", + "args": { + "file": "stdout", + "message": "Rule 2\n" + } + } + ] + }, + { + "name": "3", + "causes": [ + { + "name": "always", + "args": { + } + } + ], + "effects": [ + { + "name": "print", + "args": { + "file": "stdout", + "message": "Rule 3\n" + } + } + ] + }, + { + "name": "4", + "causes": [ + { + "name": "always", + "args": { + } + } + ], + "effects": [ + { + "name": "print", + "args": { + "file": "stdout", + "message": "Rule 4\n" + } + } + ] + }, + { + "name": "5", + "causes": [ + { + "name": "always", + "args": { + } + } + ], + "effects": [ + { + "name": "print", + "args": { + "file": "stdout", + "message": "Rule 5\n" + } + } + ] + } + ] +} diff --git a/adaptived/tests/ftests/Makefile.am b/adaptived/tests/ftests/Makefile.am index 7d31d4e..075a259 100644 --- a/adaptived/tests/ftests/Makefile.am +++ b/adaptived/tests/ftests/Makefile.am @@ -109,6 +109,7 @@ test066_SOURCES = 066-cause-cgroup_memory_setting_ll_lt.c ftests.c test067_SOURCES = 067-effect-kill_processes.c ftests.c test068_SOURCES = 068-effect-kill_processes_rss.c ftests.c test069_SOURCES = 069-effect-signal.c ftests.c +test070_SOURCES = 070-rule-multiple_rules.c ftests.c sudo1000_SOURCES = 1000-sudo-effect-sd_bus_setting_set_int.c ftests.c sudo1001_SOURCES = 1001-sudo-effect-sd_bus_setting_add_int.c ftests.c @@ -185,6 +186,7 @@ check_PROGRAMS = \ test067 \ test068 \ test069 \ + test070 \ sudo1000 \ sudo1001 \ sudo1002 \ @@ -279,7 +281,8 @@ EXTRA_DIST_CFGS = \ 066-cause-cgroup_memory_setting_ll_lt.json \ 067-effect-kill_processes.json \ 068-effect-kill_processes_rss.json \ - 069-effect-signal.json + 069-effect-signal.json \ + 070-rule-multiple_rules.json EXTRA_DIST_H_FILES = \ ftests.h