MXS-1475 Add test case for @maxscale.cache.[use|populate]
Also extend logging.
This commit is contained in:
216
maxscale-system-test/cache_runtime.cpp
Normal file
216
maxscale-system-test/cache_runtime.cpp
Normal file
@ -0,0 +1,216 @@
|
||||
/*
|
||||
* 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: 2020-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 <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "testconnections.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
void drop(TestConnections& test)
|
||||
{
|
||||
MYSQL* pMysql = test.maxscales->conn_rwsplit[0];
|
||||
|
||||
string stmt("DROP TABLE IF EXISTS cache_test");
|
||||
|
||||
cout << stmt << endl;
|
||||
test.try_query(pMysql, stmt.c_str());
|
||||
}
|
||||
|
||||
void create(TestConnections& test)
|
||||
{
|
||||
drop(test);
|
||||
|
||||
MYSQL* pMysql = test.maxscales->conn_rwsplit[0];
|
||||
|
||||
string stmt("CREATE TABLE cache_test (a INT)");
|
||||
|
||||
cout << stmt << endl;
|
||||
test.try_query(pMysql, stmt.c_str());
|
||||
}
|
||||
|
||||
void insert(TestConnections& test)
|
||||
{
|
||||
MYSQL* pMysql = test.maxscales->conn_rwsplit[0];
|
||||
|
||||
string stmt("INSERT INTO cache_test VALUES (1)");
|
||||
|
||||
cout << stmt << endl;
|
||||
test.try_query(pMysql, stmt.c_str());
|
||||
}
|
||||
|
||||
void update(TestConnections& test, int value)
|
||||
{
|
||||
MYSQL* pMysql = test.maxscales->conn_rwsplit[0];
|
||||
|
||||
string stmt("UPDATE cache_test SET a=");
|
||||
stmt += std::to_string(value);
|
||||
|
||||
cout << stmt << endl;
|
||||
test.try_query(pMysql, stmt.c_str());
|
||||
}
|
||||
|
||||
void select(TestConnections& test, int* pValue)
|
||||
{
|
||||
MYSQL* pMysql = test.maxscales->conn_rwsplit[0];
|
||||
|
||||
string stmt("SELECT * FROM cache_test");
|
||||
|
||||
cout << stmt << endl;
|
||||
|
||||
if (mysql_query(pMysql, stmt.c_str()) == 0)
|
||||
{
|
||||
if (mysql_field_count(pMysql) != 0)
|
||||
{
|
||||
size_t nRows = 0;
|
||||
|
||||
do
|
||||
{
|
||||
MYSQL_RES* pRes = mysql_store_result(pMysql);
|
||||
MYSQL_ROW row = mysql_fetch_row(pRes);
|
||||
*pValue = atoi(row[0]);
|
||||
mysql_free_result(pRes);
|
||||
++nRows;
|
||||
}
|
||||
while (mysql_next_result(pMysql) == 0);
|
||||
|
||||
test.assert(nRows == 1, "Unexpected number of rows: %u", nRows);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
test.assert(false, "SELECT failed.");
|
||||
}
|
||||
}
|
||||
|
||||
namespace Cache
|
||||
{
|
||||
|
||||
enum What
|
||||
{
|
||||
POPULATE,
|
||||
USE
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
void set(TestConnections& test, Cache::What what, bool value)
|
||||
{
|
||||
MYSQL* pMysql = test.maxscales->conn_rwsplit[0];
|
||||
|
||||
string stmt("SET @maxscale.cache.");
|
||||
stmt += ((what == Cache::POPULATE) ? "populate" : "use");
|
||||
stmt += "=";
|
||||
stmt += (value ? "true" : "false");
|
||||
|
||||
cout << stmt << endl;
|
||||
test.try_query(pMysql, stmt.c_str());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
void init(TestConnections& test)
|
||||
{
|
||||
create(test);
|
||||
insert(test);
|
||||
}
|
||||
|
||||
void run(TestConnections& test)
|
||||
{
|
||||
init(test);
|
||||
|
||||
MYSQL* pMysql = test.maxscales->conn_rwsplit[0];
|
||||
|
||||
int value;
|
||||
|
||||
// Let's populate the cache.
|
||||
set(test, Cache::POPULATE, true);
|
||||
set(test, Cache::USE, false);
|
||||
select(test, &value);
|
||||
test.assert(value == 1, "Initial value was not 1.");
|
||||
|
||||
// And update the real value.
|
||||
update(test, 2); // Now the cache contains 1 and the db 2.
|
||||
|
||||
// With @maxscale.cache.use==false we should get the updated value.
|
||||
set(test, Cache::POPULATE, false);
|
||||
set(test, Cache::USE, false);
|
||||
select(test, &value);
|
||||
test.assert(value == 2, "The value received was not the latest one.");
|
||||
|
||||
// With @maxscale.cache.use==true we should get the old one, since
|
||||
// it was not updated above as @maxscale.cache.populate==false.
|
||||
set(test, Cache::POPULATE, false);
|
||||
set(test, Cache::USE, true);
|
||||
select(test, &value);
|
||||
test.assert(value == 1, "The value received was not the populated one.");
|
||||
|
||||
// The hard_ttl is 8, so we sleep(10) seconds to ensure that TTL has passed.
|
||||
cout << "Sleeping 10 seconds." << endl;
|
||||
sleep(10);
|
||||
|
||||
// With @maxscale.cache.use==true we should now get the latest value.
|
||||
// The value in the cache is stale, so it will be updated even if
|
||||
// @maxscale.cache.populate==false.
|
||||
set(test, Cache::POPULATE, false);
|
||||
set(test, Cache::USE, true);
|
||||
select(test, &value);
|
||||
test.assert(value == 2, "The cache was not updated even if TTL was passed.");
|
||||
|
||||
// Let's update again
|
||||
update(test, 3);
|
||||
|
||||
// And fetch again. Should still be 2, as the item in the cache is not stale.
|
||||
set(test, Cache::POPULATE, false);
|
||||
set(test, Cache::USE, true);
|
||||
select(test, &value);
|
||||
test.assert(value == 2, "New value %d, although the value in the cache is not stale.", value);
|
||||
|
||||
// Force an update.
|
||||
set(test, Cache::POPULATE, true);
|
||||
set(test, Cache::USE, false);
|
||||
select(test, &value);
|
||||
test.assert(value == 3, "Did not get new value.");
|
||||
|
||||
// And check that the cache indeed was updated, but update the DB first.
|
||||
update(test, 4);
|
||||
|
||||
set(test, Cache::POPULATE, false);
|
||||
set(test, Cache::USE, true);
|
||||
select(test, &value);
|
||||
test.assert(value == 3, "Got a newer value than expected.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
std::ios::sync_with_stdio(true);
|
||||
|
||||
TestConnections test(argc, argv);
|
||||
|
||||
if (test.maxscales->connect_rwsplit() == 0)
|
||||
{
|
||||
run(test);
|
||||
}
|
||||
|
||||
return test.global_result;
|
||||
}
|
Reference in New Issue
Block a user