diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d927559..628a139 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,96 +8,94 @@ on: jobs: build: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v3 - with: - submodules: 'recursive' + strategy: + matrix: + os: + - "ubuntu-latest" + - "macos-latest" + version: + - "5.0" + - "6.0" + - "6.2" + - "7.0" + - "7.2" + - "7.4" + - "unstable" + compiler: + - "gcc" + - "clang" - - name: Install Prerequisites and clone Redis - run: | - sudo apt-get update - sudo apt-get install -y cmake libssl-dev valgrind git - git clone https://git.cryptomilk.org/projects/cmocka.git - cd cmocka - mkdir build - cd build - cmake .. -DCMAKE_INSTALL_PREFIX=/usr/local - make - ctest - sudo make install - git clone https://github.com/redis/redis.git ~/redis + exclude: + - os: macos-latest + compiler: gcc + - os: macos-latest + version: "5.0" + - os: macos-latest + version: "6.0" + - os: macos-latest + version: "7.0" - shell: bash + runs-on: ${{ matrix.os }} - - name: Test librdb vs. redis-5.0 - run: | - pushd ~/redis - git checkout 5.0 - make distclean - make -j 4 -C ~/redis - popd - export LIBRDB_REDIS_FOLDER=~/redis/src - make test - working-directory: ${{github.workspace}} + env: + DEBIAN_FRONTEND: noninteractive + CC: ${{ matrix.compiler }} - - name: Test librdb vs. redis-unstable - run: | - pushd ~/redis - git checkout unstable - make -j 4 -C ~/redis - make -C ~/redis/tests/modules - popd - export LIBRDB_REDIS_FOLDER=~/redis/src - make all example valgrind - working-directory: ${{github.workspace}} + # TODO: would be nice to connect to a redis server instead of building from source + # services: + # redis: + # image: redis:${{ matrix.version }} + # options: >- + # --health-cmd "redis-cli ping" + # --health-interval 10s + # --health-timeout 5s + # --health-retries 5 - build-clang: - runs-on: ubuntu-latest - env: - CC: clang steps: - - name: Checkout - uses: actions/checkout@v3 + - name: Checkout librdb + uses: actions/checkout@v4 + with: + submodules: "recursive" + + - name: Clone Redis (${{ matrix.version }}) + uses: actions/checkout@v4 with: - submodules: 'recursive' + repository: redis/redis + ref: ${{ matrix.version }} + path: redis - - name: Install Prerequisites and clone Redis + - name: Install prerequisites run: | - sudo apt-get update - sudo apt-get install -y cmake libssl-dev git clang - git clone https://git.cryptomilk.org/projects/cmocka.git - cd cmocka - mkdir build - cd build - cmake .. -DCMAKE_INSTALL_PREFIX=/usr/local - make - sudo make install - - git clone https://github.com/redis/redis.git ~/redis - shell: bash + if [ "${RUNNER_OS}" = "Linux" ]; then + sudo apt-get update + sudo apt-get install -y cmake clang libssl-dev valgrind git bc + + # Build and install cmocka + git clone https://git.cryptomilk.org/projects/cmocka.git + cd cmocka + mkdir build + cd build + cmake .. -DCMAKE_INSTALL_PREFIX=/usr/local + make + sudo make install + elif [ "${RUNNER_OS}" = "macOS" ]; then + brew install cmocka bc llvm grep + echo "PATH=$(brew --prefix)/opt/grep/libexec/gnubin:${PATH}" >> "${GITHUB_ENV}" + fi - - name: Test librdb vs. redis-6.0 + - name: Build Redis ${{ matrix.version }} run: | - pushd ~/redis - git checkout 6.0 - make distclean - make -j 4 -C ~/redis - popd - export LIBRDB_REDIS_FOLDER=~/redis/src - make test - working-directory: ${{github.workspace}} + make -j -C redis - - name: Test librdb vs. redis-6.2 + if [ $(bc -l <<< "${{ matrix.version }} >= 6.2") -eq 1 ] || [ "${{ matrix.version }}" = "unstable" ]; then + make -j -C redis/tests/modules + fi + + - name: Run tests with shared lib run: | - # clang is more strict to shared-obj versioning. Satisfy its needs. - pushd ~/redis - git checkout 6.2 - make -j 4 -C ~/redis - make -C ~/redis/tests/modules - popd - export LIBRDB_REDIS_FOLDER=~/redis/src - make clean debug test - working-directory: ${{github.workspace}} + LIBRDB_REDIS_FOLDER="$(pwd)/redis/src" make clean debug test + - name: Run tests with static lib and valgrind + if: runner.os == 'Linux' + run: | + LIBRDB_REDIS_FOLDER="$(pwd)/redis/src" make clean all valgrind diff --git a/Makefile b/Makefile index 8585174..64f0b2b 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,13 @@ -PREFIX?=/usr/local +PREFIX? = /usr/local DESTDIR?= INSTALL = /usr/bin/install -c -BINDIR=$(DESTDIR)$(PREFIX)/bin -LIBDIR=$(DESTDIR)$(PREFIX)/lib -INCDIR=$(DESTDIR)$(PREFIX)/include/librdb/ -LIBRDB_INSTALL_SHARED:=yes -LIBRDB_INSTALL_STATIC:=yes +BINDIR = $(DESTDIR)$(PREFIX)/bin +LIBDIR = $(DESTDIR)$(PREFIX)/lib +INCDIR = $(DESTDIR)$(PREFIX)/include/librdb/ +LIBRDB_INSTALL_SHARED := yes +LIBRDB_INSTALL_STATIC := yes UNAME := $(shell uname) @@ -23,19 +23,19 @@ export LIBRDB_VERSION # ------------------------- ALL -------------------------------------- all: ./deps/hiredis/hiredis.h - $(MAKE) -C deps all - $(MAKE) -C src/lib all - $(MAKE) -C src/ext all - $(MAKE) -C src/cli all - $(MAKE) -C examples all + $(MAKE) -C deps all + $(MAKE) -C src/lib all + $(MAKE) -C src/ext all + $(MAKE) -C src/cli all + $(MAKE) -C examples all clean: - $(MAKE) -C deps clean - $(MAKE) -C src/lib clean - $(MAKE) -C src/ext clean - $(MAKE) -C src/cli clean - $(MAKE) -C examples clean - $(MAKE) -C test clean + $(MAKE) -C deps clean + $(MAKE) -C src/lib clean + $(MAKE) -C src/ext clean + $(MAKE) -C src/cli clean + $(MAKE) -C examples clean + $(MAKE) -C test clean rm -f librdb.pc rm -f librdb-ext.pc diff --git a/deps/redis/listpack_malloc.h b/deps/redis/listpack_malloc.h index c8f96e2..4a76ccd 100644 --- a/deps/redis/listpack_malloc.h +++ b/deps/redis/listpack_malloc.h @@ -38,13 +38,21 @@ #ifndef LISTPACK_ALLOC_H #define LISTPACK_ALLOC_H -//#include "zmalloc.h" + +#ifdef __APPLE__ +#include +#else #include "malloc.h" -/* We use zmalloc_usable/zrealloc_usable instead of zmalloc/zrealloc - * to ensure the safe invocation of 'zmalloc_usable_size(). - * See comment in zmalloc_usable_size(). */ +#endif + #define lp_malloc(sz) malloc(sz) #define lp_realloc(ptr,sz) realloc(ptr,sz) #define lp_free free + +#ifdef __APPLE__ +#define lp_malloc_size malloc_size +#else #define lp_malloc_size malloc_usable_size #endif + +#endif diff --git a/src/cli/Makefile b/src/cli/Makefile index 72add76..f26780c 100644 --- a/src/cli/Makefile +++ b/src/cli/Makefile @@ -1,29 +1,30 @@ default: all LIB_DIR = ../../lib -LIB_NAME = librdb.a -LIB_NAME_EXT = librdb-ext.a +LIB_NAME = rdb +LIB_NAME_EXT = $(LIB_NAME)-ext # Artifacts: -TARGET_APP = rdb-cli +TARGET_APP = rdb-cli +TARGET_LIB_STATIC_EXT = $(LIB_DIR)/lib$(LIB_NAME_EXT).a ######################################################################################### SOURCES = $(notdir $(basename $(wildcard *.c))) OBJECTS = $(patsubst %,%.o,$(SOURCES)) TARGETS = $(basename $(SOURCES)) -OPTIMIZATION?=-O3 +OPTIMIZATION ?= -O3 STD = -std=c99 STACK = -fstack-protector-all -Wstack-protector WARNS = -Wall -Wextra -pedantic -Werror CFLAGS = -fPIC $(OPTIMIZATION) $(STD) $(STACK) $(WARNS) DEBUG = -g3 -DDEBUG=1 -LIBS = -L /usr/lib -L $(LIB_DIR) -l:$(LIB_NAME_EXT) -l:$(LIB_NAME) +LIBS = -L /usr/lib -L $(LIB_DIR) -l $(LIB_NAME_EXT) -l $(LIB_NAME) ifeq ($(BUILD_TLS),yes) -CFLAGS+=-DUSE_OPENSSL=1 -LIBS+=-lssl -lcrypto + CFLAGS += -DUSE_OPENSSL=1 + LIBS += -lssl -lcrypto endif ######################################### RULES ####################################### @@ -32,10 +33,10 @@ all: $(TARGET_APP) cp $(TARGET_APP) ../../bin/ @echo "Done."; -$(TARGET_APP): %: %.c lib_dependency +$(TARGET_APP): %: %.c lib_dependency $(CC) $(CFLAGS) -o $@ $< $(DEBUG) $(LIBS) -lib_dependency: $(LIB_DIR)/$(LIB_NAME_EXT) +lib_dependency: $(LIB_DIR)/lib$(LIB_NAME_EXT).a clean: @rm -rvf $(TARGETS) ./*.o ../../bin/$(TARGET_APP) diff --git a/src/ext/Makefile b/src/ext/Makefile index fc88679..6c8277f 100644 --- a/src/ext/Makefile +++ b/src/ext/Makefile @@ -1,11 +1,10 @@ default: all +LIB_DIR = ../../lib LIB_NAME = rdb LIB_NAME_EXT = $(LIB_NAME)-ext -LIB_DIR = ../../lib LIBRDB_SONAME_EXT = lib$(LIB_NAME_EXT).so.${LIBRDB_VERSION} -TARGET_LIB_STATIC = $(LIB_DIR)/lib$(LIB_NAME).a # Artifacts: TARGET_LIB_EXT = $(LIB_DIR)/$(LIBRDB_SONAME_EXT) TARGET_LIB_STATIC_EXT = $(LIB_DIR)/lib$(LIB_NAME_EXT).a @@ -20,8 +19,8 @@ OBJECTS = $(patsubst %,%.o,$(SOURCES)) REDIS_SOURCES = $(notdir $(basename $(wildcard ../../deps/redis/*.c))) REDIS_OBJECTS = $(patsubst %,../../deps/redis/%.o,$(REDIS_SOURCES)) -OPTIMIZATION?=-O3 -LIBRDB_DEBUG?=0 +OPTIMIZATION? = -O3 +LIBRDB_DEBUG? = 0 STD = -std=c99 STACK = -fstack-protector-all -Wstack-protector @@ -32,14 +31,26 @@ LDFLAGS = LIBS = -L $(LIB_DIR) -l $(LIB_NAME) ifeq ($(BUILD_TLS),yes) -CFLAGS+=-DUSE_OPENSSL=1 + CFLAGS += -DUSE_OPENSSL=1 +endif + +# Platform-specific overrides +uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not') + +ifeq ($(uname_S),Darwin) + SONAME_FLAG = -install_name + SHARED_FLAG = -dynamiclib +else + SONAME_FLAG = -soname + SHARED_FLAG = -shared endif + ######################################### RULES ####################################### all: $(TARGET_LIB_EXT) $(TARGET_LIB_STATIC_EXT) @echo "Done."; $(TARGET_LIB_EXT): $(OBJECTS) $(REDIS_OBJECTS) - $(CC) -o $@ -shared -Wl,-soname,${LIBRDB_SONAME_EXT} ${LDFLAGS} $^ $(LIBS) + $(CC) -o $@ $(SHARED_FLAG) -Wl,$(SONAME_FLAG),${LIBRDB_SONAME_EXT} ${LDFLAGS} $^ $(LIBS) $(TARGET_LIB_STATIC_EXT): $(OBJECTS) $(REDIS_OBJECTS) ar rcs $@ $^ diff --git a/src/lib/Makefile b/src/lib/Makefile index 25e8e9f..9d7dbbe 100644 --- a/src/lib/Makefile +++ b/src/lib/Makefile @@ -1,7 +1,7 @@ default: all -LIB_NAME = rdb LIB_DIR = ../../lib +LIB_NAME = rdb LIBRDB_SONAME = lib$(LIB_NAME).so.${LIBRDB_VERSION} # Artifacts: @@ -18,8 +18,8 @@ OBJECTS = $(patsubst %,%.o,$(SOURCES)) REDIS_SOURCES = $(notdir $(basename $(wildcard ../../deps/redis/*.c))) REDIS_OBJECTS = $(patsubst %,../../deps/redis/%.o,$(REDIS_SOURCES)) -OPTIMIZATION?=-O3 -LIBRDB_DEBUG?=0 +OPTIMIZATION ?= -O3 +LIBRDB_DEBUG ?= 0 STD = -std=c99 STACK = -fstack-protector-all -Wstack-protector @@ -34,12 +34,23 @@ else CFLAGS += -DNDEBUG=1 endif +# Platform-specific overrides +uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not') + +ifeq ($(uname_S),Darwin) + SONAME_FLAG = -install_name + SHARED_FLAG = -dynamiclib +else + SONAME_FLAG = -soname + SHARED_FLAG = -shared +endif + ######################################### RULES ####################################### all: $(TARGET_LIB) $(TARGET_LIB_STATIC) @echo "Done."; $(TARGET_LIB): $(OBJECTS) $(REDIS_OBJECTS) - $(CC) -o $@ -shared -Wl,-soname,${LIBRDB_SONAME} ${LDFLAGS} $^ + $(CC) -o $@ $(SHARED_FLAG) -Wl,$(SONAME_FLAG),${LIBRDB_SONAME} ${LDFLAGS} $^ $(TARGET_LIB_STATIC): $(OBJECTS) $(REDIS_OBJECTS) ar rcs $@ $^ diff --git a/test/Makefile b/test/Makefile index 693d9f8..8062703 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,9 +1,9 @@ default: all -LIB_NAME = rdb LIB_DIR = ../lib +LIB_NAME = rdb LIB_NAME_EXT = $(LIB_NAME)-ext -LIBHIREDIS=../deps/hiredis/libhiredis.a +LIBHIREDIS = ../deps/hiredis/libhiredis.a # Artifacts: TARGET_TEST = test_lib @@ -17,16 +17,25 @@ STD = -std=c99 STACK = -fstack-protector-all -Wstack-protector WARNS = -Wall -Wextra -pedantic -Werror -Wno-unused-function -OPTIMIZATION?=-O0 +OPTIMIZATION ?= -O0 CFLAGS = -D_DEFAULT_SOURCE -fPIC $(OPTIMIZATION) $(STD) $(STACK) $(WARNS) DEBUG = -g3 -DDEBUG=1 -LIBS = -l cmocka -L /usr/lib -L $(LIB_DIR) -l $(LIB_NAME) -l $(LIB_NAME_EXT) -l:$(LIBHIREDIS) -LIBS_STATIC = -l cmocka -L /usr/lib -L $(LIB_DIR) -l:lib$(LIB_NAME_EXT).a -l:$(LIBHIREDIS) +LIBS = -l cmocka -L /usr/lib -L $(LIB_DIR) -l $(LIB_NAME) -l $(LIB_NAME_EXT) $(LIBHIREDIS) +LIBS_STATIC = -l cmocka -L /usr/lib -L $(LIB_DIR) $(LIB_DIR)/lib$(LIB_NAME).a $(LIB_DIR)/lib$(LIB_NAME_EXT).a $(LIBHIREDIS) ifeq ($(BUILD_TLS),yes) -CFLAGS+=-DUSE_OPENSSL=1 -LIBS+=-lssl -lcrypto + CFLAGS += -DUSE_OPENSSL=1 + LIBS += -lssl -lcrypto +endif + +# Platform-specific overrides +uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not') + +ifeq ($(uname_S),Darwin) + CFLAGS += -I$(shell brew --prefix)/include + LIBS += -L$(shell brew --prefix)/lib + LIBS_STATIC += -L$(shell brew --prefix)/lib endif ######################################### RULES ####################################### @@ -37,7 +46,7 @@ $(TARGET_TEST): $(OBJECTS) $(CC) $(OBJECTS) -o $@ $(DEBUG) $(CFLAGS) $(LIBS) $(TARGET_TEST_STATIC): $(OBJECTS) - $(CC) $(OBJECTS) -o $@ $(DEBUG) $(CFLAGS) $(LIBS) $(LIBS_STATIC) + $(CC) $(OBJECTS) -o $@ $(DEBUG) $(CFLAGS) $(LIBS_STATIC) -include $(OBJECTS:.o=.d) diff --git a/test/test_common.c b/test/test_common.c index 21443f5..68455e0 100644 --- a/test/test_common.c +++ b/test/test_common.c @@ -138,7 +138,7 @@ void cleanTmpFolder(void) { closedir(dir); } -void setEnvVar (const char *name, const char *val) { +void setEnvVar(const char *name, const char *val) { setenv(name, val, 1); } @@ -422,8 +422,8 @@ void setupRedisServer(const char *extraArgs) { exit(1); } - /* Sleep 50msec */ - struct timespec req = {0, 50000*1000}, rem; + /* Sleep 500msec */ + struct timespec req = {0, 500000*1000}, rem; nanosleep(&req, &rem); redisConnContext = redisConnect("localhost", port); diff --git a/test/test_common.h b/test/test_common.h index 289a0a5..f34aa0f 100644 --- a/test/test_common.h +++ b/test/test_common.h @@ -73,7 +73,7 @@ void *xrealloc(void *ptr, size_t size); char *readFile(const char *filename, size_t *len, char *ignoredCh); void cleanTmpFolder(void); -void setEnvVar (const char *name, const char *val); +void setEnvVar(const char *name, const char *val); char *substring(char *str, size_t len, char *substr); void assert_file_payload(const char *filename, char *expData, int expLen, MatchType matchType, int expMatch);