From d3266d516baf7027d9eb6323bec130ea396fb291 Mon Sep 17 00:00:00 2001
From: antirez <antirez@gmail.com>
Date: Wed, 23 Oct 2019 18:38:30 +0200
Subject: [PATCH] Modules hooks: test module draft.

---
 tests/modules/Makefile |  6 +++-
 tests/modules/hooks.c  | 77 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 82 insertions(+), 1 deletion(-)
 create mode 100644 tests/modules/hooks.c

diff --git a/tests/modules/Makefile b/tests/modules/Makefile
index c1c8ffa2e..988ecf58a 100644
--- a/tests/modules/Makefile
+++ b/tests/modules/Makefile
@@ -13,7 +13,7 @@ endif
 
 .SUFFIXES: .c .so .xo .o
 
-all: commandfilter.so testrdb.so fork.so infotest.so propagate.so
+all: commandfilter.so testrdb.so fork.so infotest.so propagate.so hooks.so
 
 .c.xo:
 	$(CC) -I../../src $(CFLAGS) $(SHOBJ_CFLAGS) -fPIC -c $< -o $@
@@ -23,6 +23,7 @@ fork.xo: ../../src/redismodule.h
 testrdb.xo: ../../src/redismodule.h
 infotest.xo: ../../src/redismodule.h
 propagate.xo: ../../src/redismodule.h
+hooks.xo: ../../src/redismodule.h
 
 commandfilter.so: commandfilter.xo
 	$(LD) -o $@ $< $(SHOBJ_LDFLAGS) $(LIBS) -lc
@@ -38,3 +39,6 @@ infotest.so: infotest.xo
 
 propagate.so: propagate.xo
 	$(LD) -o $@ $< $(SHOBJ_LDFLAGS) $(LIBS) -lc
+
+hooks.so: hooks.xo
+	$(LD) -o $@ $< $(SHOBJ_LDFLAGS) $(LIBS) -lc
diff --git a/tests/modules/hooks.c b/tests/modules/hooks.c
new file mode 100644
index 000000000..f23f8a2a4
--- /dev/null
+++ b/tests/modules/hooks.c
@@ -0,0 +1,77 @@
+/* This module is used to test the server events hooks API.
+ *
+ * -----------------------------------------------------------------------------
+ *
+ * Copyright (c) 2019, Salvatore Sanfilippo <antirez at gmail dot com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   * Redistributions of source code must retain the above copyright notice,
+ *     this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *   * Neither the name of Redis nor the names of its contributors may be used
+ *     to endorse or promote products derived from this software without
+ *     specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define REDISMODULE_EXPERIMENTAL_API
+#include "redismodule.h"
+
+/* Client state change callback. */
+void clientChangeCallback(RedisModuleCtx *ctx, RedisModuleEvent e, uint64_t sub, void *data)
+{
+    REDISMODULE_NOT_USED(ctx);
+    REDISMODULE_NOT_USED(e);
+
+    RedisModuleClientInfo *ci = data;
+    char *keyname = (sub == REDISMODULE_SUBEVENT_CLIENT_CHANGE_CONNECTED) ?
+        "connected" : "disconnected";
+    RedisModuleCallReply *reply;
+    reply = RedisModule_Call(ctx,"RPUSH","cl",keyname,(long)ci->id);
+    RedisModule_FreeCallReply(reply);
+}
+
+void flushdbCallback(RedisModuleCtx *ctx, RedisModuleEvent e, uint64_t sub, void *data)
+{
+    REDISMODULE_NOT_USED(ctx);
+    REDISMODULE_NOT_USED(e);
+
+    RedisModuleFlushInfo *fi = data;
+    char *keyname = (sub == REDISMODULE_SUBEVENT_FLUSHDB_START) ?
+        "flush-start" : "flush-end";
+    RedisModuleCallReply *reply;
+    reply = RedisModule_Call(ctx,"RPUSH","cl",keyname,(long)fi->dbnum);
+    RedisModule_FreeCallReply(reply);
+}
+
+/* This function must be present on each Redis module. It is used in order to
+ * register the commands into the Redis server. */
+int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
+    REDISMODULE_NOT_USED(argv);
+    REDISMODULE_NOT_USED(argc);
+
+    if (RedisModule_Init(ctx,"testhook",1,REDISMODULE_APIVER_1)
+        == REDISMODULE_ERR) return REDISMODULE_ERR;
+
+    RedisModule_SubscribeToServerEvent(ctx,
+        RedisModuleEvent_ClientChange, clientChangeCallback);
+    RedisModule_SubscribeToServerEvent(ctx,
+        RedisModuleEvent_FlushDB, flushdbCallback);
+    return REDISMODULE_OK;
+}