First release of open-appsec source code

This commit is contained in:
roybarda
2022-10-26 19:33:19 +03:00
parent 3883109caf
commit a883352f79
1353 changed files with 276290 additions and 1 deletions

View File

@@ -0,0 +1,5 @@
add_unit_test(
environment_ut
"context_ut.cc;parsing_ut.cc;base_evaluators_ut.cc;environment_rest_ut.cc;span_ut.cc;trace_ut.cc;tracing_ut.cc;environment_ut.cc"
"environment;singleton;rest;mainloop;metric;-lboost_context;event_is;-lboost_regex"
)

View File

@@ -0,0 +1,199 @@
#include "environment_evaluator.h"
#include "cptest.h"
#include "environment.h"
#include "config.h"
#include "config_component.h"
#include "mock/mock_mainloop.h"
#include "mock/mock_time_get.h"
using namespace std;
using namespace testing;
class EvaluatorTest : public Test
{
public:
EvaluatorTest() {
env.preload();
env.init();
}
~EvaluatorTest() {
env.fini();
}
private:
NiceMock<MockMainLoop> mock_mainloop;
NiceMock<MockTimeGet> mock_timer;
ConfigComponent conf;
::Environment env;
};
std::ostream & operator<<(std::ostream &os, const Context::Error &);
std::ostream &
operator<<(std::ostream &os, const std::function<Maybe<bool, Context::Error>()> &)
{
return os;
}
TEST_F(EvaluatorTest, empty_all)
{
auto eval = genEvaluator<bool>("All()");
EXPECT_TRUE(eval.ok());
auto function = eval.unpack();
EXPECT_THAT(function(), IsValue(true));
}
TEST_F(EvaluatorTest, empty_any)
{
auto eval = genEvaluator<bool>("Any()");
EXPECT_TRUE(eval.ok());
auto function = eval.unpack();
EXPECT_THAT(function(), IsValue(false));
}
TEST_F(EvaluatorTest, not_true)
{
auto eval = genEvaluator<bool>("Not(All())");
EXPECT_TRUE(eval.ok());
auto function = eval.unpack();
EXPECT_THAT(function(), IsValue(false));
}
TEST_F(EvaluatorTest, not_false)
{
auto eval = genEvaluator<bool>("Not(Any())");
EXPECT_TRUE(eval.ok());
auto function = eval.unpack();
EXPECT_THAT(function(), IsValue(true));
}
TEST_F(EvaluatorTest, no_true_any)
{
auto eval = genEvaluator<bool>("Any(Any(),Any(),Any())");
EXPECT_TRUE(eval.ok());
auto function = eval.unpack();
EXPECT_THAT(function(), IsValue(false));
}
TEST_F(EvaluatorTest, one_true_any)
{
auto eval = genEvaluator<bool>("Any(Any(),All(),Any())");
EXPECT_TRUE(eval.ok());
auto function = eval.unpack();
EXPECT_THAT(function(), IsValue(true));
}
TEST_F(EvaluatorTest, one_false_all)
{
auto eval = genEvaluator<bool>("All(All(),All(),Any())");
EXPECT_TRUE(eval.ok());
auto function = eval.unpack();
EXPECT_THAT(function(), IsValue(false));
}
TEST_F(EvaluatorTest, all_true_all)
{
auto eval = genEvaluator<bool>("All(All(),All(),All())");
EXPECT_TRUE(eval.ok());
auto function = eval.unpack();
EXPECT_THAT(function(), IsValue(true));
}
TEST_F(EvaluatorTest, all_true_all_with_spaces)
{
auto eval = genEvaluator<bool>("All(All() , All( ) ,All() )");
EXPECT_TRUE(eval.ok());
auto function = eval.unpack();
EXPECT_THAT(function(), IsValue(true));
}
TEST_F(EvaluatorTest, select_all_all)
{
auto eval = genEvaluator<bool>("Select(All(),All())");
EXPECT_TRUE(eval.ok());
auto function = eval.unpack();
EXPECT_THAT(function(), IsValue(true));
}
TEST_F(EvaluatorTest, select_all_any)
{
auto eval = genEvaluator<bool>("Select(All(),Any())");
EXPECT_TRUE(eval.ok());
auto function = eval.unpack();
EXPECT_THAT(function(), IsValue(true));
}
TEST_F(EvaluatorTest, select_any_all)
{
auto eval = genEvaluator<bool>("Select(Any(),All())");
EXPECT_TRUE(eval.ok());
auto function = eval.unpack();
EXPECT_THAT(function(), IsValue(false));
}
TEST_F(EvaluatorTest, empty_not)
{
auto eval = genEvaluator<bool>("Not()");
EXPECT_THAT(eval, IsError("Wrong number of parameters for 'Not'. Got 0 parameters instead of expected 1"));
}
TEST_F(EvaluatorTest, too_many_inputs_not)
{
auto eval = genEvaluator<bool>("Not(Any(), Any())");
EXPECT_THAT(eval, IsError("Wrong number of parameters for 'Not'. Got 2 parameters instead of expected 1"));
}
TEST_F(EvaluatorTest, malformed_evaluator_leading_comma)
{
auto eval = genEvaluator<bool>("Any(, Any())");
EXPECT_THAT(eval, IsError("Could not find the opening bracket in the string"));
}
TEST_F(EvaluatorTest, malformed_evaluator_fake_evaluator)
{
auto eval = genEvaluator<bool>("Not(NOTHING())");
EXPECT_THAT(eval, IsError("Evaluator 'NOTHING' doesn't exist for the required type"));
}
TEST_F(EvaluatorTest, malformed_evaluator_fake_evaluator2)
{
auto eval = genEvaluator<bool>("All(Any(), NOTHING())");
EXPECT_THAT(eval, IsError("Evaluator 'NOTHING' doesn't exist for the required type"));
}
TEST_F(EvaluatorTest, empty_get)
{
auto eval = genEvaluator<bool>("Get()");
EXPECT_THAT(eval, IsError("Wrong number of parameters for 'Get'. Got 0 parameters instead of expected 1"));
}
TEST_F(EvaluatorTest, empty_select)
{
auto eval = genEvaluator<bool>("Select()");
EXPECT_THAT(
eval,
IsError("Wrong number of parameters for 'Select'. Got 0 parameters instead of expected more than 2")
);
}
TEST_F(EvaluatorTest, single_in_select)
{
auto eval = genEvaluator<bool>("Select(one)");
EXPECT_THAT(
eval,
IsError("Wrong number of parameters for 'Select'. Got 1 parameters instead of expected more than 2")
);
}
TEST_F(EvaluatorTest, select_bad_evaluators)
{
auto eval = genEvaluator<bool>("Select(X(),Y())");
EXPECT_THAT(eval, IsError("Evaluator 'X' doesn't exist for the required type"));
}
TEST_F(EvaluatorTest, malformed_evaluator_within_parameter)
{
auto eval = genEvaluator<bool>("Any(All(), Any(BOB()))");
EXPECT_THAT(eval, IsError("Evaluator 'BOB' doesn't exist for the required type"));
}

View File

@@ -0,0 +1,237 @@
#include "cptest.h"
#include "context.h"
#include "environment.h"
#include "config.h"
#include "config_component.h"
#include "mock/mock_mainloop.h"
#include "mock/mock_time_get.h"
using namespace std;
using namespace testing;
class ContextTest : public Test
{
public:
Context ctx;
class TestObject
{
public:
TestObject(const string &_x, int _y) : x(_x), y(_y) {};
bool
operator==(const TestObject &rsh) const
{
return x == rsh.x && y == rsh.y;
}
private:
string x;
int y;
};
static Maybe<int, Context::Error> maybeIntFunc() { return 1; }
static Maybe<double, Context::Error> maybeDoubleFunc() { return 1.1; }
static Maybe<string, Context::Error> maybeStrFunc() { return string("str1"); }
static Maybe<char, Context::Error> maybeCharFunc() { return 'a'; }
static Maybe<TestObject, Context::Error> maybeObjectFunc() { return ContextTest::TestObject("test_object", 1); }
static int intFunc() { return 2; }
static double doubleFunc() { return 2.2; }
static string strFunc() { return string("str2"); }
static char charFunc() { return 'b'; }
static TestObject objectFunc() { return ContextTest::TestObject("test_object", 2); }
};
std::ostream &
operator<<(std::ostream &os, const Context::Error &)
{
return os;
}
std::ostream &
operator<<(std::ostream &os, const ContextTest::TestObject &)
{
return os;
}
TEST_F(ContextTest, register_int)
{
ctx.registerValue("_int", 10);
EXPECT_THAT(ctx.get<int>("_int"), IsValue(10));
}
TEST_F(ContextTest, register_double)
{
ctx.registerValue("_double", 2.2);
EXPECT_THAT(ctx.get<double>("_double"), IsValue(2.2));
}
TEST_F(ContextTest, register_char)
{
ctx.registerValue("_char", 'a');
EXPECT_THAT(ctx.get<char>("_char"), IsValue('a'));
}
TEST_F(ContextTest, register_string)
{
ctx.registerValue("_string", string("string"));
EXPECT_THAT(ctx.get<string>("_string"), IsValue("string"));
}
TEST_F(ContextTest, register_object)
{
ctx.registerValue("_obj", ContextTest::TestObject("value", 1));
EXPECT_THAT(ctx.get<TestObject>("_obj"), IsValue(ContextTest::TestObject("value", 1)));
}
TEST_F(ContextTest, register_2_values_same_key)
{
ctx.registerValue("same_value_key", 1);
ctx.registerValue("same_value_key", 2);
EXPECT_THAT(ctx.get<int>("same_value_key"), IsValue(2));
}
TEST_F(ContextTest, register_2_values_same_key_diff_context)
{
ConfigComponent conf;
NiceMock<MockMainLoop> mock_mainloop;
NiceMock<MockTimeGet> mock_timer;
::Environment env;
auto i_env = Singleton::Consume<I_Environment>::from(env);
ctx.registerValue("same_value_key", 1);
ctx.activate();
EXPECT_THAT(i_env->get<int>("same_value_key"), IsValue(1));
Context another_ctx;
another_ctx.registerValue("same_value_key", 2);
another_ctx.activate();
EXPECT_THAT(i_env->get<int>("same_value_key"), IsValue(2));
}
TEST_F(ContextTest, register_2_func_same_key)
{
ctx.registerFunc<int>("same_func_key", ContextTest::maybeIntFunc);
ctx.registerFunc<double>("same_func_key", ContextTest::maybeDoubleFunc);
EXPECT_THAT(ctx.get<double>("same_func_key"), IsValue(1.1));
}
TEST_F(ContextTest, register_return_maybe_obj_func)
{
ctx.registerFunc<TestObject>("maybe_obj_func", ContextTest::maybeObjectFunc);
EXPECT_THAT(ctx.get<TestObject>("maybe_obj_func"), IsValue(ContextTest::TestObject("test_object", 1)));
}
TEST_F(ContextTest, register_return_maybe_int_func)
{
ctx.registerFunc<int>("maybe_int_func", ContextTest::maybeIntFunc);
EXPECT_THAT(ctx.get<int>("maybe_int_func"), IsValue(1));
}
TEST_F(ContextTest, register_return_maybe_str_func)
{
ctx.registerFunc<string>("maybe_str_func", ContextTest::maybeStrFunc);
EXPECT_THAT(ctx.get<string>("maybe_str_func"), IsValue("str1"));
}
TEST_F(ContextTest, register_return_maybe_double_func)
{
ctx.registerFunc<double>("maybe_double_func", ContextTest::maybeDoubleFunc);
EXPECT_THAT(ctx.get<double>("maybe_double_func"), IsValue(1.1));
}
TEST_F(ContextTest, register_return_maybe_char_func)
{
ctx.registerFunc<char>("maybe_char_func", ContextTest::maybeCharFunc);
EXPECT_THAT(ctx.get<char>("maybe_char_func"), IsValue('a'));
}
TEST_F(ContextTest, register_return_obj_func)
{
ctx.registerFunc<TestObject>("obj_func", ContextTest::objectFunc);
EXPECT_THAT(ctx.get<TestObject>("obj_func"), IsValue(ContextTest::TestObject("test_object", 2)));
}
TEST_F(ContextTest, register_return_int_func)
{
ctx.registerFunc<int>("int_func", ContextTest::intFunc);
EXPECT_THAT(ctx.get<int>("int_func"), IsValue(2));
}
TEST_F(ContextTest, register_return_str_func)
{
ctx.registerFunc<string>("str_func", ContextTest::strFunc);
EXPECT_THAT(ctx.get<string>("str_func"), IsValue("str2"));
}
TEST_F(ContextTest, register_return_double_func)
{
ctx.registerFunc<double>("double_func", ContextTest::doubleFunc);
EXPECT_THAT(ctx.get<double>("double_func"), IsValue(2.2));
}
TEST_F(ContextTest, register_return_char_func)
{
ctx.registerFunc<char>("char_func", ContextTest::charFunc);
EXPECT_THAT(ctx.get<char>("char_func"), IsValue('b'));
}
TEST_F(ContextTest, get_wrong_type_value)
{
ctx.registerValue("wrong_type", 1);
EXPECT_THAT(ctx.get<string>("wrong_type"), IsError(Context::Error::NO_VALUE));
}
TEST_F(ContextTest, get_wrong_key_name)
{
ctx.registerValue("wrong_key", 1);
EXPECT_THAT(ctx.get<int>("wrong_keyy"), IsError(Context::Error::NO_VALUE));
}
TEST_F(ContextTest, unregister_key_of_value)
{
ctx.registerValue("new_value_key", 1);
ctx.unregisterKey<int>("new_value_key");
EXPECT_THAT(ctx.get<int>("new_value_key"), IsError(Context::Error::NO_VALUE));
}
TEST_F(ContextTest, unregister_key_of_func)
{
ctx.registerFunc<int>("new_func_key", maybeIntFunc);
ctx.unregisterKey<int>("new_func_key");
EXPECT_THAT(ctx.get<int>("new_func_key"), IsError(Context::Error::NO_VALUE));
}
TEST(ParamTest, matching)
{
using namespace EnvKeyAttr;
ParamAttr empty;
ParamAttr verb1(Verbosity::LOW);
ParamAttr verb2(Verbosity::HIGH);
ParamAttr log(LogSection::SOURCE);
ParamAttr both1(LogSection::SOURCE, Verbosity::LOW);
ParamAttr both2(Verbosity::LOW, LogSection::SOURCE);
ParamAttr both3(LogSection::SOURCE, Verbosity::HIGH);
EXPECT_TRUE(empty.doesMatch(empty));
EXPECT_TRUE(verb1.doesMatch(empty));
EXPECT_TRUE(log.doesMatch(empty));
EXPECT_TRUE(both1.doesMatch(empty));
EXPECT_FALSE(empty.doesMatch(verb1));
EXPECT_FALSE(empty.doesMatch(log));
EXPECT_FALSE(empty.doesMatch(both1));
EXPECT_TRUE(verb1.doesMatch(verb1));
EXPECT_TRUE(both1.doesMatch(verb1));
EXPECT_FALSE(verb2.doesMatch(verb1));
EXPECT_FALSE(log.doesMatch(verb1));
EXPECT_FALSE(both3.doesMatch(verb1));
EXPECT_TRUE(both1.doesMatch(log));
EXPECT_TRUE(both1.doesMatch(both1));
EXPECT_TRUE(both1.doesMatch(both2));
EXPECT_FALSE(both1.doesMatch(both3));
}

View File

@@ -0,0 +1,68 @@
#include "environment.h"
#include "cptest.h"
#include "mock/mock_rest_api.h"
#include "config.h"
#include "config_component.h"
#include "mock/mock_mainloop.h"
#include "mock/mock_time_get.h"
using namespace std;
using namespace testing;
class EnvRestTest : public Test
{
public:
EnvRestTest()
{
EXPECT_CALL(mock_rs, mockRestCall(RestAction::ADD, "declare-boolean-variable", _))
.WillOnce(WithArg<2>(Invoke(this, &EnvRestTest::declareVariable)));
env.preload();
env.init();
i_env = Singleton::Consume<I_Environment>::from(env);
}
unique_ptr<ServerRest> declare_variable;
I_Environment *i_env;
private:
bool declareVariable(const unique_ptr<RestInit> &p) { declare_variable = p->getRest(); return true; }
NiceMock<MockMainLoop> mock_mainloop;
NiceMock<MockTimeGet> mock_timer;
ConfigComponent conf;
::Environment env;
StrictMock<MockRestApi> mock_rs;
};
static ostream & operator<<(ostream &os, const Context::Error &) { return os; }
TEST_F(EnvRestTest, declare_variable)
{
EXPECT_THAT(i_env->get<bool>("true_val"), IsError(Context::Error::NO_VALUE));
stringstream is;
is << "{\"name\": \"true_val\", \"expr\": \"All()\"}";
auto output = declare_variable->performRestCall(is);
EXPECT_THAT(output, IsValue(""));
EXPECT_THAT(i_env->get<bool>("true_val"), IsValue(true));
}
TEST_F(EnvRestTest, no_expr)
{
stringstream is;
is << "{\"name\": \"true_val\"}";
auto output = declare_variable->performRestCall(is);
EXPECT_THAT(output, IsError("Couldn't get variable expr"));
}
TEST_F(EnvRestTest, no_name)
{
stringstream is;
is << "{\"expr\": \"All()\"}";
auto output = declare_variable->performRestCall(is);
EXPECT_THAT(output, IsError("Couldn't get variable name"));
}

View File

@@ -0,0 +1,87 @@
#include "environment.h"
#include "cptest.h"
using namespace testing;
using namespace std;
class EnvironmentTest : public Test
{
public:
EnvironmentTest() { ctx.activate(); ctx2.activate(); }
~EnvironmentTest() { ctx2.deactivate(); ctx.deactivate(); }
::Environment env;
I_Environment *i_env = Singleton::Consume<I_Environment>::from(env);
Context ctx, ctx2;
};
class ConvertableToString
{
public:
ConvertableToString(int _i, int _j) : i(_i), j(_j) {}
int i, j;
};
ostream &
operator<<(ostream &os, const ConvertableToString &obj)
{
return os << obj.i << "---" << obj.j;
}
TEST_F(EnvironmentTest, all_strings)
{
string key_a = "A";
string key_b = "B";
string key_c = "C";
string key_d = "D";
string key_e = "E";
string key_f = "F";
string key_g = "G";
string val_num = "123";
string val_alpha = "abc";
ctx.registerValue(key_a, val_num);
ctx.registerValue(key_b, val_alpha, EnvKeyAttr::LogSection::SOURCE);
ctx.registerValue(key_c, ConvertableToString(2, 9), EnvKeyAttr::LogSection::DATA, EnvKeyAttr::Verbosity::LOW);
ctx.registerValue(key_g, false, EnvKeyAttr::Verbosity::HIGH);
ctx2.registerValue(key_d, ConvertableToString(5, 3), EnvKeyAttr::LogSection::DATA);
ctx2.registerValue(key_e, 9);
ctx2.registerValue(key_f, true);
EXPECT_THAT(
i_env->getAllStrings(),
UnorderedElementsAre(
make_pair(key_a, val_num),
make_pair(key_b, val_alpha),
make_pair(key_d, "5---3"),
make_pair(key_c, "2---9")
)
);
EXPECT_THAT(
i_env->getAllStrings(EnvKeyAttr::Verbosity::HIGH),
UnorderedElementsAre()
);
EXPECT_THAT(
i_env->getAllStrings(EnvKeyAttr::LogSection::SOURCE),
UnorderedElementsAre(
make_pair(key_b, val_alpha)
)
);
EXPECT_THAT(
i_env->getAllStrings(EnvKeyAttr::LogSection::DATA),
UnorderedElementsAre(
make_pair(key_d, "5---3"),
make_pair(key_c, "2---9")
)
);
EXPECT_THAT(i_env->getAllUints(), UnorderedElementsAre(make_pair(key_e, 9)));
EXPECT_THAT(i_env->getAllBools(), UnorderedElementsAre(make_pair(key_f, true), make_pair(key_g, false)));
}

View File

@@ -0,0 +1,156 @@
#include "cptest.h"
#include "environment_evaluator.h"
using namespace std;
using namespace testing;
using namespace EnvironmentHelper;
static const string error = "EvaluatorParseError not thrown as it should have been! Test Failed.";
TEST(ParsingTest, wrong_param_number_test_range)
{
try {
reportWrongNumberOfParams("wrong_param_number_test_range", 4, 1, 3);
}
catch (EvaluatorParseError e) {
string output = e.getError();
string expected = "Wrong number of parameters for 'wrong_param_number_test_range'. "
"Got 4 parameters instead of expected between 1 and 3";
EXPECT_EQ(output, expected);
return;
}
ADD_FAILURE() << error;
}
TEST(ParsingTest, wrong_param_number_test_min_eq_max)
{
try {
reportWrongNumberOfParams("wrong_param_number_test_min_eq_max", 0, 1, 1);
}
catch (EvaluatorParseError e) {
string output = e.getError();
string expected = "Wrong number of parameters for 'wrong_param_number_test_min_eq_max'. "
"Got 0 parameters instead of expected 1";
EXPECT_EQ(output, expected);
return;
}
ADD_FAILURE() << error;
}
TEST(ParsingTest, wrong_param_number_test_too_few)
{
try {
reportWrongNumberOfParams("wrong_param_number_test_too_few", 0, 2, -1);
}
catch (EvaluatorParseError e) {
string output = e.getError();
string expected = "Wrong number of parameters for 'wrong_param_number_test_too_few'. "
"Got 0 parameters instead of expected more than 2";
EXPECT_EQ(output, expected);
return;
}
ADD_FAILURE() << error;
}
TEST(ParsingTest, wrong_param_type_test)
{
try {
reportWrongParamType("wrong_param_type_test", "bad_param", "good_reason");
}
catch (EvaluatorParseError e) {
string output = e.getError();
string expected = "Parameter 'bad_param' for 'wrong_param_type_test' is of the "
"wrong type because: good_reason";
EXPECT_EQ(output, expected);
return;
}
ADD_FAILURE() << error;
}
TEST(ParsingTest, unkown_evaluator_type_test)
{
try {
reportUnknownEvaluatorType("bad_eval");
}
catch (EvaluatorParseError e) {
string output = e.getError();
string expected = "Evaluator 'bad_eval' doesn't exist for the required type";
EXPECT_EQ(output, expected);
return;
}
ADD_FAILURE() << error;
}
TEST(ParsingTest, break_to_params_test_empty_input)
{
vector<string> res;
EXPECT_EQ(breakEvaluatorString("()").second, res);
}
TEST(ParsingTest, break_to_params_test_single_in)
{
vector<string> res = { "(X)" };
EXPECT_EQ(breakEvaluatorString("((X))").second, res);
}
TEST(ParsingTest, break_to_params_common_use)
{
vector<string> res = { "a", "1234 asd", "((1+2)*3)" };
EXPECT_EQ(breakEvaluatorString("(a , 1234 asd ,((1+2)*3))").second, res);
}
TEST(ParsingTest, break_to_params_test_commas_and_ignore_spaces)
{
vector<string> res = { "", "", "" };
EXPECT_EQ(breakEvaluatorString("(,, , )").second, res);
}
TEST(ParsingTest, break_to_params_bracket_games)
{
vector<string> res = { ") ,x x(()", ")))," };
EXPECT_EQ(breakEvaluatorString("() ,x x((),))),)").second, res);
}
TEST(ParsingTest, break_evaluator_string_test_empty_legal_input)
{
string normalized = "()";
auto pair = breakEvaluatorString(normalized);
string s = "";
vector<string> v;
EXPECT_EQ(pair, make_pair(s, v));
}
TEST(ParsingTest, break_evaluator_string_test_legal_input)
{
string normalized = "CMD((3 + 3 ) * 7 (), abc)";
auto pair = breakEvaluatorString(normalized);
string s = "CMD";
vector<string> v = { "(3 + 3 ) * 7 ()", "abc" };
EXPECT_EQ(pair, make_pair(s, v));
}
TEST(ParsingTest, break_evaluator_string_test_no_open_bracket)
{
try {
breakEvaluatorString("EVALUATOR)");
}
catch (EvaluatorParseError e) {
EXPECT_EQ(e.getError(), "Could not find the opening bracket in the string");
return;
}
ADD_FAILURE() << error;
}
TEST(ParsingTest, break_evaluator_string_test_no_close_bracket)
{
try {
breakEvaluatorString("EVALUATOR(x+1 = 3");
}
catch (EvaluatorParseError e) {
EXPECT_EQ(e.getError(), "Could not find the closing bracket in the string");
return;
}
ADD_FAILURE() << error;
}

View File

@@ -0,0 +1,95 @@
#include "environment/span.h"
#include "cptest.h"
#include "environment.h"
#include "debug.h"
#include "config.h"
#include "config_component.h"
#include "mock/mock_mainloop.h"
#include "mock/mock_time_get.h"
using namespace std;
using namespace testing;
USE_DEBUG_FLAG(D_TRACE);
class SpanTest : public Test
{
public:
SpanTest()
{
Debug::setNewDefaultStdout(&debug_output);
Debug::setUnitTestFlag(D_TRACE, Debug::DebugLevel::TRACE);
}
~SpanTest()
{
Debug::setNewDefaultStdout(&cout);
}
template <typename T>
void
getSpanValues(const T &span)
{
trace_id_str = span.getTraceId();
span_id_str = span.getSpanId();
prev_id_str = span.getPrevSpanId();
type = span.getSpanContextType();
}
NiceMock<MockMainLoop> mock_mainloop;
NiceMock<MockTimeGet> mock_timer;
ConfigComponent conf;
::Environment env;
stringstream debug_output;
string trace_id = "4cc6bce7-4f68-42d6-94fc-e4127ac65ded";
string prev_span_id = "4cc6bce7-4f68-42d6-94fc-e4127ac65fef";
string trace_id_str;
string span_id_str;
string prev_id_str;
Span::ContextType type = Span::ContextType::NEW;
};
TEST_F(SpanTest, newSpanInNewTraceTest)
{
{
Span span(trace_id);
getSpanValues<Span>(span);
}
EXPECT_EQ(type, Span::ContextType::NEW);
EXPECT_THAT(debug_output.str(), HasSubstr("New span was created " + span_id_str));
EXPECT_THAT(debug_output.str(), HasSubstr("trace id "+ trace_id_str));
EXPECT_THAT(debug_output.str(), HasSubstr("context type New"));
EXPECT_THAT(debug_output.str(), HasSubstr("Current span has ended " + span_id_str));
}
TEST_F(SpanTest, newSpanTest)
{
{
Span span(trace_id, Span::ContextType::CHILD_OF, prev_span_id);
getSpanValues<Span>(span);
}
EXPECT_EQ(type, Span::ContextType::CHILD_OF);
EXPECT_THAT(debug_output.str(), HasSubstr("New span was created " + span_id_str));
EXPECT_THAT(debug_output.str(), HasSubstr("trace id " + trace_id_str));
EXPECT_THAT(debug_output.str(), HasSubstr("context type Child of"));
EXPECT_THAT(debug_output.str(), HasSubstr("previous span id " + prev_id_str));
EXPECT_THAT(debug_output.str(), HasSubstr("Current span has ended " + span_id_str));
}
TEST_F(SpanTest, newSpanWrapperTest)
{
{
SpanWrapper span(trace_id, Span::ContextType::CHILD_OF, prev_span_id);
getSpanValues<SpanWrapper>(span);
}
EXPECT_EQ(type, Span::ContextType::CHILD_OF);
EXPECT_THAT(debug_output.str(), HasSubstr("New span was created " + span_id_str));
EXPECT_THAT(debug_output.str(), HasSubstr("trace id " + trace_id_str));
EXPECT_THAT(debug_output.str(), HasSubstr("context type Child of"));
EXPECT_THAT(debug_output.str(), HasSubstr("previous span id " + prev_id_str));
EXPECT_THAT(debug_output.str(), HasSubstr("Current span has ended " + span_id_str));
}

View File

@@ -0,0 +1,59 @@
#include "environment/trace.h"
#include "cptest.h"
#include "environment.h"
#include "debug.h"
#include "config.h"
#include "config_component.h"
#include "mock/mock_mainloop.h"
#include "mock/mock_time_get.h"
using namespace std;
using namespace testing;
USE_DEBUG_FLAG(D_TRACE);
class TraceTest : public Test
{
public:
TraceTest()
{
Debug::setNewDefaultStdout(&debug_output);
Debug::setUnitTestFlag(D_TRACE, Debug::DebugLevel::TRACE);
}
~TraceTest()
{
Debug::setNewDefaultStdout(&cout);
}
NiceMock<MockMainLoop> mock_mainloop;
NiceMock<MockTimeGet> mock_timer;
ConfigComponent conf;
::Environment env;
stringstream debug_output;
};
TEST_F(TraceTest, defaultTraceTest)
{
string trace_id;
{
Trace trace;
trace_id = trace.getTraceId();
}
EXPECT_THAT(debug_output.str(), HasSubstr("New trace was created " + trace_id));
EXPECT_THAT(debug_output.str(), HasSubstr("Current trace has ended " + trace_id));
}
TEST_F(TraceTest, nonDefaultTraceTest)
{
string trace_id("4cc6bce7-4f68-42d6-94fc-e4127ac65ded");
string trace_id_str;
{
Trace trace(trace_id);
trace_id_str = trace.getTraceId();
}
EXPECT_THAT(debug_output.str(), HasSubstr("New trace was created " + trace_id));
EXPECT_THAT(debug_output.str(), HasSubstr("Current trace has ended " + trace_id));
}

View File

@@ -0,0 +1,384 @@
#include "environment.h"
#include "cptest.h"
#include "i_mainloop.h"
#include "mainloop.h"
#include "config.h"
#include "config_component.h"
#include "mock/mock_time_get.h"
#include "mock/mock_mainloop.h"
#include "mock/mock_messaging.h"
#include "mock/mock_agent_details.h"
#include "config.h"
using namespace std;
using namespace testing;
USE_DEBUG_FLAG(D_TRACE);
USE_DEBUG_FLAG(D_METRICS);
class TracingTest : public Test
{
public:
TracingTest()
{
env.preload();
i_env = Singleton::Consume<I_Environment>::from(env);
Debug::setNewDefaultStdout(&debug_output);
Debug::setUnitTestFlag(D_TRACE, Debug::DebugLevel::TRACE);
Debug::setUnitTestFlag(D_METRICS, Debug::DebugLevel::TRACE);
setConfiguration<bool>(true, "environment", "enable tracing");
setConfiguration<bool>(false, string("metric"), string("fogMetricSendEnable"));
EXPECT_CALL(mock_mainloop, addRecurringRoutine(I_MainLoop::RoutineType::System, _, _, _, _))
.WillOnce(DoAll(SaveArg<2>(&routine), Return(0)));
env.init();
}
~TracingTest()
{
Debug::setNewDefaultStdout(&cout);
}
I_MainLoop::Routine routine;
StrictMock<MockMainLoop> mock_mainloop;
StrictMock<MockTimeGet> mock_timer;
ConfigComponent conf;
::Environment env;
I_Environment *i_env;
stringstream debug_output;
};
TEST_F(TracingTest, noTraceTest)
{
auto empty_trace = i_env->getCurrentTrace();
EXPECT_EQ("", empty_trace);
auto empty_span = i_env->getCurrentSpan();
EXPECT_EQ("", empty_span);
}
TEST_F(TracingTest, disabledTraces)
{
setConfiguration<bool>(false, "environment", "enable tracing");
env.init();
i_env->startNewTrace();
auto trace_id = i_env->getCurrentTrace();
auto span_id = i_env->getCurrentSpan();
EXPECT_EQ("", i_env->getCurrentSpan());
EXPECT_EQ("", i_env->getCurrentTrace());
EXPECT_EQ("", debug_output.str());
i_env->finishSpan();
EXPECT_EQ("", debug_output.str());
EXPECT_EQ("", i_env->getCurrentSpan());
i_env->finishTrace();
EXPECT_EQ("", debug_output.str());
EXPECT_EQ("", i_env->getCurrentTrace());
}
TEST_F(TracingTest, newTraceSpanTest)
{
i_env->startNewTrace();
auto trace_id = i_env->getCurrentTrace();
auto span_id = i_env->getCurrentSpan();
EXPECT_NE("", i_env->getCurrentSpan());
EXPECT_NE("", i_env->getCurrentTrace());
EXPECT_THAT(debug_output.str(), HasSubstr("New trace was created " + trace_id));
EXPECT_THAT(debug_output.str(), HasSubstr("New span was created " + span_id));
EXPECT_THAT(debug_output.str(), HasSubstr(", trace id " + trace_id));
EXPECT_THAT(debug_output.str(), HasSubstr(", context type New"));
i_env->finishSpan();
EXPECT_THAT(debug_output.str(), HasSubstr("Current span has ended " + span_id));
EXPECT_EQ("", i_env->getCurrentSpan());
routine();
EXPECT_THAT(debug_output.str(), HasSubstr("\"Metric\": \"tracing\""));
EXPECT_THAT(debug_output.str(), HasSubstr("\"currentTraceNumber\": 1"));
i_env->finishTrace();
EXPECT_THAT(debug_output.str(), HasSubstr("Current trace has ended " + trace_id));
EXPECT_EQ("", i_env->getCurrentTrace());
routine();
EXPECT_THAT(debug_output.str(), HasSubstr("\"Metric\": \"tracing\""));
EXPECT_THAT(debug_output.str(), HasSubstr("\"currentTraceNumber\": 0"));
EXPECT_THAT(debug_output.str(), HasSubstr("\"maxSpanPerTrace\": 1"));
EXPECT_THAT(debug_output.str(), HasSubstr("\"avgSpanPerTrace\": 1.0"));
}
TEST_F(TracingTest, newSpanScopeTest)
{
string trace_id;
string span_id;
i_env->startNewTrace(false);
EXPECT_NE("", i_env->getCurrentTrace());
EXPECT_EQ("", i_env->getCurrentSpan());
trace_id = i_env->getCurrentTrace();
EXPECT_THAT(debug_output.str(), HasSubstr("New trace was created " + trace_id));
{
auto span_scope = i_env->startNewSpanScope(Span::ContextType::NEW);
span_id = i_env->getCurrentSpan();
EXPECT_NE("", i_env->getCurrentSpan());
EXPECT_THAT(debug_output.str(), HasSubstr("New span was created " + span_id));
EXPECT_THAT(debug_output.str(), HasSubstr(", trace id " + trace_id));
EXPECT_THAT(debug_output.str(), HasSubstr(", context type New"));
EXPECT_NE("", i_env->getCurrentSpan());
}
EXPECT_EQ("", i_env->getCurrentSpan());
EXPECT_THAT(debug_output.str(), HasSubstr("Current span has ended " + span_id));
i_env->finishTrace();
EXPECT_THAT(debug_output.str(), HasSubstr("Current trace has ended " + trace_id));
EXPECT_EQ("", i_env->getCurrentTrace());
routine();
EXPECT_THAT(debug_output.str(), HasSubstr("\"Metric\": \"tracing\""));
EXPECT_THAT(debug_output.str(), HasSubstr("\"currentTraceNumber\": 0"));
EXPECT_THAT(debug_output.str(), HasSubstr("\"maxSpanPerTrace\": 1"));
EXPECT_THAT(debug_output.str(), HasSubstr("\"avgSpanPerTrace\": 1.0"));
}
TEST_F(TracingTest, oldTraceNewSpanTest)
{
i_env->startNewTrace(true, "a687b388-1108-4083-9852-07c33b1074e9");
auto trace_id = i_env->getCurrentTrace();
auto span_id = i_env->getCurrentSpan();
EXPECT_EQ(trace_id, "a687b388-1108-4083-9852-07c33b1074e9");
EXPECT_NE("", i_env->getCurrentSpan());
EXPECT_NE("", i_env->getCurrentTrace());
EXPECT_THAT(debug_output.str(), HasSubstr("New trace was created " + trace_id));
EXPECT_THAT(debug_output.str(), HasSubstr("New span was created " + span_id));
EXPECT_THAT(debug_output.str(), HasSubstr("trace id " + trace_id));
EXPECT_THAT(debug_output.str(), HasSubstr("context type New"));
i_env->finishSpan();
EXPECT_THAT(debug_output.str(), HasSubstr("Current span has ended " + span_id));
EXPECT_EQ("", i_env->getCurrentSpan());
i_env->finishTrace();
EXPECT_THAT(debug_output.str(), HasSubstr("Current trace has ended " + trace_id));
EXPECT_EQ("", i_env->getCurrentTrace());
}
TEST_F(TracingTest, finishSpecificTraceSpan)
{
i_env->startNewTrace(true, "a687b388-1108-4083-9852-07c33b1074e9");
auto trace_id = i_env->getCurrentTrace();
auto span_id = i_env->getCurrentSpan();
EXPECT_EQ(trace_id, "a687b388-1108-4083-9852-07c33b1074e9");
EXPECT_NE("", i_env->getCurrentSpan());
EXPECT_NE("", i_env->getCurrentTrace());
EXPECT_THAT(debug_output.str(), HasSubstr("New trace was created " + trace_id));
EXPECT_THAT(debug_output.str(), HasSubstr("New span was created " + span_id));
EXPECT_THAT(debug_output.str(), HasSubstr("trace id " + trace_id));
EXPECT_THAT(debug_output.str(), HasSubstr("context type New"));
i_env->finishSpan(span_id);
EXPECT_THAT(debug_output.str(), HasSubstr("Current span has ended " + span_id));
EXPECT_EQ("", i_env->getCurrentSpan());
i_env->finishTrace(trace_id);
EXPECT_THAT(debug_output.str(), HasSubstr("Current trace has ended " + trace_id));
EXPECT_EQ("", i_env->getCurrentTrace());
}
TEST_F(TracingTest, 2SpansSameFlow)
{
i_env->startNewTrace(true, "a687b388-1108-4083-9852-07c33b1074e9");
auto trace_id = i_env->getCurrentTrace();
auto span_id = i_env->getCurrentSpan();
EXPECT_EQ(trace_id, "a687b388-1108-4083-9852-07c33b1074e9");
EXPECT_NE("", i_env->getCurrentSpan());
EXPECT_NE("", i_env->getCurrentTrace());
EXPECT_THAT(debug_output.str(), HasSubstr("New trace was created " + trace_id));
EXPECT_THAT(debug_output.str(), HasSubstr("New span was created " + span_id));
EXPECT_THAT(debug_output.str(), HasSubstr("trace id " + trace_id));
EXPECT_THAT(debug_output.str(), HasSubstr("context type New"));
i_env->finishSpan();
EXPECT_THAT(debug_output.str(), HasSubstr("Current span has ended " + span_id));
EXPECT_EQ("", i_env->getCurrentSpan());
i_env->startNewSpan(Span::ContextType::FOLLOWS_FROM, span_id);
auto another_span_id = i_env->getCurrentSpan();
EXPECT_EQ(trace_id, i_env->getCurrentTrace());
EXPECT_NE(another_span_id, span_id);
EXPECT_THAT(debug_output.str(), HasSubstr("New span was created " + another_span_id));
EXPECT_THAT(debug_output.str(), HasSubstr("trace id " + trace_id));
EXPECT_THAT(debug_output.str(), HasSubstr("context type Follows from"));
i_env->finishSpan();
EXPECT_THAT(debug_output.str(), HasSubstr("Current span has ended " + another_span_id));
EXPECT_EQ("", i_env->getCurrentSpan());
i_env->finishTrace();
EXPECT_THAT(debug_output.str(), HasSubstr("Current trace has ended " + trace_id));
EXPECT_EQ("", i_env->getCurrentTrace());
routine();
EXPECT_THAT(debug_output.str(), HasSubstr("\"Metric\": \"tracing\""));
EXPECT_THAT(debug_output.str(), HasSubstr("\"currentTraceNumber\": 0"));
EXPECT_THAT(debug_output.str(), HasSubstr("\"maxSpanPerTrace\": 2"));
EXPECT_THAT(debug_output.str(), HasSubstr("\"avgSpanPerTrace\": 2.0"));
}
TEST_F(TracingTest, metricTracingTest)
{
i_env->startNewTrace();
auto span_id = i_env->getCurrentSpan();
i_env->finishSpan();
i_env->startNewSpan(Span::ContextType::FOLLOWS_FROM, span_id);
auto another_span_id = i_env->getCurrentSpan();
i_env->finishSpan();
i_env->startNewSpan(Span::ContextType::FOLLOWS_FROM, another_span_id);
i_env->finishSpan();
i_env->finishTrace();
routine();
EXPECT_THAT(debug_output.str(), HasSubstr("\"Metric\": \"tracing\""));
EXPECT_THAT(debug_output.str(), HasSubstr("\"currentTraceNumber\": 0"));
EXPECT_THAT(debug_output.str(), HasSubstr("\"maxSpanPerTrace\": 3"));
EXPECT_THAT(debug_output.str(), HasSubstr("\"avgSpanPerTrace\": 3.0"));
i_env->startNewTrace();
i_env->finishSpan();
i_env->finishTrace();
routine();
EXPECT_THAT(debug_output.str(), HasSubstr("\"Metric\": \"tracing\""));
EXPECT_THAT(debug_output.str(), HasSubstr("\"currentTraceNumber\": 0"));
EXPECT_THAT(debug_output.str(), HasSubstr("\"maxSpanPerTrace\": 3"));
EXPECT_THAT(debug_output.str(), HasSubstr("\"avgSpanPerTrace\": 2.0"));
}
class TracingCompRoutinesTest : public Test
{
public:
TracingCompRoutinesTest()
{
env.preload();
setConfiguration<bool>(true, "environment", "enable tracing");
env.init();
mainloop_comp.init();
mainloop = Singleton::Consume<I_MainLoop>::from(mainloop_comp);
i_env = Singleton::Consume<I_Environment>::from(env);
Debug::setNewDefaultStdout(&debug_output);
Debug::setUnitTestFlag(D_TRACE, Debug::DebugLevel::TRACE);
I_MainLoop::Routine another_routine = [&] () {
while (!stop) {
mainloop->yield(true);
}
i_env->startNewTrace(true, "a687b388-1108-4083-9852-07c33b107589");
auto another_trace_id = i_env->getCurrentTrace();
auto another_span_id = i_env->getCurrentSpan();
EXPECT_NE(trace_id, another_trace_id);
EXPECT_NE(span_id, another_span_id);
EXPECT_NE("", i_env->getCurrentSpan());
EXPECT_NE("", i_env->getCurrentTrace());
EXPECT_THAT(debug_output.str(), HasSubstr("New trace was created " + another_trace_id));
EXPECT_THAT(debug_output.str(), HasSubstr("New span was created " + another_span_id));
EXPECT_THAT(debug_output.str(), HasSubstr("trace id " + another_trace_id));
EXPECT_THAT(debug_output.str(), HasSubstr("context type New"));
i_env->finishSpan();
EXPECT_THAT(debug_output.str(), HasSubstr("Current span has ended " + another_span_id));
EXPECT_EQ("", i_env->getCurrentSpan());
i_env->finishTrace();
EXPECT_THAT(debug_output.str(), HasSubstr("Current trace has ended " + another_trace_id));
EXPECT_EQ("", i_env->getCurrentTrace());
};
mainloop->addOneTimeRoutine(
I_MainLoop::RoutineType::RealTime,
another_routine,
"TracingCompRoutinesTest routine",
true
);
}
~TracingCompRoutinesTest()
{
Debug::setNewDefaultStdout(&cout);
mainloop_comp.fini();
}
bool stop = false;
stringstream debug_output;
ConfigComponent config;
NiceMock<MockAgentDetails> agent_details_mocker;
NiceMock<MockTimeGet> mock_time;
NiceMock<MockMessaging> mock_messaging;
MainloopComponent mainloop_comp;
::Environment env;
I_MainLoop *mainloop;
I_Environment *i_env;
string trace_id;
string span_id;
};
TEST_F(TracingCompRoutinesTest, 2SpansDifFlow)
{
ON_CALL(mock_messaging, mockSendPersistentMessage(_, _, _, _, _, _, _)).WillByDefault(Return(string()));
I_MainLoop::Routine routine = [&] () {
i_env->startNewTrace(true, "a687b388-1108-4083-9852-07c33b1074e9");
trace_id = i_env->getCurrentTrace();
span_id = i_env->getCurrentSpan();
string headers = i_env->getCurrentHeaders();
EXPECT_THAT(headers, HasSubstr("X-Trace-Id: " + trace_id));
EXPECT_THAT(headers, HasSubstr("X-Span-Id: " + span_id));
EXPECT_EQ(trace_id, "a687b388-1108-4083-9852-07c33b1074e9");
EXPECT_NE("", i_env->getCurrentSpan());
EXPECT_NE("", i_env->getCurrentTrace());
EXPECT_THAT(debug_output.str(), HasSubstr("New trace was created " + trace_id));
EXPECT_THAT(debug_output.str(), HasSubstr("New span was created " + span_id));
EXPECT_THAT(debug_output.str(), HasSubstr("trace id " + trace_id));
EXPECT_THAT(debug_output.str(), HasSubstr("context type New"));
stop = true;
mainloop->yield(true);
i_env->finishSpan();
EXPECT_THAT(debug_output.str(), HasSubstr("Current span has ended " + span_id));
EXPECT_EQ("", i_env->getCurrentSpan());
i_env->finishTrace();
EXPECT_THAT(debug_output.str(), HasSubstr("Current trace has ended " + trace_id));
EXPECT_EQ("", i_env->getCurrentTrace());
};
mainloop->addOneTimeRoutine(I_MainLoop::RoutineType::RealTime, routine, "2SpansDifFlow test routine");
try {
mainloop->run();
} catch(...) {
}
}