Browse Source

Import: corresponding tests from libpEpAdapter

pull/1/head
heck 3 years ago
parent
commit
b6cdb6ed9a
  1. 110
      test/test_counting_semaphore.cc
  2. 24
      test/test_file_rw_bin.cc
  3. 39
      test/test_hexbin.cc
  4. 105
      test/test_library.cc
  5. 64
      test/test_rand.cc
  6. 37
      test/test_semaphore.cc

110
test/test_counting_semaphore.cc

@ -0,0 +1,110 @@
// This file is under GNU General Public License 3.0
// see LICENSE.txt
#include <iostream>
#include <thread>
#include <cassert>
#include <pEp/std_utils.hh>
#include "../src/CountingSemaphore.hh"
using namespace std;
using namespace pEp;
thread make_two_threads_for_many_threads()
{
thread res([&]() {
CountingSemaphore semaphore;
semaphore = 3;
thread thread1([&]() {
semaphore.p ();
semaphore.p ();
semaphore.p ();
// Now the count is at 0, assuming the other thread has not
// started yet; otherwise it should be at 1.
semaphore.p ();
//cout << "1: done\n";
});
Utils::sleep_millis(1000);
thread thread2([&]() {
semaphore.v();
});
thread1.join();
thread2.join();
assert (semaphore.load() == 0);
});
return res;
}
void many_threads()
{
int i;
#define N 1000
thread threads[N];
std::cout << "starting " << N
<< " threads, each starting and joining a thread pair...\n";
for (i = 0; i < N; i ++)
threads [i] = make_two_threads_for_many_threads ();
std::cout << "joining threads...\n";
for (i = 0; i < N; i ++)
threads [i].join();
#undef N
std::cout << "many_threads done.\n\n";
}
void v_times (CountingSemaphore &semaphore,
int times)
{
std::cout << "V'ing " << times << " times...\n";
for (int i = 0; i < times; i ++)
semaphore.v ();
std::cout << "... I V'd " << times << " times.\n";
}
void p_times (CountingSemaphore &semaphore,
int times)
{
std::cout << "P'ing " << times << " times...\n";
for (int i = 0; i < times; i ++)
semaphore.p ();
std::cout << "... I P'd " << times << " times.\n";
}
void few_threads()
{
#define HALF_N (1000 * 1000 * 10)
#define N (HALF_N * 2)
CountingSemaphore semaphore;
thread thread_p1([&]() {
p_times (semaphore, HALF_N);
});
thread thread_v([&]() {
v_times (semaphore, N);
});
thread thread_p2([&]() {
p_times (semaphore, HALF_N);
});
#undef HALF_N
#undef N
thread_v.join();
thread_p1.join();
thread_p2.join();
assert (semaphore.load() == 0);
std::cout << "few_thrads done.\n\n";
}
int main()
{
many_threads ();
few_threads ();
return 0;
}

24
test/test_file_rw_bin.cc

@ -0,0 +1,24 @@
// This file is under GNU General Public License 3.0
// see LICENSE.txt
#include <iostream>
#include <cassert>
#include <pEp/pEpLog.hh>
#include <pEp/std_utils.hh>
int main(int argc, char* argv[])
{
pEp::Adapter::pEpLog::set_enabled(true);
std::string filename = "test_rw.bin";
std::vector<char> v_out{};
for (int i = 0; i < 1000; i++) {
v_out.push_back(pEp::Utils::random_char(0, 255));
}
pEp::Utils::file_write_bin(filename, v_out);
std::vector<char> v_in = pEp::Utils::file_read_bin(filename);
assert(v_in == v_out);
}

39
test/test_hexbin.cc

@ -0,0 +1,39 @@
#include <pEp/std_utils.hh>
#include <pEp/pEpLog.hh>
#include <iostream>
#include <cassert>
#include <pEp/pitytest11/PityTest.hh>
using namespace pEp;
int main()
{
pEp::Adapter::pEpLog::set_enabled(true);
{
// Valid hex string
std::string str_in{ "FFABCD00EF123200" };
std::vector<unsigned char> bin = Utils::hex2bin<unsigned char>(str_in);
PITYASSERT(str_in.length() == bin.size() * 2, "Size error");
std::string str_out = pEp::Utils::bin2hex(bin);
pEpLog("Hex_IN : '" + Utils::to_lower(str_in) + "'");
pEpLog("Hex_OUT : '" + Utils::to_lower(str_out) + "'");
PITYASSERT(Utils::to_lower(str_in) == Utils::to_lower(str_out), "roundtrip failed");
}
{
// Uneven string throws
std::string str_in{ "FFA" };
PITYASSERT_THROWS(Utils::hex2bin<char>(str_in), "Uneven string should throw");
}
{
// Non-hex chars
std::string str_in{ "pEp!" };
PITYASSERT_THROWS(Utils::hex2bin<char>(str_in), "Invalid hex chars should throw");
}
pEpLog("All tests passsed");
}

105
test/test_library.cc

@ -0,0 +1,105 @@
// This file is under GNU General Public License 3.0
// see LICENSE.txt
#include "pc_container.hh"
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <thread>
using namespace pEp;
// Producer's data:
class P {
public:
P(int i) : data{ new char[64] }
{
snprintf(data, 63, "%i", i);
}
P(const P&) = delete;
void operator=(const P&) = delete;
~P()
{
std::cerr << "~P(): data=" << (data ? data : "(NULL)") << '\n';
delete[] data;
}
char* data;
};
// Consumer's data:
class C {
public:
C(int _i) : i(_i) {}
int i;
};
pc_container<P, C> pc;
void consumer_thread()
{
bool keep_running = true;
int sum = 0;
while (keep_running) {
for (auto& q : pc) {
switch (q.state()) {
case PC_State::Created: {
const int value = atoi(q.pdata->data);
if (value < 0) {
std::cerr << "Q\n";
keep_running = false;
} else {
std::cerr << "C";
q.cdata = new C(value);
sum += q.cdata->i;
}
break;
}
case PC_State::Deleted: {
std::cerr << "D";
sum -= q.cdata->i;
delete q.cdata;
break;
}
case PC_State::Changed: {
std::cerr << "X";
sum -= q.cdata->i;
delete q.cdata;
q.cdata = new C(atoi(q.pdata->data));
sum += q.cdata->i;
break;
}
default:
throw "Illegal state";
}
}
}
std::cout << "Consumer sum: " << sum << ".\n";
}
int main()
{
for (int i = 0; i < 10; ++i) {
pc.insert(new P(i));
}
std::thread t{ &consumer_thread };
for (int i = 10; i < 100; ++i) {
pc.insert(new P(i));
}
while (!pc.empty()) {
auto q = pc.begin();
delete q->pdata;
pc.erase(q);
}
pc.insert(new P(-1));
t.join();
}

64
test/test_rand.cc

@ -0,0 +1,64 @@
#include <pEp/std_utils.hh>
#include <pEp/pEpLog.hh>
#include <pEp/pitytest11/PityTest.hh>
#include <iostream>
#include <chrono>
using namespace pEp;
int test_random_string_fast()
{
pEpLog("Test test_random_string_fast() correct length, min & max");
for (int i = 0; i < 1000; i++) {
uint len = Utils::random_fast(5000);
std::string res = Utils::random_string_fast(0, 255, len);
PITYASSERT(
res.length() == len,
"random_string_fast: wrong length: " +
std::to_string(res.length()) + " is not " + std::to_string(len));
}
return 0;
}
int main()
{
pEp::Adapter::pEpLog::set_enabled(true);
test_random_string_fast();
pEpLog("Random functions benchmark");
int nr_mb = 10;
int nr_bytes = 1024 * 1024 * nr_mb;
pEpLog("generating " + std::to_string(nr_mb) + "MB's of random");
{
pEpLog("Utils::random_char()");
auto time_start = std::chrono::steady_clock::now();
for (int i = 0; i < nr_bytes; i++) {
Utils::random_char(0, 255);
}
auto time_end = std::chrono::steady_clock::now();
double duration_ms = (double)std::chrono::duration_cast<std::chrono::microseconds>(
time_end - time_start)
.count() /
1000;
pEpLog("Time [ms/mbyte]:" + std::to_string(duration_ms / double(nr_mb)));
}
std::cout << "" << std::endl;
{
pEpLog("Utils::Fastrand()");
auto time_start = std::chrono::steady_clock::now();
for (int i = 0; i < nr_bytes; i++) {
Utils::random_fast(255);
}
auto time_end = std::chrono::steady_clock::now();
double duration_ms = (double)std::chrono::duration_cast<std::chrono::microseconds>(
time_end - time_start)
.count() /
1000;
pEpLog("Time [ms/mbyte]:" + std::to_string(duration_ms / double(nr_mb)));
}
return 0;
}

37
test/test_semaphore.cc

@ -0,0 +1,37 @@
// This file is under GNU General Public License 3.0
// see LICENSE.txt
#include <iostream>
#include <thread>
#include <pEp/std_utils.hh>
#include "../src/Semaphore.hh"
using namespace std;
using namespace pEp;
int main()
{
Semaphore semaphore;
thread thread1([&]() {
cout << "1: before stop\n";
semaphore.stop();
cout << "1: now on stop\n";
semaphore.try_wait();
cout << "1: and on go again\n";
semaphore.try_wait();
cout << "1: keep going\n";
});
Utils::sleep_millis(1000);
thread thread2([&]() {
cout << "2: setting go\n";
semaphore.go();
});
thread1.join();
thread2.join();
return 0;
}
Loading…
Cancel
Save