mirror of
https://github.com/openappsec/openappsec.git
synced 2025-09-30 03:34:26 +03:00
First release of open-appsec source code
This commit is contained in:
3
core/environment/CMakeLists.txt
Normal file
3
core/environment/CMakeLists.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
add_library(environment environment.cc context.cc parsing.cc base_evaluators.cc trace.cc span.cc param_attr.cc)
|
||||
|
||||
add_subdirectory(environment_ut)
|
103
core/environment/base_evaluators.cc
Normal file
103
core/environment/base_evaluators.cc
Normal file
@@ -0,0 +1,103 @@
|
||||
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "environment_evaluator.h"
|
||||
#include "evaluator_registration.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace EnvironmentHelper;
|
||||
|
||||
class AllEvaluator : public EnvironmentEvaluator<bool>
|
||||
{
|
||||
public:
|
||||
AllEvaluator(const vector<string> ¶ms)
|
||||
{
|
||||
for (const auto ¶m : params) {
|
||||
conditions.push_back(getMatcher<bool>(param));
|
||||
}
|
||||
}
|
||||
|
||||
Maybe<bool, Context::Error>
|
||||
evalVariable() const override
|
||||
{
|
||||
for (auto &cond : conditions) {
|
||||
auto res = cond->evalVariable();
|
||||
if (!res.ok()) return res;
|
||||
if (res.unpack() == false) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static std::string getName() { return "All"; }
|
||||
|
||||
private:
|
||||
vector<EvaluatorPtr<bool>> conditions;
|
||||
};
|
||||
|
||||
class AnyEvaluator : public EnvironmentEvaluator<bool>
|
||||
{
|
||||
public:
|
||||
AnyEvaluator(const vector<string> ¶ms)
|
||||
{
|
||||
for (const auto ¶m : params) {
|
||||
conditions.push_back(getMatcher<bool>(param));
|
||||
}
|
||||
}
|
||||
|
||||
Maybe<bool, Context::Error>
|
||||
evalVariable() const override
|
||||
{
|
||||
for (auto &cond : conditions) {
|
||||
auto res = cond->evalVariable();
|
||||
if (!res.ok()) return res;
|
||||
if (res.unpack() == true) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static std::string getName() { return "Any"; }
|
||||
|
||||
private:
|
||||
vector<EvaluatorPtr<bool>> conditions;
|
||||
};
|
||||
|
||||
class NotEvaluator : public EnvironmentEvaluator<bool>
|
||||
{
|
||||
public:
|
||||
NotEvaluator(const vector<string> ¶ms)
|
||||
{
|
||||
if (params.size() != 1) reportWrongNumberOfParams(getName(), params.size(), 1, 1);
|
||||
cond = getMatcher<bool>(params[0]);
|
||||
}
|
||||
|
||||
Maybe<bool, Context::Error>
|
||||
evalVariable() const override
|
||||
{
|
||||
auto res = cond->evalVariable();
|
||||
if (!res.ok()) return res;
|
||||
return !(res.unpack());
|
||||
}
|
||||
|
||||
static std::string getName() { return "Not"; }
|
||||
|
||||
private:
|
||||
EvaluatorPtr<bool> cond;
|
||||
};
|
||||
|
||||
void
|
||||
registerBaseEvaluators()
|
||||
{
|
||||
addMatcher<AllEvaluator>();
|
||||
addMatcher<AnyEvaluator>();
|
||||
addMatcher<NotEvaluator>();
|
||||
}
|
101
core/environment/context.cc
Normal file
101
core/environment/context.cc
Normal file
@@ -0,0 +1,101 @@
|
||||
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "context.h"
|
||||
#include "i_environment.h"
|
||||
#include "singleton.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
void
|
||||
Context::activate()
|
||||
{
|
||||
Singleton::Consume<I_Environment>::by<Context>()->registerContext(this);
|
||||
}
|
||||
|
||||
void
|
||||
Context::deactivate()
|
||||
{
|
||||
Singleton::Consume<I_Environment>::by<Context>()->unregisterContext(this);
|
||||
}
|
||||
|
||||
map<string, string>
|
||||
Context::getAllStrings(const EnvKeyAttr::ParamAttr ¶m) const
|
||||
{
|
||||
map<string, string> result;
|
||||
for (auto &entry : values) {
|
||||
if (entry.first.doesMatch(param)) {
|
||||
auto entry_value = entry.second->getString();
|
||||
if (entry_value.ok()) result[entry.first.first] = *entry_value;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
const std::string
|
||||
Context::convertToString(MetaDataType type)
|
||||
{
|
||||
switch (type) {
|
||||
case MetaDataType::File: return "file";
|
||||
case MetaDataType::SubjectIpAddr: return "subjectIp";
|
||||
case MetaDataType::OtherIpAddr: return "otherIp";
|
||||
case MetaDataType::Port: return "port";
|
||||
case MetaDataType::Protocol: return "protocol";
|
||||
case MetaDataType::Service: return "service";
|
||||
case MetaDataType::User: return "user";
|
||||
case MetaDataType::Domain: return "domain";
|
||||
case MetaDataType::Url: return "url";
|
||||
case MetaDataType::Direction: return "direction";
|
||||
case MetaDataType::Email: return "email";
|
||||
case MetaDataType::COUNT:
|
||||
dbgAssert(false) << "COUNT is not a valid meta data type";
|
||||
}
|
||||
dbgAssert(false) << "Reached impossible case with type=" << static_cast<int>(type);
|
||||
return "";
|
||||
}
|
||||
|
||||
map<string, uint64_t>
|
||||
Context::getAllUints(const EnvKeyAttr::ParamAttr ¶m) const
|
||||
{
|
||||
map<string, uint64_t> result;
|
||||
for (auto &entry : values) {
|
||||
if (entry.first.doesMatch(param)) {
|
||||
auto entry_value = entry.second->getUint();
|
||||
if (entry_value.ok()) result[entry.first.first] = *entry_value;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
map<string, bool>
|
||||
Context::getAllBools(const EnvKeyAttr::ParamAttr ¶m) const
|
||||
{
|
||||
map<string, bool> result;
|
||||
for (auto &entry : values) {
|
||||
if (entry.first.doesMatch(param)) {
|
||||
auto entry_value = entry.second->getBool();
|
||||
if (entry_value.ok()) result[entry.first.first] = *entry_value;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ScopedContext::ScopedContext()
|
||||
{
|
||||
activate();
|
||||
}
|
||||
|
||||
ScopedContext::~ScopedContext()
|
||||
{
|
||||
deactivate();
|
||||
}
|
421
core/environment/environment.cc
Normal file
421
core/environment/environment.cc
Normal file
@@ -0,0 +1,421 @@
|
||||
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "environment.h"
|
||||
#include "context.h"
|
||||
#include "singleton.h"
|
||||
#include "common.h"
|
||||
#include "debug.h"
|
||||
#include "evaluator_registration.h"
|
||||
#include "environment_evaluator.h"
|
||||
#include "i_rest_api.h"
|
||||
#include "rest.h"
|
||||
#include "environment/trace.h"
|
||||
#include "boost/uuid/uuid.hpp"
|
||||
#include "boost/uuid/uuid_generators.hpp"
|
||||
#include "boost/uuid/uuid_io.hpp"
|
||||
#include "config.h"
|
||||
#include "environment/tracing_metric.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
USE_DEBUG_FLAG(D_ENVIRONMENT);
|
||||
USE_DEBUG_FLAG(D_TRACE);
|
||||
|
||||
class Environment::Impl
|
||||
:
|
||||
public Singleton::Provide<I_Environment>::From<Environment>
|
||||
{
|
||||
public:
|
||||
void init();
|
||||
void fini();
|
||||
|
||||
void preload();
|
||||
|
||||
void setActiveTenant(const string &tenant_id) override;
|
||||
void unsetActiveTenant() override;
|
||||
|
||||
void registerContext(Context *ptr) override;
|
||||
void unregisterContext(Context *ptr) override;
|
||||
ActiveContexts createEnvironment() override;
|
||||
ActiveContexts saveEnvironment() override;
|
||||
void loadEnvironment(ActiveContexts &&env) override;
|
||||
Context & getConfigurationContext() override;
|
||||
|
||||
map<string, string> getAllStrings(const EnvKeyAttr::ParamAttr ¶ms) const override;
|
||||
map<string, uint64_t> getAllUints(const EnvKeyAttr::ParamAttr ¶ms) const override;
|
||||
map<string, bool> getAllBools(const EnvKeyAttr::ParamAttr ¶ms) const override;
|
||||
|
||||
string getCurrentTrace() const override;
|
||||
string getCurrentSpan() const override;
|
||||
string getCurrentHeaders() override;
|
||||
|
||||
void startNewTrace(bool new_span, const string &_trace_id) override;
|
||||
void startNewSpan(Span::ContextType _type, const string &prev_span, const string &trace) override;
|
||||
using on_exit = scope_exit<function<void(void)>>;
|
||||
on_exit startNewSpanScope(Span::ContextType _type, const string &prev_span, const string &trace) override;
|
||||
void finishTrace(const string &trace) override;
|
||||
void finishSpan(const string &span) override;
|
||||
|
||||
private:
|
||||
const ActiveContexts & getActiveContexts() const override { return active_contexts; }
|
||||
void loadEnvConfig();
|
||||
|
||||
I_TenantManager *tenant_manager = nullptr;
|
||||
ActiveContexts active_contexts;
|
||||
Context global;
|
||||
map<string, TraceWrapper> active_traces;
|
||||
map<string, SpanWrapper> active_spans;
|
||||
map<string, int> tracing_stats;
|
||||
TracingMetric tracing_metric;
|
||||
TraceEvent trace_event;
|
||||
TraceFinishEvent trace_finish_event;
|
||||
bool is_metric_enabled = false;
|
||||
TracingStatus tracing_status = TracingStatus::OFF;
|
||||
bool was_initialized = false;
|
||||
};
|
||||
|
||||
class DeclareBooleanVariable : public ServerRest
|
||||
{
|
||||
public:
|
||||
void
|
||||
doCall() override
|
||||
{
|
||||
auto func = genEvaluator<bool>(expr);
|
||||
if (!func.ok()) {
|
||||
dbgWarning(D_ENVIRONMENT) << "Failed to generate boolean function: " << func.getErr();
|
||||
return;
|
||||
}
|
||||
dbgTrace(D_ENVIRONMENT) << "Boolean function was generated";
|
||||
auto env = Singleton::Consume<I_Environment>::from<Environment>();
|
||||
env->getConfigurationContext().registerFunc(name, func.unpackMove());
|
||||
}
|
||||
|
||||
private:
|
||||
C2S_PARAM(string, name);
|
||||
C2S_PARAM(string, expr);
|
||||
};
|
||||
|
||||
void
|
||||
Environment::Impl::loadEnvConfig()
|
||||
{
|
||||
auto tracing_conf = getConfigurationWithDefault<bool>(false, "environment", "enable tracing");
|
||||
if (tracing_status == TracingStatus::DISABLED) return;
|
||||
tracing_status = tracing_conf ? TracingStatus::ON : TracingStatus::OFF;
|
||||
if (tracing_status == TracingStatus::ON && !is_metric_enabled) {
|
||||
auto metric_report_interval = chrono::seconds(
|
||||
getConfigurationWithDefault<uint>(600, "environment", "tracingMetricReportInterval")
|
||||
);
|
||||
tracing_metric.init(
|
||||
"tracing",
|
||||
ReportIS::AudienceTeam::AGENT_CORE,
|
||||
ReportIS::IssuingEngine::AGENT_CORE,
|
||||
metric_report_interval,
|
||||
false
|
||||
);
|
||||
tracing_metric.registerListener();
|
||||
is_metric_enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Environment::Impl::init()
|
||||
{
|
||||
was_initialized = true;
|
||||
loadEnvConfig();
|
||||
if (!Singleton::exists<I_RestApi>()) return;
|
||||
auto rest = Singleton::Consume<I_RestApi>::by<Environment>();
|
||||
rest->addRestCall<DeclareBooleanVariable>(RestAction::ADD, "declare-boolean-variable");
|
||||
}
|
||||
|
||||
void
|
||||
Environment::Impl::fini()
|
||||
{
|
||||
global.deactivate();
|
||||
}
|
||||
|
||||
void
|
||||
Environment::Impl::setActiveTenant(const string &tenant_id)
|
||||
{
|
||||
if (tenant_manager == nullptr) tenant_manager = Singleton::Consume<I_TenantManager>::by<Environment>();
|
||||
tenant_manager->addActiveTenant(tenant_id);
|
||||
registerValue<string>("ActiveTenantId", tenant_id);
|
||||
}
|
||||
|
||||
void
|
||||
Environment::Impl::unsetActiveTenant()
|
||||
{
|
||||
getConfigurationContext().unregisterKey<string>("ActiveTenantId");
|
||||
}
|
||||
|
||||
map<string, string>
|
||||
Environment::Impl::getAllStrings(const EnvKeyAttr::ParamAttr ¶ms) const
|
||||
{
|
||||
map<string, string> result;
|
||||
|
||||
for (auto &iter : active_contexts.first) {
|
||||
auto partial_results = iter->getAllStrings(params);
|
||||
for (auto &entry : partial_results) {
|
||||
result.emplace(entry);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
map<string, uint64_t>
|
||||
Environment::Impl::getAllUints(const EnvKeyAttr::ParamAttr ¶ms) const
|
||||
{
|
||||
map<string, uint64_t> result;
|
||||
|
||||
for (auto &iter : active_contexts.first) {
|
||||
auto partial_results = iter->getAllUints(params);
|
||||
for (auto &entry : partial_results) {
|
||||
result.emplace(entry);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
map<string, bool>
|
||||
Environment::Impl::getAllBools(const EnvKeyAttr::ParamAttr ¶ms) const
|
||||
{
|
||||
map<string, bool> result;
|
||||
|
||||
for (auto &iter : active_contexts.first) {
|
||||
auto partial_results = iter->getAllBools(params);
|
||||
for (auto &entry : partial_results) {
|
||||
result.emplace(entry);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
Environment::Impl::registerContext(Context *ptr)
|
||||
{
|
||||
active_contexts.first.push_back(ptr);
|
||||
}
|
||||
|
||||
void
|
||||
Environment::Impl::unregisterContext(Context *ptr)
|
||||
{
|
||||
dbgAssert(active_contexts.first.back() == ptr) <<
|
||||
"Contexts are supposed to unregister in reverse order to their registration";
|
||||
active_contexts.first.pop_back();
|
||||
}
|
||||
|
||||
string
|
||||
Environment::Impl::getCurrentTrace() const
|
||||
{
|
||||
if (tracing_status != TracingStatus::ON) return "";
|
||||
|
||||
auto trace = get<string>("trace id");
|
||||
if (trace.ok()) return trace.unpack();
|
||||
return "";
|
||||
}
|
||||
|
||||
string
|
||||
Environment::Impl::getCurrentSpan() const
|
||||
{
|
||||
if (tracing_status != TracingStatus::ON) return "";
|
||||
|
||||
auto span = get<string>("span id");
|
||||
if (span.ok()) return span.unpack();
|
||||
return "";
|
||||
}
|
||||
|
||||
string
|
||||
Environment::Impl::getCurrentHeaders()
|
||||
{
|
||||
string tracing_headers;
|
||||
auto trace_id = getCurrentTrace();
|
||||
if (!trace_id.empty()) {
|
||||
tracing_headers += "X-Trace-Id: " + trace_id + "\r\n";
|
||||
} else {
|
||||
string correlation_id_string = "00000000-0000-0000-0000-000000000000";
|
||||
try {
|
||||
boost::uuids::random_generator uuid_random_gen;
|
||||
correlation_id_string = boost::uuids::to_string(uuid_random_gen());
|
||||
} catch (const boost::uuids::entropy_error &e) {
|
||||
dbgTrace(D_ENVIRONMENT)
|
||||
<< "Failed to generate random correlation id - entropy exception. Exception: "
|
||||
<< e.what();
|
||||
tracing_status = TracingStatus::DISABLED;
|
||||
}
|
||||
tracing_headers += "X-Trace-Id: " + correlation_id_string + "\r\n";
|
||||
}
|
||||
|
||||
auto span_id = getCurrentSpan();
|
||||
if (!span_id.empty()) {
|
||||
tracing_headers += "X-Span-Id: " + span_id + "\r\n";
|
||||
}
|
||||
return tracing_headers;
|
||||
}
|
||||
|
||||
void
|
||||
Environment::Impl::startNewTrace(bool new_span, const string &_trace_id)
|
||||
{
|
||||
if (tracing_status != TracingStatus::ON) return;
|
||||
|
||||
try {
|
||||
TraceWrapper trace(_trace_id);
|
||||
auto trace_id = trace.getTraceId();
|
||||
active_traces.emplace(trace_id, trace);
|
||||
tracing_stats[trace_id] = 0;
|
||||
if (new_span) {
|
||||
SpanWrapper span(trace_id);
|
||||
auto span_id = span.getSpanId();
|
||||
active_spans.emplace(span_id, span);
|
||||
}
|
||||
trace_event.setTraceAmount(active_traces.size());
|
||||
trace_event.notify();
|
||||
|
||||
} catch (const boost::uuids::entropy_error &e) {
|
||||
tracing_status = TracingStatus::DISABLED;
|
||||
dbgWarning(D_TRACE)
|
||||
<< "Failed to generate random id - entropy exception. Exception: "
|
||||
<< e.what();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Environment::Impl::startNewSpan(Span::ContextType context_type, const string &prev_span, const string &trace)
|
||||
{
|
||||
if (tracing_status != TracingStatus::ON) return;
|
||||
|
||||
string selected_trace = !trace.empty() ? trace : getCurrentTrace();
|
||||
string selected_span = !prev_span.empty() ? prev_span : getCurrentSpan();
|
||||
try {
|
||||
SpanWrapper span(selected_trace, context_type, selected_span);
|
||||
active_spans.emplace(span.getSpanId(), span);
|
||||
} catch (const boost::uuids::entropy_error &e) {
|
||||
tracing_status = TracingStatus::DISABLED;
|
||||
dbgWarning(D_TRACE)
|
||||
<< "Failed to generate random id - entropy exception. Exception: "
|
||||
<< e.what();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Environment::Impl::finishTrace(const string &trace)
|
||||
{
|
||||
if (tracing_status != TracingStatus::ON) return;
|
||||
|
||||
auto deleted_trace = trace.empty() ? getCurrentTrace() : trace;
|
||||
if (deleted_trace.empty()) {
|
||||
dbgWarning(D_ENVIRONMENT) << "There is no current trace to finish";
|
||||
return;
|
||||
}
|
||||
|
||||
trace_finish_event.setSpanAmount(tracing_stats[deleted_trace]);
|
||||
active_traces.erase(deleted_trace);
|
||||
tracing_stats.erase(deleted_trace);
|
||||
|
||||
trace_event.setTraceAmount(active_traces.size());
|
||||
trace_event.notify();
|
||||
trace_finish_event.notify();
|
||||
}
|
||||
|
||||
void
|
||||
Environment::Impl::finishSpan(const string &span)
|
||||
{
|
||||
if (tracing_status != TracingStatus::ON) return;
|
||||
|
||||
auto deleted_span = span.empty() ? getCurrentSpan() : span;
|
||||
if (deleted_span.empty()) {
|
||||
dbgWarning(D_ENVIRONMENT) << "There is no current span to finish";
|
||||
return;
|
||||
}
|
||||
auto span_iter = active_spans.find(deleted_span);
|
||||
if (span_iter != active_spans.end()) {
|
||||
auto trace_id = span_iter->second.getTraceId();
|
||||
tracing_stats[trace_id]++;
|
||||
}
|
||||
|
||||
active_spans.erase(deleted_span);
|
||||
}
|
||||
|
||||
scope_exit<function<void(void)>>
|
||||
Environment::Impl::startNewSpanScope(Span::ContextType context_type, const string &prev_span, const string &trace)
|
||||
{
|
||||
startNewSpan(context_type, prev_span, trace);
|
||||
function<void(void)> release_function = [&] () { finishSpan(""); };
|
||||
return make_scope_exit(move(release_function));
|
||||
}
|
||||
|
||||
I_Environment::ActiveContexts
|
||||
Environment::Impl::createEnvironment()
|
||||
{
|
||||
return ActiveContexts({ &global }, Debug::DebugLockState::getState());
|
||||
}
|
||||
|
||||
I_Environment::ActiveContexts
|
||||
Environment::Impl::saveEnvironment()
|
||||
{
|
||||
return move(active_contexts);
|
||||
}
|
||||
|
||||
void
|
||||
Environment::Impl::loadEnvironment(ActiveContexts &&env)
|
||||
{
|
||||
active_contexts = move(env);
|
||||
Debug::DebugLockState::setState(active_contexts.second);
|
||||
}
|
||||
|
||||
Context &
|
||||
Environment::Impl::getConfigurationContext()
|
||||
{
|
||||
return global;
|
||||
}
|
||||
|
||||
void
|
||||
Environment::Impl::preload()
|
||||
{
|
||||
registerBaseEvaluators();
|
||||
global.activate();
|
||||
registerExpectedConfiguration<bool>("environment", "enable tracing");
|
||||
registerExpectedConfiguration<uint>("environment", "tracingMetricReportInterval");
|
||||
registerConfigLoadCb(
|
||||
[this] ()
|
||||
{
|
||||
if (was_initialized) loadEnvConfig();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
Environment::Environment() : Component("Environment"), pimpl(make_unique<Impl>()) {}
|
||||
|
||||
Environment::~Environment() {}
|
||||
|
||||
void
|
||||
Environment::init()
|
||||
{
|
||||
pimpl->init();
|
||||
}
|
||||
|
||||
void
|
||||
Environment::fini()
|
||||
{
|
||||
pimpl->fini();
|
||||
}
|
||||
|
||||
void
|
||||
Environment::preload()
|
||||
{
|
||||
pimpl->preload();
|
||||
}
|
5
core/environment/environment_ut/CMakeLists.txt
Executable file
5
core/environment/environment_ut/CMakeLists.txt
Executable 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"
|
||||
)
|
199
core/environment/environment_ut/base_evaluators_ut.cc
Executable file
199
core/environment/environment_ut/base_evaluators_ut.cc
Executable 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"));
|
||||
}
|
237
core/environment/environment_ut/context_ut.cc
Executable file
237
core/environment/environment_ut/context_ut.cc
Executable 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));
|
||||
}
|
68
core/environment/environment_ut/environment_rest_ut.cc
Normal file
68
core/environment/environment_ut/environment_rest_ut.cc
Normal 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"));
|
||||
}
|
87
core/environment/environment_ut/environment_ut.cc
Normal file
87
core/environment/environment_ut/environment_ut.cc
Normal 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)));
|
||||
}
|
156
core/environment/environment_ut/parsing_ut.cc
Executable file
156
core/environment/environment_ut/parsing_ut.cc
Executable 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;
|
||||
}
|
95
core/environment/environment_ut/span_ut.cc
Executable file
95
core/environment/environment_ut/span_ut.cc
Executable 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));
|
||||
}
|
59
core/environment/environment_ut/trace_ut.cc
Executable file
59
core/environment/environment_ut/trace_ut.cc
Executable 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));
|
||||
}
|
384
core/environment/environment_ut/tracing_ut.cc
Executable file
384
core/environment/environment_ut/tracing_ut.cc
Executable 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(...) {
|
||||
}
|
||||
}
|
19
core/environment/evaluator_registration.h
Normal file
19
core/environment/evaluator_registration.h
Normal file
@@ -0,0 +1,19 @@
|
||||
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef __EVALUATOR_REGISTRATION_H__
|
||||
#define __EVALUATOR_REGISTRATION_H__
|
||||
|
||||
void registerBaseEvaluators();
|
||||
|
||||
#endif // __EVALUATOR_REGISTRATION_H__
|
23
core/environment/param_attr.cc
Normal file
23
core/environment/param_attr.cc
Normal file
@@ -0,0 +1,23 @@
|
||||
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "context.h"
|
||||
|
||||
bool
|
||||
EnvKeyAttr::ParamAttr::doesMatch(const EnvKeyAttr::ParamAttr ¶m) const
|
||||
{
|
||||
if (param.log_section != LogSection::NONE && param.log_section != log_section) return false;
|
||||
if (param.verbosity_level != Verbosity::NONE && param.verbosity_level != verbosity_level) return false;
|
||||
|
||||
return true;
|
||||
}
|
137
core/environment/parsing.cc
Normal file
137
core/environment/parsing.cc
Normal file
@@ -0,0 +1,137 @@
|
||||
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "environment_evaluator.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
|
||||
#include "enum_range.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace EnvironmentHelper;
|
||||
|
||||
USE_DEBUG_FLAG(D_ENVIRONMENT);
|
||||
|
||||
void
|
||||
reportWrongNumberOfParams(const string &eval_name, uint no_params, uint min, uint max)
|
||||
{
|
||||
ostringstream os;
|
||||
os <<
|
||||
"Wrong number of parameters for '" <<
|
||||
eval_name <<
|
||||
"'. Got " <<
|
||||
no_params <<
|
||||
" parameters instead of expected ";
|
||||
if (min == max) {
|
||||
os << min;
|
||||
} else if (max == static_cast<uint>(-1)) {
|
||||
os << "more than " << min;
|
||||
} else {
|
||||
os << "between " << min << " and " << max;
|
||||
}
|
||||
dbgTrace(D_ENVIRONMENT) << os.str();
|
||||
EvaluatorParseError err(os.str());
|
||||
throw err;
|
||||
}
|
||||
|
||||
void
|
||||
reportWrongParamType(const string &eval_name, const string ¶m, const string &reason)
|
||||
{
|
||||
ostringstream os;
|
||||
os << "Parameter '" << param << "' for '" << eval_name << "' is of the wrong type because: " << reason;
|
||||
dbgTrace(D_ENVIRONMENT) << os.str();
|
||||
|
||||
EvaluatorParseError err(os.str());
|
||||
throw err;
|
||||
}
|
||||
|
||||
void
|
||||
reportUnknownEvaluatorType(const string &eval_name)
|
||||
{
|
||||
ostringstream os;
|
||||
os << "Evaluator '" << eval_name << "' doesn't exist for the required type";
|
||||
dbgTrace(D_ENVIRONMENT) << os.str();
|
||||
|
||||
EvaluatorParseError err(os.str());
|
||||
throw err;
|
||||
}
|
||||
|
||||
static string
|
||||
trim(const string &str)
|
||||
{
|
||||
auto first = str.find_first_not_of(' ');
|
||||
if (first == string::npos) return "";
|
||||
auto last = str.find_last_not_of(' ');
|
||||
return str.substr(first, (last-first+1));
|
||||
}
|
||||
|
||||
static vector<string>
|
||||
breakToParams(const string &list)
|
||||
{
|
||||
vector<string> res;
|
||||
|
||||
uint brackets = 0;
|
||||
uint start = 0;
|
||||
for (uint iter : makeRange(list.size())) {
|
||||
switch (list[iter]) {
|
||||
case ',': {
|
||||
if (brackets == 0) {
|
||||
res.push_back(trim(list.substr(start, iter-start)));
|
||||
start = iter + 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case '(': {
|
||||
brackets++;
|
||||
break;
|
||||
}
|
||||
case ')': {
|
||||
brackets--;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add the last section
|
||||
if (start < list.size()) res.push_back(trim(list.substr(start, list.size()-start)));
|
||||
|
||||
dbgTrace(D_ENVIRONMENT) << "Param vector size: " << res.size();
|
||||
return res;
|
||||
}
|
||||
|
||||
pair<string, vector<string>>
|
||||
EnvironmentHelper::breakEvaluatorString(const string &str)
|
||||
{
|
||||
auto trimmed = trim(str);
|
||||
|
||||
auto open_bracket = trimmed.find('(');
|
||||
if (open_bracket == string::npos) {
|
||||
dbgTrace(D_ENVIRONMENT) << "Could not find the opening bracket in the string";
|
||||
throw EvaluatorParseError("Could not find the opening bracket in the string");
|
||||
}
|
||||
auto close_bracket = trimmed.size() - 1;
|
||||
if (trimmed[close_bracket] != ')') {
|
||||
dbgTrace(D_ENVIRONMENT) << "Could not find the closing bracket in the string";
|
||||
throw EvaluatorParseError("Could not find the closing bracket in the string");
|
||||
}
|
||||
|
||||
auto command = trimmed.substr(0, open_bracket);
|
||||
auto params = trimmed.substr(open_bracket + 1, close_bracket - open_bracket - 1);
|
||||
|
||||
dbgTrace(D_ENVIRONMENT) << "Breaking evaluator string passed successfully";
|
||||
return make_pair(trim(command), breakToParams(trim(params)));
|
||||
}
|
131
core/environment/span.cc
Executable file
131
core/environment/span.cc
Executable file
@@ -0,0 +1,131 @@
|
||||
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "environment/span.h"
|
||||
|
||||
#include "boost/uuid/uuid.hpp"
|
||||
#include "boost/uuid/uuid_generators.hpp"
|
||||
#include "boost/uuid/uuid_io.hpp"
|
||||
#include "debug.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace boost::uuids;
|
||||
|
||||
USE_DEBUG_FLAG(D_TRACE);
|
||||
|
||||
Span::Span(string _trace_id, ContextType _type, string _prev_span)
|
||||
:
|
||||
trace_id(_trace_id),
|
||||
context_type(_type),
|
||||
prev_span_id(_prev_span)
|
||||
{
|
||||
|
||||
if (trace_id.empty()) {
|
||||
dbgError(D_TRACE) << "Provided trace id is empty. Span cannot be created";
|
||||
return;
|
||||
}
|
||||
|
||||
if (context_type != ContextType::NEW && prev_span_id.empty()) {
|
||||
dbgError(D_TRACE) << "The provided previous span ID is empty. Cannot create span.";
|
||||
return;
|
||||
}
|
||||
|
||||
boost::uuids::random_generator uuid_random_gen;
|
||||
span_id = to_string(uuid_random_gen());
|
||||
|
||||
context.registerValue<string>("span id", span_id);
|
||||
context.activate();
|
||||
|
||||
dbgTrace(D_TRACE) << "New span was created " << span_id
|
||||
<< ", trace id " << trace_id
|
||||
<< ", context type " << convertSpanContextTypeToString(context_type)
|
||||
<< (context_type == ContextType::NEW ? string() : ", previous span id " + prev_span_id);
|
||||
}
|
||||
|
||||
Span::~Span()
|
||||
{
|
||||
dbgTrace(D_TRACE) << "Current span has ended " << span_id;
|
||||
context.unregisterKey<string>("span id");
|
||||
context.deactivate();
|
||||
}
|
||||
|
||||
string
|
||||
Span::getTraceId() const
|
||||
{
|
||||
return trace_id;
|
||||
}
|
||||
|
||||
string
|
||||
Span::getSpanId() const
|
||||
{
|
||||
return span_id;
|
||||
}
|
||||
|
||||
Span::ContextType
|
||||
Span::getSpanContextType() const
|
||||
{
|
||||
return context_type;
|
||||
}
|
||||
|
||||
string
|
||||
Span::getPrevSpanId() const
|
||||
{
|
||||
return prev_span_id;
|
||||
}
|
||||
|
||||
string
|
||||
Span::convertSpanContextTypeToString(ContextType type)
|
||||
{
|
||||
switch(type) {
|
||||
case ContextType::NEW: {
|
||||
return "New";
|
||||
}
|
||||
case ContextType::CHILD_OF: {
|
||||
return "Child of";
|
||||
}
|
||||
case ContextType::FOLLOWS_FROM: {
|
||||
return "Follows from";
|
||||
}
|
||||
}
|
||||
dbgAssert(false) << "Span context not supported";
|
||||
return string();
|
||||
}
|
||||
|
||||
SpanWrapper::SpanWrapper(string _trace_id, Span::ContextType _type, string _prev_span)
|
||||
:
|
||||
span(make_shared<Span>(_trace_id, _type, _prev_span))
|
||||
{}
|
||||
|
||||
string
|
||||
SpanWrapper::getTraceId() const
|
||||
{
|
||||
return span->getTraceId();
|
||||
}
|
||||
|
||||
string
|
||||
SpanWrapper::getSpanId() const
|
||||
{
|
||||
return span->getSpanId();
|
||||
}
|
||||
|
||||
Span::ContextType
|
||||
SpanWrapper::getSpanContextType() const
|
||||
{
|
||||
return span->getSpanContextType();
|
||||
}
|
||||
|
||||
string
|
||||
SpanWrapper::getPrevSpanId() const
|
||||
{
|
||||
return span->getPrevSpanId();
|
||||
}
|
58
core/environment/trace.cc
Executable file
58
core/environment/trace.cc
Executable file
@@ -0,0 +1,58 @@
|
||||
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "environment/trace.h"
|
||||
|
||||
#include "boost/uuid/uuid.hpp"
|
||||
#include "boost/uuid/uuid_generators.hpp"
|
||||
#include "boost/uuid/uuid_io.hpp"
|
||||
#include "debug.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace boost::uuids;
|
||||
|
||||
USE_DEBUG_FLAG(D_TRACE);
|
||||
|
||||
Trace::Trace(string _id)
|
||||
:
|
||||
trace_id(_id)
|
||||
{
|
||||
if (trace_id.empty()) {
|
||||
boost::uuids::random_generator uuid_random_gen;
|
||||
trace_id = to_string(uuid_random_gen());
|
||||
}
|
||||
context.registerValue<string>("trace id", trace_id);
|
||||
context.activate();
|
||||
dbgTrace(D_TRACE) << "New trace was created " << trace_id;
|
||||
}
|
||||
|
||||
Trace::~Trace()
|
||||
{
|
||||
dbgTrace(D_TRACE) << "Current trace has ended " << trace_id;
|
||||
context.unregisterKey<string>("trace id");
|
||||
context.deactivate();
|
||||
}
|
||||
|
||||
string
|
||||
Trace::getTraceId() const
|
||||
{
|
||||
return trace_id;
|
||||
}
|
||||
|
||||
TraceWrapper::TraceWrapper(string _id) : trace(make_shared<Trace>(_id)) {}
|
||||
|
||||
string
|
||||
TraceWrapper::getTraceId() const
|
||||
{
|
||||
return trace->getTraceId();
|
||||
}
|
Reference in New Issue
Block a user