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 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386
|
set testmodule [file normalize tests/modules/moduleconfigs.so]
set testmoduletwo [file normalize tests/modules/moduleconfigstwo.so]
start_server {tags {"modules"}} {
r module load $testmodule
test {Config get commands work} {
# Make sure config get module config works
assert_not_equal [lsearch [lmap x [r module list] {dict get $x name}] moduleconfigs] -1
assert_equal [r config get moduleconfigs.mutable_bool] "moduleconfigs.mutable_bool yes"
assert_equal [r config get moduleconfigs.immutable_bool] "moduleconfigs.immutable_bool no"
assert_equal [r config get moduleconfigs.memory_numeric] "moduleconfigs.memory_numeric 1024"
assert_equal [r config get moduleconfigs.string] "moduleconfigs.string {secret password}"
assert_equal [r config get moduleconfigs.enum] "moduleconfigs.enum one"
assert_equal [r config get moduleconfigs.flags] "moduleconfigs.flags {one two}"
assert_equal [r config get moduleconfigs.numeric] "moduleconfigs.numeric -1"
# Check un-prefixed and aliased configuration
assert_equal [r config get unprefix-bool] "unprefix-bool yes"
assert_equal [r config get unprefix-noalias-bool] "unprefix-noalias-bool yes"
assert_equal [r config get unprefix-bool-alias] "unprefix-bool-alias yes"
assert_equal [r config get unprefix.numeric] "unprefix.numeric -1"
assert_equal [r config get unprefix.numeric-alias] "unprefix.numeric-alias -1"
assert_equal [r config get unprefix-string] "unprefix-string {secret unprefix}"
assert_equal [r config get unprefix.string-alias] "unprefix.string-alias {secret unprefix}"
assert_equal [r config get unprefix-enum] "unprefix-enum one"
assert_equal [r config get unprefix-enum-alias] "unprefix-enum-alias one"
}
test {Config set commands work} {
# Make sure that config sets work during runtime
r config set moduleconfigs.mutable_bool no
assert_equal [r config get moduleconfigs.mutable_bool] "moduleconfigs.mutable_bool no"
r config set moduleconfigs.memory_numeric 1mb
assert_equal [r config get moduleconfigs.memory_numeric] "moduleconfigs.memory_numeric 1048576"
r config set moduleconfigs.string wafflewednesdays
assert_equal [r config get moduleconfigs.string] "moduleconfigs.string wafflewednesdays"
set not_embstr [string repeat A 50]
r config set moduleconfigs.string $not_embstr
assert_equal [r config get moduleconfigs.string] "moduleconfigs.string $not_embstr"
r config set moduleconfigs.string \x73\x75\x70\x65\x72\x20\x00\x73\x65\x63\x72\x65\x74\x20\x70\x61\x73\x73\x77\x6f\x72\x64
assert_equal [r config get moduleconfigs.string] "moduleconfigs.string {super \0secret password}"
r config set moduleconfigs.enum two
assert_equal [r config get moduleconfigs.enum] "moduleconfigs.enum two"
r config set moduleconfigs.flags two
assert_equal [r config get moduleconfigs.flags] "moduleconfigs.flags two"
r config set moduleconfigs.numeric -2
assert_equal [r config get moduleconfigs.numeric] "moduleconfigs.numeric -2"
# Check un-prefixed and aliased configuration
r config set unprefix-bool no
assert_equal [r config get unprefix-bool] "unprefix-bool no"
assert_equal [r config get unprefix-bool-alias] "unprefix-bool-alias no"
r config set unprefix-bool-alias yes
assert_equal [r config get unprefix-bool] "unprefix-bool yes"
assert_equal [r config get unprefix-bool-alias] "unprefix-bool-alias yes"
r config set unprefix.numeric 5
assert_equal [r config get unprefix.numeric] "unprefix.numeric 5"
assert_equal [r config get unprefix.numeric-alias] "unprefix.numeric-alias 5"
r config set unprefix.numeric-alias 6
assert_equal [r config get unprefix.numeric] "unprefix.numeric 6"
r config set unprefix.string-alias "blabla"
assert_equal [r config get unprefix-string] "unprefix-string blabla"
assert_equal [r config get unprefix.string-alias] "unprefix.string-alias blabla"
r config set unprefix-enum two
assert_equal [r config get unprefix-enum] "unprefix-enum two"
assert_equal [r config get unprefix-enum-alias] "unprefix-enum-alias two"
}
test {Config set commands enum flags} {
r config set moduleconfigs.flags "none"
assert_equal [r config get moduleconfigs.flags] "moduleconfigs.flags none"
r config set moduleconfigs.flags "two four"
assert_equal [r config get moduleconfigs.flags] "moduleconfigs.flags {two four}"
r config set moduleconfigs.flags "five"
assert_equal [r config get moduleconfigs.flags] "moduleconfigs.flags five"
r config set moduleconfigs.flags "one four"
assert_equal [r config get moduleconfigs.flags] "moduleconfigs.flags five"
r config set moduleconfigs.flags "one two four"
assert_equal [r config get moduleconfigs.flags] "moduleconfigs.flags {five two}"
}
test {Immutable flag works properly and rejected strings dont leak} {
# Configs flagged immutable should not allow sets
catch {[r config set moduleconfigs.immutable_bool yes]} e
assert_match {*can't set immutable config*} $e
catch {[r config set moduleconfigs.string rejectisfreed]} e
assert_match {*Cannot set string to 'rejectisfreed'*} $e
}
test {Numeric limits work properly} {
# Configs over/under the limit shouldn't be allowed, and memory configs should only take memory values
catch {[r config set moduleconfigs.memory_numeric 200gb]} e
assert_match {*argument must be between*} $e
catch {[r config set moduleconfigs.memory_numeric -5]} e
assert_match {*argument must be a memory value*} $e
catch {[r config set moduleconfigs.numeric -10]} e
assert_match {*argument must be between*} $e
}
test {Enums only able to be set to passed in values} {
# Module authors specify what values are valid for enums, check that only those values are ok on a set
catch {[r config set moduleconfigs.enum asdf]} e
assert_match {*must be one of the following*} $e
}
test {test blocking of config registration and load outside of OnLoad} {
assert_equal [r block.register.configs.outside.onload] OK
}
test {Unload removes module configs} {
r module unload moduleconfigs
assert_equal [r config get moduleconfigs.*] ""
r module load $testmodule
# these should have reverted back to their module specified values
assert_equal [r config get moduleconfigs.mutable_bool] "moduleconfigs.mutable_bool yes"
assert_equal [r config get moduleconfigs.immutable_bool] "moduleconfigs.immutable_bool no"
assert_equal [r config get moduleconfigs.memory_numeric] "moduleconfigs.memory_numeric 1024"
assert_equal [r config get moduleconfigs.string] "moduleconfigs.string {secret password}"
assert_equal [r config get moduleconfigs.enum] "moduleconfigs.enum one"
assert_equal [r config get moduleconfigs.flags] "moduleconfigs.flags {one two}"
assert_equal [r config get moduleconfigs.numeric] "moduleconfigs.numeric -1"
# Check un-prefixed and aliased configuration
assert_equal [r config get unprefix-bool] "unprefix-bool yes"
assert_equal [r config get unprefix-bool-alias] "unprefix-bool-alias yes"
assert_equal [r config get unprefix.numeric] "unprefix.numeric -1"
assert_equal [r config get unprefix.numeric-alias] "unprefix.numeric-alias -1"
assert_equal [r config get unprefix-string] "unprefix-string {secret unprefix}"
assert_equal [r config get unprefix.string-alias] "unprefix.string-alias {secret unprefix}"
assert_equal [r config get unprefix-enum] "unprefix-enum one"
assert_equal [r config get unprefix-enum-alias] "unprefix-enum-alias one"
r module unload moduleconfigs
}
test {test loadex functionality} {
r module loadex $testmodule CONFIG moduleconfigs.mutable_bool no \
CONFIG moduleconfigs.immutable_bool yes \
CONFIG moduleconfigs.memory_numeric 2mb \
CONFIG moduleconfigs.string tclortickle \
CONFIG unprefix-bool no \
CONFIG unprefix.numeric-alias 123 \
CONFIG unprefix-string abc_def \
assert_not_equal [lsearch [lmap x [r module list] {dict get $x name}] moduleconfigs] -1
assert_equal [r config get moduleconfigs.mutable_bool] "moduleconfigs.mutable_bool no"
assert_equal [r config get moduleconfigs.immutable_bool] "moduleconfigs.immutable_bool yes"
assert_equal [r config get moduleconfigs.memory_numeric] "moduleconfigs.memory_numeric 2097152"
assert_equal [r config get moduleconfigs.string] "moduleconfigs.string tclortickle"
# Configs that were not changed should still be their module specified value
assert_equal [r config get moduleconfigs.enum] "moduleconfigs.enum one"
assert_equal [r config get moduleconfigs.flags] "moduleconfigs.flags {one two}"
assert_equal [r config get moduleconfigs.numeric] "moduleconfigs.numeric -1"
# Check un-prefixed and aliased configuration
assert_equal [r config get unprefix-bool] "unprefix-bool no"
assert_equal [r config get unprefix-bool-alias] "unprefix-bool-alias no"
assert_equal [r config get unprefix.numeric] "unprefix.numeric 123"
assert_equal [r config get unprefix.numeric-alias] "unprefix.numeric-alias 123"
assert_equal [r config get unprefix-string] "unprefix-string abc_def"
assert_equal [r config get unprefix.string-alias] "unprefix.string-alias abc_def"
assert_equal [r config get unprefix-enum] "unprefix-enum one"
assert_equal [r config get unprefix-enum-alias] "unprefix-enum-alias one"
}
test {apply function works} {
catch {[r config set moduleconfigs.mutable_bool yes]} e
assert_match {*Bool configs*} $e
assert_equal [r config get moduleconfigs.mutable_bool] "moduleconfigs.mutable_bool no"
catch {[r config set moduleconfigs.memory_numeric 1000 moduleconfigs.numeric 1000]} e
assert_match {*cannot equal*} $e
assert_equal [r config get moduleconfigs.memory_numeric] "moduleconfigs.memory_numeric 2097152"
assert_equal [r config get moduleconfigs.numeric] "moduleconfigs.numeric -1"
r module unload moduleconfigs
}
test {test double config argument to loadex} {
r module loadex $testmodule CONFIG moduleconfigs.mutable_bool yes \
CONFIG moduleconfigs.mutable_bool no \
CONFIG unprefix.numeric-alias 1 \
CONFIG unprefix.numeric-alias 2 \
CONFIG unprefix-string blabla
assert_equal [r config get moduleconfigs.mutable_bool] "moduleconfigs.mutable_bool no"
# Check un-prefixed and aliased configuration
assert_equal [r config get unprefix.numeric-alias] "unprefix.numeric-alias 2"
assert_equal [r config get unprefix.numeric] "unprefix.numeric 2"
assert_equal [r config get unprefix-string] "unprefix-string blabla"
assert_equal [r config get unprefix.string-alias] "unprefix.string-alias blabla"
r module unload moduleconfigs
}
test {missing loadconfigs call} {
catch {[r module loadex $testmodule CONFIG moduleconfigs.string "cool" ARGS noload]} e
assert_match {*ERR*} $e
}
test {test loadex rejects bad configs} {
# Bad config 200gb is over the limit
catch {[r module loadex $testmodule CONFIG moduleconfigs.memory_numeric 200gb ARGS]} e
assert_match {*ERR*} $e
# We should completely remove all configs on a failed load
assert_equal [r config get moduleconfigs.*] ""
# No value for config, should error out
catch {[r module loadex $testmodule CONFIG moduleconfigs.mutable_bool CONFIG moduleconfigs.enum two ARGS]} e
assert_match {*ERR*} $e
assert_equal [r config get moduleconfigs.*] ""
# Asan will catch this if this string is not freed
catch {[r module loadex $testmodule CONFIG moduleconfigs.string rejectisfreed]}
assert_match {*ERR*} $e
assert_equal [r config get moduleconfigs.*] ""
# test we can't set random configs
catch {[r module loadex $testmodule CONFIG maxclients 333]}
assert_match {*ERR*} $e
assert_equal [r config get moduleconfigs.*] ""
assert_not_equal [r config get maxclients] "maxclients 333"
# test we can't set other module's configs
r module load $testmoduletwo
catch {[r module loadex $testmodule CONFIG configs.test no]}
assert_match {*ERR*} $e
assert_equal [r config get configs.test] "configs.test yes"
r module unload configs
# Verify config name and its alias being used together gets failed
catch {[r module loadex $testmodule CONFIG unprefix.numeric 1 CONFIG unprefix.numeric-alias 1]}
assert_match {*ERR*} $e
}
test {test config rewrite with dynamic load} {
#translates to: super \0secret password
r module loadex $testmodule CONFIG moduleconfigs.string \x73\x75\x70\x65\x72\x20\x00\x73\x65\x63\x72\x65\x74\x20\x70\x61\x73\x73\x77\x6f\x72\x64 ARGS
assert_not_equal [lsearch [lmap x [r module list] {dict get $x name}] moduleconfigs] -1
assert_equal [r config get moduleconfigs.string] "moduleconfigs.string {super \0secret password}"
r config set moduleconfigs.mutable_bool yes
r config set moduleconfigs.memory_numeric 750
r config set moduleconfigs.enum two
r config set moduleconfigs.flags "four two"
r config set unprefix-bool-alias no
r config set unprefix.numeric 456
r config set unprefix.string-alias "unprefix"
r config set unprefix-enum two
r config rewrite
restart_server 0 true false
# Ensure configs we rewrote are present and that the conf file is readable
assert_equal [r config get moduleconfigs.mutable_bool] "moduleconfigs.mutable_bool yes"
assert_equal [r config get moduleconfigs.memory_numeric] "moduleconfigs.memory_numeric 750"
assert_equal [r config get moduleconfigs.string] "moduleconfigs.string {super \0secret password}"
assert_equal [r config get moduleconfigs.enum] "moduleconfigs.enum two"
assert_equal [r config get moduleconfigs.flags] "moduleconfigs.flags {two four}"
assert_equal [r config get moduleconfigs.numeric] "moduleconfigs.numeric -1"
# Check unprefixed configuration and alias
assert_equal [r config get unprefix-bool] "unprefix-bool no"
assert_equal [r config get unprefix-bool-alias] "unprefix-bool-alias no"
assert_equal [r config get unprefix.numeric] "unprefix.numeric 456"
assert_equal [r config get unprefix.numeric-alias] "unprefix.numeric-alias 456"
assert_equal [r config get unprefix-string] "unprefix-string unprefix"
assert_equal [r config get unprefix.string-alias] "unprefix.string-alias unprefix"
assert_equal [r config get unprefix-enum] "unprefix-enum two"
assert_equal [r config get unprefix-enum-alias] "unprefix-enum-alias two"
r module unload moduleconfigs
}
test {test multiple modules with configs} {
r module load $testmodule
r module loadex $testmoduletwo CONFIG configs.test yes
assert_equal [r config get moduleconfigs.mutable_bool] "moduleconfigs.mutable_bool yes"
assert_equal [r config get moduleconfigs.immutable_bool] "moduleconfigs.immutable_bool no"
assert_equal [r config get moduleconfigs.memory_numeric] "moduleconfigs.memory_numeric 1024"
assert_equal [r config get moduleconfigs.string] "moduleconfigs.string {secret password}"
assert_equal [r config get moduleconfigs.enum] "moduleconfigs.enum one"
assert_equal [r config get moduleconfigs.numeric] "moduleconfigs.numeric -1"
assert_equal [r config get configs.test] "configs.test yes"
r config set moduleconfigs.mutable_bool no
r config set moduleconfigs.string nice
r config set moduleconfigs.enum two
r config set configs.test no
assert_equal [r config get moduleconfigs.mutable_bool] "moduleconfigs.mutable_bool no"
assert_equal [r config get moduleconfigs.string] "moduleconfigs.string nice"
assert_equal [r config get moduleconfigs.enum] "moduleconfigs.enum two"
assert_equal [r config get configs.test] "configs.test no"
r config rewrite
# test we can load from conf file with multiple different modules.
restart_server 0 true false
assert_equal [r config get moduleconfigs.mutable_bool] "moduleconfigs.mutable_bool no"
assert_equal [r config get moduleconfigs.string] "moduleconfigs.string nice"
assert_equal [r config get moduleconfigs.enum] "moduleconfigs.enum two"
assert_equal [r config get configs.test] "configs.test no"
r module unload moduleconfigs
r module unload configs
}
test {test 1.module load 2.config rewrite 3.module unload 4.config rewrite works} {
# Configs need to be removed from the old config file in this case.
r module loadex $testmodule CONFIG moduleconfigs.memory_numeric 500 ARGS
assert_not_equal [lsearch [lmap x [r module list] {dict get $x name}] moduleconfigs] -1
r config rewrite
r module unload moduleconfigs
r config rewrite
restart_server 0 true false
# Ensure configs we rewrote are no longer present
assert_equal [r config get moduleconfigs.*] ""
}
test {startup moduleconfigs} {
# No loadmodule directive
catch {exec src/redis-server --moduleconfigs.string "hello"} err
assert_match {*Module Configuration detected without loadmodule directive or no ApplyConfig call: aborting*} $err
# Bad config value
catch {exec src/redis-server --loadmodule "$testmodule" --moduleconfigs.string "rejectisfreed"} err
assert_match {*Issue during loading of configuration moduleconfigs.string : Cannot set string to 'rejectisfreed'*} $err
# missing LoadConfigs call
catch {exec src/redis-server --loadmodule "$testmodule" noload --moduleconfigs.string "hello"} err
assert_match {*Module Configurations were not set, missing LoadConfigs call. Unloading the module.*} $err
# successful
start_server [list overrides [list loadmodule "$testmodule" moduleconfigs.string "bootedup" moduleconfigs.enum two moduleconfigs.flags "two four"]] {
assert_equal [r config get moduleconfigs.string] "moduleconfigs.string bootedup"
assert_equal [r config get moduleconfigs.mutable_bool] "moduleconfigs.mutable_bool yes"
assert_equal [r config get moduleconfigs.immutable_bool] "moduleconfigs.immutable_bool no"
assert_equal [r config get moduleconfigs.enum] "moduleconfigs.enum two"
assert_equal [r config get moduleconfigs.flags] "moduleconfigs.flags {two four}"
assert_equal [r config get moduleconfigs.numeric] "moduleconfigs.numeric -1"
assert_equal [r config get moduleconfigs.memory_numeric] "moduleconfigs.memory_numeric 1024"
# Check un-prefixed and aliased configuration
assert_equal [r config get unprefix-bool] "unprefix-bool yes"
assert_equal [r config get unprefix-bool-alias] "unprefix-bool-alias yes"
assert_equal [r config get unprefix.numeric] "unprefix.numeric -1"
assert_equal [r config get unprefix.numeric-alias] "unprefix.numeric-alias -1"
assert_equal [r config get unprefix-string] "unprefix-string {secret unprefix}"
assert_equal [r config get unprefix.string-alias] "unprefix.string-alias {secret unprefix}"
assert_equal [r config get unprefix-enum] "unprefix-enum one"
assert_equal [r config get unprefix-enum-alias] "unprefix-enum-alias one"
}
}
test {loadmodule CONFIG values take precedence over module loadex ARGS values} {
# Load module with conflicting CONFIG and ARGS values
r module loadex $testmodule \
CONFIG moduleconfigs.string goo \
CONFIG moduleconfigs.memory_numeric 2mb \
ARGS override-default
# Verify CONFIG values took precedence over the values that override-default would have caused the module to set
assert_equal [r config get moduleconfigs.string] "moduleconfigs.string goo"
assert_equal [r config get moduleconfigs.memory_numeric] "moduleconfigs.memory_numeric 2097152"
r module unload moduleconfigs
}
# Test: Ensure that modified configuration values from ARGS are correctly written to the config file
test {Modified ARGS values are persisted after config rewrite when set through CONFIG commands} {
# Load module with non-default ARGS values
r module loadex $testmodule ARGS override-default
# Verify the initial values were overwritten
assert_equal [r config get moduleconfigs.memory_numeric] "moduleconfigs.memory_numeric 123"
assert_equal [r config get moduleconfigs.string] "moduleconfigs.string foo"
# Set new values to simulate user configuration changes
r config set moduleconfigs.memory_numeric 1mb
r config set moduleconfigs.string "modified_value"
# Verify that the changes took effect
assert_equal [r config get moduleconfigs.memory_numeric] "moduleconfigs.memory_numeric 1048576"
assert_equal [r config get moduleconfigs.string] "moduleconfigs.string modified_value"
# Perform a config rewrite
r config rewrite
restart_server 0 true false
assert_equal [r config get moduleconfigs.memory_numeric] "moduleconfigs.memory_numeric 1048576"
assert_equal [r config get moduleconfigs.string] "moduleconfigs.string modified_value"
r module unload moduleconfigs
}
}
|