/* * Copyright (c) 2020-2023 Vasile Vilvoiu * * specgram is free software; you can redistribute it and/or modify * it under the terms of the MIT license. See LICENSE for details. */ #include "test.hpp" #include "../src/input-reader.hpp" #include #include #include #include #include std::vector random_data(std::size_t size) { std::vector data(size); std::random_device rd; std::default_random_engine re(rd()); std::uniform_int_distribution ud; for (std::size_t i = 0; i < size; i ++) { data[i] = ud(re); } return data; } void generate_file(const std::string& temp_file_name, const std::vector& buffer) { /* dump */ std::ofstream file(temp_file_name, std::ios::out | std::ios::binary); if (file.fail()) { throw std::runtime_error("cannot open temp file " + temp_file_name); } file.write(buffer.data(), buffer.size()); file.close(); } void check_same(const std::vector& expected, const std::vector& actual, std::size_t max_len_diff) { EXPECT_GE(expected.size(), actual.size()); EXPECT_LE(expected.size() - actual.size(), max_len_diff); for (std::size_t i = 0; i output; output.reserve(memory); while (true) { auto block = reader.GetBlock(); if (!block.has_value()) { break; } EXPECT_EQ((*block).size(), block_size); output.insert(output.end(), (*block).begin(), (*block).end()); } EXPECT_TRUE(reader.ReachedEOF()); file.close(); check_same(expected, output, block_size); } } TEST(TestInputReader, AsyncInputReader) { constexpr std::size_t max_block_size = 4096; constexpr std::size_t memory = 4096; const std::string file_name = "/dev/shm/TestInputReader_AsyncInputReader.data"; auto expected = random_data(memory); generate_file(file_name, expected); for (std::size_t block_size = 1; block_size < max_block_size; block_size++) { std::ifstream file(file_name, std::ios::in | std::ios::binary); EXPECT_FALSE(file.fail()); std::vector output; output.reserve(memory); std::signal(SIGINT, [](int) { }); /* SIGINT is sent to the reader thread upon destruction of AsyncInputReader */ { /* scope out the reader so it does not die when we close the file */ AsyncInputReader reader(&file, block_size); while (output.size() < expected.size() - block_size) { auto block = reader.GetBlock(); if (block.has_value()) { EXPECT_EQ((*block).size(), block_size); output.insert(output.end(), (*block).begin(), (*block).end()); } } EXPECT_FALSE(reader.ReachedEOF()); } std::signal(SIGINT, nullptr); file.close(); check_same(expected, output, block_size); } }