blob: 11aa96249ac59d8afc5cc6e054227a3e449f7347 (
plain)
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
|
set testmodule [file normalize tests/modules/configaccess.so]
set othermodule [file normalize tests/modules/moduleconfigs.so]
start_server {tags {"modules external:skip"}} {
r module load $testmodule
r module loadex $othermodule CONFIG moduleconfigs.mutable_bool yes
test {Test module config get with standard Redis configs} {
# Test getting standard Redis configs of different types
set maxmemory [r config get maxmemory]
assert_equal [lindex $maxmemory 1] [r configaccess.getnumeric maxmemory]
set port [r config get port]
assert_equal [lindex $port 1] [r configaccess.getnumeric port]
set appendonly [r config get appendonly]
assert_equal [string is true [lindex $appendonly 1]] [r configaccess.getbool appendonly]
# Test string config
set logfile [r config get logfile]
assert_equal [lindex $logfile 1] [r configaccess.get logfile]
# Test SDS config
set requirepass [r config get requirepass]
assert_equal [lindex $requirepass 1] [r configaccess.get requirepass]
# Test special config
set oom_score_adj_values [r config get oom-score-adj-values]
assert_equal [lindex $oom_score_adj_values 1] [r configaccess.get oom-score-adj-values]
set maxmemory_policy_name [r configaccess.getenum maxmemory-policy]
assert_equal [lindex [r config get maxmemory-policy] 1] $maxmemory_policy_name
# Test percent config
r config set maxmemory 100000
r configaccess.setnumeric maxmemory-clients -50
assert_equal [lindex [r config get maxmemory-clients] 1] 50%
# Test multi-argument enum config
r config set moduleconfigs.flags "one two four"
assert_equal "five two" [r configaccess.getenum moduleconfigs.flags]
# Test getting multi-argument enum config via generic get
r config set moduleconfigs.flags "two four"
assert_equal "two four" [r configaccess.get moduleconfigs.flags]
}
test {Test module config get with non-existent configs} {
# Test getting non-existent configs
catch {r configaccess.getnumeric nonexistent_config} err
assert_match "ERR*" $err
catch {r configaccess.getbool nonexistent_config} err
assert_match "ERR*" $err
catch {r configaccess.get nonexistent_config} err
assert_match "ERR*" $err
catch {r configaccess.getenum nonexistent_config} err
assert_match "ERR*" $err
}
test {Test module config set with standard Redis configs} {
# Test setting numeric config
set old_maxmemory_samples [r config get maxmemory-samples]
r configaccess.setnumeric maxmemory-samples 10
assert_equal "maxmemory-samples 10" [r config get maxmemory-samples]
r config set maxmemory-samples [lindex $old_maxmemory_samples 1]
# Test setting bool config
set old_protected_mode [r config get protected-mode]
r configaccess.setbool protected-mode no
assert_equal "protected-mode no" [r config get protected-mode]
r config set protected-mode [lindex $old_protected_mode 1]
# Test setting string config
set old_masteruser [r config get masteruser]
r configaccess.set masteruser "__newmasteruser__"
assert_equal "__newmasteruser__" [lindex [r config get masteruser] 1]
r config set masteruser [lindex $old_masteruser 1]
# Test setting enum config
set old_loglevel [r config get loglevel]
r config set loglevel "notice" ; # Set to some value we are sure is different than the one tested
r configaccess.setenum loglevel warning
assert_equal "loglevel warning" [r config get loglevel]
r config set loglevel [lindex $old_loglevel 1]
# Test setting multi-argument enum config
r config set moduleconfigs.flags "one two four"
assert_equal "moduleconfigs.flags {five two}" [r config get moduleconfigs.flags]
r configaccess.setenum moduleconfigs.flags "two four"
assert_equal "moduleconfigs.flags {two four}" [r config get moduleconfigs.flags]
# Test setting multi-argument enum config via generic set
r config set moduleconfigs.flags "one two four"
assert_equal "moduleconfigs.flags {five two}" [r config get moduleconfigs.flags]
r configaccess.set moduleconfigs.flags "two four"
assert_equal "moduleconfigs.flags {two four}" [r config get moduleconfigs.flags]
}
test {Test module config set with module configs} {
# Test setting module bool config
assert_equal "OK" [r configaccess.setbool configaccess.bool no]
assert_equal "configaccess.bool no" [r config get configaccess.bool]
# Test setting module bool config from another module
assert_equal "OK" [r configaccess.setbool moduleconfigs.mutable_bool no]
assert_equal "moduleconfigs.mutable_bool no" [r config get moduleconfigs.mutable_bool]
# Test setting module numeric config
assert_equal "OK" [r configaccess.setnumeric moduleconfigs.numeric 100]
assert_equal "moduleconfigs.numeric 100" [r config get moduleconfigs.numeric]
# Test setting module enum config
assert_equal "OK" [r configaccess.setenum moduleconfigs.enum "five"]
assert_equal "moduleconfigs.enum five" [r config get moduleconfigs.enum]
}
test {Test module config set with error cases} {
# Test setting a non-existent config
catch {r configaccess.setbool nonexistent_config yes} err
assert_match "*ERR*" $err
# Test setting a read-only config
catch {r configaccess.setbool moduleconfigs.immutable_bool yes} err
assert_match "*ERR*" $err
# Test setting an enum config with invalid value
catch {r configaccess.setenumname moduleconfigs.enum "invalid_value"} err
assert_match "*ERR*" $err
# Test setting a numeric config with out-of-range value
catch {r configaccess.setnumeric moduleconfigs.numeric 5000} err
assert_match "*ERR*" $err
catch {r configaccess.setnumeric maxclients -1} err
assert_match "*Failed to set numeric config maxclients: argument must be between*" $err
catch {r configaccess.setnumeric maxclients -9223372036854775808} err
assert_match "*Failed to set numeric config maxclients: argument must be between*" $err
# Sanity check
assert_equal [r configaccess.setnumeric maxmemory 18446744073709551615] "OK"
assert_equal [r configaccess.setnumeric maxmemory -1] "OK"
}
test {Test module get all configs} {
# Get all configs using the module command
set all_configs [r configaccess.getconfigs]
# Verify the number of configs matches the number of configs returned
# by Redis's native CONFIG GET command.
set all_configs_std_pairs [llength [r config get *]]
# When comparing with the standard CONFIG GET command, we need to divide
# by 2 because the standard command returns a flattened array of
# key-value pairs whereas our testing command returns an array of pairs.
assert_equal [llength $all_configs] [expr $all_configs_std_pairs / 2]
# Verify all the configs are present in both replies.
foreach config_pair $all_configs {
assert_equal 2 [llength $config_pair]
set config_name [lindex $config_pair 0]
set config_value [lindex $config_pair 1]
# Verify that we can get this config using standard config get
set redis_config [r config get $config_name]
assert {[llength $redis_config] != 0}
assert_equal $config_value [lindex $redis_config 1]
}
# Test that module configs are also included
set found_module_config 0
foreach config_pair $all_configs {
set config_name [lindex $config_pair 0]
if {$config_name eq "configaccess.bool"} {
set found_module_config 1
break
}
}
assert {$found_module_config == 1}
# Test pattern matching
set moduleconfigs_count [r configaccess.getconfigs "moduleconfigs.*"]
assert_equal 7 [llength $moduleconfigs_count]
set memoryconfigs_count [r configaccess.getconfigs "*memory"]
assert_equal 3 [llength $memoryconfigs_count]
}
test {Test module config type detection} {
# Test getting config types for different config types
assert_equal "bool" [r configaccess.getconfigtype appendonly]
assert_equal "numeric" [r configaccess.getconfigtype port]
assert_equal "string" [r configaccess.getconfigtype logfile]
assert_equal "enum" [r configaccess.getconfigtype maxmemory-policy]
# Test with module config
assert_equal "bool" [r configaccess.getconfigtype configaccess.bool]
# Test with non-existent config
catch {r configaccess.getconfigtype nonexistent_config} err
assert_match "ERR Config does not exist" $err
}
test {Test config rollback on apply} {
set og_port [lindex [r config get port] 1]
set used_port [find_available_port $::baseport $::portcount]
# Run a dummy server on used_port so we know we can't configure redis to
# use it. It's ok for this to fail because that means used_port is invalid
# anyway
catch {set sockfd [socket -server dummy_accept -myaddr 127.0.0.1 $used_port]} e
if {$::verbose} { puts "dummy_accept: $e" }
# Try to listen on the used port, pass some more configs to make sure the
# returned failure message is for the first bad config and everything is rolled back.
assert_error "ERR Failed to set numeric config port: Unable to listen on this port*" {
eval "r configaccess.setnumeric port $used_port"
}
assert_equal [lindex [r config get port] 1] $og_port
close $sockfd
}
}
|