26ed02ca8c117f13a1eceb3021dfd32ab4e2076c
[platform/core/system/dlog.git] / src / tests / limiter_pos.c
1 /*
2  * Copyright (c) 2018-2020, Samsung Electronics Co., Ltd. All rights reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "limiter_wrap.c"
18
19 int main()
20 {
21         struct log_config conf = {NULL, NULL};
22         assert(!__log_limiter_create(&conf));
23
24         log_config_set(&conf, "limiter|*|*"  , "allow");
25         log_config_set(&conf, "limiter|FOO|*", "deny");
26         log_config_set(&conf, "limiter|*|E"  , "deny");
27         log_config_set(&conf, "limiter|FOO|E", "7");
28         assert(__log_limiter_create(&conf));
29         __log_limiter_update(&conf);
30
31         for (int i = 0; i < 100; ++i) {
32                 assert(__log_limiter_pass_log("FOO", 'F').decision == DECISION_DENIED);
33                 assert(__log_limiter_pass_log("BAR", 'F').decision == DECISION_ALLOWED);
34                 assert(__log_limiter_pass_log("BAR", 'E').decision == DECISION_DENIED);
35         }
36
37         __log_limiter_destroy();
38         assert(__log_limiter_create(&conf));
39
40         for (int i = 0; i < 7; ++i)
41                 assert(__log_limiter_pass_log("FOO", 'E').decision == DECISION_ALLOWED);
42         assert(__log_limiter_pass_log("FOO", 'E').decision == DECISION_TAG_LIMIT_EXCEEDED_MESSAGE);
43         for (int i = 0; i < 2; ++i)
44                 assert(__log_limiter_pass_log("FOO", 'E').decision == DECISION_DENIED);
45
46         fail_time = false;
47         assert(__log_limiter_pass_log("FOO", 'E').decision == DECISION_DENIED);
48         future_time = true;
49         assert(__log_limiter_pass_log("FOO", 'E').decision == DECISION_ALLOWED);
50         future_time = false;
51         assert(__log_limiter_pass_log("FOO", 'E').decision == DECISION_ALLOWED);
52
53         int rulecount = get_rulecount();
54         assert(rulecount == 4);
55
56         const struct limiter_limits limits = __log_limiter_get_limits("FOO", 'E');
57         assert(limits.tag_and_prio == 7);
58         assert(limits.tag          == 0);
59         assert(limits.prio         == 0);
60         assert(limits.global       == __LOG_LIMITER_LIMIT_MAX + 1);
61
62         const struct limiter_limits lim_lowercase = __log_limiter_get_limits("FOO", 'e');
63         const struct limiter_limits lim_enum      = __log_limiter_get_limits("FOO", DLOG_ERROR);
64         const struct limiter_limits lim_numerical = __log_limiter_get_limits("FOO", '6');
65         assert(!memcmp(&limits, &lim_lowercase, sizeof limits));
66         assert(!memcmp(&limits, &lim_enum     , sizeof limits));
67         assert(!memcmp(&limits, &lim_numerical, sizeof limits));
68
69         log_config_set(&conf, "limiter|FOO|E", "12");
70         __log_limiter_update(&conf);
71
72         const struct limiter_limits limits_updated = __log_limiter_get_limits("FOO", 'E');
73         assert(limits_updated.tag_and_prio == 12);
74         assert(get_rulecount() == rulecount);
75
76         log_config_set(&conf, "limiter", "1");
77         log_config_set(&conf, "limiter||E", "2");
78         log_config_set(&conf, "limiter|QUUX|", "3");
79         log_config_set(&conf, "limiter|", "4");
80         log_config_set(&conf, "limiter||", "5");
81         __log_limiter_update(&conf);
82         assert(get_rulecount() == rulecount);
83
84         log_config_set(&conf, "limiter|ABC|?", "13");
85         __log_limiter_update(&conf);
86
87         const struct limiter_limits lim_unknown = __log_limiter_get_limits("ABC", DLOG_UNKNOWN);
88         assert(lim_unknown.tag_and_prio == 13);
89
90         // bulk tests to test hashing and buckets
91 #define S(T) \
92         log_config_set(&conf, "limiter|" #T "|D", "73"); \
93         log_config_set(&conf, "limiter|" #T "|E", "74"); \
94         log_config_set(&conf, "limiter|" #T "|F", "75")
95
96         S(ABC);
97         S(BCA);
98         S(CAB);
99         S(CBA);
100         S(BAC);
101         S(ACB);
102 #undef S
103         __log_limiter_update(&conf);
104
105 #define A(T) \
106         assert(__log_limiter_get_limits(#T, 'D').tag_and_prio == 73); \
107         assert(__log_limiter_get_limits(#T, 'E').tag_and_prio == 74); \
108         assert(__log_limiter_get_limits(#T, 'F').tag_and_prio == 75)
109
110         A(ABC);
111         A(BCA);
112         A(CAB);
113         A(CBA);
114         A(BAC);
115         A(ACB);
116
117 #undef A
118
119         struct rule r1 = {
120                 .prio = 'E',
121                 .hash = util_hash_key("*", '*'),
122                 .tag = "QWE",
123                 .limit = 0,
124         }, r2 = {
125                 .prev = &r1,
126                 .prio = 'E',
127                 .hash = util_hash_key("*", '*'),
128                 .tag = "QWE",
129                 .limit = 0,
130         };
131         __log_limiter_destroy();
132         __log_limiter_initialize(&r1);
133
134         assert(__log_limiter_pass_log("FOO", 'E').decision == DECISION_ALLOWED);
135
136         /* Searching a hashmap kinda doesn't work if you
137          * fake hashes (esp. identical ones) so this just
138          * checks whether stuff explodes on creation. */
139         r1.hash = r2.hash = 42;
140         struct rule r3 = {
141                 .prev = &r2,
142                 .prio = 'E',
143                 .hash = 42,
144                 .tag = "ASD",
145                 .limit = 0,
146         }, r4 = {
147                 .prev = &r3,
148                 .prio = 'F',
149                 .hash = 42,
150                 .tag = "ZXC",
151                 .limit = 0,
152         };
153
154         __log_limiter_destroy();
155         __log_limiter_initialize(&r3);
156
157         struct rule r5 = {
158                 .prev = &r4,
159                 .prio = 'E',
160                 .hash = 69,
161                 .tag = "ZAQ",
162                 .limit = 0,
163         }, r6 = {
164                 .prev = &r5,
165                 .prio = 'D',
166                 .hash = 69,
167                 .tag = "WSX",
168                 .limit = 0,
169         };
170
171         __log_limiter_destroy();
172         __log_limiter_initialize(&r6);
173
174         // empty tag never gets blocked
175         struct rule block_all = {
176                 .prio = '*',
177                 .hash = util_hash_key("*", '*'),
178                 .tag = "*",
179                 .limit = 0,
180         };
181         __log_limiter_destroy();
182         __log_limiter_initialize(&block_all);
183         assert(__log_limiter_pass_log("tag", 'W').decision == DECISION_DENIED);
184         assert(__log_limiter_pass_log("", 'W').decision == DECISION_ALLOWED);
185
186         log_config_free(&conf);
187         __log_limiter_destroy();
188 }