summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/libstat/backends/redis_backend.cxx118
-rw-r--r--test/functional/cases/110_statistics/090-peruser.robot15
-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.robot52
-rw-r--r--test/functional/configs/stats.conf8
-rw-r--r--test/rspamd_rrd_test.c16
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));