Add basic testsuite (using GTest)
(The test suite will only be created if googletest is availavble)
This commit is contained in:
parent
de6bb75542
commit
76f17ecebb
@ -28,6 +28,8 @@ cmake_minimum_required( VERSION 3.5 )
|
|||||||
|
|
||||||
project(archive_cpp_wrapper)
|
project(archive_cpp_wrapper)
|
||||||
|
|
||||||
|
include(CTest)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 11)
|
set(CMAKE_CXX_STANDARD 11)
|
||||||
|
|
||||||
find_package(LibArchive)
|
find_package(LibArchive)
|
||||||
@ -88,3 +90,6 @@ install(
|
|||||||
|
|
||||||
# alias target
|
# alias target
|
||||||
add_library(LibArchive::archive_cpp_wrapper ALIAS ${PROJECT_NAME})
|
add_library(LibArchive::archive_cpp_wrapper ALIAS ${PROJECT_NAME})
|
||||||
|
|
||||||
|
add_subdirectory(test)
|
||||||
|
|
||||||
|
51
test/CMakeLists.txt
Normal file
51
test/CMakeLists.txt
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
#BSD 2-Clause license
|
||||||
|
#
|
||||||
|
#Copyright (c) 2014, Domen Vrankar
|
||||||
|
#Copyright (c) 2021, Tobias Frost
|
||||||
|
#All rights reserved.
|
||||||
|
#
|
||||||
|
#Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
#are permitted provided that the following conditions are met:
|
||||||
|
#
|
||||||
|
#1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
# list of conditions and the following disclaimer.
|
||||||
|
#
|
||||||
|
#2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
# this list of conditions and the following disclaimer in the documentation
|
||||||
|
# and/or other materials provided with the distribution.
|
||||||
|
#
|
||||||
|
#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
#ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
#WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
#DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
#ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
#(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
#LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
#ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
#(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
#SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
find_package(GTest)
|
||||||
|
|
||||||
|
if(GTEST_FOUND)
|
||||||
|
add_executable(libarchive_cpp_wrapper_test)
|
||||||
|
|
||||||
|
target_sources(libarchive_cpp_wrapper_test
|
||||||
|
PRIVATE
|
||||||
|
test.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(libarchive_cpp_wrapper_test
|
||||||
|
PRIVATE
|
||||||
|
LibArchive::archive_cpp_wrapper
|
||||||
|
GTest::gtest_main
|
||||||
|
)
|
||||||
|
|
||||||
|
add_test(NAME libarchive_cpp_wrapper_test COMMAND libarchive_cpp_wrapper_test)
|
||||||
|
|
||||||
|
# this avoids that the test fails if it is not built.(cmake will say "not run", not "failed")
|
||||||
|
set_tests_properties(libarchive_cpp_wrapper_test PROPERTIES REQUIRED_FILES "$<TARGET_FILE:libarchive_cpp_wrapper_test>")
|
||||||
|
|
||||||
|
set_tests_properties(libarchive_cpp_wrapper_test
|
||||||
|
PROPERTIES ENVIRONMENT "TEST_RESOURCES=${CMAKE_CURRENT_SOURCE_DIR}/resources/")
|
||||||
|
endif()
|
11
test/resources/README
Normal file
11
test/resources/README
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
The resources in this directory are generated with :
|
||||||
|
|
||||||
|
# test1.tar.gz
|
||||||
|
|
||||||
|
dd if=/dev/urandom of=file1_random bs=1 count=16k
|
||||||
|
dd if=/dev/urandom of=file1_random bs=1 count=16k
|
||||||
|
dd if=/dev/zero of=file3_zero bs=1 count=16k
|
||||||
|
|
||||||
|
tar czf test1.tar.gz file*
|
||||||
|
|
||||||
|
|
BIN
test/resources/dir/file1_random
Normal file
BIN
test/resources/dir/file1_random
Normal file
Binary file not shown.
BIN
test/resources/dir/file2_random
Normal file
BIN
test/resources/dir/file2_random
Normal file
Binary file not shown.
BIN
test/resources/dir/file3_zeros
Normal file
BIN
test/resources/dir/file3_zeros
Normal file
Binary file not shown.
BIN
test/resources/file1_random
Normal file
BIN
test/resources/file1_random
Normal file
Binary file not shown.
BIN
test/resources/file2_random
Normal file
BIN
test/resources/file2_random
Normal file
Binary file not shown.
BIN
test/resources/file3_zeros
Normal file
BIN
test/resources/file3_zeros
Normal file
Binary file not shown.
BIN
test/resources/test1.tar.gz
Normal file
BIN
test/resources/test1.tar.gz
Normal file
Binary file not shown.
BIN
test/resources/test2.tar.gz
Normal file
BIN
test/resources/test2.tar.gz
Normal file
Binary file not shown.
231
test/test.cpp
Normal file
231
test/test.cpp
Normal file
@ -0,0 +1,231 @@
|
|||||||
|
/*
|
||||||
|
* testsuite for libarchive_cpp_wrapper
|
||||||
|
*
|
||||||
|
* Created on: Feb 8, 2021
|
||||||
|
* Author: coldtobi
|
||||||
|
* LICENSE is BSD-2 clause.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "archive_reader.hpp"
|
||||||
|
#include "archive_writer.hpp"
|
||||||
|
#include "archive_exception.hpp"
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
#include <string>
|
||||||
|
#include <set>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
namespace ar = ns_archive::ns_reader;
|
||||||
|
|
||||||
|
class LibArchiveWrapperTest : public testing::Test {
|
||||||
|
public:
|
||||||
|
LibArchiveWrapperTest() = default;
|
||||||
|
virtual ~LibArchiveWrapperTest() {
|
||||||
|
if (!HasFailure()) {
|
||||||
|
for (auto const &x : cleanup_files) {
|
||||||
|
::unlink(x.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Let the test know about archives to de deleted after the test
|
||||||
|
// (will only be deleted if it succeded, not on failures.)
|
||||||
|
void deleteAfterTest(const std::string &cleanup) {
|
||||||
|
cleanup_files.insert(cleanup);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string getResourceDir() {
|
||||||
|
auto resources = ::getenv("TEST_RESOURCES");
|
||||||
|
if(!resources) return "";
|
||||||
|
std::string ret(resources);
|
||||||
|
if(ret.size() && (ret.at(ret.size()-1) != '/')) { ret += '/'; }
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string getcwd() {
|
||||||
|
auto cwd = ::getcwd(nullptr, 0);
|
||||||
|
if(!cwd) { return "/tmp/"; }
|
||||||
|
std::string ret(cwd);
|
||||||
|
if(ret.size() && (ret.at(ret.size()-1) != '/')) { ret += '/'; }
|
||||||
|
free(cwd);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::set<std::string> cleanup_files;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_F(LibArchiveWrapperTest, TestReadSimpleArchive) {
|
||||||
|
// Reading an archive.
|
||||||
|
auto dutarchive = getResourceDir() + "test1.tar.gz";
|
||||||
|
|
||||||
|
std::cerr << dutarchive << std::endl;
|
||||||
|
|
||||||
|
std::set<std::string> expected_files{"file1_random", "file2_random", "file3_zeros"};
|
||||||
|
try
|
||||||
|
{
|
||||||
|
std::ifstream fs(dutarchive);
|
||||||
|
ns_archive::reader reader = ns_archive::reader::make_reader<ar::format::_ALL, ar::filter::_ALL>(fs, 32000);
|
||||||
|
|
||||||
|
for(auto entry : reader)
|
||||||
|
{
|
||||||
|
std::string filename = entry->get_header_value_pathname();
|
||||||
|
std::string comparefile = getResourceDir() + filename;
|
||||||
|
bool isdirectory = (filename.size() && filename[filename.size()-1] == '/');
|
||||||
|
|
||||||
|
auto it = expected_files.find(filename);
|
||||||
|
ASSERT_TRUE(it != expected_files.end());
|
||||||
|
struct stat sb;
|
||||||
|
auto statret = stat(comparefile.c_str(),&sb);
|
||||||
|
EXPECT_EQ(0, statret);
|
||||||
|
|
||||||
|
EXPECT_TRUE(S_ISDIR(sb.st_mode) == isdirectory);
|
||||||
|
|
||||||
|
if (!isdirectory) {
|
||||||
|
EXPECT_EQ(sb.st_size, entry->get_header_value_size());
|
||||||
|
auto original = std::ifstream(comparefile, std::ios::in | std::ios::binary);
|
||||||
|
auto *buf = new char[sb.st_size];
|
||||||
|
auto *buf2 = new char[sb.st_size];
|
||||||
|
auto &entrystream = entry->get_stream();
|
||||||
|
original.read(buf, sb.st_size);
|
||||||
|
entrystream.read(buf2, sb.st_size);
|
||||||
|
EXPECT_TRUE(original.good());
|
||||||
|
EXPECT_TRUE(entrystream.good());
|
||||||
|
EXPECT_EQ(0,::memcmp(buf, buf2, sb.st_size));
|
||||||
|
delete[] buf, buf2;
|
||||||
|
}
|
||||||
|
expected_files.erase(filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(ns_archive::archive_exception& e)
|
||||||
|
{
|
||||||
|
ADD_FAILURE() << e.what();
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPECT_EQ(0, expected_files.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TEST_F(LibArchiveWrapperTest, TestReadDirectoryArchive) {
|
||||||
|
// Reading an archive.
|
||||||
|
auto dutarchive = getResourceDir() + "test2.tar.gz";
|
||||||
|
|
||||||
|
std::set<std::string> expected_files{"dir/", "dir/file1_random", "dir/file2_random", "dir/file3_zeros"};
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
std::ifstream fs(dutarchive);
|
||||||
|
ns_archive::reader reader = ns_archive::reader::make_reader<ar::format::_ALL, ar::filter::_ALL>(fs, 32000);
|
||||||
|
|
||||||
|
for(auto entry : reader)
|
||||||
|
{
|
||||||
|
std::string filename = entry->get_header_value_pathname();
|
||||||
|
std::string comparefile = getResourceDir() + filename;
|
||||||
|
|
||||||
|
bool isdirectory = (filename.size() && filename[filename.size()-1] == '/');
|
||||||
|
|
||||||
|
auto it = expected_files.find(filename);
|
||||||
|
ASSERT_TRUE(it != expected_files.end());
|
||||||
|
struct stat sb;
|
||||||
|
auto statret = stat(comparefile.c_str(),&sb);
|
||||||
|
EXPECT_EQ(0, statret);
|
||||||
|
|
||||||
|
EXPECT_TRUE(S_ISDIR(sb.st_mode) == isdirectory);
|
||||||
|
|
||||||
|
if (!isdirectory) {
|
||||||
|
EXPECT_EQ(sb.st_size, entry->get_header_value_size());
|
||||||
|
auto original = std::ifstream(comparefile, std::ios::in | std::ios::binary);
|
||||||
|
auto *buf = new char[sb.st_size];
|
||||||
|
auto *buf2 = new char[sb.st_size];
|
||||||
|
auto &entrystream = entry->get_stream();
|
||||||
|
original.read(buf, sb.st_size);
|
||||||
|
entrystream.read(buf2, sb.st_size);
|
||||||
|
EXPECT_TRUE(original.good());
|
||||||
|
EXPECT_TRUE(entrystream.good());
|
||||||
|
EXPECT_EQ(0,::memcmp(buf, buf2, sb.st_size));
|
||||||
|
delete[] buf, buf2;
|
||||||
|
}
|
||||||
|
expected_files.erase(filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(ns_archive::archive_exception& e)
|
||||||
|
{
|
||||||
|
ADD_FAILURE() << e.what();
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPECT_EQ(0, expected_files.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(LibArchiveWrapperTest, TestCreateDirectoryArchive) {
|
||||||
|
auto dutarchive = getcwd() + "test_create.tar.gz";
|
||||||
|
|
||||||
|
std::cerr << "DUT: " << dutarchive << std::endl;
|
||||||
|
std::set<std::string> expected_files{"dir/file1_random", "dir/file2_random", "dir/file3_zeros"};
|
||||||
|
|
||||||
|
// Create an archive.
|
||||||
|
try {
|
||||||
|
std::ofstream outfs(dutarchive, std::ios::trunc | std::ios::out);
|
||||||
|
ns_archive::writer writer = ns_archive::writer::make_writer<ns_archive::ns_writer::format::_TAR, ns_archive::ns_writer::filter::_GZIP>(outfs, 10240);
|
||||||
|
|
||||||
|
for(const auto& x: expected_files) {
|
||||||
|
std::ifstream file(getResourceDir() + x);
|
||||||
|
ASSERT_TRUE(file.good());
|
||||||
|
ns_archive::entry out_entry(file);
|
||||||
|
out_entry.set_header_value_pathname(x);
|
||||||
|
writer.add_entry(out_entry);
|
||||||
|
}
|
||||||
|
} catch (ns_archive::archive_exception& e)
|
||||||
|
{
|
||||||
|
ADD_FAILURE() << e.what();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read back the archive and compare the files.
|
||||||
|
try
|
||||||
|
{
|
||||||
|
std::ifstream fs(dutarchive);
|
||||||
|
deleteAfterTest(dutarchive);
|
||||||
|
ns_archive::reader reader = ns_archive::reader::make_reader<ar::format::_ALL, ar::filter::_ALL>(fs, 32000);
|
||||||
|
|
||||||
|
for(auto entry : reader)
|
||||||
|
{
|
||||||
|
std::string filename = entry->get_header_value_pathname();
|
||||||
|
std::string comparefile = getResourceDir() + filename;
|
||||||
|
|
||||||
|
bool isdirectory = (filename.size() && filename[filename.size()-1] == '/');
|
||||||
|
|
||||||
|
auto it = expected_files.find(filename);
|
||||||
|
ASSERT_TRUE(it != expected_files.end());
|
||||||
|
struct stat sb;
|
||||||
|
auto statret = stat(comparefile.c_str(),&sb);
|
||||||
|
EXPECT_EQ(0, statret);
|
||||||
|
|
||||||
|
EXPECT_TRUE(S_ISDIR(sb.st_mode) == isdirectory);
|
||||||
|
|
||||||
|
if (!isdirectory) {
|
||||||
|
EXPECT_EQ(sb.st_size, entry->get_header_value_size());
|
||||||
|
auto original = std::ifstream(comparefile, std::ios::in | std::ios::binary);
|
||||||
|
auto *buf = new char[sb.st_size];
|
||||||
|
auto *buf2 = new char[sb.st_size];
|
||||||
|
auto &entrystream = entry->get_stream();
|
||||||
|
original.read(buf, sb.st_size);
|
||||||
|
entrystream.read(buf2, sb.st_size);
|
||||||
|
EXPECT_TRUE(original.good());
|
||||||
|
EXPECT_TRUE(entrystream.good());
|
||||||
|
EXPECT_EQ(0,::memcmp(buf, buf2, sb.st_size));
|
||||||
|
delete[] buf, buf2;
|
||||||
|
}
|
||||||
|
expected_files.erase(filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(ns_archive::archive_exception& e)
|
||||||
|
{
|
||||||
|
ADD_FAILURE() << e.what() << " Archive: " << dutarchive;
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPECT_EQ(0, expected_files.size());
|
||||||
|
std::cerr << dutarchive << std::endl;
|
||||||
|
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user