diff options
Diffstat (limited to 'examples/redis-unstable/tests/modules/moduleconfigs.c')
| -rw-r--r-- | examples/redis-unstable/tests/modules/moduleconfigs.c | 287 |
1 files changed, 0 insertions, 287 deletions
diff --git a/examples/redis-unstable/tests/modules/moduleconfigs.c b/examples/redis-unstable/tests/modules/moduleconfigs.c deleted file mode 100644 index 04974f7..0000000 --- a/examples/redis-unstable/tests/modules/moduleconfigs.c +++ /dev/null | |||
| @@ -1,287 +0,0 @@ | |||
| 1 | #include "redismodule.h" | ||
| 2 | #include <strings.h> | ||
| 3 | int mutable_bool_val, no_prefix_bool, no_prefix_bool2; | ||
| 4 | int immutable_bool_val; | ||
| 5 | long long longval, no_prefix_longval; | ||
| 6 | long long memval, no_prefix_memval; | ||
| 7 | RedisModuleString *strval = NULL; | ||
| 8 | RedisModuleString *strval2 = NULL; | ||
| 9 | int enumval, no_prefix_enumval; | ||
| 10 | int flagsval; | ||
| 11 | |||
| 12 | /* Series of get and set callbacks for each type of config, these rely on the privdata ptr | ||
| 13 | * to point to the config, and they register the configs as such. Note that one could also just | ||
| 14 | * use names if they wanted, and store anything in privdata. */ | ||
| 15 | int getBoolConfigCommand(const char *name, void *privdata) { | ||
| 16 | REDISMODULE_NOT_USED(name); | ||
| 17 | return (*(int *)privdata); | ||
| 18 | } | ||
| 19 | |||
| 20 | int setBoolConfigCommand(const char *name, int new, void *privdata, RedisModuleString **err) { | ||
| 21 | REDISMODULE_NOT_USED(name); | ||
| 22 | REDISMODULE_NOT_USED(err); | ||
| 23 | *(int *)privdata = new; | ||
| 24 | return REDISMODULE_OK; | ||
| 25 | } | ||
| 26 | |||
| 27 | long long getNumericConfigCommand(const char *name, void *privdata) { | ||
| 28 | REDISMODULE_NOT_USED(name); | ||
| 29 | return (*(long long *) privdata); | ||
| 30 | } | ||
| 31 | |||
| 32 | int setNumericConfigCommand(const char *name, long long new, void *privdata, RedisModuleString **err) { | ||
| 33 | REDISMODULE_NOT_USED(name); | ||
| 34 | REDISMODULE_NOT_USED(err); | ||
| 35 | *(long long *)privdata = new; | ||
| 36 | return REDISMODULE_OK; | ||
| 37 | } | ||
| 38 | |||
| 39 | RedisModuleString *getStringConfigCommand(const char *name, void *privdata) { | ||
| 40 | REDISMODULE_NOT_USED(name); | ||
| 41 | REDISMODULE_NOT_USED(privdata); | ||
| 42 | return strval; | ||
| 43 | } | ||
| 44 | int setStringConfigCommand(const char *name, RedisModuleString *new, void *privdata, RedisModuleString **err) { | ||
| 45 | REDISMODULE_NOT_USED(name); | ||
| 46 | REDISMODULE_NOT_USED(err); | ||
| 47 | REDISMODULE_NOT_USED(privdata); | ||
| 48 | size_t len; | ||
| 49 | if (!strcasecmp(RedisModule_StringPtrLen(new, &len), "rejectisfreed")) { | ||
| 50 | *err = RedisModule_CreateString(NULL, "Cannot set string to 'rejectisfreed'", 36); | ||
| 51 | return REDISMODULE_ERR; | ||
| 52 | } | ||
| 53 | if (strval) RedisModule_FreeString(NULL, strval); | ||
| 54 | RedisModule_RetainString(NULL, new); | ||
| 55 | strval = new; | ||
| 56 | return REDISMODULE_OK; | ||
| 57 | } | ||
| 58 | |||
| 59 | int getEnumConfigCommand(const char *name, void *privdata) { | ||
| 60 | REDISMODULE_NOT_USED(name); | ||
| 61 | REDISMODULE_NOT_USED(privdata); | ||
| 62 | return enumval; | ||
| 63 | } | ||
| 64 | |||
| 65 | int setEnumConfigCommand(const char *name, int val, void *privdata, RedisModuleString **err) { | ||
| 66 | REDISMODULE_NOT_USED(name); | ||
| 67 | REDISMODULE_NOT_USED(err); | ||
| 68 | REDISMODULE_NOT_USED(privdata); | ||
| 69 | enumval = val; | ||
| 70 | return REDISMODULE_OK; | ||
| 71 | } | ||
| 72 | |||
| 73 | int getFlagsConfigCommand(const char *name, void *privdata) { | ||
| 74 | REDISMODULE_NOT_USED(name); | ||
| 75 | REDISMODULE_NOT_USED(privdata); | ||
| 76 | return flagsval; | ||
| 77 | } | ||
| 78 | |||
| 79 | int setFlagsConfigCommand(const char *name, int val, void *privdata, RedisModuleString **err) { | ||
| 80 | REDISMODULE_NOT_USED(name); | ||
| 81 | REDISMODULE_NOT_USED(err); | ||
| 82 | REDISMODULE_NOT_USED(privdata); | ||
| 83 | flagsval = val; | ||
| 84 | return REDISMODULE_OK; | ||
| 85 | } | ||
| 86 | |||
| 87 | int boolApplyFunc(RedisModuleCtx *ctx, void *privdata, RedisModuleString **err) { | ||
| 88 | REDISMODULE_NOT_USED(ctx); | ||
| 89 | REDISMODULE_NOT_USED(privdata); | ||
| 90 | if (mutable_bool_val && immutable_bool_val) { | ||
| 91 | *err = RedisModule_CreateString(NULL, "Bool configs cannot both be yes.", 32); | ||
| 92 | return REDISMODULE_ERR; | ||
| 93 | } | ||
| 94 | return REDISMODULE_OK; | ||
| 95 | } | ||
| 96 | |||
| 97 | int longlongApplyFunc(RedisModuleCtx *ctx, void *privdata, RedisModuleString **err) { | ||
| 98 | REDISMODULE_NOT_USED(ctx); | ||
| 99 | REDISMODULE_NOT_USED(privdata); | ||
| 100 | if (longval == memval) { | ||
| 101 | *err = RedisModule_CreateString(NULL, "These configs cannot equal each other.", 38); | ||
| 102 | return REDISMODULE_ERR; | ||
| 103 | } | ||
| 104 | return REDISMODULE_OK; | ||
| 105 | } | ||
| 106 | |||
| 107 | RedisModuleString *getStringConfigUnprefix(const char *name, void *privdata) { | ||
| 108 | REDISMODULE_NOT_USED(name); | ||
| 109 | REDISMODULE_NOT_USED(privdata); | ||
| 110 | return strval2; | ||
| 111 | } | ||
| 112 | |||
| 113 | int setStringConfigUnprefix(const char *name, RedisModuleString *new, void *privdata, RedisModuleString **err) { | ||
| 114 | REDISMODULE_NOT_USED(name); | ||
| 115 | REDISMODULE_NOT_USED(err); | ||
| 116 | REDISMODULE_NOT_USED(privdata); | ||
| 117 | if (strval2) RedisModule_FreeString(NULL, strval2); | ||
| 118 | RedisModule_RetainString(NULL, new); | ||
| 119 | strval2 = new; | ||
| 120 | return REDISMODULE_OK; | ||
| 121 | } | ||
| 122 | |||
| 123 | int getEnumConfigUnprefix(const char *name, void *privdata) { | ||
| 124 | REDISMODULE_NOT_USED(name); | ||
| 125 | REDISMODULE_NOT_USED(privdata); | ||
| 126 | return no_prefix_enumval; | ||
| 127 | } | ||
| 128 | |||
| 129 | int setEnumConfigUnprefix(const char *name, int val, void *privdata, RedisModuleString **err) { | ||
| 130 | REDISMODULE_NOT_USED(name); | ||
| 131 | REDISMODULE_NOT_USED(err); | ||
| 132 | REDISMODULE_NOT_USED(privdata); | ||
| 133 | no_prefix_enumval = val; | ||
| 134 | return REDISMODULE_OK; | ||
| 135 | } | ||
| 136 | |||
| 137 | int registerBlockCheck(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { | ||
| 138 | REDISMODULE_NOT_USED(argv); | ||
| 139 | REDISMODULE_NOT_USED(argc); | ||
| 140 | int response_ok = 0; | ||
| 141 | int result = RedisModule_RegisterBoolConfig(ctx, "mutable_bool", 1, REDISMODULE_CONFIG_DEFAULT, getBoolConfigCommand, setBoolConfigCommand, boolApplyFunc, &mutable_bool_val); | ||
| 142 | response_ok |= (result == REDISMODULE_OK); | ||
| 143 | |||
| 144 | result = RedisModule_RegisterStringConfig(ctx, "string", "secret password", REDISMODULE_CONFIG_DEFAULT, getStringConfigCommand, setStringConfigCommand, NULL, NULL); | ||
| 145 | response_ok |= (result == REDISMODULE_OK); | ||
| 146 | |||
| 147 | const char *enum_vals[] = {"none", "five", "one", "two", "four"}; | ||
| 148 | const int int_vals[] = {0, 5, 1, 2, 4}; | ||
| 149 | result = RedisModule_RegisterEnumConfig(ctx, "enum", 1, REDISMODULE_CONFIG_DEFAULT, enum_vals, int_vals, 5, getEnumConfigCommand, setEnumConfigCommand, NULL, NULL); | ||
| 150 | response_ok |= (result == REDISMODULE_OK); | ||
| 151 | |||
| 152 | result = RedisModule_RegisterNumericConfig(ctx, "numeric", -1, REDISMODULE_CONFIG_DEFAULT, -5, 2000, getNumericConfigCommand, setNumericConfigCommand, longlongApplyFunc, &longval); | ||
| 153 | response_ok |= (result == REDISMODULE_OK); | ||
| 154 | |||
| 155 | result = RedisModule_LoadConfigs(ctx); | ||
| 156 | response_ok |= (result == REDISMODULE_OK); | ||
| 157 | |||
| 158 | /* This validates that it's not possible to register/load configs outside OnLoad, | ||
| 159 | * thus returns an error if they succeed. */ | ||
| 160 | if (response_ok) { | ||
| 161 | RedisModule_ReplyWithError(ctx, "UNEXPECTEDOK"); | ||
| 162 | } else { | ||
| 163 | RedisModule_ReplyWithSimpleString(ctx, "OK"); | ||
| 164 | } | ||
| 165 | return REDISMODULE_OK; | ||
| 166 | } | ||
| 167 | |||
| 168 | void cleanup(RedisModuleCtx *ctx) { | ||
| 169 | if (strval) { | ||
| 170 | RedisModule_FreeString(ctx, strval); | ||
| 171 | strval = NULL; | ||
| 172 | } | ||
| 173 | if (strval2) { | ||
| 174 | RedisModule_FreeString(ctx, strval2); | ||
| 175 | strval2 = NULL; | ||
| 176 | } | ||
| 177 | } | ||
| 178 | |||
| 179 | int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { | ||
| 180 | REDISMODULE_NOT_USED(argv); | ||
| 181 | REDISMODULE_NOT_USED(argc); | ||
| 182 | |||
| 183 | if (RedisModule_Init(ctx, "moduleconfigs", 1, REDISMODULE_APIVER_1) == REDISMODULE_ERR) { | ||
| 184 | RedisModule_Log(ctx, "warning", "Failed to init module"); | ||
| 185 | return REDISMODULE_ERR; | ||
| 186 | } | ||
| 187 | |||
| 188 | if (RedisModule_RegisterBoolConfig(ctx, "mutable_bool", 1, REDISMODULE_CONFIG_DEFAULT, getBoolConfigCommand, setBoolConfigCommand, boolApplyFunc, &mutable_bool_val) == REDISMODULE_ERR) { | ||
| 189 | RedisModule_Log(ctx, "warning", "Failed to register mutable_bool"); | ||
| 190 | return REDISMODULE_ERR; | ||
| 191 | } | ||
| 192 | /* Immutable config here. */ | ||
| 193 | if (RedisModule_RegisterBoolConfig(ctx, "immutable_bool", 0, REDISMODULE_CONFIG_IMMUTABLE, getBoolConfigCommand, setBoolConfigCommand, boolApplyFunc, &immutable_bool_val) == REDISMODULE_ERR) { | ||
| 194 | RedisModule_Log(ctx, "warning", "Failed to register immutable_bool"); | ||
| 195 | return REDISMODULE_ERR; | ||
| 196 | } | ||
| 197 | if (RedisModule_RegisterStringConfig(ctx, "string", "secret password", REDISMODULE_CONFIG_DEFAULT, getStringConfigCommand, setStringConfigCommand, NULL, NULL) == REDISMODULE_ERR) { | ||
| 198 | RedisModule_Log(ctx, "warning", "Failed to register string"); | ||
| 199 | return REDISMODULE_ERR; | ||
| 200 | } | ||
| 201 | |||
| 202 | /* On the stack to make sure we're copying them. */ | ||
| 203 | const char *enum_vals[] = {"none", "five", "one", "two", "four"}; | ||
| 204 | const int int_vals[] = {0, 5, 1, 2, 4}; | ||
| 205 | |||
| 206 | if (RedisModule_RegisterEnumConfig(ctx, "enum", 1, REDISMODULE_CONFIG_DEFAULT, enum_vals, int_vals, 5, getEnumConfigCommand, setEnumConfigCommand, NULL, NULL) == REDISMODULE_ERR) { | ||
| 207 | RedisModule_Log(ctx, "warning", "Failed to register enum"); | ||
| 208 | return REDISMODULE_ERR; | ||
| 209 | } | ||
| 210 | if (RedisModule_RegisterEnumConfig(ctx, "flags", 3, REDISMODULE_CONFIG_DEFAULT | REDISMODULE_CONFIG_BITFLAGS, enum_vals, int_vals, 5, getFlagsConfigCommand, setFlagsConfigCommand, NULL, NULL) == REDISMODULE_ERR) { | ||
| 211 | RedisModule_Log(ctx, "warning", "Failed to register flags"); | ||
| 212 | return REDISMODULE_ERR; | ||
| 213 | } | ||
| 214 | /* Memory config here. */ | ||
| 215 | if (RedisModule_RegisterNumericConfig(ctx, "memory_numeric", 1024, REDISMODULE_CONFIG_DEFAULT | REDISMODULE_CONFIG_MEMORY, 0, 3000000, getNumericConfigCommand, setNumericConfigCommand, longlongApplyFunc, &memval) == REDISMODULE_ERR) { | ||
| 216 | RedisModule_Log(ctx, "warning", "Failed to register memory_numeric"); | ||
| 217 | return REDISMODULE_ERR; | ||
| 218 | } | ||
| 219 | if (RedisModule_RegisterNumericConfig(ctx, "numeric", -1, REDISMODULE_CONFIG_DEFAULT, -5, 2000, getNumericConfigCommand, setNumericConfigCommand, longlongApplyFunc, &longval) == REDISMODULE_ERR) { | ||
| 220 | RedisModule_Log(ctx, "warning", "Failed to register numeric"); | ||
| 221 | return REDISMODULE_ERR; | ||
| 222 | } | ||
| 223 | |||
| 224 | /*** unprefixed and aliased configuration ***/ | ||
| 225 | if (RedisModule_RegisterBoolConfig(ctx, "unprefix-bool|unprefix-bool-alias", 1, REDISMODULE_CONFIG_DEFAULT|REDISMODULE_CONFIG_UNPREFIXED, | ||
| 226 | getBoolConfigCommand, setBoolConfigCommand, NULL, &no_prefix_bool) == REDISMODULE_ERR) { | ||
| 227 | RedisModule_Log(ctx, "warning", "Failed to register unprefix-bool"); | ||
| 228 | return REDISMODULE_ERR; | ||
| 229 | } | ||
| 230 | if (RedisModule_RegisterBoolConfig(ctx, "unprefix-noalias-bool", 1, REDISMODULE_CONFIG_DEFAULT|REDISMODULE_CONFIG_UNPREFIXED, | ||
| 231 | getBoolConfigCommand, setBoolConfigCommand, NULL, &no_prefix_bool2) == REDISMODULE_ERR) { | ||
| 232 | RedisModule_Log(ctx, "warning", "Failed to register unprefix-noalias-bool"); | ||
| 233 | return REDISMODULE_ERR; | ||
| 234 | } | ||
| 235 | if (RedisModule_RegisterNumericConfig(ctx, "unprefix.numeric|unprefix.numeric-alias", -1, REDISMODULE_CONFIG_DEFAULT|REDISMODULE_CONFIG_UNPREFIXED, | ||
| 236 | -5, 2000, getNumericConfigCommand, setNumericConfigCommand, NULL, &no_prefix_longval) == REDISMODULE_ERR) { | ||
| 237 | RedisModule_Log(ctx, "warning", "Failed to register unprefix.numeric"); | ||
| 238 | return REDISMODULE_ERR; | ||
| 239 | } | ||
| 240 | if (RedisModule_RegisterStringConfig(ctx, "unprefix-string|unprefix.string-alias", "secret unprefix", REDISMODULE_CONFIG_DEFAULT|REDISMODULE_CONFIG_UNPREFIXED, | ||
| 241 | getStringConfigUnprefix, setStringConfigUnprefix, NULL, NULL) == REDISMODULE_ERR) { | ||
| 242 | RedisModule_Log(ctx, "warning", "Failed to register unprefix-string"); | ||
| 243 | return REDISMODULE_ERR; | ||
| 244 | } | ||
| 245 | if (RedisModule_RegisterEnumConfig(ctx, "unprefix-enum|unprefix-enum-alias", 1, REDISMODULE_CONFIG_DEFAULT|REDISMODULE_CONFIG_UNPREFIXED, | ||
| 246 | enum_vals, int_vals, 5, getEnumConfigUnprefix, setEnumConfigUnprefix, NULL, NULL) == REDISMODULE_ERR) { | ||
| 247 | RedisModule_Log(ctx, "warning", "Failed to register unprefix-enum"); | ||
| 248 | return REDISMODULE_ERR; | ||
| 249 | } | ||
| 250 | |||
| 251 | RedisModule_Log(ctx, "debug", "Registered configuration"); | ||
| 252 | size_t len; | ||
| 253 | if (argc && !strcasecmp(RedisModule_StringPtrLen(argv[0], &len), "noload")) { | ||
| 254 | return REDISMODULE_OK; | ||
| 255 | } else if (argc && !strcasecmp(RedisModule_StringPtrLen(argv[0], &len), "override-default")) { | ||
| 256 | if (RedisModule_LoadDefaultConfigs(ctx) == REDISMODULE_ERR) { | ||
| 257 | RedisModule_Log(ctx, "warning", "Failed to load default configuration"); | ||
| 258 | goto err; | ||
| 259 | } | ||
| 260 | // simulate configuration values being overwritten by the command line | ||
| 261 | RedisModule_Log(ctx, "debug", "Overriding configuration values"); | ||
| 262 | if (strval) RedisModule_FreeString(ctx, strval); | ||
| 263 | strval = RedisModule_CreateString(ctx, "foo", 3); | ||
| 264 | longval = memval = 123; | ||
| 265 | } | ||
| 266 | RedisModule_Log(ctx, "debug", "Loading configuration"); | ||
| 267 | if (RedisModule_LoadConfigs(ctx) == REDISMODULE_ERR) { | ||
| 268 | RedisModule_Log(ctx, "warning", "Failed to load configuration"); | ||
| 269 | goto err; | ||
| 270 | } | ||
| 271 | /* Creates a command which registers configs outside OnLoad() function. */ | ||
| 272 | if (RedisModule_CreateCommand(ctx,"block.register.configs.outside.onload", registerBlockCheck, "write", 0, 0, 0) == REDISMODULE_ERR) { | ||
| 273 | RedisModule_Log(ctx, "warning", "Failed to register command"); | ||
| 274 | goto err; | ||
| 275 | } | ||
| 276 | |||
| 277 | return REDISMODULE_OK; | ||
| 278 | err: | ||
| 279 | cleanup(ctx); | ||
| 280 | return REDISMODULE_ERR; | ||
| 281 | } | ||
| 282 | |||
| 283 | int RedisModule_OnUnload(RedisModuleCtx *ctx) { | ||
| 284 | REDISMODULE_NOT_USED(ctx); | ||
| 285 | cleanup(ctx); | ||
| 286 | return REDISMODULE_OK; | ||
| 287 | } | ||
