mirror of
https://github.com/openappsec/openappsec.git
synced 2025-09-29 19:24:26 +03:00
First release of open-appsec source code
This commit is contained in:
3
core/time_proxy/CMakeLists.txt
Normal file
3
core/time_proxy/CMakeLists.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
add_library(time_proxy time_proxy.cc)
|
||||
|
||||
add_subdirectory(time_proxy_ut)
|
137
core/time_proxy/time_proxy.cc
Normal file
137
core/time_proxy/time_proxy.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 "time_proxy.h"
|
||||
#include <chrono>
|
||||
#include <string>
|
||||
#include <time.h>
|
||||
#include <sstream>
|
||||
#include "debug.h"
|
||||
|
||||
#include "singleton.h"
|
||||
#include "i_time_get.h"
|
||||
#include "i_time_set.h"
|
||||
|
||||
using namespace std;
|
||||
using std::chrono::microseconds;
|
||||
using std::chrono::seconds;
|
||||
using std::chrono::steady_clock;
|
||||
using std::chrono::system_clock;
|
||||
using std::chrono::time_point;
|
||||
using std::chrono::duration_cast;
|
||||
|
||||
static const int no_of_ticks_in_a_second = 1000000;
|
||||
static const int no_of_digits_after_the_dot_precision = 6;
|
||||
|
||||
class TimeProxyComponent::Impl
|
||||
:
|
||||
Singleton::Provide<I_TimeGet>::From<TimeProxyComponent>,
|
||||
Singleton::Provide<I_TimeSet>::From<TimeProxyComponent>
|
||||
{
|
||||
public:
|
||||
// Monotonic Time API
|
||||
microseconds
|
||||
getMonotonicTime() override
|
||||
{
|
||||
if (is_monotomic_set) return monotonic_now;
|
||||
|
||||
return duration_cast<microseconds>(steady_clock::now() - monotonic_start);
|
||||
}
|
||||
|
||||
void
|
||||
setMonotonicTime(microseconds new_time) override
|
||||
{
|
||||
if (is_monotomic_set) {
|
||||
dbgAssert((new_time+monotonic_delta) >= monotonic_now) << "Monotonic time must not go back!";
|
||||
} else {
|
||||
// The first time that the monotonic time is been set, we take the current value to be the base line.
|
||||
// This is in order to avoid the clock going backwards.
|
||||
// So we calulate the delta from the current time to the vale we were given, and later on add it to
|
||||
// any we get. That delta assures that setMonotonicTime can be used without concern as to what was the
|
||||
// exact time when we started setting it.
|
||||
auto curr = duration_cast<microseconds>(steady_clock::now() - monotonic_start);
|
||||
monotonic_delta = curr - new_time;
|
||||
is_monotomic_set = true;
|
||||
}
|
||||
|
||||
monotonic_now = new_time + monotonic_delta;
|
||||
}
|
||||
|
||||
// Wall Time API
|
||||
microseconds
|
||||
getWalltime() override
|
||||
{
|
||||
if (is_walltime_set) return walltime_now;
|
||||
|
||||
return duration_cast<microseconds>(system_clock::now().time_since_epoch());
|
||||
}
|
||||
|
||||
void
|
||||
setWalltime(microseconds new_time)
|
||||
{
|
||||
walltime_now = new_time;
|
||||
is_walltime_set = true;
|
||||
}
|
||||
|
||||
std::string getWalltimeStr() override { return getWalltimeStr(getWalltime()); }
|
||||
|
||||
std::string
|
||||
getWalltimeStr(const microseconds &time_to_convert)
|
||||
{
|
||||
time_t ttime = duration_cast<seconds>(time_to_convert).count();
|
||||
struct tm *gm_time = gmtime(&ttime);
|
||||
return parseTime(time_to_convert, gm_time);
|
||||
}
|
||||
|
||||
std::string
|
||||
getLocalTimeStr()
|
||||
{
|
||||
microseconds time_in_microseconds = getWalltime();
|
||||
time_t ttime = duration_cast<seconds>(time_in_microseconds).count();
|
||||
struct tm *local_time = localtime(&ttime);
|
||||
return parseTime(time_in_microseconds, local_time);
|
||||
}
|
||||
|
||||
private:
|
||||
bool is_monotomic_set = false;
|
||||
bool is_walltime_set = false;
|
||||
microseconds walltime_now;
|
||||
microseconds monotonic_now;
|
||||
microseconds monotonic_delta;
|
||||
time_point<steady_clock> monotonic_start = steady_clock::now();
|
||||
|
||||
std::string
|
||||
parseTime(const microseconds &time_in_microseconds, const struct tm *time_struct)
|
||||
{
|
||||
// Using ISO 8601 Format: YYYY-MM-DD'T'hh:mm:ss
|
||||
char date[24];
|
||||
size_t date_len = strftime(date, sizeof(date), "%FT%T", time_struct);
|
||||
// Adding micro seconds too
|
||||
stringstream str;
|
||||
str.width(no_of_digits_after_the_dot_precision);
|
||||
str.fill('0');
|
||||
str << (time_in_microseconds.count() % no_of_ticks_in_a_second);
|
||||
return string(date, date_len) + "." + str.str();
|
||||
}
|
||||
};
|
||||
|
||||
TimeProxyComponent::TimeProxyComponent()
|
||||
:
|
||||
Component("TimeProxyComponent"),
|
||||
pimpl(make_unique<Impl>())
|
||||
{
|
||||
}
|
||||
|
||||
TimeProxyComponent::~TimeProxyComponent()
|
||||
{
|
||||
}
|
1
core/time_proxy/time_proxy_ut/CMakeLists.txt
Normal file
1
core/time_proxy/time_proxy_ut/CMakeLists.txt
Normal file
@@ -0,0 +1 @@
|
||||
add_unit_test(time_proxy_ut "time_proxy_ut.cc;time_print_ut.cc" "time_proxy;singleton;rest")
|
45
core/time_proxy/time_proxy_ut/time_print_ut.cc
Executable file
45
core/time_proxy/time_proxy_ut/time_print_ut.cc
Executable file
@@ -0,0 +1,45 @@
|
||||
#include "time_print.h"
|
||||
#include "cptest.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace testing;
|
||||
|
||||
TEST(time_printTest, time_print_operator_for_microseconds)
|
||||
{
|
||||
chrono::microseconds usec(1000);
|
||||
stringstream buf;
|
||||
buf << usec;
|
||||
EXPECT_EQ(buf.str(), "1000usec");
|
||||
}
|
||||
|
||||
TEST(time_printTest, time_print_operator_for_milliseconds)
|
||||
{
|
||||
chrono::milliseconds ms(1000);
|
||||
stringstream buf;
|
||||
buf << ms;
|
||||
EXPECT_EQ(buf.str(), "1000ms");
|
||||
}
|
||||
|
||||
TEST(time_printTest, time_print_operator_for_seconds)
|
||||
{
|
||||
chrono::seconds sec(1000);
|
||||
stringstream buf;
|
||||
buf << sec;
|
||||
EXPECT_EQ(buf.str(), "1000s");
|
||||
}
|
||||
|
||||
TEST(time_printTest, time_print_operator_for_minutes)
|
||||
{
|
||||
chrono::minutes m(1000);
|
||||
stringstream buf;
|
||||
buf << m;
|
||||
EXPECT_EQ(buf.str(), "1000m");
|
||||
}
|
||||
|
||||
TEST(time_printTest, time_print_operator_for_hours)
|
||||
{
|
||||
chrono::hours hours_val(1000);
|
||||
stringstream buf;
|
||||
buf << hours_val;
|
||||
EXPECT_EQ(buf.str(), "1000h");
|
||||
}
|
67
core/time_proxy/time_proxy_ut/time_proxy_ut.cc
Normal file
67
core/time_proxy/time_proxy_ut/time_proxy_ut.cc
Normal file
@@ -0,0 +1,67 @@
|
||||
#include <string>
|
||||
|
||||
#include "cptest.h"
|
||||
#include "time_proxy.h"
|
||||
#include "singleton.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace testing;
|
||||
using namespace std::chrono;
|
||||
|
||||
class TimeProxyTest : public Test
|
||||
{
|
||||
public:
|
||||
TimeProxyComponent proxy;
|
||||
I_TimeGet *i_time_get = Singleton::Consume<I_TimeGet>::from(proxy);
|
||||
I_TimeSet *i_time_set = Singleton::Consume<I_TimeSet>::from(proxy);
|
||||
};
|
||||
|
||||
TEST_F(TimeProxyTest, get_without_set)
|
||||
{
|
||||
auto mono1 = i_time_get->getMonotonicTime(); // Check that it doesn't crash - but we can't verify the value.
|
||||
usleep(1000);
|
||||
auto mono2 = i_time_get->getMonotonicTime();
|
||||
EXPECT_LT(mono1, mono2);
|
||||
|
||||
i_time_get->getWalltime(); // Check that it doesn't crash - but we can't verify the value.
|
||||
|
||||
// Checking that ISO-8601 time format is used, e.g.: 2016-11-11T15:33:01.034
|
||||
EXPECT_THAT(
|
||||
i_time_get->getWalltimeStr(),
|
||||
MatchesRegex("[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{6}")
|
||||
);
|
||||
EXPECT_THAT(
|
||||
i_time_get->getLocalTimeStr(),
|
||||
MatchesRegex("[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{6}")
|
||||
);
|
||||
}
|
||||
|
||||
TEST_F(TimeProxyTest, set)
|
||||
{
|
||||
auto marty_mcfly_time = microseconds((1445455680L)*1000000); // 21 Oct 2015, 19:28
|
||||
std::string marty_mcfly_time_str = "2015-10-21T19:28:00.000000";
|
||||
i_time_set->setWalltime(marty_mcfly_time);
|
||||
EXPECT_EQ(i_time_get->getWalltime(), marty_mcfly_time);
|
||||
EXPECT_EQ(i_time_get->getWalltimeStr(), marty_mcfly_time_str);
|
||||
|
||||
i_time_set->setMonotonicTime(microseconds(0));
|
||||
auto time = i_time_get->getMonotonicTime();
|
||||
i_time_set->setMonotonicTime(microseconds(1337000));
|
||||
EXPECT_EQ(i_time_get->getMonotonicTime(), time + microseconds(1337000));
|
||||
usleep(1000);
|
||||
EXPECT_EQ(i_time_get->getMonotonicTime(), time + microseconds(1337000));
|
||||
|
||||
// No problem reseting walltime to whatever
|
||||
i_time_set->setWalltime(microseconds(1000000));
|
||||
i_time_set->setWalltime(microseconds(2001000));
|
||||
EXPECT_EQ(i_time_get->getWalltime(), microseconds(2001000));
|
||||
EXPECT_EQ(i_time_get->getWalltimeStr(), "1970-01-01T00:00:02.001000");
|
||||
|
||||
// You can move monotonic time forwards
|
||||
i_time_set->setMonotonicTime(microseconds(2000000));
|
||||
EXPECT_EQ(i_time_get->getMonotonicTime(), time + microseconds(2000000));
|
||||
|
||||
// But not backwards
|
||||
cptestPrepareToDie();
|
||||
EXPECT_DEATH(i_time_set->setMonotonicTime(microseconds(1000)), "Monotonic time must not go back!");
|
||||
}
|
Reference in New Issue
Block a user