MXS-1401 Add test cases
Test that an array of rules is parsed and used properly.
This commit is contained in:
30
server/modules/filter/cache/rules.cc
vendored
30
server/modules/filter/cache/rules.cc
vendored
@ -429,6 +429,24 @@ std::auto_ptr<CacheRules> CacheRules::create(uint32_t debug)
|
|||||||
return sThis;
|
return sThis;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
bool CacheRules::parse(const char* zJson, uint32_t debug, std::vector<SCacheRules>* pRules)
|
||||||
|
{
|
||||||
|
bool rv = false;
|
||||||
|
|
||||||
|
pRules->clear();
|
||||||
|
|
||||||
|
CACHE_RULES** ppRules;
|
||||||
|
int32_t nRules;
|
||||||
|
|
||||||
|
if (cache_rules_parse(zJson, debug, &ppRules, &nRules))
|
||||||
|
{
|
||||||
|
rv = create_cache_rules(ppRules, nRules, pRules);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
bool CacheRules::load(const char *zPath, uint32_t debug, std::vector<SCacheRules>* pRules)
|
bool CacheRules::load(const char *zPath, uint32_t debug, std::vector<SCacheRules>* pRules)
|
||||||
{
|
{
|
||||||
@ -441,6 +459,17 @@ bool CacheRules::load(const char *zPath, uint32_t debug, std::vector<SCacheRules
|
|||||||
|
|
||||||
if (cache_rules_load(zPath, debug, &ppRules, &nRules))
|
if (cache_rules_load(zPath, debug, &ppRules, &nRules))
|
||||||
{
|
{
|
||||||
|
rv = create_cache_rules(ppRules, nRules, pRules);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
//static
|
||||||
|
bool CacheRules::create_cache_rules(CACHE_RULES** ppRules, int32_t nRules, std::vector<SCacheRules>* pRules)
|
||||||
|
{
|
||||||
|
bool rv = false;
|
||||||
|
|
||||||
int j = 0;
|
int j = 0;
|
||||||
|
|
||||||
try
|
try
|
||||||
@ -470,7 +499,6 @@ bool CacheRules::load(const char *zPath, uint32_t debug, std::vector<SCacheRules
|
|||||||
}
|
}
|
||||||
|
|
||||||
MXS_FREE(ppRules);
|
MXS_FREE(ppRules);
|
||||||
}
|
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
21
server/modules/filter/cache/rules.h
vendored
21
server/modules/filter/cache/rules.h
vendored
@ -186,6 +186,9 @@ class CacheRules
|
|||||||
public:
|
public:
|
||||||
typedef std::tr1::shared_ptr<CacheRules> SCacheRules;
|
typedef std::tr1::shared_ptr<CacheRules> SCacheRules;
|
||||||
|
|
||||||
|
CacheRules(const CacheRules&) = delete;
|
||||||
|
CacheRules& operator = (const CacheRules&) = delete;
|
||||||
|
|
||||||
~CacheRules();
|
~CacheRules();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -198,7 +201,18 @@ public:
|
|||||||
static std::auto_ptr<CacheRules> create(uint32_t debug);
|
static std::auto_ptr<CacheRules> create(uint32_t debug);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads the caching rules from a file and returns corresponding object.
|
* Parses the caching rules from a string.
|
||||||
|
*
|
||||||
|
* @param zJson Null-terminate string containing JSON.
|
||||||
|
* @param debug The debug level.
|
||||||
|
* @param pRules [out] The loaded rules.
|
||||||
|
*
|
||||||
|
* @return True, if the rules could be parsed, false otherwise.
|
||||||
|
*/
|
||||||
|
static bool parse(const char* zJson, uint32_t debug, std::vector<SCacheRules>* pRules);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the caching rules from a file.
|
||||||
*
|
*
|
||||||
* @param path The path of the file containing the rules.
|
* @param path The path of the file containing the rules.
|
||||||
* @param debug The debug level.
|
* @param debug The debug level.
|
||||||
@ -240,8 +254,9 @@ public:
|
|||||||
private:
|
private:
|
||||||
CacheRules(CACHE_RULES* pRules);
|
CacheRules(CACHE_RULES* pRules);
|
||||||
|
|
||||||
CacheRules(const CacheRules&);
|
static bool create_cache_rules(CACHE_RULES** ppRules,
|
||||||
CacheRules& operator = (const CacheRules&);
|
int32_t nRules,
|
||||||
|
std::vector<SCacheRules>* pRules);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CACHE_RULES* m_pRules;
|
CACHE_RULES* m_pRules;
|
||||||
|
125
server/modules/filter/cache/test/testrules.cc
vendored
125
server/modules/filter/cache/test/testrules.cc
vendored
@ -12,7 +12,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "rules.h"
|
#include "rules.h"
|
||||||
|
#include <algorithm>
|
||||||
|
#include <iostream>
|
||||||
#include <maxscale/alloc.h>
|
#include <maxscale/alloc.h>
|
||||||
#include <maxscale/config.h>
|
#include <maxscale/config.h>
|
||||||
#include <maxscale/log_manager.h>
|
#include <maxscale/log_manager.h>
|
||||||
@ -20,6 +21,8 @@
|
|||||||
#include <maxscale/protocol/mysql.h>
|
#include <maxscale/protocol/mysql.h>
|
||||||
#include <maxscale/query_classifier.h>
|
#include <maxscale/query_classifier.h>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
#if !defined(SS_DEBUG)
|
#if !defined(SS_DEBUG)
|
||||||
#define SS_DEBUG
|
#define SS_DEBUG
|
||||||
#endif
|
#endif
|
||||||
@ -188,7 +191,7 @@ const struct store_test_case store_test_cases[] =
|
|||||||
STORE_TEST_CASE("column", "=", "a", true, NULL, "SELECT a, b FROM tbl WHERE a = 5"),
|
STORE_TEST_CASE("column", "=", "a", true, NULL, "SELECT a, b FROM tbl WHERE a = 5"),
|
||||||
};
|
};
|
||||||
|
|
||||||
const size_t n_store_test_cases = sizeof(store_test_cases) / sizeof(store_test_cases[0]);
|
const int n_store_test_cases = sizeof(store_test_cases) / sizeof(store_test_cases[0]);
|
||||||
|
|
||||||
int test_store()
|
int test_store()
|
||||||
{
|
{
|
||||||
@ -242,12 +245,130 @@ int test_store()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const char ARRAY_RULES[] =
|
||||||
|
"["
|
||||||
|
" {"
|
||||||
|
" \"store\": ["
|
||||||
|
" {"
|
||||||
|
" \"attribute\": \"column\","
|
||||||
|
" \"op\": \"=\","
|
||||||
|
" \"value\": \"a\""
|
||||||
|
" }"
|
||||||
|
" ]"
|
||||||
|
" },"
|
||||||
|
" {"
|
||||||
|
" \"store\": ["
|
||||||
|
" {"
|
||||||
|
" \"attribute\": \"column\","
|
||||||
|
" \"op\": \"=\","
|
||||||
|
" \"value\": \"b\""
|
||||||
|
" }"
|
||||||
|
" ]"
|
||||||
|
" },"
|
||||||
|
" {"
|
||||||
|
" \"store\": ["
|
||||||
|
" {"
|
||||||
|
" \"attribute\": \"column\","
|
||||||
|
" \"op\": \"=\","
|
||||||
|
" \"value\": \"c\""
|
||||||
|
" }"
|
||||||
|
" ]"
|
||||||
|
" }"
|
||||||
|
"]";
|
||||||
|
|
||||||
|
struct ARRAY_TEST_CASE
|
||||||
|
{
|
||||||
|
const char* zStmt; // Statement
|
||||||
|
int32_t index; // Index of rule to match, -1 if none.
|
||||||
|
} array_test_cases[] =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
"select a from tbl",
|
||||||
|
0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"select b from tbl",
|
||||||
|
1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"select c from tbl",
|
||||||
|
2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"select a, b from tbl",
|
||||||
|
0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"select d from tbl",
|
||||||
|
-1
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const int n_array_test_cases = sizeof(array_test_cases) / sizeof(array_test_cases[0]);
|
||||||
|
|
||||||
|
int test_array_store()
|
||||||
|
{
|
||||||
|
int errors = 0;
|
||||||
|
|
||||||
|
typedef CacheRules::SCacheRules SCacheRules;
|
||||||
|
std::vector<SCacheRules> rules;
|
||||||
|
|
||||||
|
if (CacheRules::parse(ARRAY_RULES, 0, &rules))
|
||||||
|
{
|
||||||
|
for (int i = 0; i < n_array_test_cases; ++i)
|
||||||
|
{
|
||||||
|
const ARRAY_TEST_CASE& tc = array_test_cases[i];
|
||||||
|
|
||||||
|
cout << tc.zStmt << endl;
|
||||||
|
|
||||||
|
GWBUF* pStmt = create_gwbuf(tc.zStmt);
|
||||||
|
auto it = std::find_if(rules.begin(), rules.end(), [pStmt](SCacheRules sRules)
|
||||||
|
{
|
||||||
|
return sRules->should_store(NULL, pStmt);
|
||||||
|
});
|
||||||
|
|
||||||
|
int index = (it == rules.end()) ? -1 : std::distance(rules.begin(), it);
|
||||||
|
|
||||||
|
if (it != rules.end())
|
||||||
|
{
|
||||||
|
if (tc.index == index)
|
||||||
|
{
|
||||||
|
cout << "OK: Rule " << tc.index << " matches as expected." << endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
++errors;
|
||||||
|
cout << "ERROR: Rule " << tc.index << " should have matched, but " << index << " did." << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (tc.index == -1)
|
||||||
|
{
|
||||||
|
cout << "OK: No rule matched, as expected." << endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
++errors;
|
||||||
|
cout << "ERROR: Rule " << tc.index << " should have matched, but none did." << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cout << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int test()
|
int test()
|
||||||
{
|
{
|
||||||
int errors = 0;
|
int errors = 0;
|
||||||
|
|
||||||
errors += test_user();
|
errors += test_user();
|
||||||
errors += test_store();
|
errors += test_store();
|
||||||
|
errors += test_array_store();
|
||||||
|
|
||||||
return errors ? EXIT_FAILURE : EXIT_SUCCESS;
|
return errors ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user