From ce0d6bcef2d03e2ad6f3105db36f0813b45e42a2 Mon Sep 17 00:00:00 2001 From: Kent Slaney Date: Sat, 18 Nov 2023 20:39:57 -0600 Subject: [PATCH 01/31] added support for UNIX domain sockets --- include/Connection.h | 4 +++- libmc/_client.pyx | 20 +++++++++++------ misc/memcached_server | 25 +++++++++++++++++++++ src/Connection.cpp | 52 ++++++++++++++++++++++++++++++++++++++----- tests/test_common.h | 11 +++++++++ tests/test_unix.cpp | 14 ++++++++++++ 6 files changed, 112 insertions(+), 14 deletions(-) create mode 100644 tests/test_unix.cpp diff --git a/include/Connection.h b/include/Connection.h index 79a63c52..e1fd2a81 100644 --- a/include/Connection.h +++ b/include/Connection.h @@ -61,7 +61,8 @@ class Connection { size_t m_counter; protected: - int connectPoll(int fd, struct addrinfo* ai_ptr); + int connectPoll(int fd, const sockaddr* ai_ptr, const socklen_t ai_addrlen); + inline int local(); char m_name[MC_NI_MAXHOST + 1 + MC_NI_MAXSERV]; char m_host[MC_NI_MAXHOST]; @@ -70,6 +71,7 @@ class Connection { int m_socketFd; bool m_alive; bool m_hasAlias; + bool m_local; time_t m_deadUntil; io::BufferWriter* m_buffer_writer; // for send io::BufferReader* m_buffer_reader; // for recv diff --git a/libmc/_client.pyx b/libmc/_client.pyx index 903a64e5..6472e4b6 100644 --- a/libmc/_client.pyx +++ b/libmc/_client.pyx @@ -378,19 +378,25 @@ cdef class PyClient: servers_ = [] for srv in servers: - addr_alias = srv.split(' ') + addr_alias = srv.rsplit(' ', 1) addr = addr_alias[0] if len(addr_alias) == 1: alias = None + elif addr.endswith("\\"): + addr = srv + alias = None else: alias = addr_alias[1] - - host_port = addr.split(':') - host = host_port[0] - if len(host_port) == 1: - port = MC_DEFAULT_PORT + + if addr.startswith("/"): + port = 0 else: - port = int(host_port[1]) + host_port = addr.split(':') + host = host_port[0] + if len(host_port) == 1: + port = MC_DEFAULT_PORT + else: + port = int(host_port[1]) if PY_MAJOR_VERSION > 2: host = PyUnicode_AsUTF8String(host) alias = PyUnicode_AsUTF8String(alias) if alias else None diff --git a/misc/memcached_server b/misc/memcached_server index 77a71ac8..b08dd0cb 100755 --- a/misc/memcached_server +++ b/misc/memcached_server @@ -32,6 +32,18 @@ function start() fi } +function unix() +{ + name="${1:-unix_test}" + if [ ! -f $basedir/var/log/${name}.log ]; then + mkdir -p $basedir/var/log + touch $basedir/var/log/${name}.log + fi + mkdir -p $basedir/var/run + $cmd -d -u $USER -s $basedir/var/run/${name}.socket -t $threads -m ${memory} -P $basedir/var/run/${name}.pid > $basedir/var/log/${name}.log 2>&1 + echo "Starting the memcached server on '$basedir/var/run/${name}.socket'... " +} + function stop() { port="$1" @@ -78,6 +90,19 @@ case "$1" in wait fi ;; + unix) + shift + unix $@ + ;; + unixstop) + if [ `ls $basedir/var/run/ | grep -c .pid` -ge 1 ]; then + names="`basename $basedir/var/run/*.pid | cut -d. -f1`" + for name in $names; do + stop $name & + done + fi + wait + ;; *) printf 'Usage: %s {start|stop|restart} \n' "$prog" exit 1 diff --git a/src/Connection.cpp b/src/Connection.cpp index 2be7de55..af92b247 100644 --- a/src/Connection.cpp +++ b/src/Connection.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -21,8 +22,8 @@ namespace mc { Connection::Connection() : m_counter(0), m_port(0), m_socketFd(-1), - m_alive(false), m_hasAlias(false), m_deadUntil(0), - m_connectTimeout(MC_DEFAULT_CONNECT_TIMEOUT), + m_alive(false), m_hasAlias(false), m_local(false), + m_deadUntil(0), m_connectTimeout(MC_DEFAULT_CONNECT_TIMEOUT), m_retryTimeout(MC_DEFAULT_RETRY_TIMEOUT), m_maxRetries(MC_DEFAULT_MAX_RETRIES), m_retires(0) { m_name[0] = '\0'; @@ -45,9 +46,14 @@ Connection::~Connection() { int Connection::init(const char* host, uint32_t port, const char* alias) { snprintf(m_host, sizeof m_host, "%s", host); m_port = port; + m_local = m_host[0] == '/'; // un.h UNIX_PATH_MAX < netdb.h NI_MAXHOST if (alias == NULL) { m_hasAlias = false; - snprintf(m_name, sizeof m_name, "%s:%u", m_host, m_port); + if (m_local) { + snprintf(m_name, sizeof m_name, "%s", m_host); + } else { + snprintf(m_name, sizeof m_name, "%s:%u", m_host, m_port); + } } else { m_hasAlias = true; snprintf(m_name, sizeof m_name, "%s", alias); @@ -59,6 +65,10 @@ int Connection::init(const char* host, uint32_t port, const char* alias) { int Connection::connect() { assert(!m_alive); this->close(); + if (m_local) { + return local(); + } + struct addrinfo hints, *server_addrinfo = NULL, *ai_ptr = NULL; memset(&hints, 0, sizeof hints); hints.ai_family = AF_INET; @@ -104,7 +114,7 @@ int Connection::connect() { } // make sure the connection is established - if (connectPoll(fd, ai_ptr) == 0) { + if (connectPoll(fd, ai_ptr->ai_addr, ai_ptr->ai_addrlen) == 0) { m_socketFd = fd; m_alive = true; break; @@ -121,8 +131,38 @@ int Connection::connect() { return m_alive ? 0 : -1; } -int Connection::connectPoll(int fd, struct addrinfo* ai_ptr) { - int conn_rv = ::connect(fd, ai_ptr->ai_addr, ai_ptr->ai_addrlen); +inline int Connection::local() { + int fd, flags, opt_keepalive = 1; + + if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { + log_err("socket()"); + return -1; + } + + if ((flags = fcntl(fd, F_GETFL, 0)) < 0 || + fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) { + log_err("setting O_NONBLOCK"); + ::close(fd); + return -1; + } + + setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&opt_keepalive, sizeof opt_keepalive); + + struct sockaddr_un addr; + memset(&addr, 0, sizeof(addr)); + addr.sun_family = AF_UNIX; + strncpy(addr.sun_path, m_host, sizeof(addr.sun_path) - 1); + assert(strcmp(addr.sun_path, m_host) == 0); + if (connectPoll(fd, (const struct sockaddr *)&addr, sizeof addr) != 0) { + return -1; + } + m_socketFd = fd; + m_alive = true; + return 0; +} + +int Connection::connectPoll(int fd, const sockaddr* ai_addr, const socklen_t ai_addrlen) { + int conn_rv = ::connect(fd, ai_addr, ai_addrlen); if (conn_rv == 0) { return 0; } diff --git a/tests/test_common.h b/tests/test_common.h index 7db98a01..56863f08 100644 --- a/tests/test_common.h +++ b/tests/test_common.h @@ -73,6 +73,11 @@ mc::Client* newClient(int n) { "sierra", "tango" }; + return md5Client(hosts, ports, n, aliases); +} + +mc::Client* md5Client(const char* const * hosts, const uint32_t* ports, const size_t n, + const char* const * aliases = NULL) { mc::Client* client = new mc::Client(); client->config(CFG_HASH_FUNCTION, OPT_HASH_MD5); client->init(hosts, ports, n, aliases); @@ -87,6 +92,12 @@ mc::Client* newClient(int n) { return client; } +mc::Client* newUnixClient() { + const char * hosts[] = { "/tmp/env_mc_dev/var/run/unix_test.socket" }; + const uint32_t ports[] = { 0 }; + return md5Client(hosts, ports, 1); +} + std::string get_resource_path(const char* basename) { std::string this_path(__FILE__); diff --git a/tests/test_unix.cpp b/tests/test_unix.cpp new file mode 100644 index 00000000..d2ed79d8 --- /dev/null +++ b/tests/test_unix.cpp @@ -0,0 +1,14 @@ +#include "Client.h" +#include "test_common.h" + +#include +#include "gtest/gtest.h" + +using douban::mc::Client; +using douban::mc::tests::newUnixClient; + +TEST(test_unix, establish_connection) { + Client* client = newUnixClient(); + EXPECT_TRUE(client != NULL); + delete client; +} \ No newline at end of file From db189f16bda63322c5317224cad507ed0e261bd5 Mon Sep 17 00:00:00 2001 From: Kent Slaney Date: Sun, 19 Nov 2023 20:21:34 -0600 Subject: [PATCH 02/31] untested progress --- .github/workflows/golang.yml | 4 ++-- .github/workflows/python.yml | 4 ++-- include/Common.h | 2 ++ libmc/_client.pyx | 4 +++- misc/memcached_server | 9 ++++++++- misc/travis/cpptest.sh | 4 ++-- src/Common.cpp | 31 +++++++++++++++++++++++++++++++ src/Connection.cpp | 4 ++-- src/golibmc.go | 1 + tests/test_common.h | 32 ++++++++++++++++---------------- 10 files changed, 69 insertions(+), 26 deletions(-) diff --git a/.github/workflows/golang.yml b/.github/workflows/golang.yml index f0d441e7..355796b5 100644 --- a/.github/workflows/golang.yml +++ b/.github/workflows/golang.yml @@ -25,11 +25,11 @@ jobs: with: go-version: ${{ matrix.gover }} - name: Start memcached servers - run: ./misc/memcached_server start + run: ./misc/memcached_server startall - name: Run gotest run: | if [[ ${{ matrix.compiler }} = "gcc" ]]; then export CC=gcc CXX=g++; fi if [[ ${{ matrix.compiler }} = "clang" ]]; then export CC=clang CXX=clang++; fi ./misc/travis/gotest.sh - name: Stop memcached servers - run: ./misc/memcached_server stop + run: ./misc/memcached_server stopall diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index 0c8606c4..a54ae940 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -29,14 +29,14 @@ jobs: python -m pip install --upgrade pip pip install setuptools future pytest greenify gevent numpy - name: Start memcached servers - run: ./misc/memcached_server start + run: ./misc/memcached_server startall - name: Run unittest run: | if [[ ${{ matrix.compiler }} = "gcc" ]]; then export CC=gcc CXX=g++; fi if [[ ${{ matrix.compiler }} = "clang" ]]; then export CC=clang CXX=clang++; fi ./misc/travis/unittest.sh - name: Stop memcached servers - run: ./misc/memcached_server stop + run: ./misc/memcached_server stopall benchmark: runs-on: ubuntu-latest diff --git a/include/Common.h b/include/Common.h index 06baf1a8..4e8538d9 100644 --- a/include/Common.h +++ b/include/Common.h @@ -226,6 +226,8 @@ typedef enum { } op_code_t; const char* errCodeToString(err_code_t err); +bool isLocalSocket(const char* host); +char** splitServerString(char* input); } // namespace mc } // namespace douban diff --git a/libmc/_client.pyx b/libmc/_client.pyx index 6472e4b6..e07c5d89 100644 --- a/libmc/_client.pyx +++ b/libmc/_client.pyx @@ -45,6 +45,8 @@ cdef extern from "Common.h" namespace "douban::mc": VERSION_OP QUIT_OP + #bool isLocalSocket(const char* host) nogil + cdef extern from "Export.h": ctypedef enum config_options_t: @@ -382,7 +384,7 @@ cdef class PyClient: addr = addr_alias[0] if len(addr_alias) == 1: alias = None - elif addr.endswith("\\"): + elif (len(addr) - len(addr.rstrip("\\"))) % 2 == 1: addr = srv alias = None else: diff --git a/misc/memcached_server b/misc/memcached_server index b08dd0cb..dc389d2d 100755 --- a/misc/memcached_server +++ b/misc/memcached_server @@ -94,7 +94,14 @@ case "$1" in shift unix $@ ;; - unixstop) + startall) + unix & + for port in $PORTS; do + start $port & + done + wait + ;; + stopall) if [ `ls $basedir/var/run/ | grep -c .pid` -ge 1 ]; then names="`basename $basedir/var/run/*.pid | cut -d. -f1`" for name in $names; do diff --git a/misc/travis/cpptest.sh b/misc/travis/cpptest.sh index c095ce76..033fb737 100755 --- a/misc/travis/cpptest.sh +++ b/misc/travis/cpptest.sh @@ -2,7 +2,7 @@ set -ex echo "CXX=${CXX}" -./misc/memcached_server start &>/dev/null & +./misc/memcached_server startall &>/dev/null & python misc/generate_hash_dataset.py tests/resources/keys.txt &>/dev/null & mkdir -p build cd build @@ -11,4 +11,4 @@ make -j8 &>/dev/null wait ARGS=-V make test cd .. -./misc/memcached_server stop &>/dev/null & +./misc/memcached_server stopall &>/dev/null & diff --git a/src/Common.cpp b/src/Common.cpp index 674750a6..43ef3585 100644 --- a/src/Common.cpp +++ b/src/Common.cpp @@ -50,5 +50,36 @@ const char* errCodeToString(err_code_t err) { } } +bool isLocalPath(const char* host) { + return host[0] == '/'; +} + +char** splitServerString(char* input) { + bool escaped = false; + char *res[3] = { input--, NULL, NULL }; + for (;;) { + switch (*(++input)) + { + case ':': // invalid in a UNIX path + *input = '\0'; + res[1] = input + 1; + case '\0': + break; + case ' ': + if (!escaped) { + *input = '\0'; + res[2] = input + 1; + break; + } + default: + escaped = false; + continue; + case '\\': + escaped ^= 1; + } + } + return res; +} + } // namespace mc } // namespace douban diff --git a/src/Connection.cpp b/src/Connection.cpp index af92b247..2f6aacf4 100644 --- a/src/Connection.cpp +++ b/src/Connection.cpp @@ -46,7 +46,7 @@ Connection::~Connection() { int Connection::init(const char* host, uint32_t port, const char* alias) { snprintf(m_host, sizeof m_host, "%s", host); m_port = port; - m_local = m_host[0] == '/'; // un.h UNIX_PATH_MAX < netdb.h NI_MAXHOST + m_local = isLocalSocket(m_host); // un.h UNIX_PATH_MAX < netdb.h NI_MAXHOST if (alias == NULL) { m_hasAlias = false; if (m_local) { @@ -131,7 +131,7 @@ int Connection::connect() { return m_alive ? 0 : -1; } -inline int Connection::local() { +int Connection::local() { int fd, flags, opt_keepalive = 1; if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { diff --git a/src/golibmc.go b/src/golibmc.go index dcdcc235..ce465f3f 100644 --- a/src/golibmc.go +++ b/src/golibmc.go @@ -338,6 +338,7 @@ func (client *Client) newConn() (*conn, error) { cAliases := make([]*C.char, n) for i, srv := range client.servers { + // TODO: UNIX paths addrAndAlias := strings.Split(srv, " ") addr := addrAndAlias[0] diff --git a/tests/test_common.h b/tests/test_common.h index 56863f08..0b1a6627 100644 --- a/tests/test_common.h +++ b/tests/test_common.h @@ -23,6 +23,22 @@ void gen_random(char *s, const int len) { } +mc::Client* md5Client(const char* const * hosts, const uint32_t* ports, const size_t n, + const char* const * aliases = NULL) { + mc::Client* client = new mc::Client(); + client->config(CFG_HASH_FUNCTION, OPT_HASH_MD5); + client->init(hosts, ports, n, aliases); + broadcast_result_t* results; + size_t nHosts; + int ret = client->version(&results, &nHosts); + client->destroyBroadcastResult(); + if (ret != 0) { + delete client; + return NULL; + } + return client; +} + mc::Client* newClient(int n) { assert(n <= 20); const char * hosts[] = { @@ -76,22 +92,6 @@ mc::Client* newClient(int n) { return md5Client(hosts, ports, n, aliases); } -mc::Client* md5Client(const char* const * hosts, const uint32_t* ports, const size_t n, - const char* const * aliases = NULL) { - mc::Client* client = new mc::Client(); - client->config(CFG_HASH_FUNCTION, OPT_HASH_MD5); - client->init(hosts, ports, n, aliases); - broadcast_result_t* results; - size_t nHosts; - int ret = client->version(&results, &nHosts); - client->destroyBroadcastResult(); - if (ret != 0) { - delete client; - return NULL; - } - return client; -} - mc::Client* newUnixClient() { const char * hosts[] = { "/tmp/env_mc_dev/var/run/unix_test.socket" }; const uint32_t ports[] = { 0 }; From e54938f5aed185d4b02ec3910ecba552f8435185 Mon Sep 17 00:00:00 2001 From: Kent Slaney Date: Mon, 27 Nov 2023 20:37:29 -0800 Subject: [PATCH 03/31] moved cython server string parse to c --- include/Common.h | 8 +++++++- libmc/_client.pyx | 46 ++++++++++++++++----------------------------- src/Common.cpp | 24 +++++++++++++++-------- src/Connection.cpp | 1 + tests/test_unix.cpp | 2 +- 5 files changed, 41 insertions(+), 40 deletions(-) diff --git a/include/Common.h b/include/Common.h index 4e8538d9..da4142d8 100644 --- a/include/Common.h +++ b/include/Common.h @@ -225,9 +225,15 @@ typedef enum { QUIT_OP, } op_code_t; +struct ServerSpec { + char* host; + char* port; + char* alias; +}; + const char* errCodeToString(err_code_t err); bool isLocalSocket(const char* host); -char** splitServerString(char* input); +ServerSpec splitServerString(char* input); } // namespace mc } // namespace douban diff --git a/libmc/_client.pyx b/libmc/_client.pyx index e07c5d89..9ad7c2d6 100644 --- a/libmc/_client.pyx +++ b/libmc/_client.pyx @@ -3,6 +3,7 @@ # cython: profile=False, c_string_type=unicode, c_string_encoding=utf8 from libc.stdint cimport uint8_t, uint32_t, uint64_t, int64_t +from libc.stdlib cimport atoi from libcpp cimport bool as bool_t from libcpp.string cimport string from libcpp.vector cimport vector @@ -45,7 +46,12 @@ cdef extern from "Common.h" namespace "douban::mc": VERSION_OP QUIT_OP - #bool isLocalSocket(const char* host) nogil + cdef struct ServerSpec: + char* host + char* port + char* alias + + ServerSpec splitServerString(char* input) nogil cdef extern from "Export.h": @@ -380,39 +386,19 @@ cdef class PyClient: servers_ = [] for srv in servers: - addr_alias = srv.rsplit(' ', 1) - addr = addr_alias[0] - if len(addr_alias) == 1: - alias = None - elif (len(addr) - len(addr.rstrip("\\"))) % 2 == 1: - addr = srv - alias = None - else: - alias = addr_alias[1] - - if addr.startswith("/"): - port = 0 - else: - host_port = addr.split(':') - host = host_port[0] - if len(host_port) == 1: - port = MC_DEFAULT_PORT - else: - port = int(host_port[1]) if PY_MAJOR_VERSION > 2: - host = PyUnicode_AsUTF8String(host) - alias = PyUnicode_AsUTF8String(alias) if alias else None - servers_.append((host, port, alias)) + srv = PyUnicode_AsUTF8String(srv) + srv = PyString_AsString(srv) + servers_.append(srv) Py_INCREF(servers_) for i in range(n): - host, port, alias = servers_[i] - c_hosts[i] = PyString_AsString(host) - c_ports[i] = PyInt_AsLong(port) - if alias is None: - c_aliases[i] = NULL - else: - c_aliases[i] = PyString_AsString(alias) + c_split = splitServerString(servers_[i]) + host, port, alias = c_split + + c_hosts[i] = c_split.host + c_ports[i] = MC_DEFAULT_PORT if c_split.port == NULL else atoi(c_split.port) + c_aliases[i] = c_split.alias if init: rv = self._imp.init(c_hosts, c_ports, n, c_aliases) diff --git a/src/Common.cpp b/src/Common.cpp index 43ef3585..be1a98b6 100644 --- a/src/Common.cpp +++ b/src/Common.cpp @@ -50,28 +50,36 @@ const char* errCodeToString(err_code_t err) { } } -bool isLocalPath(const char* host) { +bool isLocalSocket(const char* host) { return host[0] == '/'; } -char** splitServerString(char* input) { - bool escaped = false; - char *res[3] = { input--, NULL, NULL }; +ServerSpec splitServerString(char* input) { + bool escaped = false, num = false; + ServerSpec res = { input--, NULL, NULL }; for (;;) { switch (*(++input)) { case ':': // invalid in a UNIX path *input = '\0'; - res[1] = input + 1; + res.port = input + 1; + num = true; case '\0': - break; + return res; case ' ': if (!escaped) { *input = '\0'; - res[2] = input + 1; - break; + res.alias = input + 1; + return res; } default: + if (num) { + *res.port = ':'; + res.port = NULL; + num = false; + } + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': escaped = false; continue; case '\\': diff --git a/src/Connection.cpp b/src/Connection.cpp index 2f6aacf4..9acc510a 100644 --- a/src/Connection.cpp +++ b/src/Connection.cpp @@ -11,6 +11,7 @@ #include #include +#include "Common.h" #include "Connection.h" #include "Keywords.h" diff --git a/tests/test_unix.cpp b/tests/test_unix.cpp index d2ed79d8..5341aae8 100644 --- a/tests/test_unix.cpp +++ b/tests/test_unix.cpp @@ -11,4 +11,4 @@ TEST(test_unix, establish_connection) { Client* client = newUnixClient(); EXPECT_TRUE(client != NULL); delete client; -} \ No newline at end of file +} From 316a68e9f75f8cd730c9545333f0d32b8d4f1a3b Mon Sep 17 00:00:00 2001 From: Kent Slaney Date: Tue, 28 Nov 2023 00:30:27 -0800 Subject: [PATCH 04/31] regression test for host parse --- libmc/_client.pyx | 1 - src/Common.cpp | 5 +++-- tests/test_unix.cpp | 11 +++++++++++ 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/libmc/_client.pyx b/libmc/_client.pyx index 9ad7c2d6..785a44a6 100644 --- a/libmc/_client.pyx +++ b/libmc/_client.pyx @@ -394,7 +394,6 @@ cdef class PyClient: Py_INCREF(servers_) for i in range(n): c_split = splitServerString(servers_[i]) - host, port, alias = c_split c_hosts[i] = c_split.host c_ports[i] = MC_DEFAULT_PORT if c_split.port == NULL else atoi(c_split.port) diff --git a/src/Common.cpp b/src/Common.cpp index be1a98b6..9826666b 100644 --- a/src/Common.cpp +++ b/src/Common.cpp @@ -60,12 +60,13 @@ ServerSpec splitServerString(char* input) { for (;;) { switch (*(++input)) { + case '\0': + return res; case ':': // invalid in a UNIX path *input = '\0'; res.port = input + 1; num = true; - case '\0': - return res; + continue; case ' ': if (!escaped) { *input = '\0'; diff --git a/tests/test_unix.cpp b/tests/test_unix.cpp index 5341aae8..0646f084 100644 --- a/tests/test_unix.cpp +++ b/tests/test_unix.cpp @@ -1,3 +1,4 @@ +#include "Common.h" #include "Client.h" #include "test_common.h" @@ -6,9 +7,19 @@ using douban::mc::Client; using douban::mc::tests::newUnixClient; +using douban::mc::splitServerString; +using douban::mc::ServerSpec; TEST(test_unix, establish_connection) { Client* client = newUnixClient(); EXPECT_TRUE(client != NULL); delete client; } + +TEST(test_unix, host_parse_regression) { + char test[] = "127.0.0.1:21211 testing"; + ServerSpec out = splitServerString(test); + ASSERT_STREQ(out.host, "127.0.0.1"); + ASSERT_STREQ(out.port, "21211"); + ASSERT_STREQ(out.alias, "testing"); +} From 9892b127a10d529c82e4365011caded7bfd826f9 Mon Sep 17 00:00:00 2001 From: Kent Slaney Date: Tue, 28 Nov 2023 09:44:14 -0800 Subject: [PATCH 05/31] updated cppcheck suppression --- misc/.cppcheck-supp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/misc/.cppcheck-supp b/misc/.cppcheck-supp index 5b2f1453..27a77986 100644 --- a/misc/.cppcheck-supp +++ b/misc/.cppcheck-supp @@ -41,5 +41,5 @@ unusedFunction:src/c_client.cpp:149 unusedFunction:src/c_client.cpp:154 unusedFunction:src/c_client.cpp:159 unusedFunction:src/Utility.cpp:43 -*:src/Connection.cpp:30 -*:src/Connection.cpp:35 +*:src/Connection.cpp:32 +*:src/Connection.cpp:37 From aeff5290ce6f3c5a30cb24ba9b815bf1d1cfd092 Mon Sep 17 00:00:00 2001 From: Kent Slaney Date: Tue, 28 Nov 2023 10:57:32 -0800 Subject: [PATCH 06/31] golang bindings --- include/Common.h | 6 ------ include/Export.h | 6 ++++++ include/c_client.h | 1 + libmc/_client.pyx | 14 +++++++++----- src/Common.cpp | 10 +--------- src/c_client.cpp | 4 ++++ src/golibmc.go | 27 +++++++++------------------ tests/test_unix.cpp | 1 - 8 files changed, 30 insertions(+), 39 deletions(-) diff --git a/include/Common.h b/include/Common.h index da4142d8..2414ed41 100644 --- a/include/Common.h +++ b/include/Common.h @@ -225,12 +225,6 @@ typedef enum { QUIT_OP, } op_code_t; -struct ServerSpec { - char* host; - char* port; - char* alias; -}; - const char* errCodeToString(err_code_t err); bool isLocalSocket(const char* host); ServerSpec splitServerString(char* input); diff --git a/include/Export.h b/include/Export.h index d43cdbde..832c0bc9 100644 --- a/include/Export.h +++ b/include/Export.h @@ -38,6 +38,12 @@ typedef enum { RET_OK = 0 } err_code_t; +typedef struct { + char* host; + char* port; + char* alias; +} ServerSpec; + typedef int64_t exptime_t; typedef uint32_t flags_t; diff --git a/include/c_client.h b/include/c_client.h index 445b7901..53201c8f 100644 --- a/include/c_client.h +++ b/include/c_client.h @@ -68,6 +68,7 @@ extern "C" { err_code_t client_quit(void* client); const char* err_code_to_string(err_code_t err); + ServerSpec splitServerString(char* input); #ifdef __cplusplus } #endif diff --git a/libmc/_client.pyx b/libmc/_client.pyx index 785a44a6..2caf4e3c 100644 --- a/libmc/_client.pyx +++ b/libmc/_client.pyx @@ -46,11 +46,6 @@ cdef extern from "Common.h" namespace "douban::mc": VERSION_OP QUIT_OP - cdef struct ServerSpec: - char* host - char* port - char* alias - ServerSpec splitServerString(char* input) nogil @@ -107,6 +102,11 @@ cdef extern from "Export.h": RET_INCOMPLETE_BUFFER_ERR RET_OK + ctypedef struct ServerSpec: + char* host + char* port + char* alias + ctypedef struct unsigned_result_t: char* key size_t key_len @@ -398,6 +398,10 @@ cdef class PyClient: c_hosts[i] = c_split.host c_ports[i] = MC_DEFAULT_PORT if c_split.port == NULL else atoi(c_split.port) c_aliases[i] = c_split.alias + if c_split.port == NULL: + c_ports[i] = MC_DEFAULT_PORT + else: + c_ports[i] = PyInt_AsLong(int(c_split.port)) if init: rv = self._imp.init(c_hosts, c_ports, n, c_aliases) diff --git a/src/Common.cpp b/src/Common.cpp index 9826666b..3b24a538 100644 --- a/src/Common.cpp +++ b/src/Common.cpp @@ -55,7 +55,7 @@ bool isLocalSocket(const char* host) { } ServerSpec splitServerString(char* input) { - bool escaped = false, num = false; + bool escaped = false; ServerSpec res = { input--, NULL, NULL }; for (;;) { switch (*(++input)) @@ -65,7 +65,6 @@ ServerSpec splitServerString(char* input) { case ':': // invalid in a UNIX path *input = '\0'; res.port = input + 1; - num = true; continue; case ' ': if (!escaped) { @@ -74,13 +73,6 @@ ServerSpec splitServerString(char* input) { return res; } default: - if (num) { - *res.port = ':'; - res.port = NULL; - num = false; - } - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': escaped = false; continue; case '\\': diff --git a/src/c_client.cpp b/src/c_client.cpp index 9fab71c9..cc01cccd 100644 --- a/src/c_client.cpp +++ b/src/c_client.cpp @@ -159,3 +159,7 @@ err_code_t client_quit(void* client) { const char* err_code_to_string(err_code_t err) { return douban::mc::errCodeToString(err); } + +ServerSpec splitServerString(char* input) { + return douban::mc::splitServerString(input); +} \ No newline at end of file diff --git a/src/golibmc.go b/src/golibmc.go index ce465f3f..924e98ab 100644 --- a/src/golibmc.go +++ b/src/golibmc.go @@ -338,30 +338,21 @@ func (client *Client) newConn() (*conn, error) { cAliases := make([]*C.char, n) for i, srv := range client.servers { - // TODO: UNIX paths - addrAndAlias := strings.Split(srv, " ") - - addr := addrAndAlias[0] - if len(addrAndAlias) == 2 { - cAlias := C.CString(addrAndAlias[1]) - defer C.free(unsafe.Pointer(cAlias)) - cAliases[i] = cAlias - } + csrv := C.CString(srv) + defer C.free(unsafe.Pointer(csrv)) + split := C.splitServerString(csrv) - hostAndPort := strings.Split(addr, ":") - host := hostAndPort[0] - cHost := C.CString(host) - defer C.free(unsafe.Pointer(cHost)) - cHosts[i] = cHost + cAliases[i] = split.alias + cHosts[i] = split.host - if len(hostAndPort) == 2 { - port, err := strconv.Atoi(hostAndPort[1]) + if split.port == nil { + cPorts[i] = C.uint32_t(DefaultPort) + } else { + port, err := strconv.Atoi(C.GoString(split.port)) if err != nil { return nil, err } cPorts[i] = C.uint32_t(port) - } else { - cPorts[i] = C.uint32_t(DefaultPort) } } diff --git a/tests/test_unix.cpp b/tests/test_unix.cpp index 0646f084..e26b243e 100644 --- a/tests/test_unix.cpp +++ b/tests/test_unix.cpp @@ -8,7 +8,6 @@ using douban::mc::Client; using douban::mc::tests::newUnixClient; using douban::mc::splitServerString; -using douban::mc::ServerSpec; TEST(test_unix, establish_connection) { Client* client = newUnixClient(); From b515fce7cd77869c7736041eb688fa311f94b2e6 Mon Sep 17 00:00:00 2001 From: Kent Slaney Date: Tue, 28 Nov 2023 11:09:09 -0800 Subject: [PATCH 07/31] update c_client cppcheck --- misc/.cppcheck-supp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/misc/.cppcheck-supp b/misc/.cppcheck-supp index 27a77986..09bd44de 100644 --- a/misc/.cppcheck-supp +++ b/misc/.cppcheck-supp @@ -40,6 +40,8 @@ unusedFunction:src/c_client.cpp:145 unusedFunction:src/c_client.cpp:149 unusedFunction:src/c_client.cpp:154 unusedFunction:src/c_client.cpp:159 +unusedFunction:src/c_client.cpp:159 +unusedFunction:src/c_client.cpp:163 unusedFunction:src/Utility.cpp:43 *:src/Connection.cpp:32 *:src/Connection.cpp:37 From eed34278aee3d5d020e3fda54bb82ff5e6040469 Mon Sep 17 00:00:00 2001 From: Kent Slaney Date: Tue, 28 Nov 2023 11:59:29 -0800 Subject: [PATCH 08/31] removed duplicated line --- misc/.cppcheck-supp | 1 - 1 file changed, 1 deletion(-) diff --git a/misc/.cppcheck-supp b/misc/.cppcheck-supp index 09bd44de..b694e60c 100644 --- a/misc/.cppcheck-supp +++ b/misc/.cppcheck-supp @@ -40,7 +40,6 @@ unusedFunction:src/c_client.cpp:145 unusedFunction:src/c_client.cpp:149 unusedFunction:src/c_client.cpp:154 unusedFunction:src/c_client.cpp:159 -unusedFunction:src/c_client.cpp:159 unusedFunction:src/c_client.cpp:163 unusedFunction:src/Utility.cpp:43 *:src/Connection.cpp:32 From e85c2a71bc82327c93a147585979a07f709ac7e0 Mon Sep 17 00:00:00 2001 From: Kent Slaney Date: Tue, 28 Nov 2023 12:24:19 -0800 Subject: [PATCH 09/31] removed github workflow changes --- .github/workflows/golang.yml | 4 ++-- .github/workflows/python.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/golang.yml b/.github/workflows/golang.yml index 355796b5..f0d441e7 100644 --- a/.github/workflows/golang.yml +++ b/.github/workflows/golang.yml @@ -25,11 +25,11 @@ jobs: with: go-version: ${{ matrix.gover }} - name: Start memcached servers - run: ./misc/memcached_server startall + run: ./misc/memcached_server start - name: Run gotest run: | if [[ ${{ matrix.compiler }} = "gcc" ]]; then export CC=gcc CXX=g++; fi if [[ ${{ matrix.compiler }} = "clang" ]]; then export CC=clang CXX=clang++; fi ./misc/travis/gotest.sh - name: Stop memcached servers - run: ./misc/memcached_server stopall + run: ./misc/memcached_server stop diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index a54ae940..0c8606c4 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -29,14 +29,14 @@ jobs: python -m pip install --upgrade pip pip install setuptools future pytest greenify gevent numpy - name: Start memcached servers - run: ./misc/memcached_server startall + run: ./misc/memcached_server start - name: Run unittest run: | if [[ ${{ matrix.compiler }} = "gcc" ]]; then export CC=gcc CXX=g++; fi if [[ ${{ matrix.compiler }} = "clang" ]]; then export CC=clang CXX=clang++; fi ./misc/travis/unittest.sh - name: Stop memcached servers - run: ./misc/memcached_server stopall + run: ./misc/memcached_server stop benchmark: runs-on: ubuntu-latest From 96500cbb1e37b16f879e7bf19fd3b5c8405446fe Mon Sep 17 00:00:00 2001 From: Kent Slaney Date: Tue, 28 Nov 2023 12:30:06 -0800 Subject: [PATCH 10/31] moved unix client to test_unix --- tests/test_unix.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/test_unix.cpp b/tests/test_unix.cpp index e26b243e..ce141e75 100644 --- a/tests/test_unix.cpp +++ b/tests/test_unix.cpp @@ -6,9 +6,15 @@ #include "gtest/gtest.h" using douban::mc::Client; -using douban::mc::tests::newUnixClient; +using douban::mc::tests::md5Client; using douban::mc::splitServerString; +Client* newUnixClient() { + const char * hosts[] = { "/tmp/env_mc_dev/var/run/unix_test.socket" }; + const uint32_t ports[] = { 0 }; + return md5Client(hosts, ports, 1); +} + TEST(test_unix, establish_connection) { Client* client = newUnixClient(); EXPECT_TRUE(client != NULL); From 313287b5a040bf6e0bacbe7d6bd1fd175f083c98 Mon Sep 17 00:00:00 2001 From: Kent Slaney Date: Tue, 28 Nov 2023 12:33:48 -0800 Subject: [PATCH 11/31] missed file --- src/c_client.cpp | 2 +- tests/test_common.h | 7 +------ 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/c_client.cpp b/src/c_client.cpp index cc01cccd..424e11d1 100644 --- a/src/c_client.cpp +++ b/src/c_client.cpp @@ -162,4 +162,4 @@ const char* err_code_to_string(err_code_t err) { ServerSpec splitServerString(char* input) { return douban::mc::splitServerString(input); -} \ No newline at end of file +} diff --git a/tests/test_common.h b/tests/test_common.h index 0b1a6627..765cf046 100644 --- a/tests/test_common.h +++ b/tests/test_common.h @@ -39,6 +39,7 @@ mc::Client* md5Client(const char* const * hosts, const uint32_t* ports, const si return client; } + mc::Client* newClient(int n) { assert(n <= 20); const char * hosts[] = { @@ -92,12 +93,6 @@ mc::Client* newClient(int n) { return md5Client(hosts, ports, n, aliases); } -mc::Client* newUnixClient() { - const char * hosts[] = { "/tmp/env_mc_dev/var/run/unix_test.socket" }; - const uint32_t ports[] = { 0 }; - return md5Client(hosts, ports, 1); -} - std::string get_resource_path(const char* basename) { std::string this_path(__FILE__); From 7ec46840645d1f383b9fe8d375300cadf34f9d65 Mon Sep 17 00:00:00 2001 From: Kent Slaney Date: Tue, 28 Nov 2023 12:39:50 -0800 Subject: [PATCH 12/31] remove atoi usage --- libmc/_client.pyx | 2 -- 1 file changed, 2 deletions(-) diff --git a/libmc/_client.pyx b/libmc/_client.pyx index 2caf4e3c..611bbcc5 100644 --- a/libmc/_client.pyx +++ b/libmc/_client.pyx @@ -3,7 +3,6 @@ # cython: profile=False, c_string_type=unicode, c_string_encoding=utf8 from libc.stdint cimport uint8_t, uint32_t, uint64_t, int64_t -from libc.stdlib cimport atoi from libcpp cimport bool as bool_t from libcpp.string cimport string from libcpp.vector cimport vector @@ -396,7 +395,6 @@ cdef class PyClient: c_split = splitServerString(servers_[i]) c_hosts[i] = c_split.host - c_ports[i] = MC_DEFAULT_PORT if c_split.port == NULL else atoi(c_split.port) c_aliases[i] = c_split.alias if c_split.port == NULL: c_ports[i] = MC_DEFAULT_PORT From b55e658cd8638befa41b38cf85ee31487653b6b7 Mon Sep 17 00:00:00 2001 From: Kent Slaney Date: Tue, 28 Nov 2023 13:16:41 -0800 Subject: [PATCH 13/31] warning explanation --- src/Connection.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Connection.cpp b/src/Connection.cpp index 9acc510a..c664abde 100644 --- a/src/Connection.cpp +++ b/src/Connection.cpp @@ -47,7 +47,7 @@ Connection::~Connection() { int Connection::init(const char* host, uint32_t port, const char* alias) { snprintf(m_host, sizeof m_host, "%s", host); m_port = port; - m_local = isLocalSocket(m_host); // un.h UNIX_PATH_MAX < netdb.h NI_MAXHOST + m_local = isLocalSocket(m_host); if (alias == NULL) { m_hasAlias = false; if (m_local) { @@ -152,6 +152,8 @@ int Connection::local() { struct sockaddr_un addr; memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; + // un.h UNIX_PATH_MAX < netdb.h NI_MAXHOST + // storing the unix path as a host doesn't limit the input but can overflow strncpy(addr.sun_path, m_host, sizeof(addr.sun_path) - 1); assert(strcmp(addr.sun_path, m_host) == 0); if (connectPoll(fd, (const struct sockaddr *)&addr, sizeof addr) != 0) { From 501fe499b8c30da6e831f22c64eb3f861c7a9dcf Mon Sep 17 00:00:00 2001 From: Kent Slaney Date: Tue, 28 Nov 2023 13:21:15 -0800 Subject: [PATCH 14/31] removed unused cppcheck suppression --- misc/.cppcheck-supp | 1 - 1 file changed, 1 deletion(-) diff --git a/misc/.cppcheck-supp b/misc/.cppcheck-supp index b694e60c..27a77986 100644 --- a/misc/.cppcheck-supp +++ b/misc/.cppcheck-supp @@ -40,7 +40,6 @@ unusedFunction:src/c_client.cpp:145 unusedFunction:src/c_client.cpp:149 unusedFunction:src/c_client.cpp:154 unusedFunction:src/c_client.cpp:159 -unusedFunction:src/c_client.cpp:163 unusedFunction:src/Utility.cpp:43 *:src/Connection.cpp:32 *:src/Connection.cpp:37 From 6c36996864318f5c27c01866fe0825c52a0befd8 Mon Sep 17 00:00:00 2001 From: Kent Slaney Date: Tue, 28 Nov 2023 13:28:13 -0800 Subject: [PATCH 15/31] startall for cython valgrind --- .github/workflows/python.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index 0c8606c4..a54ae940 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -29,14 +29,14 @@ jobs: python -m pip install --upgrade pip pip install setuptools future pytest greenify gevent numpy - name: Start memcached servers - run: ./misc/memcached_server start + run: ./misc/memcached_server startall - name: Run unittest run: | if [[ ${{ matrix.compiler }} = "gcc" ]]; then export CC=gcc CXX=g++; fi if [[ ${{ matrix.compiler }} = "clang" ]]; then export CC=clang CXX=clang++; fi ./misc/travis/unittest.sh - name: Stop memcached servers - run: ./misc/memcached_server stop + run: ./misc/memcached_server stopall benchmark: runs-on: ubuntu-latest From f4cc59fb8a4ba189faf07f99e9e9275173d5fff5 Mon Sep 17 00:00:00 2001 From: Kent Slaney Date: Tue, 28 Nov 2023 19:44:38 -0800 Subject: [PATCH 16/31] better string iteration --- src/Common.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Common.cpp b/src/Common.cpp index 3b24a538..51491ae8 100644 --- a/src/Common.cpp +++ b/src/Common.cpp @@ -56,9 +56,9 @@ bool isLocalSocket(const char* host) { ServerSpec splitServerString(char* input) { bool escaped = false; - ServerSpec res = { input--, NULL, NULL }; - for (;;) { - switch (*(++input)) + ServerSpec res = { input, NULL, NULL }; + for (;input++;) { + switch (*input) { case '\0': return res; From efb13388781fcce733e9994b127aaea2f09e67e7 Mon Sep 17 00:00:00 2001 From: Kent Slaney Date: Tue, 28 Nov 2023 19:46:45 -0800 Subject: [PATCH 17/31] sorry to commit after requesting review --- src/Common.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Common.cpp b/src/Common.cpp index 51491ae8..01f1f556 100644 --- a/src/Common.cpp +++ b/src/Common.cpp @@ -57,7 +57,7 @@ bool isLocalSocket(const char* host) { ServerSpec splitServerString(char* input) { bool escaped = false; ServerSpec res = { input, NULL, NULL }; - for (;input++;) { + for (;;input++) { switch (*input) { case '\0': From 2a1c906fb821e9798dc7bee656bf2b167e0652a3 Mon Sep 17 00:00:00 2001 From: Kent Slaney Date: Thu, 30 Nov 2023 14:32:18 -0800 Subject: [PATCH 18/31] reverted server string parsing behavior --- src/Common.cpp | 11 ++++++++--- tests/test_unix.cpp | 24 ++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/src/Common.cpp b/src/Common.cpp index 01f1f556..747e0e68 100644 --- a/src/Common.cpp +++ b/src/Common.cpp @@ -54,10 +54,11 @@ bool isLocalSocket(const char* host) { return host[0] == '/'; } +// modifies input string and output pointers reference input ServerSpec splitServerString(char* input) { bool escaped = false; ServerSpec res = { input, NULL, NULL }; - for (;;input++) { + for (;; input++) { switch (*input) { case '\0': @@ -69,8 +70,12 @@ ServerSpec splitServerString(char* input) { case ' ': if (!escaped) { *input = '\0'; - res.alias = input + 1; - return res; + if (res.alias == NULL) { + res.alias = input + 1; + continue; + } else { + return res; + } } default: escaped = false; diff --git a/tests/test_unix.cpp b/tests/test_unix.cpp index ce141e75..bfda38a2 100644 --- a/tests/test_unix.cpp +++ b/tests/test_unix.cpp @@ -28,3 +28,27 @@ TEST(test_unix, host_parse_regression) { ASSERT_STREQ(out.port, "21211"); ASSERT_STREQ(out.alias, "testing"); } + +TEST(test_unix, socket_path_spaces) { + char test[] = "/tmp/spacey\\ path testing"; + ServerSpec out = splitServerString(test); + ASSERT_STREQ(out.host, "/tmp/spacey\\ path"); + ASSERT_EQ(out.port, nullptr); + ASSERT_STREQ(out.alias, "testing"); +} + +TEST(test_unix, socket_path_escaping) { + char test[] = "/tmp/spicy\\\\ path testing"; + ServerSpec out = splitServerString(test); + ASSERT_STREQ(out.host, "/tmp/spicy\\\\"); + ASSERT_EQ(out.port, nullptr); + ASSERT_STREQ(out.alias, "path"); +} + +TEST(test_unix, alias_space_escaping) { + char test[] = "/tmp/path testing\\ alias"; + ServerSpec out = splitServerString(test); + ASSERT_STREQ(out.host, "/tmp/path"); + ASSERT_EQ(out.port, nullptr); + ASSERT_STREQ(out.alias, "testing\\ alias"); +} From 1017ed8b711a7ac3d0a9748dafdf436a87439244 Mon Sep 17 00:00:00 2001 From: Kent Slaney Date: Thu, 30 Nov 2023 15:29:23 -0800 Subject: [PATCH 19/31] code hygiene --- libmc/__init__.py | 4 ++-- misc/memcached_server | 3 ++- src/Common.cpp | 1 + src/version.go | 4 ++-- tests/test_unix.cpp | 7 ++++++- 5 files changed, 13 insertions(+), 6 deletions(-) diff --git a/libmc/__init__.py b/libmc/__init__.py index b5ac549e..66f363b6 100644 --- a/libmc/__init__.py +++ b/libmc/__init__.py @@ -28,10 +28,10 @@ ) __VERSION__ = "1.4.2" -__version__ = "v1.4.2" +__version__ = "v1.4.2-25-g2a1c906" __author__ = "mckelvin" __email__ = "mckelvin@users.noreply.github.com" -__date__ = "Thu May 20 18:44:42 2021 +0800" +__date__ = "Thu Nov 30 14:32:18 2023 -0800" class Client(PyClient): diff --git a/misc/memcached_server b/misc/memcached_server index dc389d2d..d47acb13 100755 --- a/misc/memcached_server +++ b/misc/memcached_server @@ -53,7 +53,6 @@ function stop() kill -TERM `ps -ef | grep "$cmd" | grep $port | grep -v grep | awk '{ print $2 }'` echo "Stopping the memcached server on port '$port'... " fi - rm -rf $basedir } case "$1" in @@ -76,6 +75,7 @@ case "$1" in stop $port & done wait + rm -rf $basedir fi ;; restart) @@ -109,6 +109,7 @@ case "$1" in done fi wait + rm -rf $basedir ;; *) printf 'Usage: %s {start|stop|restart} \n' "$prog" diff --git a/src/Common.cpp b/src/Common.cpp index 747e0e68..a8288d1e 100644 --- a/src/Common.cpp +++ b/src/Common.cpp @@ -77,6 +77,7 @@ ServerSpec splitServerString(char* input) { return res; } } + /* FALLTHROUGH */ default: escaped = false; continue; diff --git a/src/version.go b/src/version.go index 28acf41f..85df6280 100644 --- a/src/version.go +++ b/src/version.go @@ -1,9 +1,9 @@ package golibmc -const _Version = "v1.4.2" +const _Version = "v1.4.2-25-g2a1c906" const _Author = "mckelvin" const _Email = "mckelvin@users.noreply.github.com" -const _Date = "Thu May 20 18:44:42 2021 +0800" +const _Date = "Thu Nov 30 14:32:18 2023 -0800" // Version of the package const Version = _Version diff --git a/tests/test_unix.cpp b/tests/test_unix.cpp index bfda38a2..0c9979fc 100644 --- a/tests/test_unix.cpp +++ b/tests/test_unix.cpp @@ -3,6 +3,7 @@ #include "test_common.h" #include +#include #include "gtest/gtest.h" using douban::mc::Client; @@ -12,12 +13,16 @@ using douban::mc::splitServerString; Client* newUnixClient() { const char * hosts[] = { "/tmp/env_mc_dev/var/run/unix_test.socket" }; const uint32_t ports[] = { 0 }; + struct stat info; + // fails if ../misc/memcached_server wasn't started with startall or unix + EXPECT_EQ(stat(hosts[0], &info), 0); + return md5Client(hosts, ports, 1); } TEST(test_unix, establish_connection) { Client* client = newUnixClient(); - EXPECT_TRUE(client != NULL); + ASSERT_TRUE(client != NULL); delete client; } From 38eb253d76a30862984df287271f19b34612818c Mon Sep 17 00:00:00 2001 From: Kent Slaney Date: Thu, 30 Nov 2023 15:43:12 -0800 Subject: [PATCH 20/31] version bump --- libmc/__init__.py | 6 +++--- src/version.go | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/libmc/__init__.py b/libmc/__init__.py index 66f363b6..57b89660 100644 --- a/libmc/__init__.py +++ b/libmc/__init__.py @@ -27,11 +27,11 @@ __file__ as _libmc_so_file ) -__VERSION__ = "1.4.2" -__version__ = "v1.4.2-25-g2a1c906" +__VERSION__ = "1.4.3" +__version__ = "v1.4.2-26-g1017ed8" __author__ = "mckelvin" __email__ = "mckelvin@users.noreply.github.com" -__date__ = "Thu Nov 30 14:32:18 2023 -0800" +__date__ = "Thu Nov 30 15:29:23 2023 -0800" class Client(PyClient): diff --git a/src/version.go b/src/version.go index 85df6280..2092de57 100644 --- a/src/version.go +++ b/src/version.go @@ -1,9 +1,9 @@ package golibmc -const _Version = "v1.4.2-25-g2a1c906" +const _Version = "v1.4.2-26-g1017ed8" const _Author = "mckelvin" const _Email = "mckelvin@users.noreply.github.com" -const _Date = "Thu Nov 30 14:32:18 2023 -0800" +const _Date = "Thu Nov 30 15:29:23 2023 -0800" // Version of the package const Version = _Version From 4d6f2d1f83c8ae6c00a7a9cb52c649db3ada21e6 Mon Sep 17 00:00:00 2001 From: Kent Slaney Date: Thu, 30 Nov 2023 16:21:51 -0800 Subject: [PATCH 21/31] syntax credit --- libmc/__init__.py | 4 ++-- src/Common.cpp | 2 ++ src/version.go | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/libmc/__init__.py b/libmc/__init__.py index 57b89660..c8534bfd 100644 --- a/libmc/__init__.py +++ b/libmc/__init__.py @@ -28,10 +28,10 @@ ) __VERSION__ = "1.4.3" -__version__ = "v1.4.2-26-g1017ed8" +__version__ = "v1.4.2-27-g38eb253" __author__ = "mckelvin" __email__ = "mckelvin@users.noreply.github.com" -__date__ = "Thu Nov 30 15:29:23 2023 -0800" +__date__ = "Thu Nov 30 15:43:12 2023 -0800" class Client(PyClient): diff --git a/src/Common.cpp b/src/Common.cpp index a8288d1e..bc197c8b 100644 --- a/src/Common.cpp +++ b/src/Common.cpp @@ -51,6 +51,8 @@ const char* errCodeToString(err_code_t err) { } bool isLocalSocket(const char* host) { + // errors on the side of false negatives, allowing syntax expansion; + // starting slash to denote socket paths is from pylibmc return host[0] == '/'; } diff --git a/src/version.go b/src/version.go index 2092de57..7ce410da 100644 --- a/src/version.go +++ b/src/version.go @@ -1,9 +1,9 @@ package golibmc -const _Version = "v1.4.2-26-g1017ed8" +const _Version = "v1.4.2-27-g38eb253" const _Author = "mckelvin" const _Email = "mckelvin@users.noreply.github.com" -const _Date = "Thu Nov 30 15:29:23 2023 -0800" +const _Date = "Thu Nov 30 15:43:12 2023 -0800" // Version of the package const Version = _Version From 687c53f8bba0e26f232f8c761d5452ff2bc5f259 Mon Sep 17 00:00:00 2001 From: Kent Slaney Date: Thu, 30 Nov 2023 16:45:29 -0800 Subject: [PATCH 22/31] version bump not overwritten by pre-commit hook --- libmc/__init__.py | 2 +- src/version.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libmc/__init__.py b/libmc/__init__.py index c8534bfd..bab2d53f 100644 --- a/libmc/__init__.py +++ b/libmc/__init__.py @@ -28,7 +28,7 @@ ) __VERSION__ = "1.4.3" -__version__ = "v1.4.2-27-g38eb253" +__version__ = "v1.4.3" __author__ = "mckelvin" __email__ = "mckelvin@users.noreply.github.com" __date__ = "Thu Nov 30 15:43:12 2023 -0800" diff --git a/src/version.go b/src/version.go index 7ce410da..d079abc7 100644 --- a/src/version.go +++ b/src/version.go @@ -1,9 +1,9 @@ package golibmc -const _Version = "v1.4.2-27-g38eb253" +const _Version = "v1.4.3" const _Author = "mckelvin" const _Email = "mckelvin@users.noreply.github.com" -const _Date = "Thu Nov 30 15:43:12 2023 -0800" +const _Date = "Fri Dec 01 07:43:12 2023 +0800" // Version of the package const Version = _Version From bb78109ff7b6686d3bded551d5629c36d7a72708 Mon Sep 17 00:00:00 2001 From: Kent Slaney Date: Thu, 30 Nov 2023 16:49:34 -0800 Subject: [PATCH 23/31] timezone matching email --- libmc/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libmc/__init__.py b/libmc/__init__.py index bab2d53f..1ba92cb7 100644 --- a/libmc/__init__.py +++ b/libmc/__init__.py @@ -31,7 +31,7 @@ __version__ = "v1.4.3" __author__ = "mckelvin" __email__ = "mckelvin@users.noreply.github.com" -__date__ = "Thu Nov 30 15:43:12 2023 -0800" +__date__ = "Fri Dec 01 07:43:12 2023 +0800" class Client(PyClient): From f486bb043832507f6ce6aa972fbb618e5048ca4d Mon Sep 17 00:00:00 2001 From: Kent Slaney Date: Thu, 30 Nov 2023 17:01:58 -0800 Subject: [PATCH 24/31] padding type --- libmc/__init__.py | 2 +- src/version.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libmc/__init__.py b/libmc/__init__.py index 1ba92cb7..a4395a6b 100644 --- a/libmc/__init__.py +++ b/libmc/__init__.py @@ -31,7 +31,7 @@ __version__ = "v1.4.3" __author__ = "mckelvin" __email__ = "mckelvin@users.noreply.github.com" -__date__ = "Fri Dec 01 07:43:12 2023 +0800" +__date__ = "Fri Dec 1 07:43:12 2023 +0800" class Client(PyClient): diff --git a/src/version.go b/src/version.go index d079abc7..38f0f52d 100644 --- a/src/version.go +++ b/src/version.go @@ -3,7 +3,7 @@ package golibmc const _Version = "v1.4.3" const _Author = "mckelvin" const _Email = "mckelvin@users.noreply.github.com" -const _Date = "Fri Dec 01 07:43:12 2023 +0800" +const _Date = "Fri Dec 1 07:43:12 2023 +0800" // Version of the package const Version = _Version From 89d31534d9a20bac03e4feeebaecff78bd8b051a Mon Sep 17 00:00:00 2001 From: Kent Slaney Date: Thu, 30 Nov 2023 19:15:05 -0800 Subject: [PATCH 25/31] fix port interpretation --- src/Common.cpp | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/src/Common.cpp b/src/Common.cpp index bc197c8b..15a85a1e 100644 --- a/src/Common.cpp +++ b/src/Common.cpp @@ -56,38 +56,54 @@ bool isLocalSocket(const char* host) { return host[0] == '/'; } +void verifyPort(const char* input, ServerSpec* res, bool* valid_port) { + if (*valid_port && input > res->port) { + res->port[-1] = '\0'; + } else if (res->alias == NULL) { + res->port = NULL; + } + *valid_port = false; +} + // modifies input string and output pointers reference input ServerSpec splitServerString(char* input) { - bool escaped = false; + bool escaped = false, valid_port = false; ServerSpec res = { input, NULL, NULL }; for (;; input++) { switch (*input) { case '\0': + verifyPort(input, &res, &valid_port); return res; - case ':': // invalid in a UNIX path - *input = '\0'; - res.port = input + 1; + case ':': + if (res.alias == NULL) { + res.port = input + 1; + valid_port = true; + } + escaped = false; continue; case ' ': if (!escaped) { *input = '\0'; if (res.alias == NULL) { res.alias = input + 1; + verifyPort(input, &res, &valid_port); continue; } else { return res; } } - /* FALLTHROUGH */ default: + valid_port = false; + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': escaped = false; continue; case '\\': escaped ^= 1; + valid_port = false; } } - return res; } } // namespace mc From 48c21f38dbe54b7e739092808660ea530958701b Mon Sep 17 00:00:00 2001 From: Kent Slaney Date: Thu, 30 Nov 2023 20:24:24 -0800 Subject: [PATCH 26/31] revert to existing distribution of responsibilities --- src/Common.cpp | 5 +++++ tests/test_unix.cpp | 16 ++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/src/Common.cpp b/src/Common.cpp index 15a85a1e..5d6f682f 100644 --- a/src/Common.cpp +++ b/src/Common.cpp @@ -57,12 +57,17 @@ bool isLocalSocket(const char* host) { } void verifyPort(const char* input, ServerSpec* res, bool* valid_port) { + /* if (*valid_port && input > res->port) { res->port[-1] = '\0'; } else if (res->alias == NULL) { res->port = NULL; } *valid_port = false; + */ + if (res->port != NULL) { + res->port[-1] = '\0'; + } } // modifies input string and output pointers reference input diff --git a/tests/test_unix.cpp b/tests/test_unix.cpp index 0c9979fc..bfc28342 100644 --- a/tests/test_unix.cpp +++ b/tests/test_unix.cpp @@ -34,6 +34,22 @@ TEST(test_unix, host_parse_regression) { ASSERT_STREQ(out.alias, "testing"); } +TEST(test_unix, host_parse_regression_tripped) { + char test[] = "127.0.0.1:21211 127.0.0.1:21211"; + ServerSpec out = splitServerString(test); + ASSERT_STREQ(out.host, "127.0.0.1"); + ASSERT_STREQ(out.port, "21211"); + ASSERT_STREQ(out.alias, "127.0.0.1:21211"); +} + +TEST(test_unix, tmpname) { + char test[] = "127.0.0.1:invalid_port"; + ServerSpec out = splitServerString(test); + ASSERT_STREQ(out.host, "127.0.0.1"); + ASSERT_STREQ(out.port, "invalid_port"); + ASSERT_EQ(out.alias, nullptr); +} + TEST(test_unix, socket_path_spaces) { char test[] = "/tmp/spacey\\ path testing"; ServerSpec out = splitServerString(test); From d6f2b44f65a681cae5abafaee5853d561ff76ccd Mon Sep 17 00:00:00 2001 From: Kent Slaney Date: Thu, 30 Nov 2023 20:36:20 -0800 Subject: [PATCH 27/31] deduplicate golang test cases --- tests/test_unix.cpp | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/tests/test_unix.cpp b/tests/test_unix.cpp index bfc28342..0c9979fc 100644 --- a/tests/test_unix.cpp +++ b/tests/test_unix.cpp @@ -34,22 +34,6 @@ TEST(test_unix, host_parse_regression) { ASSERT_STREQ(out.alias, "testing"); } -TEST(test_unix, host_parse_regression_tripped) { - char test[] = "127.0.0.1:21211 127.0.0.1:21211"; - ServerSpec out = splitServerString(test); - ASSERT_STREQ(out.host, "127.0.0.1"); - ASSERT_STREQ(out.port, "21211"); - ASSERT_STREQ(out.alias, "127.0.0.1:21211"); -} - -TEST(test_unix, tmpname) { - char test[] = "127.0.0.1:invalid_port"; - ServerSpec out = splitServerString(test); - ASSERT_STREQ(out.host, "127.0.0.1"); - ASSERT_STREQ(out.port, "invalid_port"); - ASSERT_EQ(out.alias, nullptr); -} - TEST(test_unix, socket_path_spaces) { char test[] = "/tmp/spacey\\ path testing"; ServerSpec out = splitServerString(test); From 719978040f01afab31506e8e1111178927545b56 Mon Sep 17 00:00:00 2001 From: Kent Slaney Date: Thu, 30 Nov 2023 20:50:28 -0800 Subject: [PATCH 28/31] remove unnecessary inline in header --- include/Connection.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/Connection.h b/include/Connection.h index e1fd2a81..d3c12dad 100644 --- a/include/Connection.h +++ b/include/Connection.h @@ -62,7 +62,7 @@ class Connection { protected: int connectPoll(int fd, const sockaddr* ai_ptr, const socklen_t ai_addrlen); - inline int local(); + int local(); char m_name[MC_NI_MAXHOST + 1 + MC_NI_MAXSERV]; char m_host[MC_NI_MAXHOST]; From bf1f2e1b034fcebdccec4cc4e6cf19a3275a1dd7 Mon Sep 17 00:00:00 2001 From: Kent Slaney Date: Fri, 1 Dec 2023 11:11:19 -0800 Subject: [PATCH 29/31] rewrote to match default branch parsing more closely --- src/Common.cpp | 28 +++++----------------------- 1 file changed, 5 insertions(+), 23 deletions(-) diff --git a/src/Common.cpp b/src/Common.cpp index 5d6f682f..fdcf7073 100644 --- a/src/Common.cpp +++ b/src/Common.cpp @@ -56,34 +56,21 @@ bool isLocalSocket(const char* host) { return host[0] == '/'; } -void verifyPort(const char* input, ServerSpec* res, bool* valid_port) { - /* - if (*valid_port && input > res->port) { - res->port[-1] = '\0'; - } else if (res->alias == NULL) { - res->port = NULL; - } - *valid_port = false; - */ - if (res->port != NULL) { - res->port[-1] = '\0'; - } -} - // modifies input string and output pointers reference input ServerSpec splitServerString(char* input) { - bool escaped = false, valid_port = false; + bool escaped = false; ServerSpec res = { input, NULL, NULL }; for (;; input++) { switch (*input) { case '\0': - verifyPort(input, &res, &valid_port); return res; case ':': if (res.alias == NULL) { - res.port = input + 1; - valid_port = true; + *input = '\0'; + if (res.port == NULL) { + res.port = input + 1; + } } escaped = false; continue; @@ -92,21 +79,16 @@ ServerSpec splitServerString(char* input) { *input = '\0'; if (res.alias == NULL) { res.alias = input + 1; - verifyPort(input, &res, &valid_port); continue; } else { return res; } } default: - valid_port = false; - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': escaped = false; continue; case '\\': escaped ^= 1; - valid_port = false; } } } From fd9e67690c0c1e224ad2cec837ebd82b7da6e6f1 Mon Sep 17 00:00:00 2001 From: Kent Slaney Date: Sun, 10 Dec 2023 17:01:55 -0800 Subject: [PATCH 30/31] more descriptive names --- include/Common.h | 2 +- include/Connection.h | 4 ++-- include/Export.h | 2 +- include/c_client.h | 2 +- libmc/_client.pyx | 4 ++-- src/Common.cpp | 4 ++-- src/Connection.cpp | 12 ++++++------ src/c_client.cpp | 2 +- tests/test_unix.cpp | 8 ++++---- 9 files changed, 20 insertions(+), 20 deletions(-) diff --git a/include/Common.h b/include/Common.h index 2414ed41..f7a22de8 100644 --- a/include/Common.h +++ b/include/Common.h @@ -227,7 +227,7 @@ typedef enum { const char* errCodeToString(err_code_t err); bool isLocalSocket(const char* host); -ServerSpec splitServerString(char* input); +server_string_split_t splitServerString(char* input); } // namespace mc } // namespace douban diff --git a/include/Connection.h b/include/Connection.h index d3c12dad..c54f0379 100644 --- a/include/Connection.h +++ b/include/Connection.h @@ -62,7 +62,7 @@ class Connection { protected: int connectPoll(int fd, const sockaddr* ai_ptr, const socklen_t ai_addrlen); - int local(); + int unixSocketConnect(); char m_name[MC_NI_MAXHOST + 1 + MC_NI_MAXSERV]; char m_host[MC_NI_MAXHOST]; @@ -71,7 +71,7 @@ class Connection { int m_socketFd; bool m_alive; bool m_hasAlias; - bool m_local; + bool m_unixSocket; time_t m_deadUntil; io::BufferWriter* m_buffer_writer; // for send io::BufferReader* m_buffer_reader; // for recv diff --git a/include/Export.h b/include/Export.h index 832c0bc9..97a026c0 100644 --- a/include/Export.h +++ b/include/Export.h @@ -42,7 +42,7 @@ typedef struct { char* host; char* port; char* alias; -} ServerSpec; +} server_string_split_t; typedef int64_t exptime_t; diff --git a/include/c_client.h b/include/c_client.h index 53201c8f..21b0c4e9 100644 --- a/include/c_client.h +++ b/include/c_client.h @@ -68,7 +68,7 @@ extern "C" { err_code_t client_quit(void* client); const char* err_code_to_string(err_code_t err); - ServerSpec splitServerString(char* input); + server_string_split_t splitServerString(char* input); #ifdef __cplusplus } #endif diff --git a/libmc/_client.pyx b/libmc/_client.pyx index 611bbcc5..44719d0a 100644 --- a/libmc/_client.pyx +++ b/libmc/_client.pyx @@ -45,7 +45,7 @@ cdef extern from "Common.h" namespace "douban::mc": VERSION_OP QUIT_OP - ServerSpec splitServerString(char* input) nogil + server_string_split_t splitServerString(char* input) nogil cdef extern from "Export.h": @@ -101,7 +101,7 @@ cdef extern from "Export.h": RET_INCOMPLETE_BUFFER_ERR RET_OK - ctypedef struct ServerSpec: + ctypedef struct server_string_split_t: char* host char* port char* alias diff --git a/src/Common.cpp b/src/Common.cpp index fdcf7073..2e75ffca 100644 --- a/src/Common.cpp +++ b/src/Common.cpp @@ -57,9 +57,9 @@ bool isLocalSocket(const char* host) { } // modifies input string and output pointers reference input -ServerSpec splitServerString(char* input) { +server_string_split_t splitServerString(char* input) { bool escaped = false; - ServerSpec res = { input, NULL, NULL }; + server_string_split_t res = { input, NULL, NULL }; for (;; input++) { switch (*input) { diff --git a/src/Connection.cpp b/src/Connection.cpp index c664abde..0b95c8b3 100644 --- a/src/Connection.cpp +++ b/src/Connection.cpp @@ -23,7 +23,7 @@ namespace mc { Connection::Connection() : m_counter(0), m_port(0), m_socketFd(-1), - m_alive(false), m_hasAlias(false), m_local(false), + m_alive(false), m_hasAlias(false), m_unixSocket(false), m_deadUntil(0), m_connectTimeout(MC_DEFAULT_CONNECT_TIMEOUT), m_retryTimeout(MC_DEFAULT_RETRY_TIMEOUT), m_maxRetries(MC_DEFAULT_MAX_RETRIES), m_retires(0) { @@ -47,10 +47,10 @@ Connection::~Connection() { int Connection::init(const char* host, uint32_t port, const char* alias) { snprintf(m_host, sizeof m_host, "%s", host); m_port = port; - m_local = isLocalSocket(m_host); + m_unixSocket = isLocalSocket(m_host); if (alias == NULL) { m_hasAlias = false; - if (m_local) { + if (m_unixSocket) { snprintf(m_name, sizeof m_name, "%s", m_host); } else { snprintf(m_name, sizeof m_name, "%s:%u", m_host, m_port); @@ -66,8 +66,8 @@ int Connection::init(const char* host, uint32_t port, const char* alias) { int Connection::connect() { assert(!m_alive); this->close(); - if (m_local) { - return local(); + if (m_unixSocket) { + return unixSocketConnect(); } struct addrinfo hints, *server_addrinfo = NULL, *ai_ptr = NULL; @@ -132,7 +132,7 @@ int Connection::connect() { return m_alive ? 0 : -1; } -int Connection::local() { +int Connection::unixSocketConnect() { int fd, flags, opt_keepalive = 1; if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { diff --git a/src/c_client.cpp b/src/c_client.cpp index 424e11d1..88b9d128 100644 --- a/src/c_client.cpp +++ b/src/c_client.cpp @@ -160,6 +160,6 @@ const char* err_code_to_string(err_code_t err) { return douban::mc::errCodeToString(err); } -ServerSpec splitServerString(char* input) { +server_string_split_t splitServerString(char* input) { return douban::mc::splitServerString(input); } diff --git a/tests/test_unix.cpp b/tests/test_unix.cpp index 0c9979fc..71743e57 100644 --- a/tests/test_unix.cpp +++ b/tests/test_unix.cpp @@ -28,7 +28,7 @@ TEST(test_unix, establish_connection) { TEST(test_unix, host_parse_regression) { char test[] = "127.0.0.1:21211 testing"; - ServerSpec out = splitServerString(test); + server_string_split_t out = splitServerString(test); ASSERT_STREQ(out.host, "127.0.0.1"); ASSERT_STREQ(out.port, "21211"); ASSERT_STREQ(out.alias, "testing"); @@ -36,7 +36,7 @@ TEST(test_unix, host_parse_regression) { TEST(test_unix, socket_path_spaces) { char test[] = "/tmp/spacey\\ path testing"; - ServerSpec out = splitServerString(test); + server_string_split_t out = splitServerString(test); ASSERT_STREQ(out.host, "/tmp/spacey\\ path"); ASSERT_EQ(out.port, nullptr); ASSERT_STREQ(out.alias, "testing"); @@ -44,7 +44,7 @@ TEST(test_unix, socket_path_spaces) { TEST(test_unix, socket_path_escaping) { char test[] = "/tmp/spicy\\\\ path testing"; - ServerSpec out = splitServerString(test); + server_string_split_t out = splitServerString(test); ASSERT_STREQ(out.host, "/tmp/spicy\\\\"); ASSERT_EQ(out.port, nullptr); ASSERT_STREQ(out.alias, "path"); @@ -52,7 +52,7 @@ TEST(test_unix, socket_path_escaping) { TEST(test_unix, alias_space_escaping) { char test[] = "/tmp/path testing\\ alias"; - ServerSpec out = splitServerString(test); + server_string_split_t out = splitServerString(test); ASSERT_STREQ(out.host, "/tmp/path"); ASSERT_EQ(out.port, nullptr); ASSERT_STREQ(out.alias, "testing\\ alias"); From f47811b1564c6b52852b3ce24671a71eee544270 Mon Sep 17 00:00:00 2001 From: Kent Slaney Date: Sun, 10 Dec 2023 20:52:48 -0800 Subject: [PATCH 31/31] apt-get update before install --- .github/workflows/cpp.yml | 1 + .github/workflows/golang.yml | 1 + .github/workflows/python.yml | 2 ++ 3 files changed, 4 insertions(+) diff --git a/.github/workflows/cpp.yml b/.github/workflows/cpp.yml index 0eaee9c8..c82e2482 100644 --- a/.github/workflows/cpp.yml +++ b/.github/workflows/cpp.yml @@ -14,6 +14,7 @@ jobs: - uses: actions/checkout@v2 - name: Setup system dependencies run: | + sudo apt-get update sudo apt-get -y install cppcheck - name: Run cppcheck run: | diff --git a/.github/workflows/golang.yml b/.github/workflows/golang.yml index f0d441e7..c542e54e 100644 --- a/.github/workflows/golang.yml +++ b/.github/workflows/golang.yml @@ -19,6 +19,7 @@ jobs: - uses: actions/checkout@v2 - name: Setup system dependencies run: | + sudo apt-get update sudo apt-get -y install memcached g++ - name: Set up Golang uses: actions/setup-go@v2 diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index a54ae940..f364f304 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -19,6 +19,7 @@ jobs: - uses: actions/checkout@v2 - name: Setup system dependencies run: | + sudo apt-get update sudo apt-get -y install valgrind memcached g++ - name: Set up Python uses: actions/setup-python@v2 @@ -48,6 +49,7 @@ jobs: - uses: actions/checkout@v2 - name: Setup system dependencies run: | + sudo apt-get update sudo apt-get -y install memcached libmemcached-dev g++ - name: Set up Python uses: actions/setup-python@v2