From 6a319dc6554e9d4a1a9d5ac0e87709db869114ff Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Tue, 12 Nov 2019 15:20:32 +0200 Subject: [PATCH] MXS-2727 Add test that reveals problem --- .../modules/filter/cache/test/CMakeLists.txt | 5 + .../modules/filter/cache/test/cache_bugs.cc | 113 ++++++++++++++++++ 2 files changed, 118 insertions(+) create mode 100644 server/modules/filter/cache/test/cache_bugs.cc diff --git a/server/modules/filter/cache/test/CMakeLists.txt b/server/modules/filter/cache/test/CMakeLists.txt index 2d6c50f5d..6644eacf7 100644 --- a/server/modules/filter/cache/test/CMakeLists.txt +++ b/server/modules/filter/cache/test/CMakeLists.txt @@ -46,6 +46,11 @@ target_link_libraries(test_cacheoptions maxscale-common) add_executable(cache_stress cache_stress.cc) target_link_libraries(cache_stress ${MARIADB_CONNECTOR_LIBRARIES} ssl crypt crypto dl pthread) +add_executable(cache_bugs cache_bugs.cc) +target_link_libraries(cache_bugs cache maxscale-common mysqlcommon) + +add_test(test_cache_bugs cache_bugs) + add_test(test_cache_rules testrules) add_test(test_cache_inmemory_keygeneration testkeygeneration storage_inmemory ${CMAKE_CURRENT_SOURCE_DIR}/input.test) diff --git a/server/modules/filter/cache/test/cache_bugs.cc b/server/modules/filter/cache/test/cache_bugs.cc new file mode 100644 index 000000000..82c758c19 --- /dev/null +++ b/server/modules/filter/cache/test/cache_bugs.cc @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2016 MariaDB Corporation Ab + * + * Use of this software is governed by the Business Source License included + * in the LICENSE.TXT file and at www.mariadb.com/bsl11. + * + * Change Date: 2023-01-01 + * + * On the date above, in accordance with the Business Source License, use + * of this software will be governed by version 2 or later of the General + * Public License. + */ + +#include +#include +#include +#include +#include +#include +#include "../cachemt.hh" + +using namespace std; + +namespace +{ + +GWBUF* create_gwbuf(const string& s) +{ + size_t len = s.length(); + size_t payload_len = len + 1; + size_t gwbuf_len = MYSQL_HEADER_LEN + payload_len; + + GWBUF* pBuf = gwbuf_alloc(gwbuf_len); + + *((unsigned char*)((char*)GWBUF_DATA(pBuf))) = payload_len; + *((unsigned char*)((char*)GWBUF_DATA(pBuf) + 1)) = (payload_len >> 8); + *((unsigned char*)((char*)GWBUF_DATA(pBuf) + 2)) = (payload_len >> 16); + *((unsigned char*)((char*)GWBUF_DATA(pBuf) + 3)) = 0x00; + *((unsigned char*)((char*)GWBUF_DATA(pBuf) + 4)) = 0x03; + memcpy((char*)GWBUF_DATA(pBuf) + 5, s.c_str(), len); + + return pBuf; +} + +int mxs_2727() +{ + int rv = 0; + + const size_t MAX_SIZE = 10; + + CacheConfig config("MXS-2727"); + config.storage = std::string("storage_inmemory"); + config.soft_ttl = std::chrono::seconds(1); + config.hard_ttl = std::chrono::seconds(10); + config.max_size = MAX_SIZE; + config.thread_model = CACHE_THREAD_MODEL_MT; + config.enabled = true; + + auto* pCache = CacheMT::Create("MXS-2727", &config); + + CACHE_KEY key; + GWBUF* pSelect = create_gwbuf("SELECT * FROM t"); + + cache_result_t result = pCache->get_key("test", pSelect, &key); + + if (!CACHE_RESULT_IS_OK(result)) + { + return 1; + } + + vector value(MAX_SIZE - 1); // Less than max size. + std::generate(value.begin(), value.end(), random); + + GWBUF* pValue = gwbuf_alloc_and_load(value.size(), &value.front()); + + result = pCache->put_value(key, pValue); + gwbuf_free(pValue); + + if (!CACHE_RESULT_IS_OK(result)) + { + return 1; + } + + value.push_back(4); + value.push_back(2); + // Now, larger than max size. + + pValue = gwbuf_alloc_and_load(value.size(), &value.front()); + + // This will crash without the MXS-2727 fix. + result = pCache->put_value(key, pValue); + gwbuf_free(pValue); + + if (!CACHE_RESULT_IS_OK(result)) + { + return 1; + } + + return 0; +} + +} + +int main() +{ + mxb::Log log; + + int rv = 0; + + rv += mxs_2727(); + + return rv == 0 ? EXIT_SUCCESS : EXIT_FAILURE; +}