MXS-1401 Add test cases

Test that an array of rules is parsed and used properly.
This commit is contained in:
Johan Wikman
2018-04-26 16:20:47 +03:00
parent a3a8b5523e
commit 5f7257f432
3 changed files with 198 additions and 34 deletions

View File

@ -429,6 +429,24 @@ std::auto_ptr<CacheRules> CacheRules::create(uint32_t debug)
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
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))
{
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;
try
@ -470,7 +499,6 @@ bool CacheRules::load(const char *zPath, uint32_t debug, std::vector<SCacheRules
}
MXS_FREE(ppRules);
}
return rv;
}

View File

@ -186,6 +186,9 @@ class CacheRules
public:
typedef std::tr1::shared_ptr<CacheRules> SCacheRules;
CacheRules(const CacheRules&) = delete;
CacheRules& operator = (const CacheRules&) = delete;
~CacheRules();
/**
@ -198,7 +201,18 @@ public:
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 debug The debug level.
@ -240,8 +254,9 @@ public:
private:
CacheRules(CACHE_RULES* pRules);
CacheRules(const CacheRules&);
CacheRules& operator = (const CacheRules&);
static bool create_cache_rules(CACHE_RULES** ppRules,
int32_t nRules,
std::vector<SCacheRules>* pRules);
private:
CACHE_RULES* m_pRules;

View File

@ -12,7 +12,8 @@
*/
#include "rules.h"
#include <algorithm>
#include <iostream>
#include <maxscale/alloc.h>
#include <maxscale/config.h>
#include <maxscale/log_manager.h>
@ -20,6 +21,8 @@
#include <maxscale/protocol/mysql.h>
#include <maxscale/query_classifier.h>
using namespace std;
#if !defined(SS_DEBUG)
#define SS_DEBUG
#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"),
};
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()
{
@ -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 errors = 0;
errors += test_user();
errors += test_store();
errors += test_array_store();
return errors ? EXIT_FAILURE : EXIT_SUCCESS;
}