File: logger.lua

package info (click to toggle)
rspamd 3.14.3-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 35,064 kB
  • sloc: ansic: 247,728; cpp: 107,741; javascript: 31,385; perl: 3,089; asm: 2,512; pascal: 1,625; python: 1,510; sh: 589; sql: 313; makefile: 195; xml: 74
file content (227 lines) | stat: -rw-r--r-- 7,103 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
context("Logger unit tests", function()
  test("Logger functions", function()
    local log = require "rspamd_logger"

    local cases = {
      { 'string', 'string' },
      { '%1', 'string', 'string' },
      { '%1', '1.1', 1.1 },
      { '%1', '1', 1 },
      { '%1', 'true', true },
      { '%1', '{[1] = 1, [2] = test}', { 1, 'test' } },
      { '%1', '{[1] = 1, [2] = 2.1, [k2] = test}', { 1, 2.1, k2 = 'test' } },
      { '%s', 'true', true },
    }

    for _, c in ipairs(cases) do
      local s
      if c[3] then
        s = log.slog(c[1], c[3])
      else
        s = log.slog(c[1])
      end
      assert_equal(s, c[2], string.format("'%s' doesn't match with '%s'",
          c[2], s))
    end
  end)

  test("Logger graceful error handling", function()
    local log = require "rspamd_logger"

    -- Test missing arguments
    local missing_arg_cases = {
      { '%1', '<MISSING ARGUMENT>' },
      { '%0', '<MISSING ARGUMENT>' }, -- %0 is invalid since Lua args are 1-indexed
      { '%2', '<MISSING ARGUMENT>', 'arg1' },
      { '%1 %2', 'arg1 <MISSING ARGUMENT>', 'arg1' },
      { 'prefix %1 %3 suffix', 'prefix arg1 <MISSING ARGUMENT> suffix', 'arg1' },
    }

    for _, c in ipairs(missing_arg_cases) do
      local s
      if c[3] then
        s = log.slog(c[1], c[3])
      else
        s = log.slog(c[1])
      end
      assert_equal(s, c[2], string.format("Missing arg test: '%s' doesn't match with '%s'",
          c[2], s))
    end

    -- Test extra arguments
    local extra_arg_cases = {
      { '%1', 'arg1 <EXTRA 1 ARGUMENTS>', 'arg1', 'extra1' },
      { '%1', 'arg1 <EXTRA 2 ARGUMENTS>', 'arg1', 'extra1', 'extra2' },
      { '%s', 'arg1 <EXTRA 1 ARGUMENTS>', 'arg1', 'extra1' },
      { 'prefix %1 suffix', 'prefix arg1 suffix <EXTRA 1 ARGUMENTS>', 'arg1', 'extra1' },
    }

    for _, c in ipairs(extra_arg_cases) do
      local s
      if c[4] and c[5] then
        s = log.slog(c[1], c[3], c[4], c[5])
      elseif c[4] then
        s = log.slog(c[1], c[3], c[4])
      else
        s = log.slog(c[1], c[3])
      end
      assert_equal(s, c[2], string.format("Extra arg test: '%s' doesn't match with '%s'",
          c[2], s))
    end

    -- Test literal percent sequences (should pass through as-is)
    local literal_cases = {
      { '%-1', '%-1' },
      { '%abc', '%abc' }, -- Should pass through as literal since it's not a valid number
      { '%', '%' }, -- Single percent should pass through
    }

    for _, c in ipairs(literal_cases) do
      local s = log.slog(c[1])
      assert_equal(s, c[2], string.format("Literal test: '%s' doesn't match with '%s'",
          c[2], s))
    end

    -- Test mixed scenarios
    local mixed_cases = {
      { '%1 %3', 'arg1 <MISSING ARGUMENT> <EXTRA 1 ARGUMENTS>', 'arg1', 'extra1' },
      { '%2 %4', 'extra1 <MISSING ARGUMENT> <EXTRA 1 ARGUMENTS>', 'arg1', 'extra1' },
    }

    for _, c in ipairs(mixed_cases) do
      local s
      if c[4] then
        s = log.slog(c[1], c[3], c[4])
      else
        s = log.slog(c[1], c[3])
      end
      assert_equal(s, c[2], string.format("Mixed test: '%s' doesn't match with '%s'",
          c[2], s))
    end
  end)

  test("Logger type specifiers", function()
    local log = require "rspamd_logger"

    -- Test %d (signed integer)
    local int_cases = {
      { '%d', '100', 100 },
      { '%d', '100', 100.5 },  -- Should truncate to integer
      { '%d', '-42', -42 },
      { '%d', '0', 0 },
      { '%1d', '100', 100 },
      { 'count=%d', 'count=100', 100 },
      { 'count=%1d', 'count=100', 100 },
      { '%d items', '100 items', 100 },
    }

    for _, c in ipairs(int_cases) do
      local s = log.slog(c[1], c[3])
      assert_equal(s, c[2], string.format("Int format test: '%s' doesn't match with '%s'",
          c[2], s))
    end

    -- Test %ud (unsigned integer)
    local uint_cases = {
      { '%ud', '100', 100 },
      { '%1ud', '100', 100 },
      { 'size=%ud bytes', 'size=1024 bytes', 1024 },
    }

    for _, c in ipairs(uint_cases) do
      local s = log.slog(c[1], c[3])
      assert_equal(s, c[2], string.format("Unsigned int format test: '%s' doesn't match with '%s'",
          c[2], s))
    end

    -- Test %f (float) - smart formatting without trailing zeros
    local float_cases = {
      { '%f', '1.5', 1.5 },
      { '%f', '100.0', 100 },
      { '%f', '-42.75', -42.75 },
      { '%1f', '1.5', 1.5 },
      { 'pi=%f', 'pi=3.14', 3.14 },
    }

    for _, c in ipairs(float_cases) do
      local s = log.slog(c[1], c[3])
      assert_equal(s, c[2], string.format("Float format test: '%s' doesn't match with '%s'",
          c[2], s))
    end

    -- Test %.Nf (float with precision)
    local precision_cases = {
      { '%.2f', '1.50', 1.5 },
      { '%.3f', '3.145', 3.145 },
      { '%.1f', '100.0', 100 },
      { '%.0f', '42', 42.0 },
      { 'price=%.2f', 'price=19.99', 19.99 },
    }

    for _, c in ipairs(precision_cases) do
      local s = log.slog(c[1], c[3])
      assert_equal(s, c[2], string.format("Precision format test: '%s' doesn't match with '%s'",
          c[2], s))
    end

    -- Test mixed type specifiers
    local mixed_type_cases = {
      { 'count=%1d, price=%.2f, name=%3', 'count=100, price=1.50, name=string', 100, 1.5, 'string' },
      { '%d %f %s', '42 3.14 test', 42, 3.14, 'test' },
      { 'int=%d, float=%.3f, str=%s', 'int=100, float=1.500, str=hello', 100, 1.5, 'hello' },
    }

    for _, c in ipairs(mixed_type_cases) do
      local s = log.slog(c[1], c[3], c[4], c[5])
      assert_equal(s, c[2], string.format("Mixed type format test: '%s' doesn't match with '%s'",
          c[2], s))
    end

    -- Test type conversion from strings
    local string_conversion_cases = {
      { '%d', '42', '42' },  -- String to int
      { '%f', '3.14', '3.14' },  -- String to float
      { '%.2f', '3.14', '3.14' },  -- String to float with precision
    }

    for _, c in ipairs(string_conversion_cases) do
      local s = log.slog(c[1], c[3])
      assert_equal(s, c[2], string.format("String conversion test: '%s' doesn't match with '%s'",
          c[2], s))
    end

    -- Test fallback for non-numeric types
    local fallback_cases = {
      { '%d', '0', nil },  -- nil should become 0
      { '%f', '0.0', nil },  -- nil should become 0.0
      { '%.2f', '0.00', nil },  -- nil with precision should become 0.00
    }

    for _, c in ipairs(fallback_cases) do
      local s = log.slog(c[1], c[3])
      assert_equal(s, c[2], string.format("Fallback test: '%s' doesn't match with '%s'",
          c[2], s))
    end

    -- Test %% escaping
    local escape_cases = {
      { '%%', '%' },
      { '100%%', '100%' },
      { 'price=%.2f%%', 'price=19.99%', 19.99 },
      { '%1 is %%d not %d', '100 is %d not 42', 100, 42 },
    }

    for _, c in ipairs(escape_cases) do
      local s
      if c[4] then
        s = log.slog(c[1], c[3], c[4])
      elseif c[3] then
        s = log.slog(c[1], c[3])
      else
        s = log.slog(c[1])
      end
      assert_equal(s, c[2], string.format("Escape test: '%s' doesn't match with '%s'",
          c[2], s))
    end
  end)
end)