Kaynağa Gözat

Logging tested throughly

channel
Ludovic 'Archivist' Lagouardette 3 yıl önce
ebeveyn
işleme
4dbe9850c1
7 değiştirilmiş dosya ile 240 ekleme ve 14 silme
  1. +1
    -1
      .vscode/launch.json
  2. +12
    -0
      include/gp/containers/buffer.hpp
  3. +5
    -0
      include/gp/containers/dynarray.hpp
  4. +4
    -4
      include/gp/functional/function.hpp
  5. +21
    -7
      include/gp/system/logging_segment.hpp
  6. +3
    -2
      tests.cpp
  7. +194
    -0
      tests/logging_test.cpp

+ 1
- 1
.vscode/launch.json Dosyayı Görüntüle

@ -5,9 +5,9 @@
"version": "0.2.0",
"configurations": [
{
"name": "Debug",
"type": "gdb",
"request": "launch",
"name": "Launch Program",
"target": "./bin/tests",
"cwd": "${workspaceRoot}",
"valuesFormatting": "parseText",

+ 12
- 0
include/gp/containers/buffer.hpp Dosyayı Görüntüle

@ -75,6 +75,18 @@ namespace gp{
return *(begin_elem+offset);
}
constexpr const T& operator[](std::size_t offset) const
{
if constexpr (gp_config::has_buffer_bounds)
{
gp_config::assertion(
offset < size(),
"Buffer bounds infringed"
);
}
return *(begin_elem+offset);
}
optional<pointer_iterator<T>> at(std::size_t offset)
{
auto elem = begin()+offset;

+ 5
- 0
include/gp/containers/dynarray.hpp Dosyayı Görüntüle

@ -172,6 +172,11 @@ namespace gp {
data[sz].clear();
}
gp::buffer<T> as_buffer()
{
return gp::buffer<T>{(T*)data, (T*)data+sz};
}
~dynarray() {
auto it = data;
auto end = data + size();

+ 4
- 4
include/gp/functional/function.hpp Dosyayı Görüntüle

@ -82,6 +82,10 @@ namespace gp{
this->condestructor(data_size <= sizeof(data_ptr) ? (char*)&data_ptr : data_ptr, reinterpret_cast<char*>(&f));
}
/*function(ret f_ptr(args...))
: function(f_ptr, nullopt)
{}*/
template<typename func>
function(func f, nullopt_t alloc_v)
: alloc(alloc_v)
@ -122,10 +126,6 @@ namespace gp{
);
}
function(ret f_ptr(args...))
: function(f_ptr, nullopt)
{}
function(function&& rhs)
: alloc(rhs.alloc)
, invokator(rhs.invokator)

+ 21
- 7
include/gp/system/logging_segment.hpp Dosyayı Görüntüle

@ -6,6 +6,8 @@
#include "gp/functional/optional.hpp"
#include <stdint.h>
#include <string>
#include <sstream>
struct segment{
int16_t priority = 0;
@ -27,10 +29,10 @@ template
struct static_logging_segment : virtual_logging_segment{
gp::dynarray<segment, capacity> data;
gp::optional<size_t> wrap_around;
n">gp::function<void(virtual_logging_segment&)> on_destruct = +[](virtual_logging_segment&){};
c1">//gp::function<void(virtual_logging_segment&)> on_destruct{[](virtual_logging_segment&){}, gp::nullopt};
~static_logging_segment() {
n">on_destruct(*this);
c1">//on_destruct(*this);
}
segment prepare_segment(gp::buffer<char> name, gp::buffer<char> text, int prio = 0) {
@ -64,11 +66,15 @@ struct static_logging_segment : virtual_logging_segment{
virtual size_t push_segment(gp::buffer<char> name, gp::buffer<char> text, int16_t prio = 0) {
auto prepared = prepare_segment(name, text, prio);
if(data.size() == data.capacity()) {
wrap_around = 0;
}
if(wrap_around.has_value()) {
size_t idx = wrap_around.value();
size_t override_prio = gp::min_of(data.begin(), data.end(), [](auto v){ return v.priority; });
while(b">true) {
while(">prio >= override_prio) {
if(data[idx].priority == override_prio) {
data[idx] = prepared;
break;
@ -83,15 +89,20 @@ struct static_logging_segment : virtual_logging_segment{
return data.size()-1;
}
}
virtual void set_segment(gp::buffer<char> name, gp::buffer<char> text, int16_t prio = 0) {
auto prepared = prepare_segment(name, text, prio);
auto seg = get_segment(prepared.name.as_buffer());
if(k">auto seg = get_segment(name); seg.has_value()) {
seg.value() = prepared;
} else {
n">data.push_back(prepared);
if(seg.has_value()) {
seg.value().get() = prepared;
k">return;
}
push_segment(prepared.name.as_buffer(), prepared.text.as_buffer(), prepared.priority);
}
virtual gp::optional<gp::reference_wrapper<segment>> get_segment(gp::buffer<char> name) {
decltype(segment{}.name) tname;
auto it = name.begin();
@ -106,11 +117,14 @@ struct static_logging_segment : virtual_logging_segment{
return gp::reference_wrapper<segment>(elem);
}
}
return gp::nullopt;
}
virtual size_t size() {
return data.size();
}
virtual segment& get_segment_by_idx(size_t idx) {
return data[idx];
}

+ 3
- 2
tests.cpp Dosyayı Görüntüle

@ -10,7 +10,7 @@
alignas(2048) gp::array<char, 4096> static_mapper::store;
gp::buddy<> static_mapper::impl = gp::buddy<>{store.begin().data, store.size()};
static_logging_segment<32> logger;
static_logging_segment<128> logger;
void log_failure(const char* failure) {
log_segment("FAILURE", failure, std::numeric_limits<int16_t>::max());
@ -51,6 +51,7 @@ int main()
if(value)
{
std::cout << std::dec << test->name << " failed with "<< value << std::endl;
print_logs();
}
} catch (gp::runtime_error err) {
std::cout << test->name << " failed with an exception: " << err.what() << std::endl;
@ -68,6 +69,6 @@ int main()
logger.clear();
failed += (value != 0);
}
std::cout << std::dec << "Runned "<<runned<<" tests with "<<failed<<" failures" << std::endl;
std::cout << std::dec << "Runned " << runned << " tests with " << failed << " failures" << std::endl;
return 0;
}

+ 194
- 0
tests/logging_test.cpp Dosyayı Görüntüle

@ -20,11 +20,205 @@ struct logging_test : public test_scaffold {
const gp::buffer<char> name{"FIRST TEST"};
const gp::buffer<char> text{"FIRST TEST TEXT"};
const gp::buffer<char> new_text{"NEW TEST TEXT"};
static_logging_segment<4> logger;
gp_config::assertion(logger.size() == 0, "new logger not empty");
logger.push_segment(name, text);
gp_config::assertion(logger.size() == 1, "should be 1 after insertion");
logger.set_segment(name, new_text);
gp_config::assertion(logger.size() == 1, "should still be one as key is identical");
return res;
}
};
append_test dummy_rduhk786f(new logging_test{});
struct logging_test2 : public test_scaffold {
logging_test2() {
name = __FILE__ ":2";
}
virtual int run() {
int res = 0;
const gp::buffer<char> name[5]{{"TEST 1"},{"TEST 2"},{"TEST 3"},{"TEST 4"},{"TEST 5"}};
const gp::buffer<char> texts[5] {{"NEW TEST TEXT 1"},{"NEW TEST TEXT 2"},{"NEW TEST TEXT 3"},{"NEW TEST TEXT 4"},{"NEW TEST TEXT 5"}};
static_logging_segment<4> logger;
gp_config::assertion(logger.size() == 0, "new logger not empty");
for(auto i : {0,1,2,3,4}) {
logger.push_segment(name[i], texts[i]);
}
gp_config::assertion(logger.size() <= 4, "Size should be capped at 4");
gp_config::assertion(logger.size() == 4, "Size should be 4");
return res;
}
};
append_test dummy_sghgfg6f(new logging_test2{});
struct logging_test3 : public test_scaffold {
logging_test3() {
name = __FILE__ ":3";
}
virtual int run() {
int res = 0;
const gp::buffer<char> name[5]{{"TEST 1"},{"TEST 2"},{"TEST 3"},{"TEST 4"},{"TEST 5"}};
const gp::buffer<char> texts[5] {{"NEW TEST TEXT 1"},{"NEW TEST TEXT 2"},{"NEW TEST TEXT 3"},{"NEW TEST TEXT 4"},{"NEW TEST TEXT 5"}};
static_logging_segment<4> logger;
gp_config::assertion(logger.size() == 0, "new logger not empty");
for(auto i : {0,1,2,3,4}) {
logger.set_segment(name[i], texts[i]);
log_segment("new element", name[i].begin().data);
}
log_segment("size", std::to_string(logger.size()).c_str());
gp_config::assertion(logger.size() <= 4, "Size should be capped at 4");
gp_config::assertion(logger.size() == 4, "Size should be 4");
return res;
}
};
append_test dummy_dgiudfg6f(new logging_test3{});
struct logging_test4 : public test_scaffold {
logging_test4() {
name = __FILE__ ":4";
}
virtual int run() {
int res = 0;
const gp::buffer<char> name[5]{{"TEST 1"},{"TEST 2"},{"TEST 3"},{"TEST 4"},{"TEST 5"}};
const gp::buffer<char> texts[5] {{"NEW TEST TEXT 1"},{"NEW TEST TEXT 2"},{"NEW TEST TEXT 3"},{"NEW TEST TEXT 4"},{"NEW TEST TEXT 5"}};
static_logging_segment<4> logger;
gp_config::assertion(logger.size() == 0, "new logger not empty");
for(auto i : {0,1,2,3,4}) {
logger.set_segment(name[i], texts[i]);
}
log_segment("size", std::to_string(logger.size()).c_str());
gp_config::assertion(logger.size() <= 4, "Size should be capped at 4");
gp_config::assertion(logger.size() == 4, "Size should be 4");
for(auto i : {0, 1, 2, 3}) {
auto v = logger.get_segment_by_idx(i);
bool same = true;
for(size_t it = 0; it < 4; it++) {
same &= name[0][it] == v.name[it];
}
gp_config::assertion(!same, "Should not contain oldest element");
}
return res;
}
};
append_test dummy_aertm46f(new logging_test4{});
struct logging_test5 : public test_scaffold {
logging_test5() {
name = __FILE__ ":5";
}
virtual int run() {
int res = 0;
const gp::buffer<char> name[5]{{"TEST 1"},{"TEST 2"},{"TEST 3"},{"TEST 4"},{"TEST 5"}};
const gp::buffer<char> texts[5] {{"NEW TEST TEXT 1"},{"NEW TEST TEXT 2"},{"NEW TEST TEXT 3"},{"NEW TEST TEXT 4"},{"NEW TEST TEXT 5"}};
const uint16_t prios[5] {1,1,0,1,1};
static_logging_segment<4> logger;
gp_config::assertion(logger.size() == 0, "new logger not empty");
for(auto i : {0,1,2,3,4}) {
logger.set_segment(name[i], texts[i], prios[i]);
}
log_segment("size", std::to_string(logger.size()).c_str());
gp_config::assertion(logger.size() <= 4, "Size should be capped at 4");
gp_config::assertion(logger.size() == 4, "Size should be 4");
for(auto i : {0, 1, 2, 3}) {
auto v = logger.get_segment_by_idx(i);
log_segment("prio value", std::to_string(v.priority).c_str());
gp_config::assertion(v.priority != 0, "Should not contain low prio element");
}
return res;
}
};
append_test dummy_azefdhi6f(new logging_test5{});
struct logging_test6 : public test_scaffold {
logging_test6() {
name = __FILE__ ":6";
}
virtual int run() {
int res = 0;
const gp::buffer<char> name{"FIRST TEST"};
const gp::buffer<char> text{"FIRST TEST TEXT"};
const gp::buffer<char> new_text{"NEW TEST TEXT"};
static_logging_segment<4> logger;
gp_config::assertion(logger.size() == 0, "new logger not empty");
logger.push_segment(name, text);
gp_config::assertion(logger.size() == 1, "should be 1 after insertion");
logger.set_segment(name, new_text);
gp_config::assertion(logger.size() == 1, "should still be one as key is identical");
logger.clear();
gp_config::assertion(logger.size() == 0, "should be zero after clear");
return res;
}
};
append_test dummy_ra45645sdf(new logging_test6{});

Yükleniyor…
İptal
Kaydet