diff options
Diffstat (limited to 'examples/redis-unstable/tests/modules/configaccess.c')
| -rw-r--r-- | examples/redis-unstable/tests/modules/configaccess.c | 353 |
1 files changed, 353 insertions, 0 deletions
diff --git a/examples/redis-unstable/tests/modules/configaccess.c b/examples/redis-unstable/tests/modules/configaccess.c new file mode 100644 index 0000000..7bc8a48 --- /dev/null +++ b/examples/redis-unstable/tests/modules/configaccess.c @@ -0,0 +1,353 @@ +#include "redismodule.h" +#include <assert.h> +#include <string.h> + +/* See moduleconfigs.c for registering module configs. We need to register some + * module configs with our module in order to test the interaction between + * module configs and the RM_Get/Set*Config APIs. */ +int configaccess_bool; + +int getBoolConfigCommand(const char *name, void *privdata) { + REDISMODULE_NOT_USED(name); + return (*(int *)privdata); +} + +int setBoolConfigCommand(const char *name, int new, void *privdata, RedisModuleString **err) { + REDISMODULE_NOT_USED(name); + REDISMODULE_NOT_USED(err); + *(int *)privdata = new; + return REDISMODULE_OK; +} + +/* Test command for RM_GetConfigType */ +int TestGetConfigType_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { + if (argc != 2) { + return RedisModule_WrongArity(ctx); + } + + size_t len; + const char *config_name = RedisModule_StringPtrLen(argv[1], &len); + + RedisModuleConfigType type; + int res = RedisModule_ConfigGetType(config_name, &type); + if (res == REDISMODULE_ERR) { + RedisModule_ReplyWithError(ctx, "ERR Config does not exist"); + return REDISMODULE_ERR; + } + + const char *type_str; + switch (type) { + case REDISMODULE_CONFIG_TYPE_BOOL: + type_str = "bool"; + break; + case REDISMODULE_CONFIG_TYPE_NUMERIC: + type_str = "numeric"; + break; + case REDISMODULE_CONFIG_TYPE_STRING: + type_str = "string"; + break; + case REDISMODULE_CONFIG_TYPE_ENUM: + type_str = "enum"; + break; + default: + assert(0); + break; + } + + RedisModule_ReplyWithSimpleString(ctx, type_str); + return REDISMODULE_OK; +} + +/* Test command for config iteration */ +int TestConfigIteration_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { + REDISMODULE_NOT_USED(argv); + + if (argc > 2) { + return RedisModule_WrongArity(ctx); + } + + const char *pattern = NULL; + if (argc == 2) { + pattern = RedisModule_StringPtrLen(argv[1], NULL); + } + + RedisModuleConfigIterator *iter = RedisModule_ConfigIteratorCreate(ctx, pattern); + if (!iter) { + RedisModule_ReplyWithError(ctx, "ERR Failed to get config iterator"); + return REDISMODULE_ERR; + } + + /* Start array reply for the configs */ + RedisModule_ReplyWithArray(ctx, REDISMODULE_POSTPONED_ARRAY_LEN); + + /* Iterate through the dictionary */ + const char *config_name = NULL; + long count = 0; + while ((config_name = RedisModule_ConfigIteratorNext(iter)) != NULL) { + RedisModuleString *value = NULL; + RedisModule_ConfigGet(ctx, config_name, &value); + + RedisModule_ReplyWithArray(ctx, 2); + RedisModule_ReplyWithStringBuffer(ctx, config_name, strlen(config_name)); + RedisModule_ReplyWithString(ctx, value); + + RedisModule_FreeString(ctx, value); + ++count; + } + RedisModule_ReplySetArrayLength(ctx, count); + + /* Free the iterator */ + RedisModule_ConfigIteratorRelease(ctx, iter); + + return REDISMODULE_OK; +} + +/* Test command for RM_GetBoolConfig */ +int TestGetBoolConfig_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { + if (argc != 2) { + return RedisModule_WrongArity(ctx); + } + + size_t len; + const char *config_name = RedisModule_StringPtrLen(argv[1], &len); + + int value; + if (RedisModule_ConfigGetBool(ctx, config_name, &value) == REDISMODULE_ERR) { + RedisModule_ReplyWithError(ctx, "ERR Failed to get bool config"); + return REDISMODULE_ERR; + } + + RedisModule_ReplyWithLongLong(ctx, value); + return REDISMODULE_OK; +} + +/* Test command for RM_GetNumericConfig */ +int TestGetNumericConfig_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { + if (argc != 2) { + return RedisModule_WrongArity(ctx); + } + + size_t len; + const char *config_name = RedisModule_StringPtrLen(argv[1], &len); + + long long value; + if (RedisModule_ConfigGetNumeric(ctx, config_name, &value) == REDISMODULE_ERR) { + RedisModule_ReplyWithError(ctx, "ERR Failed to get numeric config"); + return REDISMODULE_ERR; + } + + RedisModule_ReplyWithLongLong(ctx, value); + return REDISMODULE_OK; +} + +/* Test command for RM_GetConfig */ +int TestGetConfig_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { + if (argc != 2) { + return RedisModule_WrongArity(ctx); + } + + size_t len; + const char *config_name = RedisModule_StringPtrLen(argv[1], &len); + + RedisModuleString *value; + if (RedisModule_ConfigGet(ctx, config_name, &value) == REDISMODULE_ERR) { + RedisModule_ReplyWithError(ctx, "ERR Failed to get string config"); + return REDISMODULE_ERR; + } + + RedisModule_ReplyWithString(ctx, value); + RedisModule_FreeString(ctx,value); + return REDISMODULE_OK; +} + +/* Test command for RM_GetEnumConfig */ +int TestGetEnumConfig_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { + if (argc != 2) { + return RedisModule_WrongArity(ctx); + } + + size_t len; + const char *config_name = RedisModule_StringPtrLen(argv[1], &len); + + RedisModuleString *value; + if (RedisModule_ConfigGetEnum(ctx, config_name, &value) == REDISMODULE_ERR) { + RedisModule_ReplyWithError(ctx, "ERR Failed to get enum name config"); + return REDISMODULE_ERR; + } + + RedisModule_ReplyWithString(ctx, value); + RedisModule_Free(value); + return REDISMODULE_OK; +} + +/* Test command for RM_SetBoolConfig */ +int TestSetBoolConfig_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { + if (argc != 3) { + return RedisModule_WrongArity(ctx); + } + + size_t name_len, value_len; + const char *config_name = RedisModule_StringPtrLen(argv[1], &name_len); + const char *config_value = RedisModule_StringPtrLen(argv[2], &value_len); + + int bool_value; + if (!strcasecmp(config_value, "yes")) { + bool_value = 1; + } else if (!strcasecmp(config_value, "no")) { + bool_value = 0; + } else { + bool_value = -1; + } + + RedisModuleString *error = NULL; + int result = RedisModule_ConfigSetBool(ctx, config_name, bool_value, &error); + if (result == REDISMODULE_ERR) { + RedisModule_ReplyWithErrorFormat(ctx, "ERR Failed to set bool config %s: %s", config_name, RedisModule_StringPtrLen(error, NULL)); + RedisModule_FreeString(ctx, error); + return REDISMODULE_ERR; + } + + RedisModule_ReplyWithSimpleString(ctx, "OK"); + return REDISMODULE_OK; +} + +/* Test command for RM_SetNumericConfig */ +int TestSetNumericConfig_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { + if (argc != 3) { + return RedisModule_WrongArity(ctx); + } + + size_t name_len; + const char *config_name = RedisModule_StringPtrLen(argv[1], &name_len); + + long long value; + const char *value_str= RedisModule_StringPtrLen(argv[2], NULL); + if (value_str[0] == '-') { + if (RedisModule_StringToLongLong(argv[2], &value) != REDISMODULE_OK) { + RedisModule_ReplyWithError(ctx, "ERR Invalid numeric value"); + return REDISMODULE_ERR; + } + } else { + if (RedisModule_StringToULongLong(argv[2], (unsigned long long*)&value) != REDISMODULE_OK) { + RedisModule_ReplyWithError(ctx, "ERR Invalid numeric value"); + return REDISMODULE_ERR; + } + } + + RedisModuleString *error = NULL; + int result = RedisModule_ConfigSetNumeric(ctx, config_name, value, &error); + if (result == REDISMODULE_OK) { + RedisModule_ReplyWithSimpleString(ctx, "OK"); + } else { + RedisModule_ReplyWithErrorFormat(ctx, "ERR Failed to set numeric config %s: %s", config_name, RedisModule_StringPtrLen(error, NULL)); + RedisModule_FreeString(ctx, error); + return REDISMODULE_ERR; + } + + return REDISMODULE_OK; +} + +/* Test command for RM_SetConfig */ +int TestSetConfig_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { + if (argc != 3) { + return RedisModule_WrongArity(ctx); + } + + size_t name_len; + const char *config_name = RedisModule_StringPtrLen(argv[1], &name_len); + + RedisModuleString *error = NULL; + int result = RedisModule_ConfigSet(ctx, config_name, argv[2], &error); + if (result == REDISMODULE_OK) { + RedisModule_ReplyWithSimpleString(ctx, "OK"); + } else { + RedisModule_ReplyWithErrorFormat(ctx, "ERR Failed to set string config %s: %s", config_name, RedisModule_StringPtrLen(error, NULL)); + RedisModule_FreeString(ctx, error); + return REDISMODULE_ERR; + } + + return REDISMODULE_OK; +} + +/* Test command for RM_SetEnumConfig with name */ +int TestSetEnumConfig_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { + if (argc < 3) { + return RedisModule_WrongArity(ctx); + } + + const char *config_name = RedisModule_StringPtrLen(argv[1], NULL); + + RedisModuleString *error = NULL; + int result = RedisModule_ConfigSetEnum(ctx, config_name, argv[2], &error); + + if (result == REDISMODULE_OK) { + RedisModule_ReplyWithSimpleString(ctx, "OK"); + } else { + RedisModule_ReplyWithErrorFormat(ctx, "ERR Failed to set enum config %s: %s", config_name, RedisModule_StringPtrLen(error, NULL)); + RedisModule_FreeString(ctx, error); + return REDISMODULE_ERR; + } + + return REDISMODULE_OK; +} + +int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { + REDISMODULE_NOT_USED(argv); + REDISMODULE_NOT_USED(argc); + + if (RedisModule_Init(ctx, "configaccess", 1, REDISMODULE_APIVER_1) == REDISMODULE_ERR) + return REDISMODULE_ERR; + + if (RedisModule_CreateCommand(ctx, "configaccess.getconfigs", + TestConfigIteration_RedisCommand, "readonly", 0, 0, 0) == REDISMODULE_ERR) + return REDISMODULE_ERR; + + if (RedisModule_CreateCommand(ctx, "configaccess.getbool", + TestGetBoolConfig_RedisCommand, "readonly", 0, 0, 0) == REDISMODULE_ERR) + return REDISMODULE_ERR; + + if (RedisModule_CreateCommand(ctx, "configaccess.getnumeric", + TestGetNumericConfig_RedisCommand, "readonly", 0, 0, 0) == REDISMODULE_ERR) + return REDISMODULE_ERR; + + if (RedisModule_CreateCommand(ctx, "configaccess.get", + TestGetConfig_RedisCommand, "readonly", 0, 0, 0) == REDISMODULE_ERR) + return REDISMODULE_ERR; + + if (RedisModule_CreateCommand(ctx, "configaccess.getenum", + TestGetEnumConfig_RedisCommand, "readonly", 0, 0, 0) == REDISMODULE_ERR) + return REDISMODULE_ERR; + + if (RedisModule_CreateCommand(ctx, "configaccess.setbool", + TestSetBoolConfig_RedisCommand, "write", 0, 0, 0) == REDISMODULE_ERR) + return REDISMODULE_ERR; + + if (RedisModule_CreateCommand(ctx, "configaccess.setnumeric", + TestSetNumericConfig_RedisCommand, "write", 0, 0, 0) == REDISMODULE_ERR) + return REDISMODULE_ERR; + + if (RedisModule_CreateCommand(ctx, "configaccess.set", + TestSetConfig_RedisCommand, "write", 0, 0, 0) == REDISMODULE_ERR) + return REDISMODULE_ERR; + + if (RedisModule_CreateCommand(ctx, "configaccess.setenum", + TestSetEnumConfig_RedisCommand, "write", 0, 0, 0) == REDISMODULE_ERR) + return REDISMODULE_ERR; + + if (RedisModule_CreateCommand(ctx, "configaccess.getconfigtype", TestGetConfigType_RedisCommand, "readonly", 0, 0, 0) == REDISMODULE_ERR) + return REDISMODULE_ERR; + + if (RedisModule_RegisterBoolConfig(ctx, "bool", 1, REDISMODULE_CONFIG_DEFAULT, + getBoolConfigCommand, setBoolConfigCommand, NULL, &configaccess_bool) == REDISMODULE_ERR) { + RedisModule_Log(ctx, "warning", "Failed to register configaccess_bool"); + return REDISMODULE_ERR; + } + + RedisModule_Log(ctx, "debug", "Loading configaccess module configuration"); + if (RedisModule_LoadConfigs(ctx) == REDISMODULE_ERR) { + RedisModule_Log(ctx, "warning", "Failed to load configaccess module configuration"); + return REDISMODULE_ERR; + } + + return REDISMODULE_OK; +} |
