diff options
-rw-r--r-- | src/libstat/backends/redis_backend.cxx | 118 | ||||
-rw-r--r-- | test/functional/cases/110_statistics/090-peruser.robot | 15 | ||||
-rw-r--r-- | test/functional/cases/110_statistics/100-redis-keyed-siphash.robot (renamed from test/functional/cases/110_statistics/redis-keyed-siphash.robot) | 0 | ||||
-rw-r--r-- | test/functional/cases/110_statistics/110-redis-keyed-xxhash.robot (renamed from test/functional/cases/110_statistics/redis-keyed-xxhash.robot) | 0 | ||||
-rw-r--r-- | test/functional/cases/110_statistics/200-redis-plain-siphash.robot (renamed from test/functional/cases/110_statistics/redis-plain-siphash.robot) | 0 | ||||
-rw-r--r-- | test/functional/cases/110_statistics/210-redis-plain-xxhash.robot (renamed from test/functional/cases/110_statistics/redis-plain-xxhash.robot) | 0 | ||||
-rw-r--r-- | test/functional/cases/110_statistics/lib.robot | 52 | ||||
-rw-r--r-- | test/functional/configs/stats.conf | 8 | ||||
-rw-r--r-- | test/rspamd_rrd_test.c | 16 |
9 files changed, 130 insertions, 79 deletions
diff --git a/src/libstat/backends/redis_backend.cxx b/src/libstat/backends/redis_backend.cxx index cff6baf8c..cd0c37965 100644 --- a/src/libstat/backends/redis_backend.cxx +++ b/src/libstat/backends/redis_backend.cxx @@ -645,6 +645,58 @@ void rspamd_redis_close(gpointer p) delete ctx; } +static constexpr auto +msgpack_emit_str(const std::string_view st, char *out) -> std::size_t +{ + auto len = st.size(); + constexpr const unsigned char fix_mask = 0xA0, l8_ch = 0xd9, l16_ch = 0xda, l32_ch = 0xdb; + auto blen = 0; + if (len <= 0x1F) { + blen = 1; + out[0] = (len | fix_mask) & 0xff; + } + else if (len <= 0xff) { + blen = 2; + out[0] = l8_ch; + out[1] = len & 0xff; + } + else if (len <= 0xffff) { + uint16_t bl = GUINT16_TO_BE(len); + + blen = 3; + out[0] = l16_ch; + memcpy(&out[1], &bl, sizeof(bl)); + } + else { + uint32_t bl = GUINT32_TO_BE(len); + + blen = 5; + out[0] = l32_ch; + memcpy(&out[1], &bl, sizeof(bl)); + } + + memcpy(&out[blen], st.data(), st.size()); + + return blen + len; +} + +static constexpr auto +msgpack_str_len(std::size_t len) -> std::size_t +{ + if (len <= 0x1F) { + return 1 + len; + } + else if (len <= 0xff) { + return 2 + len; + } + else if (len <= 0xffff) { + return 3 + len; + } + else { + return 4 + len; + } +} + /* * Serialise stat tokens to message pack */ @@ -654,9 +706,12 @@ rspamd_redis_serialize_tokens(struct rspamd_task *task, const gchar *prefix, GPt /* Each token is int64_t that requires 10 bytes (2 int32_t) + 4 bytes array len + 1 byte array magic */ char max_int64_str[] = "18446744073709551615"; auto prefix_len = strlen(prefix); - auto req_len = tokens->len * (sizeof(max_int64_str) + prefix_len + 1) + 5; + std::size_t req_len = 5; rspamd_token_t *tok; + /* Calculate required length */ + req_len += tokens->len * (msgpack_str_len(sizeof(max_int64_str) + prefix_len) + 1); + auto *buf = (gchar *) rspamd_mempool_alloc(task->task_pool, req_len); auto *p = buf; @@ -668,16 +723,16 @@ rspamd_redis_serialize_tokens(struct rspamd_task *task, const gchar *prefix, GPt *p++ = (gchar) ((tokens->len >> 8) & 0xff); *p++ = (gchar) (tokens->len & 0xff); + int i; + auto numbuf_len = sizeof(max_int64_str) + prefix_len + 1; + auto *numbuf = (char *) g_alloca(numbuf_len); + PTR_ARRAY_FOREACH(tokens, i, tok) { - auto numbuf_len = sizeof(max_int64_str) + prefix_len + 1; - auto *numbuf = (char *) g_alloca(numbuf_len); - auto r = rspamd_snprintf(numbuf, numbuf_len, "%s_%uL", prefix, tok->data); - *p++ = (gchar) ((r & 0xff) | 0xa0); - - memcpy(p, numbuf, r); - p += r; + std::size_t r = rspamd_snprintf(numbuf, numbuf_len, "%s_%uL", prefix, tok->data); + auto shift = msgpack_emit_str({numbuf, r}, p); + p += shift; } *ser_len = p - buf; @@ -692,52 +747,6 @@ rspamd_redis_serialize_text_tokens(struct rspamd_task *task, GPtrArray *tokens, auto req_len = 5; /* Messagepack array prefix */ int i; - constexpr const auto msgpack_str_len = [](std::size_t len) { - if (len <= 0x1F) { - return 1 + len; - } - else if (len <= 0xff) { - return 2 + len; - } - else if (len <= 0xffff) { - return 3 + len; - } - else { - return 4 + len; - } - }; - constexpr const auto msgpack_emit_str = [](const std::string_view st, char *out) -> size_t { - auto len = st.size(); - constexpr const unsigned char fix_mask = 0xA0, l8_ch = 0xd9, l16_ch = 0xda, l32_ch = 0xdb; - auto blen = 0; - if (len <= 0x1F) { - blen = 1; - out[0] = (len | fix_mask) & 0xff; - } - else if (len <= 0xff) { - blen = 2; - out[0] = l8_ch; - out[1] = len & 0xff; - } - else if (len <= 0xffff) { - uint16_t bl = GUINT16_TO_BE(len); - - blen = 3; - out[0] = l16_ch; - memcpy(&out[1], &bl, sizeof(bl)); - } - else { - uint32_t bl = GUINT32_TO_BE(len); - - blen = 5; - out[0] = l32_ch; - memcpy(&out[1], &bl, sizeof(bl)); - } - - memcpy(&out[blen], st.data(), st.size()); - - return blen + len; - }; /* * First we need to determine the requested length */ @@ -896,6 +905,7 @@ rspamd_redis_process_tokens(struct rspamd_task *task, /* No need to do anything, as it is already done in the opposite class processing */ /* However, we need to store id as it is needed for further tokens processing */ rt->id = id; + rt->tokens = g_ptr_array_ref(tokens); return TRUE; } diff --git a/test/functional/cases/110_statistics/090-peruser.robot b/test/functional/cases/110_statistics/090-peruser.robot new file mode 100644 index 000000000..cd8f3ac77 --- /dev/null +++ b/test/functional/cases/110_statistics/090-peruser.robot @@ -0,0 +1,15 @@ +*** Settings *** +Suite Setup Rspamd Redis Setup +Suite Teardown Rspamd Redis Teardown +Resource lib.robot + +*** Variables *** +${RSPAMD_REDIS_SERVER} ${RSPAMD_REDIS_ADDR}:${RSPAMD_REDIS_PORT} +${RSPAMD_STATS_PER_USER} true + +*** Test Cases *** +Learn + Learn Test test@example.com + +Relearn + Relearn Test test@example.com diff --git a/test/functional/cases/110_statistics/redis-keyed-siphash.robot b/test/functional/cases/110_statistics/100-redis-keyed-siphash.robot index d889502ef..d889502ef 100644 --- a/test/functional/cases/110_statistics/redis-keyed-siphash.robot +++ b/test/functional/cases/110_statistics/100-redis-keyed-siphash.robot diff --git a/test/functional/cases/110_statistics/redis-keyed-xxhash.robot b/test/functional/cases/110_statistics/110-redis-keyed-xxhash.robot index 928a9ea14..928a9ea14 100644 --- a/test/functional/cases/110_statistics/redis-keyed-xxhash.robot +++ b/test/functional/cases/110_statistics/110-redis-keyed-xxhash.robot diff --git a/test/functional/cases/110_statistics/redis-plain-siphash.robot b/test/functional/cases/110_statistics/200-redis-plain-siphash.robot index 790a63eab..790a63eab 100644 --- a/test/functional/cases/110_statistics/redis-plain-siphash.robot +++ b/test/functional/cases/110_statistics/200-redis-plain-siphash.robot diff --git a/test/functional/cases/110_statistics/redis-plain-xxhash.robot b/test/functional/cases/110_statistics/210-redis-plain-xxhash.robot index 55e7524a3..55e7524a3 100644 --- a/test/functional/cases/110_statistics/redis-plain-xxhash.robot +++ b/test/functional/cases/110_statistics/210-redis-plain-xxhash.robot diff --git a/test/functional/cases/110_statistics/lib.robot b/test/functional/cases/110_statistics/lib.robot index c6fad2b2f..792806300 100644 --- a/test/functional/cases/110_statistics/lib.robot +++ b/test/functional/cases/110_statistics/lib.robot @@ -4,15 +4,16 @@ Resource ${RSPAMD_TESTDIR}/lib/rspamd.robot Variables ${RSPAMD_TESTDIR}/lib/vars.py *** Variables *** -${CONFIG} ${RSPAMD_TESTDIR}/configs/stats.conf -${MESSAGE_HAM} ${RSPAMD_TESTDIR}/messages/ham.eml -${MESSAGE_SPAM} ${RSPAMD_TESTDIR}/messages/spam_message.eml -${REDIS_SCOPE} Suite -${RSPAMD_REDIS_SERVER} null -${RSPAMD_SCOPE} Suite -${RSPAMD_STATS_BACKEND} redis -${RSPAMD_STATS_HASH} null -${RSPAMD_STATS_KEY} null +${CONFIG} ${RSPAMD_TESTDIR}/configs/stats.conf +${MESSAGE_HAM} ${RSPAMD_TESTDIR}/messages/ham.eml +${MESSAGE_SPAM} ${RSPAMD_TESTDIR}/messages/spam_message.eml +${REDIS_SCOPE} Suite +${RSPAMD_REDIS_SERVER} null +${RSPAMD_SCOPE} Suite +${RSPAMD_STATS_BACKEND} redis +${RSPAMD_STATS_HASH} null +${RSPAMD_STATS_KEY} null +${RSPAMD_STATS_PER_USER} ${EMPTY} *** Keywords *** Broken Learn Test @@ -26,24 +27,41 @@ Empty Part Test Scan File ${MESSAGE} Expect Symbol BAYES_SPAM +Learn + [Arguments] ${user} ${class} ${message} + IF "${user}" + ${result} = Run Rspamc -d ${user} -h ${RSPAMD_LOCAL_ADDR}:${RSPAMD_PORT_CONTROLLER} learn_${class} ${message} + ELSE + ${result} = Run Rspamc -h ${RSPAMD_LOCAL_ADDR}:${RSPAMD_PORT_CONTROLLER} learn_${class} ${message} + END + Check Rspamc ${result} + Learn Test + [Arguments] ${user}=${EMPTY} Set Suite Variable ${RSPAMD_STATS_LEARNTEST} 0 - ${result} = Run Rspamc -h ${RSPAMD_LOCAL_ADDR}:${RSPAMD_PORT_CONTROLLER} learn_spam ${MESSAGE_SPAM} - ${result} = Run Rspamc -h ${RSPAMD_LOCAL_ADDR}:${RSPAMD_PORT_CONTROLLER} learn_ham ${MESSAGE_HAM} - Check Rspamc ${result} - Scan File ${MESSAGE_SPAM} + Set Test Variable ${kwargs} &{EMPTY} + IF "${user}" + Set To Dictionary ${kwargs} Deliver-To=${user} + END + Learn ${user} spam ${MESSAGE_SPAM} + Learn ${user} ham ${MESSAGE_HAM} + Scan File ${MESSAGE_SPAM} &{kwargs} Expect Symbol BAYES_SPAM - Scan File ${MESSAGE_HAM} + Scan File ${MESSAGE_HAM} &{kwargs} Expect Symbol BAYES_HAM Set Suite Variable ${RSPAMD_STATS_LEARNTEST} 1 Relearn Test + [Arguments] ${user}=${EMPTY} IF ${RSPAMD_STATS_LEARNTEST} == 0 Fail "Learn test was not run" END - ${result} = Run Rspamc -h ${RSPAMD_LOCAL_ADDR}:${RSPAMD_PORT_CONTROLLER} learn_ham ${MESSAGE_SPAM} - Check Rspamc ${result} - Scan File ${MESSAGE_SPAM} + Learn ${user} ham ${MESSAGE_SPAM} + Set Test Variable ${kwargs} &{EMPTY} + IF "${user}" + Set To Dictionary ${kwargs} Deliver-To=${user} + END + Scan File ${MESSAGE_SPAM} &{kwargs} ${pass} = Run Keyword And Return Status Expect Symbol BAYES_HAM IF ${pass} Pass Execution What Me Worry diff --git a/test/functional/configs/stats.conf b/test/functional/configs/stats.conf index bfa39b426..ba6a5fe9c 100644 --- a/test/functional/configs/stats.conf +++ b/test/functional/configs/stats.conf @@ -71,6 +71,14 @@ classifier { cache { server = {= env.REDIS_SERVER =} } + + {% if env.STATS_PER_USER ~= '' %} + per_user = <<EOD +return function(task) + return task:get_principal_recipient() +end +EOD; + {% endif %} } lua = "{= env.TESTDIR =}/lua/test_coverage.lua"; diff --git a/test/rspamd_rrd_test.c b/test/rspamd_rrd_test.c index 00d671192..2860cd8f6 100644 --- a/test/rspamd_rrd_test.c +++ b/test/rspamd_rrd_test.c @@ -1,11 +1,11 @@ -/*- - * Copyright 2016 Vsevolod Stakhov +/* + * Copyright 2024 Vsevolod Stakhov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -46,13 +46,13 @@ void rspamd_rrd_test_func(void) rrd_make_default_rra("AVERAGE", pdp_per_cdp / 2, rows_cnt, &rra[1]); rrd_make_default_rra("AVERAGE", pdp_per_cdp / 4, rows_cnt, &rra[2]); rrd_make_default_rra("AVERAGE", pdp_per_cdp / 10, rows_cnt, &rra[3]); - ar.data = rra; + ar.data = (char *) rra; ar.len = sizeof(rra); g_assert(rspamd_rrd_add_rra(rrd, &ar, &err)); /* Add DS */ rrd_make_default_ds("test", "COUNTER", 1, &ds[0]); rrd_make_default_ds("test1", "COUNTER", 1, &ds[1]); - ar.data = ds; + ar.data = (char *) ds; ar.len = sizeof(ds); g_assert(rspamd_rrd_add_ds(rrd, &ar, &err)); /* Finalize */ @@ -66,7 +66,7 @@ void rspamd_rrd_test_func(void) for (i = 0; i < pdp_per_cdp * rows_cnt / 2; i++) { t[0] = i; t[1] = cnt++; - ar.data = t; + ar.data = (char *) t; ar.len = sizeof(t); ticks += 1.0; g_assert(rspamd_rrd_add_record(rrd, &ar, ticks, &err)); @@ -76,7 +76,7 @@ void rspamd_rrd_test_func(void) for (i = 0; i < pdp_per_cdp * rows_cnt / 4; i++) { t[0] = i + rspamd_time_jitter(1.0, 0.0); t[1] = cnt++; - ar.data = t; + ar.data = (char *) t; ar.len = sizeof(t); ticks += 1.0; g_assert(rspamd_rrd_add_record(rrd, &ar, ticks, &err)); @@ -89,7 +89,7 @@ void rspamd_rrd_test_func(void) for (i = 0; i < pdp_per_cdp * rows_cnt / 8; i++) { t[0] = i; t[1] = cnt++; - ar.data = t; + ar.data = (char *) t; ar.len = sizeof(t); ticks += 1.0; g_assert(rspamd_rrd_add_record(rrd, &ar, ticks, &err)); |