Skip to content

Commit

Permalink
tests: Some tests around the dinit-iostream
Browse files Browse the repository at this point in the history
Signed-off-by: Mobin "Hojjat" Aydinfar <[email protected]>
  • Loading branch information
mobin-2008 committed May 17, 2024
1 parent c2d7503 commit cb76b8f
Show file tree
Hide file tree
Showing 4 changed files with 220 additions and 4 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
/src/tests/proctests
/src/tests/loadtests
/src/tests/envtests
/src/tests/iostreamtests
/src/tests/cptests/cptests
/src/tests/cptests/corpus
/src/tests/cptests/fuzz
Expand Down
17 changes: 13 additions & 4 deletions src/tests/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,42 @@
ALL_TEST_CXXFLAGS=$(CPPFLAGS) $(TEST_CXXFLAGS) $(TEST_CXXFLAGS_EXTRA)
ALL_TEST_LDFLAGS=$(TEST_LDFLAGS) $(TEST_LDFLAGS_EXTRA)

objects = tests.o test-dinit.o proctests.o loadtests.o envtests.o test-run-child-proc.o test-bpsys.o
objects = tests.o test-dinit.o proctests.o loadtests.o envtests.o iostreamtests.o test-run-child-proc.o test-bpsys.o
parent_objs = service.o proc-service.o dinit-log.o load-service.o baseproc-service.o dinit-env.o control.o

check: build-tests run-tests

build-tests: tests proctests loadtests envtests
build-tests: tests proctests loadtests envtests iostreamtests
$(MAKE) -C cptests build-tests

run-tests: build-tests
./tests
./proctests
./loadtests
./envtests
./iostreamtests
$(MAKE) -C cptests run-tests

tests: $(parent_objs) tests.o test-dinit.o test-bpsys.o test-run-child-proc.o
$(CXX) -o tests $(parent_objs) tests.o test-dinit.o test-bpsys.o test-run-child-proc.o $(ALL_TEST_LDFLAGS)

proctests: $(parent_objs) proctests.o test-dinit.o test-bpsys.o test-run-child-proc.o
$(CXX) -o proctests $(parent_objs) proctests.o test-dinit.o test-bpsys.o test-run-child-proc.o $(ALL_TEST_LDFLAGS)

loadtests: $(parent_objs) loadtests.o test-dinit.o test-bpsys.o test-run-child-proc.o
$(CXX) -o loadtests $(parent_objs) loadtests.o test-dinit.o test-bpsys.o test-run-child-proc.o $(ALL_TEST_LDFLAGS)

envtests: $(parent_objs) envtests.o test-dinit.o test-bpsys.o test-run-child-proc.o
$(CXX) -o envtests $(parent_objs) envtests.o test-dinit.o test-bpsys.o test-run-child-proc.o $(ALL_TEST_LDFLAGS)

# dinit-iostream contains global objects which require special handling in test environments.
# Therefore, avoid linking it to tests by default (instead include it explicitly in relevant tests eg iostreamtests).
dinit-iostream.o: ../dinit-iostream.cc
$(CXX) $(ALL_TEST_CXXFLAGS) -MMD -MP -Itest-includes -I../../dasynq/include -I../../build/includes -I../includes -c $< -o $@

iostreamtests: iostreamtests.o dinit-iostream.o test-bpsys.o
$(CXX) -o iostreamtests iostreamtests.o dinit-iostream.o test-bpsys.o $(ALL_TEST_LDFLAGS)

$(objects): %.o: %.cc
$(CXX) $(ALL_TEST_CXXFLAGS) -MMD -MP -Itest-includes -I../../dasynq/include -I../../build/includes -I../includes -c $< -o $@

Expand All @@ -38,7 +47,7 @@ $(parent_objs): %.o: ../%.cc

clean:
$(MAKE) -C cptests clean
rm -f *.o *.d tests proctests loadtests envtests
rm -f *.o *.d tests proctests loadtests envtests iostreamtests

-include $(objects:.o=.d)
-include $(parent_objs:.o=.d)
198 changes: 198 additions & 0 deletions src/tests/iostreamtests.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
#include <array>
#include <iostream>
#include <limits>
#include <cassert>

#include "baseproc-sys.h"
#include "dinit-iostream.h"

#ifdef NDEBUG
#error "This file must be built with assertions ENABLED!"
#endif

void ostream_basic_test()
{
int fd = bp_sys::allocfd();
dio::ostream stream(fd);
dio::streambuf* buf = stream.get_buf();
assert(buf != nullptr);
assert(stream.good());

const char msg[] = "This is a test message!\n";

assert(stream.write(msg));
assert(buf->get_length() == sizeof(msg) - 1);

char* ptr = buf->get_ptr(0);
unsigned len = buf->get_contiguous_length(ptr);
assert(strncmp(ptr, msg, len) == 0);

assert(stream.flush_nx());
assert(buf->get_length() == 0);

std::vector<char> wdata;
bp_sys::extract_written_data(fd, wdata);

assert(wdata.size() == sizeof(msg) - 1);
assert(strncmp(wdata.data(), msg, wdata.size()) == 0);
}

void ostream_write_buf_test()
{
int fd = bp_sys::allocfd();
dio::ostream stream(fd);
dio::streambuf* buf = stream.get_buf();
assert(buf != nullptr);
assert(stream.good());

const char msg[] = "This is a test message!\n";

assert(stream.write_buf(msg) == sizeof(msg) - 1);
assert(buf->get_length() == sizeof(msg) - 1);

char* ptr = buf->get_ptr(0);
unsigned len = buf->get_contiguous_length(ptr);
assert(strncmp(ptr, msg, len) == 0);

assert(stream.flush_nx());
assert(buf->get_length() == 0);

std::vector<char> wdata;
bp_sys::extract_written_data(fd, wdata);

assert(wdata.size() == sizeof(msg) - 1);
assert(strncmp(wdata.data(), msg, wdata.size()) == 0);
}

void ostream_int_conversion_test()
{
int fd = bp_sys::allocfd();
dio::ostream stream(fd);
dio::streambuf *buf = stream.get_buf();
assert(buf != nullptr);
assert(stream.good());

const char msg1[] = "The 2 + 2 equals to: ";
const int msg2 = 4;
const char msg_full[] = "The 2 + 2 equals to: 4";

assert(stream.write(msg1, msg2));
assert(buf->get_length() == sizeof(msg_full) - 1);

char* ptr = buf->get_ptr(0);
unsigned len = buf->get_contiguous_length(ptr);
assert(strncmp(ptr, msg_full, len) == 0);

assert(stream.flush_nx());
assert(buf->get_length() == 0);

std::vector<char> wdata;
bp_sys::extract_written_data(fd, wdata);

assert(wdata.size() == sizeof(msg_full) - 1);
assert(strncmp(wdata.data(), msg_full, wdata.size()) == 0);
}

void ostream_large_msg_test()
{
int fd = bp_sys::allocfd();
dio::ostream stream(fd);
dio::streambuf *buf = stream.get_buf();
assert(buf != nullptr);
assert(stream.good());

char msg[IOSTREAM_BUFSIZE + 2];
std::fill_n(msg, IOSTREAM_BUFSIZE + 1, 'a');
msg[IOSTREAM_BUFSIZE + 1] = '\0';

assert(stream.write(msg));
assert(buf->get_length() == 1);
assert(stream.flush());

std::vector<char> wdata;
bp_sys::extract_written_data(fd, wdata);

assert(wdata.size() == sizeof(msg) - 1);
assert(strncmp(wdata.data(), msg, wdata.size()) == 0);
}

void istream_basic_test()
{
std::vector<char> wdata = { 'L', '1', '\n', 'L','2', '\n', '\n', 'L', '3' };
bp_sys::supply_file_content("file", std::move(wdata));

dio::istream stream;
dio::streambuf *buf = stream.get_buf();
assert(buf != nullptr);
assert(stream.good());

assert(stream.open_nx("file"));
assert(stream.is_open());
assert(stream.get_fd() >= 0);

std::string line;

assert(dio::get_line(stream, line) == 2);
assert(line.compare("L1") == 0);

assert(dio::get_line(stream, line) == 2);
assert(line.compare("L2") == 0);

assert(dio::get_line(stream, line) == 1);
assert(line.size() == 0);

assert(dio::get_line(stream, line) == 2);
assert(line.compare("L3") == 0);

assert(dio::get_line_until_eof(stream, line) == 0);
assert(stream.eof());
assert(line.compare("L3") == 0);

assert(stream.close());
}

void istream_buffer_boundary_test()
{
int fd = bp_sys::allocfd();
dio::istream stream(fd);
dio::streambuf *buf = stream.get_buf();
assert(buf != nullptr);
assert(stream.good());

std::array<char, IOSTREAM_BUFSIZE> msg;
msg.fill('a');
buf->append(msg.begin(), msg.size());

std::fill_n(msg.begin(), 100, 'b');
buf->consume(100);
buf->append(msg.begin(), 100);

std::string line;
assert(dio::get_line(stream, line) == IOSTREAM_BUFSIZE);
assert(strncmp(line.c_str(), msg.begin(), IOSTREAM_BUFSIZE));
}

#define RUN_TEST(name, spacing) \
std::cout << #name "..." spacing << std::flush; \
name(); \
std::cout << "PASSED" << std::endl;

int main(int argc, char **argv)
{
RUN_TEST(ostream_basic_test, " ");
RUN_TEST(ostream_write_buf_test, " ");
RUN_TEST(ostream_int_conversion_test, " ");
RUN_TEST(ostream_large_msg_test, " ");
RUN_TEST(istream_basic_test, " ");
RUN_TEST(istream_buffer_boundary_test, " ");

// The destructors of the cout, cerr, and cin global objects will attempt to close the associated
// file descriptors, if they are still open. The bp_sys test infrastructure may have been torn
// down by that time, however, leading to errors. So, close the (bp_sys-based) descriptors now
// to avoid that.
dio::cout.close_nx();
dio::cerr.close_nx();
dio::cin.close_nx();

return 0;
}
8 changes: 8 additions & 0 deletions src/tests/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,15 @@ envtests_exec = executable(
for_tests_dinit_sources,
include_directories: for_tests_incdir
)
iostreamtests_exec = executable(
'iostreamtests',
'iostreamtests.cc',
'../dinit-iostream.cc',
'test-bpsys.cc',
include_directories: for_tests_incdir
)
test('tests', tests_exec, suite: 'unit_tests')
test('proctests', proctests_exec, suite: 'unit_tests')
test('loadtests', loadtests_exec, workdir: meson.current_source_dir(), suite: 'unit_tests')
test('envtests', envtests_exec, suite: 'unit_tests')
test('iostreamtests', iostreamtests_exec, suite: 'unit_tests')

0 comments on commit cb76b8f

Please sign in to comment.