Cache: Use Tester facilities in testkeygeneration

This commit is contained in:
Johan Wikman
2016-12-16 14:20:04 +02:00
parent 23556cdfa2
commit 43c694020c
4 changed files with 107 additions and 91 deletions

View File

@ -15,7 +15,7 @@ add_executable(testkeygeneration
testkeygeneration.cc
../../../../../query_classifier/test/testreader.cc
)
target_link_libraries(testkeygeneration maxscale-common cache)
target_link_libraries(testkeygeneration cachetester cache maxscale-common)
add_executable(testrawstorage testrawstorage.cc)
target_link_libraries(testrawstorage cachetester cache maxscale-common)
@ -25,8 +25,8 @@ target_link_libraries(testlrustorage cachetester cache maxscale-common)
add_test(TestCache_rules testrules)
add_test(TestCache_keygeneration testkeygeneration storage_inmemory ${CMAKE_CURRENT_SOURCE_DIR}/input.test)
add_test(TestCache_keygeneration testkeygeneration storage_rocksdb ${CMAKE_CURRENT_SOURCE_DIR}/input.test)
add_test(TestCache_inmemory_keygeneration testkeygeneration storage_inmemory ${CMAKE_CURRENT_SOURCE_DIR}/input.test)
add_test(TestCache_rocksdb_keygeneration testkeygeneration storage_rocksdb ${CMAKE_CURRENT_SOURCE_DIR}/input.test)
add_test(TestCache_storage_inmemory testrawstorage 10 storage_inmemory ${CMAKE_CURRENT_SOURCE_DIR}/input.test)
add_test(TestCache_storage_rocksdb testrawstorage 10 storage_rocksdb ${CMAKE_CURRENT_SOURCE_DIR}/input.test)

View File

@ -171,11 +171,16 @@ GWBUF* Tester::gwbuf_from_vector(const std::vector<uint8_t>& v)
}
// static
bool Tester::get_statements(std::istream& in, size_t n_statements, Statements* pStatements)
bool Tester::get_unique_statements(std::istream& in, size_t n_statements, Statements* pStatements)
{
TestReader::result_t result = TestReader::RESULT_ERROR;
typedef set<string> StatementsSet;
if (n_statements == 0)
{
n_statements = UINT_MAX;
}
TestReader::result_t result = TestReader::RESULT_ERROR;
typedef set<string> StatementsSet;
StatementsSet statements;
TestReader reader(in);
@ -198,6 +203,30 @@ bool Tester::get_statements(std::istream& in, size_t n_statements, Statements* p
return result != TestReader::RESULT_ERROR;
}
// static
bool Tester::get_statements(std::istream& in, size_t n_statements, Statements* pStatements)
{
if (n_statements == 0)
{
n_statements = UINT_MAX;
}
TestReader::result_t result = TestReader::RESULT_ERROR;
TestReader reader(in);
size_t n = 0;
string statement;
while ((n < n_statements) &&
((result = reader.get_statement(statement)) == TestReader::RESULT_STMT))
{
pStatements->push_back(statement);
++n;
}
return result != TestReader::RESULT_ERROR;
}
// static
bool Tester::get_cache_items(const Statements& statements,
const StorageFactory& factory,
@ -245,7 +274,7 @@ bool Tester::get_cache_items(std::istream& in,
{
Statements statements;
bool rv = get_statements(in, n_items, &statements);
bool rv = get_unique_statements(in, n_items, &statements);
if (rv)
{

View File

@ -154,11 +154,24 @@ public:
static GWBUF* gwbuf_from_vector(const std::vector<uint8_t>& v);
/**
* Returns statements from a MySQL/MariaDB server test file.
* Returns unique statements from a MySQL/MariaDB server test file.
*
* @param in The stream from which input should be read. Assumed to refer to a
* MySQL/MariaDB test file.
* @param n_statements How many statements to return.
* @param n_statements How many statements to return; a value of 0 means no limit.
* @param pStatements Pointer to vector where statements will be back inserted.
* May contain less statements that specified in @n_statements.
*
* @return Whether reading was successful, not whether @n_statements statements were returned.
*/
static bool get_unique_statements(std::istream& in, size_t n_statements, Statements* pStatements);
/**
* Returns all statements from a MySQL/MariaDB server test file.
*
* @param in The stream from which input should be read. Assumed to refer to a
* MySQL/MariaDB test file.
* @param n_statements How many statements to return; a value of 0 means no limit.
* @param pStatements Pointer to vector where statements will be back inserted.
* May contain less statements that specified in @n_statements.
*

View File

@ -18,11 +18,8 @@
#include <maxscale/query_classifier.h>
#include <maxscale/log_manager.h>
#include "storagefactory.hh"
#include "storage.hh"
#include "cache_storage_api.hh"
// TODO: Move this to a common place.
#include "../../../../../query_classifier/test/testreader.hh"
#include "tester.hh"
using namespace std;
using namespace std::tr1;
@ -39,105 +36,82 @@ void print_usage(const char* zProgram)
<< " test-file is the name of a text file." << endl;
}
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 test(Storage& storage, istream& in)
int test(StorageFactory& factory, istream& in)
{
int rv = EXIT_SUCCESS;
typedef unordered_map<CACHE_KEY, string> Keys;
Keys keys;
typedef vector<string> Statements;
Statements statements;
maxscale::TestReader reader(in);
size_t n_statements = 0;
size_t n_keys = 0;
size_t n_collisions = 0;
string line;
while ((rv == EXIT_SUCCESS) && (reader.get_statement(line) == maxscale::TestReader::RESULT_STMT))
if (Tester::get_statements(in, 0, &statements))
{
++n_statements;
typedef unordered_map<CACHE_KEY, string> Keys;
Keys keys;
GWBUF* pQuery = create_gwbuf(line);
size_t n_keys = 0;
size_t n_collisions = 0;
CACHE_KEY key;
cache_result_t result = storage.get_key(NULL, pQuery, &key);
if (result == CACHE_RESULT_OK)
for (Statements::iterator i = statements.begin(); i < statements.end(); ++i)
{
Keys::iterator i = keys.find(key);
string statement = *i;
GWBUF* pQuery = Tester::gwbuf_from_string(statement);
ss_dassert(pQuery);
if (i != keys.end())
if (pQuery)
{
if (i->second != line)
CACHE_KEY key;
cache_result_t result = factory.get_key(NULL, pQuery, &key);
if (result == CACHE_RESULT_OK)
{
++n_collisions;
cerr << "error: Same key generated for '" << i->second << "' and '"
<< line << "'." << endl;
Keys::iterator i = keys.find(key);
if (i != keys.end())
{
if (i->second != statement)
{
++n_collisions;
cerr << "error: Same key generated for '" << i->second << "' and '"
<< statement << "'." << endl;
}
}
else
{
++n_keys;
keys.insert(make_pair(key, statement));
}
}
else
{
cerr << "error: Could not generate a key for '" << statement << "'." << endl;
rv = EXIT_FAILURE;
}
gwbuf_free(pQuery);
}
else
{
++n_keys;
keys.insert(make_pair(key, line));
rv = EXIT_FAILURE;
}
}
else
cout << statements.size() << " statements, "
<< n_keys << " unique keys, "
<< n_collisions << " collisions."
<< endl;
if (rv == EXIT_SUCCESS)
{
cerr << "error: Could not generate a key for '" << line << "'." << endl;
rv = EXIT_FAILURE;
if (n_collisions != 0)
{
rv = EXIT_FAILURE;
}
}
}
cout << n_statements << " statements, "
<< n_keys << " unique keys, "
<< n_collisions << " collisions."
<< endl;
if (rv == EXIT_SUCCESS)
else
{
if (n_collisions != 0)
{
rv = EXIT_FAILURE;
}
}
return rv;
}
int test(StorageFactory& factory, istream& in)
{
int rv = EXIT_FAILURE;
Storage* pStorage = factory.createStorage(CACHE_THREAD_MODEL_ST,
"unspecified",
INT_MAX,
INT_MAX,
INT_MAX,
0, NULL);
if (pStorage)
{
rv = test(*pStorage, in);
delete pStorage;
rv = EXIT_FAILURE;
}
return rv;