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 testkeygeneration.cc
../../../../../query_classifier/test/testreader.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) add_executable(testrawstorage testrawstorage.cc)
target_link_libraries(testrawstorage cachetester cache maxscale-common) 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_rules testrules)
add_test(TestCache_keygeneration testkeygeneration storage_inmemory ${CMAKE_CURRENT_SOURCE_DIR}/input.test) add_test(TestCache_inmemory_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_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_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) 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 // 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; if (n_statements == 0)
typedef set<string> StatementsSet; {
n_statements = UINT_MAX;
}
TestReader::result_t result = TestReader::RESULT_ERROR;
typedef set<string> StatementsSet;
StatementsSet statements; StatementsSet statements;
TestReader reader(in); 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; 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 // static
bool Tester::get_cache_items(const Statements& statements, bool Tester::get_cache_items(const Statements& statements,
const StorageFactory& factory, const StorageFactory& factory,
@ -245,7 +274,7 @@ bool Tester::get_cache_items(std::istream& in,
{ {
Statements statements; Statements statements;
bool rv = get_statements(in, n_items, &statements); bool rv = get_unique_statements(in, n_items, &statements);
if (rv) if (rv)
{ {

View File

@ -154,11 +154,24 @@ public:
static GWBUF* gwbuf_from_vector(const std::vector<uint8_t>& v); 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 * @param in The stream from which input should be read. Assumed to refer to a
* MySQL/MariaDB test file. * 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. * @param pStatements Pointer to vector where statements will be back inserted.
* May contain less statements that specified in @n_statements. * May contain less statements that specified in @n_statements.
* *

View File

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