mirror of
https://github.com/usatiuk/backup.git
synced 2025-10-26 17:37:47 +01:00
proper cmake
This commit is contained in:
@@ -1,39 +0,0 @@
|
||||
//
|
||||
// Created by Stepan Usatiuk on 27.04.2023.
|
||||
//
|
||||
|
||||
#include "BuzhashTest.h"
|
||||
#include "../src/chunkers/Buzhash.h"
|
||||
|
||||
|
||||
std::unique_ptr<TestGroup> BuzhashTest::operator()() {
|
||||
|
||||
auto tg = std::make_unique<TestGroup>("Buzhash tests");
|
||||
|
||||
tg->addTest(std::make_unique<Test>("Simple buzhash test", std::function<bool()>([]() {
|
||||
std::string loremipsum = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
|
||||
|
||||
for (int i = 15; i < 49; i++) {
|
||||
Buzhash b(i);
|
||||
std::string p1 = "reprehenderit in voluptate velit esse cillum dolore";
|
||||
for (auto c: p1) b.feed(static_cast<uint8_t>(c));
|
||||
auto h1 = b.get();
|
||||
|
||||
Buzhash b2(i);
|
||||
bool h1found = false;
|
||||
|
||||
for (int i = 0; i < loremipsum.length(); i++) {
|
||||
b2.feed((uint8_t) loremipsum[i]);
|
||||
if (b2.get() == h1) {
|
||||
HelpfulAssert<int>()(i, loremipsum.find("e eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non p"));
|
||||
h1found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
HelpfulAssert<bool>()(h1found, true);
|
||||
}
|
||||
|
||||
return true;
|
||||
})));
|
||||
return tg;
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
//
|
||||
// Created by Stepan Usatiuk on 27.04.2023.
|
||||
//
|
||||
|
||||
#ifndef SEMBACKUP_BUZHASHTEST_H
|
||||
#define SEMBACKUP_BUZHASHTEST_H
|
||||
|
||||
#include "utils/TestGroupGenerator.h"
|
||||
|
||||
class BuzhashTest : public TestGroupGenerator {
|
||||
public:
|
||||
std::unique_ptr<TestGroup> operator()() override;
|
||||
};
|
||||
|
||||
|
||||
#endif//SEMBACKUP_BUZHASHTEST_H
|
||||
@@ -1,30 +0,0 @@
|
||||
//
|
||||
// Created by Stepan Usatiuk on 10.05.2023.
|
||||
//
|
||||
|
||||
#include "CLITestWrapper.h"
|
||||
#include "utils/Cleaner.h"
|
||||
|
||||
std::unique_ptr<TestGroup> CLITestWrapper::operator()() {
|
||||
auto tg = std::make_unique<TestGroup>("CLI tests");
|
||||
|
||||
tg->addTest(std::make_unique<Test>("Test backup", std::function<bool()>([]() {
|
||||
int ret = system("../tests/clitests/backup.sh");
|
||||
HelpfulAssert<int>()(WEXITSTATUS(ret), 0);
|
||||
return true;
|
||||
})));
|
||||
tg->addTest(std::make_unique<Test>("Test ignore", std::function<bool()>([]() {
|
||||
int ret = system("../tests/clitests/ignore.sh");
|
||||
HelpfulAssert<int>()(WEXITSTATUS(ret), 0);
|
||||
return true;
|
||||
})));
|
||||
|
||||
tg->addTest(std::make_unique<Test>("Test diff", std::function<bool()>([]() {
|
||||
int ret = system("../tests/clitests/diff.sh");
|
||||
HelpfulAssert<int>()(WEXITSTATUS(ret), 0);
|
||||
return true;
|
||||
})));
|
||||
|
||||
|
||||
return tg;
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
//
|
||||
// Created by Stepan Usatiuk on 10.05.2023.
|
||||
//
|
||||
|
||||
#ifndef SEMBACKUP_CLITESTWRAPPER_H
|
||||
#define SEMBACKUP_CLITESTWRAPPER_H
|
||||
|
||||
#include "utils/TestGroupGenerator.h"
|
||||
|
||||
class CLITestWrapper : public TestGroupGenerator {
|
||||
public:
|
||||
std::unique_ptr<TestGroup> operator()() override;
|
||||
};
|
||||
|
||||
#endif//SEMBACKUP_CLITESTWRAPPER_H
|
||||
28
tests/CMakeLists.txt
Normal file
28
tests/CMakeLists.txt
Normal file
@@ -0,0 +1,28 @@
|
||||
cmake_minimum_required(VERSION 3.22)
|
||||
|
||||
# GoogleTest requires at least C++14
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.24.0")
|
||||
cmake_policy(SET CMP0135 NEW)
|
||||
endif ()
|
||||
|
||||
include(FetchContent)
|
||||
FetchContent_Declare(
|
||||
googletest
|
||||
GIT_REPOSITORY https://github.com/google/googletest.git
|
||||
GIT_TAG release-1.12.1
|
||||
)
|
||||
# For Windows: Prevent overriding the parent project's compiler/linker settings
|
||||
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
|
||||
FetchContent_MakeAvailable(googletest)
|
||||
include(GoogleTest)
|
||||
|
||||
add_subdirectory(utils)
|
||||
|
||||
add_subdirectory(chunkers)
|
||||
add_subdirectory(clitests)
|
||||
add_subdirectory(crypto)
|
||||
add_subdirectory(fulltests)
|
||||
add_subdirectory(repo)
|
||||
12
tests/chunkers/CMakeLists.txt
Normal file
12
tests/chunkers/CMakeLists.txt
Normal file
@@ -0,0 +1,12 @@
|
||||
cmake_minimum_required(VERSION 3.22)
|
||||
|
||||
add_executable(
|
||||
BuzhashTest
|
||||
srcs/BuzhashTest.cpp
|
||||
)
|
||||
target_link_libraries(
|
||||
BuzhashTest PRIVATE
|
||||
GTest::gtest_main chunkers
|
||||
)
|
||||
gtest_discover_tests(BuzhashTest)
|
||||
|
||||
31
tests/chunkers/srcs/BuzhashTest.cpp
Normal file
31
tests/chunkers/srcs/BuzhashTest.cpp
Normal file
@@ -0,0 +1,31 @@
|
||||
//
|
||||
// Created by Stepan Usatiuk on 27.04.2023.
|
||||
//
|
||||
|
||||
#include "Buzhash.h"
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
// Demonstrate some basic assertions.
|
||||
TEST(BuzhashTest, SimpleTest) {
|
||||
std::string loremipsum = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
|
||||
|
||||
for (int i = 15; i < 49; i++) {
|
||||
Buzhash b(i);
|
||||
std::string p1 = "reprehenderit in voluptate velit esse cillum dolore";
|
||||
for (auto c: p1) b.feed(static_cast<uint8_t>(c));
|
||||
auto h1 = b.get();
|
||||
|
||||
Buzhash b2(i);
|
||||
bool h1found = false;
|
||||
|
||||
for (int i = 0; i < loremipsum.length(); i++) {
|
||||
b2.feed((uint8_t) loremipsum[i]);
|
||||
if (b2.get() == h1) {
|
||||
EXPECT_EQ(i, loremipsum.find("e eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non p"));
|
||||
h1found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
EXPECT_EQ(h1found, true);
|
||||
}
|
||||
}
|
||||
15
tests/clitests/CMakeLists.txt
Normal file
15
tests/clitests/CMakeLists.txt
Normal file
@@ -0,0 +1,15 @@
|
||||
cmake_minimum_required(VERSION 3.22)
|
||||
|
||||
|
||||
add_executable(
|
||||
CLITests
|
||||
srcs/CLITestWrapper.cpp
|
||||
)
|
||||
add_dependencies(CLITests backup)
|
||||
|
||||
target_link_libraries(
|
||||
CLITests PRIVATE
|
||||
GTest::gtest_main testUtils
|
||||
)
|
||||
gtest_discover_tests(CLITests)
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
|
||||
TESTSIZE=16
|
||||
|
||||
CMD=./sembackup
|
||||
# TODO: Don't hardcode this
|
||||
CMD="../../src/backup"
|
||||
|
||||
rm -rf testdata
|
||||
rm -rf testdir
|
||||
@@ -1,6 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
CMD=./sembackup
|
||||
# TODO: Don't hardcode this
|
||||
CMD="../../src/backup"
|
||||
|
||||
rm -rf testdata
|
||||
rm -rf testdir
|
||||
@@ -1,6 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
CMD=./sembackup
|
||||
# TODO: Don't hardcode this
|
||||
CMD="../../src/backup"
|
||||
|
||||
rm -rf testdata
|
||||
rm -rf testdir
|
||||
23
tests/clitests/srcs/CLITestWrapper.cpp
Normal file
23
tests/clitests/srcs/CLITestWrapper.cpp
Normal file
@@ -0,0 +1,23 @@
|
||||
//
|
||||
// Created by Stepan Usatiuk on 10.05.2023.
|
||||
//
|
||||
|
||||
#include "Cleaner.h"
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
//TODO: Don't hardcode scripts
|
||||
|
||||
TEST(CLITest, Backup) {
|
||||
int ret = system("../../../tests/clitests/scripts/backup.sh");
|
||||
EXPECT_EQ(WEXITSTATUS(ret), 0);
|
||||
}
|
||||
|
||||
TEST(CLITest, Ignore) {
|
||||
int ret = system("../../../tests/clitests/scripts/ignore.sh");
|
||||
EXPECT_EQ(WEXITSTATUS(ret), 0);
|
||||
}
|
||||
|
||||
TEST(CLITest, Diff) {
|
||||
int ret = system("../../../tests/clitests/scripts/diff.sh");
|
||||
EXPECT_EQ(WEXITSTATUS(ret), 0);
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
//
|
||||
// Created by Stepan Usatiuk on 30.04.2023.
|
||||
//
|
||||
|
||||
#include "AESTest.h"
|
||||
#include "../../src/crypto/AES.h"
|
||||
|
||||
std::unique_ptr<TestGroup> AESTest::operator()() {
|
||||
auto tg = std::make_unique<TestGroup>("AES tests");
|
||||
|
||||
tg->addTest(std::make_unique<Test>("Simple AESTest test", std::function<bool()>([]() {
|
||||
std::string in = "hello1";
|
||||
auto enc = AES::encrypt(std::vector<char>(in.begin(), in.end()), "p1", "e");
|
||||
auto dec = AES::decrypt(enc, "p1", "e");
|
||||
HelpfulAssert<std::string>()(in, std::string(dec.begin(), dec.end()));
|
||||
|
||||
in = "1234567890asdfg";
|
||||
enc = AES::encrypt(std::vector<char>(in.begin(), in.end()), "p1", "e");
|
||||
dec = AES::decrypt(enc, "p1", "e");
|
||||
HelpfulAssert<std::string>()(in, std::string(dec.begin(), dec.end()));
|
||||
|
||||
in = "1234567890asdfgh";
|
||||
enc = AES::encrypt(std::vector<char>(in.begin(), in.end()), "p1", "e");
|
||||
dec = AES::decrypt(enc, "p1", "e");
|
||||
HelpfulAssert<std::string>()(in, std::string(dec.begin(), dec.end()));
|
||||
|
||||
in = "1234567890asdfghe";
|
||||
enc = AES::encrypt(std::vector<char>(in.begin(), in.end()), "p1", "e");
|
||||
dec = AES::decrypt(enc, "p1", "e");
|
||||
HelpfulAssert<std::string>()(in, std::string(dec.begin(), dec.end()));
|
||||
|
||||
in = "1234567890asdfgheq";
|
||||
enc = AES::encrypt(std::vector<char>(in.begin(), in.end()), "p1", "e");
|
||||
dec = AES::decrypt(enc, "p1", "e");
|
||||
HelpfulAssert<std::string>()(in, std::string(dec.begin(), dec.end()));
|
||||
|
||||
return true;
|
||||
})));
|
||||
return tg;
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
//
|
||||
// Created by Stepan Usatiuk on 30.04.2023.
|
||||
//
|
||||
|
||||
#ifndef SEMBACKUP_AESTEST_H
|
||||
#define SEMBACKUP_AESTEST_H
|
||||
|
||||
#include "../utils/TestGroupGenerator.h"
|
||||
|
||||
class AESTest : public TestGroupGenerator {
|
||||
public:
|
||||
std::unique_ptr<TestGroup> operator()() override;
|
||||
};
|
||||
|
||||
|
||||
#endif//SEMBACKUP_AESTEST_H
|
||||
14
tests/crypto/CMakeLists.txt
Normal file
14
tests/crypto/CMakeLists.txt
Normal file
@@ -0,0 +1,14 @@
|
||||
cmake_minimum_required(VERSION 3.22)
|
||||
|
||||
add_executable(
|
||||
CryptoTests
|
||||
srcs/CryptoTests.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(
|
||||
CryptoTests PRIVATE
|
||||
GTest::gtest_main crypto
|
||||
)
|
||||
|
||||
gtest_discover_tests(CryptoTests)
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
//
|
||||
// Created by Stepan Usatiuk on 15.04.2023.
|
||||
//
|
||||
|
||||
#include "MD5Test.h"
|
||||
|
||||
std::unique_ptr<TestGroup> MD5Test::operator()() {
|
||||
auto tg = std::make_unique<TestGroup>("MD5 tests");
|
||||
|
||||
tg->addTest(std::make_unique<Test>("Simple MD5 test", std::function<bool()>([]() {
|
||||
std::vector<char> data{'h', 'e', 'l', 'l', 'o'};
|
||||
std::array<unsigned char, 16> excepted{0x5d, 0x41, 0x40, 0x2a, 0xbc, 0x4b, 0x2a, 0x76, 0xb9, 0x71, 0x9d, 0x91, 0x10, 0x17, 0xc5, 0x92};
|
||||
|
||||
auto out = MD5::calculate(data);
|
||||
|
||||
HelpfulAssert<size_t>()(out.size(), 16);
|
||||
for (int i = 0; i < out.size(); i++) {
|
||||
HelpfulAssert<unsigned char>()(out[i], excepted[i]);
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
})));
|
||||
return tg;
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
//
|
||||
// Created by Stepan Usatiuk on 15.04.2023.
|
||||
//
|
||||
|
||||
#ifndef SEMBACKUP_MD5TEST_H
|
||||
#define SEMBACKUP_MD5TEST_H
|
||||
|
||||
#include "../../src/crypto/MD5.h"
|
||||
#include "../utils/TestGroupGenerator.h"
|
||||
|
||||
class MD5Test : public TestGroupGenerator {
|
||||
public:
|
||||
std::unique_ptr<TestGroup> operator()() override;
|
||||
};
|
||||
|
||||
|
||||
#endif//SEMBACKUP_MD5TEST_H
|
||||
47
tests/crypto/srcs/CryptoTests.cpp
Normal file
47
tests/crypto/srcs/CryptoTests.cpp
Normal file
@@ -0,0 +1,47 @@
|
||||
//
|
||||
// Created by Stepan Usatiuk on 30.04.2023.
|
||||
//
|
||||
|
||||
#include "AES.h"
|
||||
#include "MD5.h"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
TEST(CryptoTests, AES) {
|
||||
std::string in = "hello1";
|
||||
auto enc = AES::encrypt(std::vector<char>(in.begin(), in.end()), "p1", "e");
|
||||
auto dec = AES::decrypt(enc, "p1", "e");
|
||||
EXPECT_EQ(in, std::string(dec.begin(), dec.end()));
|
||||
|
||||
in = "1234567890asdfg";
|
||||
enc = AES::encrypt(std::vector<char>(in.begin(), in.end()), "p1", "e");
|
||||
dec = AES::decrypt(enc, "p1", "e");
|
||||
EXPECT_EQ(in, std::string(dec.begin(), dec.end()));
|
||||
|
||||
in = "1234567890asdfgh";
|
||||
enc = AES::encrypt(std::vector<char>(in.begin(), in.end()), "p1", "e");
|
||||
dec = AES::decrypt(enc, "p1", "e");
|
||||
EXPECT_EQ(in, std::string(dec.begin(), dec.end()));
|
||||
|
||||
in = "1234567890asdfghe";
|
||||
enc = AES::encrypt(std::vector<char>(in.begin(), in.end()), "p1", "e");
|
||||
dec = AES::decrypt(enc, "p1", "e");
|
||||
EXPECT_EQ(in, std::string(dec.begin(), dec.end()));
|
||||
|
||||
in = "1234567890asdfgheq";
|
||||
enc = AES::encrypt(std::vector<char>(in.begin(), in.end()), "p1", "e");
|
||||
dec = AES::decrypt(enc, "p1", "e");
|
||||
EXPECT_EQ(in, std::string(dec.begin(), dec.end()));
|
||||
}
|
||||
|
||||
TEST(CryptoTests, MD5) {
|
||||
std::vector<char> data{'h', 'e', 'l', 'l', 'o'};
|
||||
std::array<unsigned char, 16> excepted{0x5d, 0x41, 0x40, 0x2a, 0xbc, 0x4b, 0x2a, 0x76, 0xb9, 0x71, 0x9d, 0x91, 0x10, 0x17, 0xc5, 0x92};
|
||||
|
||||
auto out = MD5::calculate(data);
|
||||
|
||||
EXPECT_EQ(out.size(), 16);
|
||||
for (int i = 0; i < out.size(); i++) {
|
||||
EXPECT_EQ(static_cast<uint8_t>(out[i]), excepted[i]);
|
||||
}
|
||||
}
|
||||
14
tests/fulltests/CMakeLists.txt
Normal file
14
tests/fulltests/CMakeLists.txt
Normal file
@@ -0,0 +1,14 @@
|
||||
cmake_minimum_required(VERSION 3.22)
|
||||
|
||||
add_executable(
|
||||
FullTest
|
||||
srcs/FullTest.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(
|
||||
FullTest PRIVATE
|
||||
GTest::gtest_main commands utils testUtils repo
|
||||
)
|
||||
|
||||
gtest_discover_tests(FullTest)
|
||||
|
||||
@@ -1,418 +0,0 @@
|
||||
//
|
||||
// Created by Stepan Usatiuk on 16.04.2023.
|
||||
//
|
||||
|
||||
#include "FullTest.h"
|
||||
#include "../../src/Logger.h"
|
||||
#include "../../src/commands/CommandRestore.h"
|
||||
#include "../../src/commands/CommandRun.h"
|
||||
#include "../../src/repo/FileRepository.h"
|
||||
#include "../utils/Cleaner.h"
|
||||
|
||||
#include <filesystem>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
|
||||
void randomChange(std::string path) {
|
||||
std::fstream s(path);
|
||||
auto pos = rand() % 50;
|
||||
s.seekp(pos, std::ios::beg);
|
||||
char out = rand() % 254;
|
||||
s.write(&out, 1);
|
||||
}
|
||||
|
||||
std::unique_ptr<TestGroup> FullTest::operator()() {
|
||||
auto tg = std::make_unique<TestGroup>("Full tests");
|
||||
|
||||
tg->addTest(std::make_unique<Test>("Simple backup/restore test", std::function<bool()>([]() {
|
||||
Cleaner c({"testfrom", "testto", "testtores"});
|
||||
int aid = -1;
|
||||
{
|
||||
std::filesystem::create_directories("testfrom");
|
||||
for (int i = 0; i < 257; i++) {
|
||||
std::ofstream o(std::filesystem::path("testfrom") / ("f" + std::to_string(i)), std::ios::binary | std::ios::out | std::ios::trunc);
|
||||
for (int j = 0; j < i; j++) o.put(j % 256);
|
||||
}
|
||||
std::filesystem::create_directories("testfrom/testdir");
|
||||
|
||||
Config conf;
|
||||
conf.add("repo", "testto").add("from", "testfrom");
|
||||
|
||||
auto repo = std::make_unique<FileRepository>(conf);
|
||||
repo->init();
|
||||
|
||||
std::stringstream runnerout;
|
||||
Logger logger(1, runnerout);
|
||||
|
||||
CommandRun run;
|
||||
run.run(Context{&logger, repo.get()});
|
||||
|
||||
aid = repo->getObjects(Object::ObjectType::Archive).begin()->second;
|
||||
}
|
||||
{
|
||||
Config conf;
|
||||
conf.add("repo", "testto").add("aid", std::to_string(aid)).add("to", "testtores");
|
||||
|
||||
auto repo = std::make_unique<FileRepository>(conf);
|
||||
repo->open();
|
||||
std::stringstream runnerout;
|
||||
Logger logger(1, runnerout);
|
||||
|
||||
CommandRestore cmd;
|
||||
cmd.run(Context{&logger, repo.get()});
|
||||
}
|
||||
{
|
||||
try {
|
||||
HelpfulAssert<bool>()(std::filesystem::is_directory("testtores/testdir"), true);
|
||||
} catch (...) {
|
||||
std::cerr << "Empty directory doesn't exist!" << std::endl;
|
||||
throw;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 257; i++) {
|
||||
std::ifstream o(std::filesystem::path("testtores") / ("f" + std::to_string(i)), std::ios::binary | std::ios::in);
|
||||
try {
|
||||
HelpfulAssert<bool>()(o.is_open(), true);
|
||||
for (int j = 0; j < i; j++) {
|
||||
char c;
|
||||
HelpfulAssert<bool>()(o.get(c).operator bool(), true);
|
||||
HelpfulAssert<char>()(j % 256, c);
|
||||
}
|
||||
} catch (...) {
|
||||
std::cerr << "Error comparing file " << i << std::endl;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
})));
|
||||
tg->addTest(std::make_unique<Test>("Simple backup/restore with ignore test", std::function<bool()>([]() {
|
||||
Cleaner c({"testfrom", "testto", "testtores"});
|
||||
int aid = -1;
|
||||
{
|
||||
std::filesystem::create_directories("testfrom");
|
||||
for (int i = 0; i < 257; i++) {
|
||||
std::ofstream o(std::filesystem::path("testfrom") / ("f" + std::to_string(i)), std::ios::binary | std::ios::out | std::ios::trunc);
|
||||
for (int j = 0; j < i; j++) o.put(j % 256);
|
||||
}
|
||||
std::filesystem::create_directories("testfrom/testdir");
|
||||
std::filesystem::create_directories("testfrom/testdir2/testdir3");
|
||||
std::filesystem::create_directories("testfrom/testdir2/testdir4");
|
||||
{
|
||||
std::ofstream file("testfrom/testdir2/.ignore");
|
||||
file << "hello.txt";
|
||||
}
|
||||
{
|
||||
std::ofstream file("testfrom/testdir2/testdir3/.ignore");
|
||||
file << ".*\\.txt";
|
||||
}
|
||||
{
|
||||
std::ofstream file("testfrom/testdir2/hello.txt");
|
||||
file << "hello";
|
||||
}
|
||||
{
|
||||
std::ofstream file("testfrom/testdir2/testdir3/hello.txt");
|
||||
file << "hello2";
|
||||
}
|
||||
{
|
||||
std::ofstream file("testfrom/testdir2/testdir3/asdf.txt");
|
||||
file << "asdf1";
|
||||
}
|
||||
{
|
||||
std::ofstream file("testfrom/testdir2/testdir4/asdf.txt");
|
||||
file << "asdf2";
|
||||
}
|
||||
|
||||
Config conf;
|
||||
conf.add("repo", "testto").add("from", "testfrom");
|
||||
|
||||
auto repo = std::make_unique<FileRepository>(conf);
|
||||
repo->init();
|
||||
std::stringstream runnerout;
|
||||
Logger logger(1, runnerout);
|
||||
|
||||
CommandRun cmd;
|
||||
cmd.run(Context{&logger, repo.get()});
|
||||
aid = repo->getObjects(Object::ObjectType::Archive).begin()->second;
|
||||
}
|
||||
{
|
||||
Config conf;
|
||||
conf.add("repo", "testto").add("aid", std::to_string(aid)).add("to", "testtores");
|
||||
|
||||
auto repo = std::make_unique<FileRepository>(conf);
|
||||
repo->open();
|
||||
std::stringstream runnerout;
|
||||
Logger logger(1, runnerout);
|
||||
|
||||
CommandRestore cmd;
|
||||
cmd.run(Context{&logger, repo.get()});
|
||||
}
|
||||
{
|
||||
HelpfulAssert<bool>()(std::filesystem::is_directory("testtores/testdir"), true);
|
||||
|
||||
for (int i = 0; i < 257; i++) {
|
||||
std::ifstream o(std::filesystem::path("testtores") / ("f" + std::to_string(i)), std::ios::binary | std::ios::in);
|
||||
HelpfulAssert<bool>()(o.is_open(), true);
|
||||
for (int j = 0; j < i; j++) {
|
||||
char c;
|
||||
HelpfulAssert<bool>()(o.get(c).operator bool(), true);
|
||||
HelpfulAssert<char>()(j % 256, c);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
std::ifstream file("testtores/testdir2/.ignore");
|
||||
std::string s;
|
||||
file >> s;
|
||||
HelpfulAssert<std::string>()(s, "hello.txt");
|
||||
}
|
||||
{
|
||||
std::ifstream file("testtores/testdir2/testdir3/.ignore");
|
||||
std::string s;
|
||||
file >> s;
|
||||
HelpfulAssert<std::string>()(s, ".*\\.txt");
|
||||
}
|
||||
{
|
||||
std::ifstream file("testtores/testdir2/hello.txt");
|
||||
HelpfulAssert<bool>()(!file, true);
|
||||
}
|
||||
{
|
||||
std::ifstream file("testtores/testdir2/testdir3/hello.txt");
|
||||
HelpfulAssert<bool>()(!file, true);
|
||||
}
|
||||
{
|
||||
std::ifstream file("testtores/testdir2/testdir3/asdf.txt");
|
||||
HelpfulAssert<bool>()(!file, true);
|
||||
}
|
||||
{
|
||||
std::ifstream file("testtores/testdir2/testdir4/asdf.txt");
|
||||
std::string s;
|
||||
file >> s;
|
||||
HelpfulAssert<std::string>()(s, "asdf2");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
})));
|
||||
|
||||
tg->addTest(std::make_unique<Test>("Backup/restore test with compression", std::function<bool()>([]() {
|
||||
Cleaner c({"testfrom", "testto", "testtores"});
|
||||
int aid = -1;
|
||||
{
|
||||
std::filesystem::create_directories("testfrom");
|
||||
for (int i = 0; i < 257; i++) {
|
||||
std::ofstream o(std::filesystem::path("testfrom") / ("f" + std::to_string(i)), std::ios::binary | std::ios::out | std::ios::trunc);
|
||||
for (int j = 0; j < i; j++) o.put(j % 256);
|
||||
}
|
||||
std::filesystem::create_directories("testfrom/testdir");
|
||||
|
||||
Config conf;
|
||||
conf.add("repo", "testto").add("compression", "zlib").add("from", "testfrom");
|
||||
|
||||
auto repo = std::make_unique<FileRepository>(conf);
|
||||
repo->init();
|
||||
std::stringstream runnerout;
|
||||
Logger logger(1, runnerout);
|
||||
|
||||
CommandRun cmd;
|
||||
cmd.run(Context{&logger, repo.get()});
|
||||
aid = repo->getObjects(Object::ObjectType::Archive).begin()->second;
|
||||
}
|
||||
{
|
||||
Config conf;
|
||||
conf.add("repo", "testto").add("aid", std::to_string(aid)).add("to", "testtores");
|
||||
|
||||
auto repo = std::make_unique<FileRepository>(conf);
|
||||
repo->open();
|
||||
std::stringstream runnerout;
|
||||
Logger logger(1, runnerout);
|
||||
|
||||
CommandRestore cmd;
|
||||
cmd.run(Context{&logger, repo.get()});
|
||||
}
|
||||
{
|
||||
HelpfulAssert<bool>()(std::filesystem::is_directory("testtores/testdir"), true);
|
||||
|
||||
for (int i = 0; i < 257; i++) {
|
||||
std::ifstream o(std::filesystem::path("testtores") / ("f" + std::to_string(i)), std::ios::binary | std::ios::in);
|
||||
HelpfulAssert<bool>()(o.is_open(), true);
|
||||
for (int j = 0; j < i; j++) {
|
||||
char c;
|
||||
HelpfulAssert<bool>()(o.get(c).operator bool(), true);
|
||||
HelpfulAssert<char>()(j % 256, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
})));
|
||||
tg->addTest(std::make_unique<Test>("Backup/restore test with compression/encryption", std::function<bool()>([]() {
|
||||
Cleaner c({"testfrom", "testto", "testtores"});
|
||||
int aid = -1;
|
||||
{
|
||||
std::filesystem::create_directories("testfrom");
|
||||
for (int i = 0; i < 257; i++) {
|
||||
std::ofstream o(std::filesystem::path("testfrom") / ("f" + std::to_string(i)), std::ios::binary | std::ios::out | std::ios::trunc);
|
||||
for (int j = 0; j < i; j++) o.put(j % 256);
|
||||
}
|
||||
std::filesystem::create_directories("testfrom/testdir");
|
||||
|
||||
Config conf;
|
||||
conf.add("repo", "testto").add("compression", "zlib").add("from", "testfrom").add("encryption", "aes").add("password", "testp").add("salt", "tests");
|
||||
|
||||
auto repo = std::make_unique<FileRepository>(conf);
|
||||
repo->init();
|
||||
|
||||
std::stringstream runnerout;
|
||||
Logger logger(1, runnerout);
|
||||
|
||||
CommandRun cmd;
|
||||
cmd.run(Context{&logger, repo.get()});
|
||||
aid = repo->getObjects(Object::ObjectType::Archive).begin()->second;
|
||||
}
|
||||
{
|
||||
Config conf;
|
||||
conf.add("repo", "testto");
|
||||
|
||||
auto repo = std::make_unique<FileRepository>(conf);
|
||||
|
||||
bool ok = true;
|
||||
try {
|
||||
HelpfulAssert<bool>()(repo->open(), false);
|
||||
ok = false;
|
||||
} catch (...) {}
|
||||
HelpfulAssert<bool>()(ok, true);
|
||||
}
|
||||
{
|
||||
Config conf;
|
||||
conf.add("repo", "testto").add("password", "testp").add("aid", std::to_string(aid)).add("to", "testtores");
|
||||
|
||||
auto repo = std::make_unique<FileRepository>(conf);
|
||||
repo->open();
|
||||
|
||||
std::stringstream runnerout;
|
||||
Logger logger(1, runnerout);
|
||||
|
||||
CommandRestore cmd;
|
||||
cmd.run(Context{&logger, repo.get()});
|
||||
}
|
||||
{
|
||||
HelpfulAssert<bool>()(std::filesystem::is_directory("testtores/testdir"), true);
|
||||
|
||||
for (int i = 0; i < 257; i++) {
|
||||
std::ifstream o(std::filesystem::path("testtores") / ("f" + std::to_string(i)), std::ios::binary | std::ios::in);
|
||||
HelpfulAssert<bool>()(o.is_open(), true);
|
||||
for (int j = 0; j < i; j++) {
|
||||
char c;
|
||||
HelpfulAssert<bool>()(o.get(c).operator bool(), true);
|
||||
HelpfulAssert<char>()(j % 256, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
})));
|
||||
tg->addTest(std::make_unique<Test>("Repo data fuzz test", std::function<bool()>([]() {
|
||||
srand(time(nullptr));
|
||||
std::vector<Config> confs;
|
||||
Config conf;
|
||||
conf.add("repo", "testto").add("compression", "none").add("from", "testfrom").add("encryption", "none").add("password", "testp").add("salt", "tests").add("progress", "none");
|
||||
confs.emplace_back(conf);
|
||||
conf = Config();
|
||||
conf.add("repo", "testto").add("compression", "zlib").add("from", "testfrom").add("encryption", "none").add("password", "testp").add("salt", "tests").add("progress", "none");
|
||||
confs.emplace_back(conf);
|
||||
conf = Config();
|
||||
conf.add("repo", "testto").add("compression", "none").add("from", "testfrom").add("encryption", "zlib").add("password", "testp").add("salt", "tests").add("progress", "none");
|
||||
confs.emplace_back(conf);
|
||||
conf = Config();
|
||||
conf.add("repo", "testto").add("compression", "zlib").add("from", "testfrom").add("encryption", "aes").add("password", "testp").add("salt", "tests").add("progress", "none");
|
||||
confs.emplace_back(conf);
|
||||
|
||||
for (auto const &conf: confs) {
|
||||
for (uint8_t filetobreak = 1; filetobreak <= 15; filetobreak++) {
|
||||
std::cout << static_cast<int>(filetobreak) << " / 15 tests done" << std::endl;
|
||||
for (uint8_t cutoff = 1; cutoff < 20; cutoff++) {
|
||||
Cleaner c({"testfrom", "testto", "testtores"});
|
||||
|
||||
int aid = -1;
|
||||
{
|
||||
std::filesystem::create_directories("testfrom");
|
||||
for (int i = 0; i < 2; i++) {
|
||||
std::ofstream o(std::filesystem::path("testfrom") / ("f" + std::to_string(i)), std::ios::binary | std::ios::out | std::ios::trunc);
|
||||
for (int j = 0; j < i; j++) o.put(j % 2);
|
||||
}
|
||||
|
||||
|
||||
auto repo = std::make_unique<FileRepository>(conf);
|
||||
repo->init();
|
||||
|
||||
std::stringstream runnerout;
|
||||
Logger logger(1, runnerout);
|
||||
|
||||
CommandRun cmd;
|
||||
cmd.run(Context{&logger, repo.get()});
|
||||
aid = repo->getObjects(Object::ObjectType::Archive).begin()->second;
|
||||
}
|
||||
|
||||
{
|
||||
if (filetobreak & 0b00000001) {
|
||||
for (int i = 0; i < cutoff; i++)
|
||||
randomChange("testto/1");
|
||||
if (cutoff > 5)
|
||||
std::filesystem::resize_file("testto/1", std::filesystem::file_size("testto/1") - cutoff);
|
||||
}
|
||||
if (filetobreak & 0b00000010) {
|
||||
for (int i = 0; i < cutoff; i++)
|
||||
randomChange("testto/index");
|
||||
if (cutoff > 5)
|
||||
std::filesystem::resize_file("testto/index", std::filesystem::file_size("testto/index") - cutoff);
|
||||
}
|
||||
if (filetobreak & 0b00000100) {
|
||||
for (int i = 0; i < cutoff; i++)
|
||||
randomChange("testto/offsets");
|
||||
if (cutoff > 5)
|
||||
std::filesystem::resize_file("testto/offsets", std::filesystem::file_size("testto/offsets") - cutoff);
|
||||
}
|
||||
if (filetobreak & 0b00001000) {
|
||||
for (int i = 0; i < cutoff; i++)
|
||||
randomChange("testto/info");
|
||||
if (cutoff > 5)
|
||||
std::filesystem::resize_file("testto/info", std::filesystem::file_size("testto/info") - cutoff);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
bool ok = true;
|
||||
try {
|
||||
Config confr = conf;
|
||||
confr.add("aid", std::to_string(aid)).add("to", "testtores");
|
||||
|
||||
auto repo = std::make_unique<FileRepository>(confr);
|
||||
repo->open();
|
||||
|
||||
std::stringstream runnerout;
|
||||
Logger logger(1, runnerout);
|
||||
|
||||
CommandRestore cmd;
|
||||
cmd.run(Context{&logger, repo.get()});
|
||||
auto outstr = runnerout.str();
|
||||
if (outstr.find("Error") == std::string::npos)
|
||||
ok = false;
|
||||
} catch (...) {}
|
||||
HelpfulAssert<bool>()(ok, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
})));
|
||||
return tg;
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
//
|
||||
// Created by Stepan Usatiuk on 16.04.2023.
|
||||
//
|
||||
|
||||
#ifndef SEMBACKUP_FULLTEST_H
|
||||
#define SEMBACKUP_FULLTEST_H
|
||||
|
||||
|
||||
#include "../utils/TestGroupGenerator.h"
|
||||
|
||||
class FullTest : public TestGroupGenerator {
|
||||
public:
|
||||
std::unique_ptr<TestGroup> operator()() override;
|
||||
};
|
||||
|
||||
|
||||
#endif//SEMBACKUP_FULLTEST_H
|
||||
402
tests/fulltests/srcs/FullTest.cpp
Normal file
402
tests/fulltests/srcs/FullTest.cpp
Normal file
@@ -0,0 +1,402 @@
|
||||
//
|
||||
// Created by Stepan Usatiuk on 16.04.2023.
|
||||
//
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "Cleaner.h"
|
||||
#include "CommandRestore.h"
|
||||
#include "CommandRun.h"
|
||||
#include "FileRepository.h"
|
||||
#include "Logger.h"
|
||||
|
||||
#include <filesystem>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
|
||||
void randomChange(std::string path) {
|
||||
std::fstream s(path);
|
||||
auto pos = rand() % 50;
|
||||
s.seekp(pos, std::ios::beg);
|
||||
char out = rand() % 254;
|
||||
s.write(&out, 1);
|
||||
}
|
||||
|
||||
TEST(FullTest, Simple) {
|
||||
Cleaner c({"testfrom", "testto", "testtores"});
|
||||
int aid = -1;
|
||||
{
|
||||
std::filesystem::create_directories("testfrom");
|
||||
for (int i = 0; i < 257; i++) {
|
||||
std::ofstream o(std::filesystem::path("testfrom") / ("f" + std::to_string(i)), std::ios::binary | std::ios::out | std::ios::trunc);
|
||||
for (int j = 0; j < i; j++) o.put(static_cast<char>(j % 256));
|
||||
}
|
||||
std::filesystem::create_directories("testfrom/testdir");
|
||||
|
||||
Config conf;
|
||||
conf.add("repo", "testto").add("from", "testfrom");
|
||||
|
||||
auto repo = std::make_unique<FileRepository>(conf);
|
||||
repo->init();
|
||||
|
||||
std::stringstream runnerout;
|
||||
Logger logger(1, runnerout);
|
||||
|
||||
CommandRun run;
|
||||
run.run(Context{&logger, repo.get()});
|
||||
|
||||
aid = repo->getObjects(Object::ObjectType::Archive).begin()->second;
|
||||
}
|
||||
{
|
||||
Config conf;
|
||||
conf.add("repo", "testto").add("aid", std::to_string(aid)).add("to", "testtores");
|
||||
|
||||
auto repo = std::make_unique<FileRepository>(conf);
|
||||
repo->open();
|
||||
std::stringstream runnerout;
|
||||
Logger logger(1, runnerout);
|
||||
|
||||
CommandRestore cmd;
|
||||
cmd.run(Context{&logger, repo.get()});
|
||||
}
|
||||
{
|
||||
try {
|
||||
EXPECT_EQ(std::filesystem::is_directory("testtores/testdir"), true);
|
||||
} catch (...) {
|
||||
std::cerr << "Empty directory doesn't exist!" << std::endl;
|
||||
throw;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 257; i++) {
|
||||
std::ifstream o(std::filesystem::path("testtores") / ("f" + std::to_string(i)), std::ios::binary | std::ios::in);
|
||||
try {
|
||||
EXPECT_EQ(o.is_open(), true);
|
||||
for (int j = 0; j < i; j++) {
|
||||
char c;
|
||||
EXPECT_EQ(o.get(c).operator bool(), true);
|
||||
EXPECT_EQ(static_cast<char>(j % 256), c);
|
||||
}
|
||||
} catch (...) {
|
||||
std::cerr << "Error comparing file " << i << std::endl;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(FullTest, SimpleWithIgnore) {
|
||||
Cleaner c({"testfrom", "testto", "testtores"});
|
||||
int aid = -1;
|
||||
{
|
||||
std::filesystem::create_directories("testfrom");
|
||||
for (int i = 0; i < 257; i++) {
|
||||
std::ofstream o(std::filesystem::path("testfrom") / ("f" + std::to_string(i)), std::ios::binary | std::ios::out | std::ios::trunc);
|
||||
for (int j = 0; j < i; j++) o.put(static_cast<char>(j % 256));
|
||||
}
|
||||
std::filesystem::create_directories("testfrom/testdir");
|
||||
std::filesystem::create_directories("testfrom/testdir2/testdir3");
|
||||
std::filesystem::create_directories("testfrom/testdir2/testdir4");
|
||||
{
|
||||
std::ofstream file("testfrom/testdir2/.ignore");
|
||||
file << "hello.txt";
|
||||
}
|
||||
{
|
||||
std::ofstream file("testfrom/testdir2/testdir3/.ignore");
|
||||
file << ".*\\.txt";
|
||||
}
|
||||
{
|
||||
std::ofstream file("testfrom/testdir2/hello.txt");
|
||||
file << "hello";
|
||||
}
|
||||
{
|
||||
std::ofstream file("testfrom/testdir2/testdir3/hello.txt");
|
||||
file << "hello2";
|
||||
}
|
||||
{
|
||||
std::ofstream file("testfrom/testdir2/testdir3/asdf.txt");
|
||||
file << "asdf1";
|
||||
}
|
||||
{
|
||||
std::ofstream file("testfrom/testdir2/testdir4/asdf.txt");
|
||||
file << "asdf2";
|
||||
}
|
||||
|
||||
Config conf;
|
||||
conf.add("repo", "testto").add("from", "testfrom");
|
||||
|
||||
auto repo = std::make_unique<FileRepository>(conf);
|
||||
repo->init();
|
||||
std::stringstream runnerout;
|
||||
Logger logger(1, runnerout);
|
||||
|
||||
CommandRun cmd;
|
||||
cmd.run(Context{&logger, repo.get()});
|
||||
aid = repo->getObjects(Object::ObjectType::Archive).begin()->second;
|
||||
}
|
||||
{
|
||||
Config conf;
|
||||
conf.add("repo", "testto").add("aid", std::to_string(aid)).add("to", "testtores");
|
||||
|
||||
auto repo = std::make_unique<FileRepository>(conf);
|
||||
repo->open();
|
||||
std::stringstream runnerout;
|
||||
Logger logger(1, runnerout);
|
||||
|
||||
CommandRestore cmd;
|
||||
cmd.run(Context{&logger, repo.get()});
|
||||
}
|
||||
{
|
||||
EXPECT_EQ(std::filesystem::is_directory("testtores/testdir"), true);
|
||||
|
||||
for (int i = 0; i < 257; i++) {
|
||||
std::ifstream o(std::filesystem::path("testtores") / ("f" + std::to_string(i)), std::ios::binary | std::ios::in);
|
||||
EXPECT_EQ(o.is_open(), true);
|
||||
for (int j = 0; j < i; j++) {
|
||||
char c;
|
||||
EXPECT_EQ(o.get(c).operator bool(), true);
|
||||
EXPECT_EQ(static_cast<char>(j % 256), c);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
std::ifstream file("testtores/testdir2/.ignore");
|
||||
std::string s;
|
||||
file >> s;
|
||||
EXPECT_EQ(s, "hello.txt");
|
||||
}
|
||||
{
|
||||
std::ifstream file("testtores/testdir2/testdir3/.ignore");
|
||||
std::string s;
|
||||
file >> s;
|
||||
EXPECT_EQ(s, ".*\\.txt");
|
||||
}
|
||||
{
|
||||
std::ifstream file("testtores/testdir2/hello.txt");
|
||||
EXPECT_EQ(!file, true);
|
||||
}
|
||||
{
|
||||
std::ifstream file("testtores/testdir2/testdir3/hello.txt");
|
||||
EXPECT_EQ(!file, true);
|
||||
}
|
||||
{
|
||||
std::ifstream file("testtores/testdir2/testdir3/asdf.txt");
|
||||
EXPECT_EQ(!file, true);
|
||||
}
|
||||
{
|
||||
std::ifstream file("testtores/testdir2/testdir4/asdf.txt");
|
||||
std::string s;
|
||||
file >> s;
|
||||
EXPECT_EQ(s, "asdf2");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(FullTest, SimpleWithCompress) {
|
||||
Cleaner c({"testfrom", "testto", "testtores"});
|
||||
int aid = -1;
|
||||
{
|
||||
std::filesystem::create_directories("testfrom");
|
||||
for (int i = 0; i < 257; i++) {
|
||||
std::ofstream o(std::filesystem::path("testfrom") / ("f" + std::to_string(i)), std::ios::binary | std::ios::out | std::ios::trunc);
|
||||
for (int j = 0; j < i; j++) o.put(static_cast<char>(j % 256));
|
||||
}
|
||||
std::filesystem::create_directories("testfrom/testdir");
|
||||
|
||||
Config conf;
|
||||
conf.add("repo", "testto").add("compression", "zlib").add("from", "testfrom");
|
||||
|
||||
auto repo = std::make_unique<FileRepository>(conf);
|
||||
repo->init();
|
||||
std::stringstream runnerout;
|
||||
Logger logger(1, runnerout);
|
||||
|
||||
CommandRun cmd;
|
||||
cmd.run(Context{&logger, repo.get()});
|
||||
aid = repo->getObjects(Object::ObjectType::Archive).begin()->second;
|
||||
}
|
||||
{
|
||||
Config conf;
|
||||
conf.add("repo", "testto").add("aid", std::to_string(aid)).add("to", "testtores");
|
||||
|
||||
auto repo = std::make_unique<FileRepository>(conf);
|
||||
repo->open();
|
||||
std::stringstream runnerout;
|
||||
Logger logger(1, runnerout);
|
||||
|
||||
CommandRestore cmd;
|
||||
cmd.run(Context{&logger, repo.get()});
|
||||
}
|
||||
{
|
||||
EXPECT_EQ(std::filesystem::is_directory("testtores/testdir"), true);
|
||||
|
||||
for (int i = 0; i < 257; i++) {
|
||||
std::ifstream o(std::filesystem::path("testtores") / ("f" + std::to_string(i)), std::ios::binary | std::ios::in);
|
||||
EXPECT_EQ(o.is_open(), true);
|
||||
for (int j = 0; j < i; j++) {
|
||||
char c;
|
||||
EXPECT_EQ(o.get(c).operator bool(), true);
|
||||
EXPECT_EQ(static_cast<char>(j % 256), c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(FullTest, SimpleWithCompEnd) {
|
||||
Cleaner c({"testfrom", "testto", "testtores"});
|
||||
int aid = -1;
|
||||
{
|
||||
std::filesystem::create_directories("testfrom");
|
||||
for (int i = 0; i < 257; i++) {
|
||||
std::ofstream o(std::filesystem::path("testfrom") / ("f" + std::to_string(i)), std::ios::binary | std::ios::out | std::ios::trunc);
|
||||
for (int j = 0; j < i; j++) o.put(static_cast<char>(j % 256));
|
||||
}
|
||||
std::filesystem::create_directories("testfrom/testdir");
|
||||
|
||||
Config conf;
|
||||
conf.add("repo", "testto").add("compression", "zlib").add("from", "testfrom").add("encryption", "aes").add("password", "testp").add("salt", "tests");
|
||||
|
||||
auto repo = std::make_unique<FileRepository>(conf);
|
||||
repo->init();
|
||||
|
||||
std::stringstream runnerout;
|
||||
Logger logger(1, runnerout);
|
||||
|
||||
CommandRun cmd;
|
||||
cmd.run(Context{&logger, repo.get()});
|
||||
aid = repo->getObjects(Object::ObjectType::Archive).begin()->second;
|
||||
}
|
||||
{
|
||||
Config conf;
|
||||
conf.add("repo", "testto");
|
||||
|
||||
auto repo = std::make_unique<FileRepository>(conf);
|
||||
|
||||
bool ok = true;
|
||||
try {
|
||||
EXPECT_EQ(repo->open(), false);
|
||||
ok = false;
|
||||
} catch (...) {}
|
||||
EXPECT_EQ(ok, true);
|
||||
}
|
||||
{
|
||||
Config conf;
|
||||
conf.add("repo", "testto").add("password", "testp").add("aid", std::to_string(aid)).add("to", "testtores");
|
||||
|
||||
auto repo = std::make_unique<FileRepository>(conf);
|
||||
repo->open();
|
||||
|
||||
std::stringstream runnerout;
|
||||
Logger logger(1, runnerout);
|
||||
|
||||
CommandRestore cmd;
|
||||
cmd.run(Context{&logger, repo.get()});
|
||||
}
|
||||
{
|
||||
EXPECT_EQ(std::filesystem::is_directory("testtores/testdir"), true);
|
||||
|
||||
for (int i = 0; i < 257; i++) {
|
||||
std::ifstream o(std::filesystem::path("testtores") / ("f" + std::to_string(i)), std::ios::binary | std::ios::in);
|
||||
EXPECT_EQ(o.is_open(), true);
|
||||
for (int j = 0; j < i; j++) {
|
||||
char c;
|
||||
EXPECT_EQ(o.get(c).operator bool(), true);
|
||||
EXPECT_EQ(static_cast<char>(j % 256), c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(FullTest, Fuzz) {
|
||||
GTEST_SKIP();
|
||||
srand(time(nullptr));
|
||||
std::vector<Config> confs;
|
||||
Config conf;
|
||||
conf.add("repo", "testto").add("compression", "none").add("from", "testfrom").add("encryption", "none").add("password", "testp").add("salt", "tests").add("progress", "none");
|
||||
confs.emplace_back(conf);
|
||||
conf = Config();
|
||||
conf.add("repo", "testto").add("compression", "zlib").add("from", "testfrom").add("encryption", "none").add("password", "testp").add("salt", "tests").add("progress", "none");
|
||||
confs.emplace_back(conf);
|
||||
conf = Config();
|
||||
conf.add("repo", "testto").add("compression", "none").add("from", "testfrom").add("encryption", "zlib").add("password", "testp").add("salt", "tests").add("progress", "none");
|
||||
confs.emplace_back(conf);
|
||||
conf = Config();
|
||||
conf.add("repo", "testto").add("compression", "zlib").add("from", "testfrom").add("encryption", "aes").add("password", "testp").add("salt", "tests").add("progress", "none");
|
||||
confs.emplace_back(conf);
|
||||
|
||||
for (auto const &conf: confs) {
|
||||
for (uint8_t filetobreak = 1; filetobreak <= 15; filetobreak++) {
|
||||
std::cout << static_cast<int>(filetobreak) << " / 15 tests done" << std::endl;
|
||||
for (uint8_t cutoff = 1; cutoff < 20; cutoff++) {
|
||||
Cleaner c({"testfrom", "testto", "testtores"});
|
||||
|
||||
int aid = -1;
|
||||
{
|
||||
std::filesystem::create_directories("testfrom");
|
||||
for (int i = 0; i < 2; i++) {
|
||||
std::ofstream o(std::filesystem::path("testfrom") / ("f" + std::to_string(i)), std::ios::binary | std::ios::out | std::ios::trunc);
|
||||
for (int j = 0; j < i; j++) o.put(j % 2);
|
||||
}
|
||||
|
||||
|
||||
auto repo = std::make_unique<FileRepository>(conf);
|
||||
repo->init();
|
||||
|
||||
std::stringstream runnerout;
|
||||
Logger logger(1, runnerout);
|
||||
|
||||
CommandRun cmd;
|
||||
cmd.run(Context{&logger, repo.get()});
|
||||
aid = repo->getObjects(Object::ObjectType::Archive).begin()->second;
|
||||
}
|
||||
|
||||
{
|
||||
if (filetobreak & 0b00000001) {
|
||||
for (int i = 0; i < cutoff; i++)
|
||||
randomChange("testto/1");
|
||||
if (cutoff > 5)
|
||||
std::filesystem::resize_file("testto/1", std::filesystem::file_size("testto/1") - cutoff);
|
||||
}
|
||||
if (filetobreak & 0b00000010) {
|
||||
for (int i = 0; i < cutoff; i++)
|
||||
randomChange("testto/index");
|
||||
if (cutoff > 5)
|
||||
std::filesystem::resize_file("testto/index", std::filesystem::file_size("testto/index") - cutoff);
|
||||
}
|
||||
if (filetobreak & 0b00000100) {
|
||||
for (int i = 0; i < cutoff; i++)
|
||||
randomChange("testto/offsets");
|
||||
if (cutoff > 5)
|
||||
std::filesystem::resize_file("testto/offsets", std::filesystem::file_size("testto/offsets") - cutoff);
|
||||
}
|
||||
if (filetobreak & 0b00001000) {
|
||||
for (int i = 0; i < cutoff; i++)
|
||||
randomChange("testto/info");
|
||||
if (cutoff > 5)
|
||||
std::filesystem::resize_file("testto/info", std::filesystem::file_size("testto/info") - cutoff);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
bool ok = true;
|
||||
try {
|
||||
Config confr = conf;
|
||||
confr.add("aid", std::to_string(aid)).add("to", "testtores");
|
||||
|
||||
auto repo = std::make_unique<FileRepository>(confr);
|
||||
repo->open();
|
||||
|
||||
std::stringstream runnerout;
|
||||
Logger logger(1, runnerout);
|
||||
|
||||
CommandRestore cmd;
|
||||
cmd.run(Context{&logger, repo.get()});
|
||||
auto outstr = runnerout.str();
|
||||
if (outstr.find("Error") == std::string::npos)
|
||||
ok = false;
|
||||
} catch (...) {}
|
||||
EXPECT_EQ(ok, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
24
tests/repo/CMakeLists.txt
Normal file
24
tests/repo/CMakeLists.txt
Normal file
@@ -0,0 +1,24 @@
|
||||
cmake_minimum_required(VERSION 3.22)
|
||||
|
||||
add_executable(
|
||||
FileRepositoryTest
|
||||
srcs/FileRepositoryTest.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(
|
||||
FileRepositoryTest PRIVATE
|
||||
GTest::gtest_main commands utils testUtils repo
|
||||
)
|
||||
|
||||
add_executable(
|
||||
ChunkTest
|
||||
srcs/ChunkTest.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(
|
||||
ChunkTest PRIVATE
|
||||
GTest::gtest_main commands utils testUtils repo
|
||||
)
|
||||
|
||||
gtest_discover_tests(ChunkTest)
|
||||
gtest_discover_tests(FileRepositoryTest)
|
||||
@@ -1,113 +0,0 @@
|
||||
//
|
||||
// Created by Stepan Usatiuk on 14.04.2023.
|
||||
//
|
||||
|
||||
#include "ChunkTest.h"
|
||||
#include "../../src/repo/Serialize.h"
|
||||
#include "../utils/Cleaner.h"
|
||||
|
||||
std::unique_ptr<TestGroup> ChunkTest::operator()() {
|
||||
auto tg = std::make_unique<TestGroup>("Chunk tests");
|
||||
|
||||
tg->addTest(std::make_unique<Test>("De/serialize test", std::function<bool()>([]() {
|
||||
std::vector<char> s1, s2;
|
||||
{
|
||||
std::vector<char> data1{'a', 'b', 'c', 'e'};
|
||||
Chunk o1(666, {0}, data1);
|
||||
std::vector<char> data2{'q', 'w', 'e', 'r', 'b'};
|
||||
Chunk o2(777, {1}, data2);
|
||||
|
||||
s1 = Serialize::serialize(o1);
|
||||
s2 = Serialize::serialize(o2);
|
||||
}
|
||||
{
|
||||
auto s1b = s1.cbegin();
|
||||
auto s2b = s2.cbegin();
|
||||
Chunk o1(s1b, s1.cend()), o2(s2b, s2.cend());
|
||||
|
||||
std::vector<char> data1{'a', 'b', 'c', 'e'};
|
||||
Chunk o1e(666, {0}, data1);
|
||||
std::vector<char> data2{'q', 'w', 'e', 'r', 'b'};
|
||||
Chunk o2e(777, {1}, data2);
|
||||
|
||||
HelpfulAssert<Object::idType>()(o1.id, o1e.id);
|
||||
HelpfulAssert<Object::idType>()(o2.id, o2e.id);
|
||||
HelpfulAssert<int>()((int) o1.type, (int) o1e.type);
|
||||
HelpfulAssert<int>()((int) o2.type, (int) o2e.type);
|
||||
|
||||
HelpfulAssert<size_t>()(o1.data.size(), o1e.data.size());
|
||||
HelpfulAssert<size_t>()(o2.data.size(), o2e.data.size());
|
||||
for (int i = 0; i < o1.data.size(); i++) {
|
||||
HelpfulAssert<char>()(o1.data[i], o1e.data[i]);
|
||||
}
|
||||
for (int i = 0; i < o2.data.size(); i++) {
|
||||
HelpfulAssert<char>()(o2.data[i], o2e.data[i]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < o1.md5.size(); i++) {
|
||||
HelpfulAssert<char>()(o1.md5[i], o1e.md5[i]);
|
||||
}
|
||||
for (int i = 0; i < o2.md5.size(); i++) {
|
||||
HelpfulAssert<char>()(o2.md5[i], o2e.md5[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
})));
|
||||
|
||||
tg->addTest(std::make_unique<Test>("Garbage throw test", std::function<bool()>([]() {
|
||||
std::vector<char> e{'a', 'b'};
|
||||
auto eb = e.cbegin();
|
||||
try {
|
||||
Chunk o1(eb, e.cend());
|
||||
} catch (...) {
|
||||
return true;
|
||||
}
|
||||
throw Exception("Object constructed with garbage data!");
|
||||
})));
|
||||
tg->addTest(std::make_unique<Test>("Garbage throw test2", std::function<bool()>([]() {
|
||||
std::vector<char> e{'s', 'e', 'm', 'b', 'a', 'a'};
|
||||
auto eb = e.cbegin();
|
||||
try {
|
||||
Chunk o1(eb, e.cend());
|
||||
} catch (...) {
|
||||
return true;
|
||||
}
|
||||
throw Exception("Object constructed with garbage data!");
|
||||
})));
|
||||
tg->addTest(std::make_unique<Test>("Garbage throw test3", std::function<bool()>([]() {
|
||||
std::vector<char> s1, s2;
|
||||
{
|
||||
std::vector<char> data1{'a', 'b', 'c', 'e'};
|
||||
Chunk o1(666, {0}, data1);
|
||||
std::vector<char> data2{'q', 'w', 'e', 'r', 'b'};
|
||||
Chunk o2(777, {1}, data2);
|
||||
|
||||
s1 = Serialize::serialize(o1);
|
||||
s2 = Serialize::serialize(o2);
|
||||
}
|
||||
{
|
||||
s1.resize(s1.size() - 1);
|
||||
s2.resize(s1.size() - 2);
|
||||
bool fail = false;
|
||||
|
||||
try {
|
||||
Chunk o1 = Serialize::deserialize<Chunk>(s1);
|
||||
fail = true;
|
||||
} catch (...) {
|
||||
}
|
||||
|
||||
try {
|
||||
Chunk o2 = Serialize::deserialize<Chunk>(s2);
|
||||
fail = true;
|
||||
} catch (...) {
|
||||
}
|
||||
|
||||
if (fail)
|
||||
throw Exception("Object constructed with garbage data!");
|
||||
}
|
||||
return true;
|
||||
})));
|
||||
|
||||
return tg;
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
//
|
||||
// Created by Stepan Usatiuk on 14.04.2023.
|
||||
//
|
||||
|
||||
#ifndef SEMBACKUP_CHUNKTEST_H
|
||||
#define SEMBACKUP_CHUNKTEST_H
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
#include "../../src/repo/objects/Chunk.h"
|
||||
#include "../utils/TestGroupGenerator.h"
|
||||
|
||||
class ChunkTest : public TestGroupGenerator {
|
||||
public:
|
||||
std::unique_ptr<TestGroup> operator()() override;
|
||||
};
|
||||
|
||||
|
||||
#endif//SEMBACKUP_CHUNKTEST_H
|
||||
@@ -1,301 +0,0 @@
|
||||
//
|
||||
// Created by Stepan Usatiuk on 14.04.2023.
|
||||
//
|
||||
|
||||
#include "FileRepositoryTest.h"
|
||||
|
||||
std::unique_ptr<TestGroup> FileRepositoryTest::operator()() {
|
||||
auto tg = std::make_unique<TestGroup>("FileRepository tests");
|
||||
|
||||
tg->addTest(std::make_unique<Test>("De/serialize test", std::function<bool()>([]() {
|
||||
Cleaner c({"testrepo"});
|
||||
|
||||
{
|
||||
Config conf;
|
||||
conf.add("repo", "testrepo");
|
||||
FileRepository repo(conf);
|
||||
repo.init();
|
||||
std::vector<char>
|
||||
data1{'a', 'b', 'c', 'e'};
|
||||
|
||||
std::string o1k(16, '\0');
|
||||
std::string o2k(16, '\0');
|
||||
o2k[0] = 1;
|
||||
o2k[1] = 2;
|
||||
|
||||
Chunk o1(666, o1k, data1);
|
||||
std::vector<char> data2{'q', 'w', 'e', 'r', static_cast<char>(255)};
|
||||
Chunk o2(777, o2k, data2);
|
||||
|
||||
repo.putObject(o1);
|
||||
repo.putObject(o2);
|
||||
|
||||
|
||||
HelpfulAssert<Object::idType>()(repo.getObjectId(Object::ObjectType::Chunk, o1k), 666);
|
||||
HelpfulAssert<Object::idType>()(repo.getObjectId(Object::ObjectType::Chunk, o2k), 777);
|
||||
}
|
||||
{
|
||||
Config conf;
|
||||
conf.add("repo", "testrepo");
|
||||
FileRepository repo(conf);
|
||||
repo.open();
|
||||
|
||||
std::string o1k(16, '\0');
|
||||
std::string o2k(16, '\0');
|
||||
o2k[0] = 1;
|
||||
o2k[1] = 2;
|
||||
HelpfulAssert<Object::idType>()(repo.getObjectId(Object::ObjectType::Chunk, o1k), 666);
|
||||
HelpfulAssert<Object::idType>()(repo.getObjectId(Object::ObjectType::Chunk, o2k), 777);
|
||||
|
||||
auto o1o = repo.getObject(666);
|
||||
auto o2o = repo.getObject(777);
|
||||
|
||||
auto o1ob = o1o.cbegin();
|
||||
auto o2ob = o2o.cbegin();
|
||||
|
||||
Chunk o1(o1ob, o1o.cend()), o2(o2ob, o2o.cend());
|
||||
|
||||
std::vector<char> data1{'a', 'b', 'c', 'e'};
|
||||
Chunk o1e(666, o1k, data1);
|
||||
std::vector<char> data2{'q', 'w', 'e', 'r', static_cast<char>(255)};
|
||||
Chunk o2e(777, o2k, data2);
|
||||
|
||||
HelpfulAssert<Object::idType>()(o1.id, o1e.id);
|
||||
HelpfulAssert<Object::idType>()(o2.id, o2e.id);
|
||||
HelpfulAssert<int>()((int) o1.type, (int) o1e.type);
|
||||
HelpfulAssert<int>()((int) o2.type, (int) o2e.type);
|
||||
auto o1d = o1.data;
|
||||
auto o1ed = o1e.data;
|
||||
auto o2d = o2.data;
|
||||
auto o2ed = o2e.data;
|
||||
HelpfulAssert<size_t>()(o1.data.size(), o1e.data.size());
|
||||
HelpfulAssert<size_t>()(o2.data.size(), o2e.data.size());
|
||||
for (int i = 0; i < o1.data.size(); i++) {
|
||||
HelpfulAssert<char>()(o1.data[i], o1e.data[i]);
|
||||
}
|
||||
for (int i = 0; i < o2.data.size(); i++) {
|
||||
HelpfulAssert<char>()(o2.data[i], o2e.data[i]);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
})));
|
||||
|
||||
|
||||
tg->addTest(std::make_unique<Test>("De/serialize with sync/read filter", std::function<bool()>([]() {
|
||||
Cleaner c({"testrepo"});
|
||||
|
||||
{
|
||||
Config conf;
|
||||
conf.add("repo", "testrepo")
|
||||
.add("compression", "shiftC")
|
||||
.add("compression-level", "1")
|
||||
.add("encryption", "shiftE")
|
||||
.add("password", "\a")
|
||||
.add("salt", "a");
|
||||
|
||||
FileRepository repo(conf);
|
||||
repo.init();
|
||||
std::string o1k(16, '\0');
|
||||
std::string o2k(16, '\0');
|
||||
o2k[0] = 1;
|
||||
o2k[1] = 2;
|
||||
std::vector<char>
|
||||
data1{'a', 'b', 'c', 'e'};
|
||||
Chunk o1(666, o1k, data1);
|
||||
std::vector<char> data2{'q', 'w', 'e', 'r', 'b'};
|
||||
Chunk o2(777, o2k, data2);
|
||||
|
||||
repo.putObject(o1);
|
||||
repo.putObject(o2);
|
||||
|
||||
|
||||
HelpfulAssert<Object::idType>()(repo.getObjectId(Object::ObjectType::Chunk, o1k), 666);
|
||||
HelpfulAssert<Object::idType>()(repo.getObjectId(Object::ObjectType::Chunk, o2k), 777);
|
||||
}
|
||||
{
|
||||
Config conf;
|
||||
conf.add("repo", "testrepo")
|
||||
.add("compression", "shiftC")
|
||||
.add("compression-level", "1")
|
||||
.add("encryption", "shiftE")
|
||||
.add("password", "\b")
|
||||
.add("salt", "a");
|
||||
|
||||
FileRepository repo(conf);
|
||||
|
||||
bool err = false;
|
||||
|
||||
try {
|
||||
repo.open();
|
||||
err = true;
|
||||
} catch (...) {}
|
||||
|
||||
|
||||
try {
|
||||
auto o1o = repo.getObject(666);
|
||||
auto o1ob = o1o.cbegin();
|
||||
|
||||
Chunk o1(o1ob, o1o.cend());
|
||||
err = true;
|
||||
} catch (...) {}
|
||||
|
||||
try {
|
||||
auto o2o = repo.getObject(777);
|
||||
auto o2ob = o2o.cbegin();
|
||||
|
||||
Chunk o2(o2ob, o2o.cend());
|
||||
err = true;
|
||||
} catch (...) {}
|
||||
|
||||
if (err)
|
||||
throw Exception("Object constructed with garbage data!");
|
||||
}
|
||||
{
|
||||
Config conf;
|
||||
conf.add("repo", "testrepo")
|
||||
.add("compression", "shiftC")
|
||||
.add("compression-level", "1")
|
||||
.add("encryption", "shiftE")
|
||||
.add("password", "\a")
|
||||
.add("salt", "a");
|
||||
|
||||
FileRepository repo(conf);
|
||||
repo.open();
|
||||
|
||||
|
||||
std::string o1k(16, '\0');
|
||||
std::string o2k(16, '\0');
|
||||
o2k[0] = 1;
|
||||
o2k[1] = 2;
|
||||
HelpfulAssert<Object::idType>()(repo.getObjectId(Object::ObjectType::Chunk, o1k), 666);
|
||||
HelpfulAssert<Object::idType>()(repo.getObjectId(Object::ObjectType::Chunk, o2k), 777);
|
||||
|
||||
auto o1o = repo.getObject(666);
|
||||
auto o2o = repo.getObject(777);
|
||||
|
||||
auto o1ob = o1o.cbegin();
|
||||
auto o2ob = o2o.cbegin();
|
||||
|
||||
Chunk o1(o1ob, o1o.cend()), o2(o2ob, o2o.cend());
|
||||
|
||||
std::vector<char> data1{'a', 'b', 'c', 'e'};
|
||||
Chunk o1e(666, o1k, data1);
|
||||
std::vector<char> data2{'q', 'w', 'e', 'r', 'b'};
|
||||
Chunk o2e(777, o2k, data2);
|
||||
|
||||
HelpfulAssert<Object::idType>()(o1.id, o1e.id);
|
||||
HelpfulAssert<Object::idType>()(o2.id, o2e.id);
|
||||
HelpfulAssert<int>()((int) o1.type, (int) o1e.type);
|
||||
HelpfulAssert<int>()((int) o2.type, (int) o2e.type);
|
||||
auto o1d = o1.data;
|
||||
auto o1ed = o1e.data;
|
||||
auto o2d = o2.data;
|
||||
auto o2ed = o2e.data;
|
||||
HelpfulAssert<size_t>()(o1.data.size(), o1e.data.size());
|
||||
HelpfulAssert<size_t>()(o2.data.size(), o2e.data.size());
|
||||
for (int i = 0; i < o1.data.size(); i++) {
|
||||
HelpfulAssert<char>()(o1.data[i], o1e.data[i]);
|
||||
}
|
||||
for (int i = 0; i < o2.data.size(); i++) {
|
||||
HelpfulAssert<char>()(o2.data[i], o2e.data[i]);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
})));
|
||||
|
||||
tg->addTest(std::make_unique<Test>("IDs test (disabled)", std::function<bool()>([]() {
|
||||
return true;
|
||||
Cleaner c({"testrepo"});
|
||||
{
|
||||
Config conf;
|
||||
conf.add("repo", "testrepo");
|
||||
FileRepository repo(conf);
|
||||
repo.init();
|
||||
|
||||
std::string o1k(16, '\0');
|
||||
std::string o2k(16, '\0');
|
||||
o2k[0] = 1;
|
||||
|
||||
std::vector<char>
|
||||
data1{'a', 'b', 'c', 'e'};
|
||||
Chunk o1(repo.getId(), o1k, data1);
|
||||
std::vector<char> data2{'q', 'w', 'e', 'r', 'b'};
|
||||
Chunk o2(repo.getId(), o2k, data2);
|
||||
|
||||
HelpfulAssert<int>()(o1.id, 1);
|
||||
HelpfulAssert<int>()(o2.id, 2);
|
||||
|
||||
repo.putObject(o1);
|
||||
repo.putObject(o2);
|
||||
|
||||
|
||||
HelpfulAssert<Object::idType>()(repo.getObjectId(Object::ObjectType::Chunk, o1k), 1);
|
||||
HelpfulAssert<Object::idType>()(repo.getObjectId(Object::ObjectType::Chunk, o2k), 2);
|
||||
}
|
||||
{
|
||||
Config conf;
|
||||
conf.add("repo", "testrepo");
|
||||
FileRepository repo(conf);
|
||||
repo.open();
|
||||
auto o1o = repo.getObject(1);
|
||||
auto o2o = repo.getObject(2);
|
||||
|
||||
auto o1ob = o1o.cbegin();
|
||||
auto o2ob = o2o.cbegin();
|
||||
|
||||
Chunk o1(o1ob, o1o.cend()), o2(o2ob, o2o.cend());
|
||||
std::string o1k(16, '\0');
|
||||
std::string o2k(16, '\0');
|
||||
o2k[0] = 1;
|
||||
std::vector<char> data1{'a', 'b', 'c', 'e'};
|
||||
Chunk o1e(1, o1k, data1);
|
||||
std::vector<char> data2{'q', 'w', 'e', 'r', 'b'};
|
||||
Chunk o2e(2, o2k, data2);
|
||||
|
||||
HelpfulAssert<Object::idType>()(o1.id, o1e.id);
|
||||
HelpfulAssert<Object::idType>()(o2.id, o2e.id);
|
||||
HelpfulAssert<int>()((int) o1.type, (int) o1e.type);
|
||||
HelpfulAssert<int>()((int) o2.type, (int) o2e.type);
|
||||
auto o1d = o1.data;
|
||||
auto o1ed = o1e.data;
|
||||
auto o2d = o2.data;
|
||||
auto o2ed = o2e.data;
|
||||
HelpfulAssert<size_t>()(o1.data.size(), o1e.data.size());
|
||||
HelpfulAssert<size_t>()(o2.data.size(), o2e.data.size());
|
||||
for (int i = 0; i < o1.data.size(); i++) {
|
||||
HelpfulAssert<char>()(o1.data[i], o1e.data[i]);
|
||||
}
|
||||
for (int i = 0; i < o2.data.size(); i++) {
|
||||
HelpfulAssert<char>()(o2.data[i], o2e.data[i]);
|
||||
}
|
||||
|
||||
|
||||
HelpfulAssert<Object::idType>()(repo.getObjectId(Object::ObjectType::Chunk, o1k), 1);
|
||||
HelpfulAssert<Object::idType>()(repo.getObjectId(Object::ObjectType::Chunk, o2k), 2);
|
||||
|
||||
|
||||
repo.deleteObject(o1);
|
||||
}
|
||||
{
|
||||
Config conf;
|
||||
conf.add("repo", "testrepo");
|
||||
FileRepository repo(conf);
|
||||
repo.open();
|
||||
|
||||
std::string o2k(16, '\0');
|
||||
o2k[0] = 1;
|
||||
HelpfulAssert<Object::idType>()(repo.getObjectId(Object::ObjectType::Chunk, o2k), 2);
|
||||
|
||||
auto id = repo.getId();
|
||||
HelpfulAssert<int>()(id, 1);
|
||||
std::vector<char>
|
||||
data1{'a', 'b', 'c', 'e'};
|
||||
Chunk o1(id, o2k, data1);
|
||||
HelpfulAssert<int>()(repo.getId(), 3);
|
||||
}
|
||||
return true;
|
||||
})));
|
||||
|
||||
|
||||
return tg;
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
//
|
||||
// Created by Stepan Usatiuk on 14.04.2023.
|
||||
//
|
||||
|
||||
#ifndef SEMBACKUP_FILEREPOSITORYTEST_H
|
||||
#define SEMBACKUP_FILEREPOSITORYTEST_H
|
||||
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
#include "../../src/repo/FileRepository.h"
|
||||
#include "../../src/repo/objects/Chunk.h"
|
||||
#include "../utils/Cleaner.h"
|
||||
#include "../utils/TestGroupGenerator.h"
|
||||
|
||||
class FileRepositoryTest : public TestGroupGenerator {
|
||||
public:
|
||||
std::unique_ptr<TestGroup> operator()() override;
|
||||
};
|
||||
|
||||
|
||||
#endif//SEMBACKUP_FILEREPOSITORYTEST_H
|
||||
108
tests/repo/srcs/ChunkTest.cpp
Normal file
108
tests/repo/srcs/ChunkTest.cpp
Normal file
@@ -0,0 +1,108 @@
|
||||
//
|
||||
// Created by Stepan Usatiuk on 14.04.2023.
|
||||
//
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "Cleaner.h"
|
||||
#include "Serialize.h"
|
||||
#include "objects/Chunk.h"
|
||||
|
||||
TEST(Chunk, Deserialize) {
|
||||
std::vector<char> s1, s2;
|
||||
{
|
||||
std::vector<char> data1{'a', 'b', 'c', 'e'};
|
||||
Chunk o1(666, {0}, data1);
|
||||
std::vector<char> data2{'q', 'w', 'e', 'r', 'b'};
|
||||
Chunk o2(777, {1}, data2);
|
||||
|
||||
s1 = Serialize::serialize(o1);
|
||||
s2 = Serialize::serialize(o2);
|
||||
}
|
||||
{
|
||||
auto s1b = s1.cbegin();
|
||||
auto s2b = s2.cbegin();
|
||||
Chunk o1(s1b, s1.cend()), o2(s2b, s2.cend());
|
||||
|
||||
std::vector<char> data1{'a', 'b', 'c', 'e'};
|
||||
Chunk o1e(666, {0}, data1);
|
||||
std::vector<char> data2{'q', 'w', 'e', 'r', 'b'};
|
||||
Chunk o2e(777, {1}, data2);
|
||||
|
||||
EXPECT_EQ(o1.id, o1e.id);
|
||||
EXPECT_EQ(o2.id, o2e.id);
|
||||
EXPECT_EQ((int) o1.type, (int) o1e.type);
|
||||
EXPECT_EQ((int) o2.type, (int) o2e.type);
|
||||
|
||||
EXPECT_EQ(o1.data.size(), o1e.data.size());
|
||||
EXPECT_EQ(o2.data.size(), o2e.data.size());
|
||||
for (int i = 0; i < o1.data.size(); i++) {
|
||||
EXPECT_EQ(o1.data[i], o1e.data[i]);
|
||||
}
|
||||
for (int i = 0; i < o2.data.size(); i++) {
|
||||
EXPECT_EQ(o2.data[i], o2e.data[i]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < o1.md5.size(); i++) {
|
||||
EXPECT_EQ(o1.md5[i], o1e.md5[i]);
|
||||
}
|
||||
for (int i = 0; i < o2.md5.size(); i++) {
|
||||
EXPECT_EQ(o2.md5[i], o2e.md5[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Chunk, Garbage) {
|
||||
std::vector<char> e{'a', 'b'};
|
||||
auto eb = e.cbegin();
|
||||
try {
|
||||
Chunk o1(eb, e.cend());
|
||||
} catch (...) {
|
||||
return;
|
||||
}
|
||||
FAIL() << "Object constructed with garbage data!";
|
||||
}
|
||||
|
||||
TEST(Chunk, Garbage2) {
|
||||
std::vector<char> e{'s', 'e', 'm', 'b', 'a', 'a'};
|
||||
auto eb = e.cbegin();
|
||||
try {
|
||||
Chunk o1(eb, e.cend());
|
||||
} catch (...) {
|
||||
return;
|
||||
}
|
||||
FAIL() << "Object constructed with garbage data!";
|
||||
}
|
||||
|
||||
TEST(Chunk, Garbage3) {
|
||||
std::vector<char> s1, s2;
|
||||
{
|
||||
std::vector<char> data1{'a', 'b', 'c', 'e'};
|
||||
Chunk o1(666, {0}, data1);
|
||||
std::vector<char> data2{'q', 'w', 'e', 'r', 'b'};
|
||||
Chunk o2(777, {1}, data2);
|
||||
|
||||
s1 = Serialize::serialize(o1);
|
||||
s2 = Serialize::serialize(o2);
|
||||
}
|
||||
{
|
||||
s1.resize(s1.size() - 1);
|
||||
s2.resize(s1.size() - 2);
|
||||
bool fail = false;
|
||||
|
||||
try {
|
||||
Chunk o1 = Serialize::deserialize<Chunk>(s1);
|
||||
fail = true;
|
||||
} catch (...) {
|
||||
}
|
||||
|
||||
try {
|
||||
Chunk o2 = Serialize::deserialize<Chunk>(s2);
|
||||
fail = true;
|
||||
} catch (...) {
|
||||
}
|
||||
|
||||
if (fail)
|
||||
FAIL() << "Object constructed with garbage data!";
|
||||
}
|
||||
}
|
||||
295
tests/repo/srcs/FileRepositoryTest.cpp
Normal file
295
tests/repo/srcs/FileRepositoryTest.cpp
Normal file
@@ -0,0 +1,295 @@
|
||||
//
|
||||
// Created by Stepan Usatiuk on 14.04.2023.
|
||||
//
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "Cleaner.h"
|
||||
#include "Exception.h"
|
||||
#include "FileRepository.h"
|
||||
#include "objects/Chunk.h"
|
||||
|
||||
TEST(FileRepository, Deserialize) {
|
||||
Cleaner c({"testrepo"});
|
||||
|
||||
{
|
||||
Config conf;
|
||||
conf.add("repo", "testrepo");
|
||||
FileRepository repo(conf);
|
||||
repo.init();
|
||||
std::vector<char>
|
||||
data1{'a', 'b', 'c', 'e'};
|
||||
|
||||
std::string o1k(16, '\0');
|
||||
std::string o2k(16, '\0');
|
||||
o2k[0] = 1;
|
||||
o2k[1] = 2;
|
||||
|
||||
Chunk o1(666, o1k, data1);
|
||||
std::vector<char> data2{'q', 'w', 'e', 'r', static_cast<char>(255)};
|
||||
Chunk o2(777, o2k, data2);
|
||||
|
||||
repo.putObject(o1);
|
||||
repo.putObject(o2);
|
||||
|
||||
|
||||
EXPECT_EQ(repo.getObjectId(Object::ObjectType::Chunk, o1k), 666);
|
||||
EXPECT_EQ(repo.getObjectId(Object::ObjectType::Chunk, o2k), 777);
|
||||
}
|
||||
{
|
||||
Config conf;
|
||||
conf.add("repo", "testrepo");
|
||||
FileRepository repo(conf);
|
||||
repo.open();
|
||||
|
||||
std::string o1k(16, '\0');
|
||||
std::string o2k(16, '\0');
|
||||
o2k[0] = 1;
|
||||
o2k[1] = 2;
|
||||
EXPECT_EQ(repo.getObjectId(Object::ObjectType::Chunk, o1k), 666);
|
||||
EXPECT_EQ(repo.getObjectId(Object::ObjectType::Chunk, o2k), 777);
|
||||
|
||||
auto o1o = repo.getObject(666);
|
||||
auto o2o = repo.getObject(777);
|
||||
|
||||
auto o1ob = o1o.cbegin();
|
||||
auto o2ob = o2o.cbegin();
|
||||
|
||||
Chunk o1(o1ob, o1o.cend()), o2(o2ob, o2o.cend());
|
||||
|
||||
std::vector<char> data1{'a', 'b', 'c', 'e'};
|
||||
Chunk o1e(666, o1k, data1);
|
||||
std::vector<char> data2{'q', 'w', 'e', 'r', static_cast<char>(255)};
|
||||
Chunk o2e(777, o2k, data2);
|
||||
|
||||
EXPECT_EQ(o1.id, o1e.id);
|
||||
EXPECT_EQ(o2.id, o2e.id);
|
||||
EXPECT_EQ((int) o1.type, (int) o1e.type);
|
||||
EXPECT_EQ((int) o2.type, (int) o2e.type);
|
||||
auto o1d = o1.data;
|
||||
auto o1ed = o1e.data;
|
||||
auto o2d = o2.data;
|
||||
auto o2ed = o2e.data;
|
||||
EXPECT_EQ(o1.data.size(), o1e.data.size());
|
||||
EXPECT_EQ(o2.data.size(), o2e.data.size());
|
||||
for (int i = 0; i < o1.data.size(); i++) {
|
||||
EXPECT_EQ(o1.data[i], o1e.data[i]);
|
||||
}
|
||||
for (int i = 0; i < o2.data.size(); i++) {
|
||||
EXPECT_EQ(o2.data[i], o2e.data[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(FileRepository, Filters) {
|
||||
Cleaner c({"testrepo"});
|
||||
|
||||
{
|
||||
Config conf;
|
||||
conf.add("repo", "testrepo")
|
||||
.add("compression", "shiftC")
|
||||
.add("compression-level", "1")
|
||||
.add("encryption", "shiftE")
|
||||
.add("password", "\a")
|
||||
.add("salt", "a");
|
||||
|
||||
FileRepository repo(conf);
|
||||
repo.init();
|
||||
std::string o1k(16, '\0');
|
||||
std::string o2k(16, '\0');
|
||||
o2k[0] = 1;
|
||||
o2k[1] = 2;
|
||||
std::vector<char>
|
||||
data1{'a', 'b', 'c', 'e'};
|
||||
Chunk o1(666, o1k, data1);
|
||||
std::vector<char> data2{'q', 'w', 'e', 'r', 'b'};
|
||||
Chunk o2(777, o2k, data2);
|
||||
|
||||
repo.putObject(o1);
|
||||
repo.putObject(o2);
|
||||
|
||||
|
||||
EXPECT_EQ(repo.getObjectId(Object::ObjectType::Chunk, o1k), 666);
|
||||
EXPECT_EQ(repo.getObjectId(Object::ObjectType::Chunk, o2k), 777);
|
||||
}
|
||||
{
|
||||
Config conf;
|
||||
conf.add("repo", "testrepo")
|
||||
.add("compression", "shiftC")
|
||||
.add("compression-level", "1")
|
||||
.add("encryption", "shiftE")
|
||||
.add("password", "\b")
|
||||
.add("salt", "a");
|
||||
|
||||
FileRepository repo(conf);
|
||||
|
||||
bool err = false;
|
||||
|
||||
try {
|
||||
repo.open();
|
||||
err = true;
|
||||
} catch (...) {}
|
||||
|
||||
|
||||
try {
|
||||
auto o1o = repo.getObject(666);
|
||||
auto o1ob = o1o.cbegin();
|
||||
|
||||
Chunk o1(o1ob, o1o.cend());
|
||||
err = true;
|
||||
} catch (...) {}
|
||||
|
||||
try {
|
||||
auto o2o = repo.getObject(777);
|
||||
auto o2ob = o2o.cbegin();
|
||||
|
||||
Chunk o2(o2ob, o2o.cend());
|
||||
err = true;
|
||||
} catch (...) {}
|
||||
|
||||
if (err)
|
||||
throw Exception("Object constructed with garbage data!");
|
||||
}
|
||||
{
|
||||
Config conf;
|
||||
conf.add("repo", "testrepo")
|
||||
.add("compression", "shiftC")
|
||||
.add("compression-level", "1")
|
||||
.add("encryption", "shiftE")
|
||||
.add("password", "\a")
|
||||
.add("salt", "a");
|
||||
|
||||
FileRepository repo(conf);
|
||||
repo.open();
|
||||
|
||||
|
||||
std::string o1k(16, '\0');
|
||||
std::string o2k(16, '\0');
|
||||
o2k[0] = 1;
|
||||
o2k[1] = 2;
|
||||
EXPECT_EQ(repo.getObjectId(Object::ObjectType::Chunk, o1k), 666);
|
||||
EXPECT_EQ(repo.getObjectId(Object::ObjectType::Chunk, o2k), 777);
|
||||
|
||||
auto o1o = repo.getObject(666);
|
||||
auto o2o = repo.getObject(777);
|
||||
|
||||
auto o1ob = o1o.cbegin();
|
||||
auto o2ob = o2o.cbegin();
|
||||
|
||||
Chunk o1(o1ob, o1o.cend()), o2(o2ob, o2o.cend());
|
||||
|
||||
std::vector<char> data1{'a', 'b', 'c', 'e'};
|
||||
Chunk o1e(666, o1k, data1);
|
||||
std::vector<char> data2{'q', 'w', 'e', 'r', 'b'};
|
||||
Chunk o2e(777, o2k, data2);
|
||||
|
||||
EXPECT_EQ(o1.id, o1e.id);
|
||||
EXPECT_EQ(o2.id, o2e.id);
|
||||
EXPECT_EQ((int) o1.type, (int) o1e.type);
|
||||
EXPECT_EQ((int) o2.type, (int) o2e.type);
|
||||
auto o1d = o1.data;
|
||||
auto o1ed = o1e.data;
|
||||
auto o2d = o2.data;
|
||||
auto o2ed = o2e.data;
|
||||
EXPECT_EQ(o1.data.size(), o1e.data.size());
|
||||
EXPECT_EQ(o2.data.size(), o2e.data.size());
|
||||
for (int i = 0; i < o1.data.size(); i++) {
|
||||
EXPECT_EQ(o1.data[i], o1e.data[i]);
|
||||
}
|
||||
for (int i = 0; i < o2.data.size(); i++) {
|
||||
EXPECT_EQ(o2.data[i], o2e.data[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(FileRepository, IDsDisabled) {
|
||||
GTEST_SKIP();
|
||||
Cleaner c({"testrepo"});
|
||||
{
|
||||
Config conf;
|
||||
conf.add("repo", "testrepo");
|
||||
FileRepository repo(conf);
|
||||
repo.init();
|
||||
|
||||
std::string o1k(16, '\0');
|
||||
std::string o2k(16, '\0');
|
||||
o2k[0] = 1;
|
||||
|
||||
std::vector<char>
|
||||
data1{'a', 'b', 'c', 'e'};
|
||||
Chunk o1(repo.getId(), o1k, data1);
|
||||
std::vector<char> data2{'q', 'w', 'e', 'r', 'b'};
|
||||
Chunk o2(repo.getId(), o2k, data2);
|
||||
|
||||
EXPECT_EQ(o1.id, 1);
|
||||
EXPECT_EQ(o2.id, 2);
|
||||
|
||||
repo.putObject(o1);
|
||||
repo.putObject(o2);
|
||||
|
||||
|
||||
EXPECT_EQ(repo.getObjectId(Object::ObjectType::Chunk, o1k), 1);
|
||||
EXPECT_EQ(repo.getObjectId(Object::ObjectType::Chunk, o2k), 2);
|
||||
}
|
||||
{
|
||||
Config conf;
|
||||
conf.add("repo", "testrepo");
|
||||
FileRepository repo(conf);
|
||||
repo.open();
|
||||
auto o1o = repo.getObject(1);
|
||||
auto o2o = repo.getObject(2);
|
||||
|
||||
auto o1ob = o1o.cbegin();
|
||||
auto o2ob = o2o.cbegin();
|
||||
|
||||
Chunk o1(o1ob, o1o.cend()), o2(o2ob, o2o.cend());
|
||||
std::string o1k(16, '\0');
|
||||
std::string o2k(16, '\0');
|
||||
o2k[0] = 1;
|
||||
std::vector<char> data1{'a', 'b', 'c', 'e'};
|
||||
Chunk o1e(1, o1k, data1);
|
||||
std::vector<char> data2{'q', 'w', 'e', 'r', 'b'};
|
||||
Chunk o2e(2, o2k, data2);
|
||||
|
||||
EXPECT_EQ(o1.id, o1e.id);
|
||||
EXPECT_EQ(o2.id, o2e.id);
|
||||
EXPECT_EQ((int) o1.type, (int) o1e.type);
|
||||
EXPECT_EQ((int) o2.type, (int) o2e.type);
|
||||
auto o1d = o1.data;
|
||||
auto o1ed = o1e.data;
|
||||
auto o2d = o2.data;
|
||||
auto o2ed = o2e.data;
|
||||
EXPECT_EQ(o1.data.size(), o1e.data.size());
|
||||
EXPECT_EQ(o2.data.size(), o2e.data.size());
|
||||
for (int i = 0; i < o1.data.size(); i++) {
|
||||
EXPECT_EQ(o1.data[i], o1e.data[i]);
|
||||
}
|
||||
for (int i = 0; i < o2.data.size(); i++) {
|
||||
EXPECT_EQ(o2.data[i], o2e.data[i]);
|
||||
}
|
||||
|
||||
|
||||
EXPECT_EQ(repo.getObjectId(Object::ObjectType::Chunk, o1k), 1);
|
||||
EXPECT_EQ(repo.getObjectId(Object::ObjectType::Chunk, o2k), 2);
|
||||
|
||||
|
||||
repo.deleteObject(o1);
|
||||
}
|
||||
{
|
||||
Config conf;
|
||||
conf.add("repo", "testrepo");
|
||||
FileRepository repo(conf);
|
||||
repo.open();
|
||||
|
||||
std::string o2k(16, '\0');
|
||||
o2k[0] = 1;
|
||||
EXPECT_EQ(repo.getObjectId(Object::ObjectType::Chunk, o2k), 2);
|
||||
|
||||
auto id = repo.getId();
|
||||
EXPECT_EQ(id, 1);
|
||||
std::vector<char>
|
||||
data1{'a', 'b', 'c', 'e'};
|
||||
Chunk o1(id, o2k, data1);
|
||||
EXPECT_EQ(repo.getId(), 3);
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
//
|
||||
// Created by Stepan Usatiuk on 13.04.2023.
|
||||
//
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "BuzhashTest.h"
|
||||
#include "CLITestWrapper.h"
|
||||
#include "crypto/AESTest.h"
|
||||
#include "crypto/MD5Test.h"
|
||||
#include "fulltests/FullTest.h"
|
||||
#include "repo/ChunkTest.h"
|
||||
#include "repo/FileRepositoryTest.h"
|
||||
#include "utils/HelpfulAssertTest.h"
|
||||
|
||||
int main() {
|
||||
std::vector<std::unique_ptr<Runnable>> tests{};
|
||||
tests.emplace_back(HelpfulAssertTest()());
|
||||
tests.emplace_back(MD5Test()());
|
||||
tests.emplace_back(AESTest()());
|
||||
tests.emplace_back(ChunkTest()());
|
||||
tests.emplace_back(FileRepositoryTest()());
|
||||
tests.emplace_back(BuzhashTest()());
|
||||
tests.emplace_back(CLITestWrapper()());
|
||||
tests.emplace_back(FullTest()());
|
||||
|
||||
bool ok = true;
|
||||
for (const auto &t: tests) {
|
||||
ok = t->run(std::cout) && ok;
|
||||
}
|
||||
|
||||
return ok ? 0 : -1;
|
||||
}
|
||||
5
tests/utils/CMakeLists.txt
Normal file
5
tests/utils/CMakeLists.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
cmake_minimum_required(VERSION 3.22)
|
||||
|
||||
add_library(testUtils srcs/Cleaner.cpp)
|
||||
|
||||
target_include_directories(testUtils PUBLIC includes)
|
||||
@@ -1,43 +0,0 @@
|
||||
//
|
||||
// Created by Stepan Usatiuk on 13.04.2023.
|
||||
//
|
||||
|
||||
#ifndef SEMBACKUP_HELPFULASSERT_H
|
||||
#define SEMBACKUP_HELPFULASSERT_H
|
||||
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
#include <utility>
|
||||
|
||||
#include "../../src/Exception.h"
|
||||
|
||||
template<typename T, typename comp = std::equal_to<>>
|
||||
class HelpfulAssert {
|
||||
public:
|
||||
bool operator()(const T &lhs, const T &rhs) {
|
||||
if (!comp()(lhs, rhs)) {
|
||||
std::stringstream out;
|
||||
if constexpr (has_print_op<T>::value) {
|
||||
out << "Expected lhs to compare to " << rhs << std::endl;
|
||||
out << "But lhs is " << lhs << std::endl;
|
||||
|
||||
} else {
|
||||
out << "Error comparing!" << std::endl;
|
||||
}
|
||||
throw Exception(out.str());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
template<typename, typename = void>
|
||||
struct has_print_op : std::false_type {};
|
||||
|
||||
template<typename E>
|
||||
struct has_print_op<E, std::void_t<decltype(std::declval<std::ostream>() << std::declval<E>())>> : std::true_type {};
|
||||
};
|
||||
|
||||
|
||||
#endif//SEMBACKUP_HELPFULASSERT_H
|
||||
@@ -1,65 +0,0 @@
|
||||
//
|
||||
// Created by Stepan Usatiuk on 13.04.2023.
|
||||
//
|
||||
|
||||
#include "HelpfulAssertTest.h"
|
||||
|
||||
std::unique_ptr<TestGroup> HelpfulAssertTest::operator()() {
|
||||
auto tg = std::make_unique<TestGroup>("HelpfulAssert tests");
|
||||
|
||||
tg->addTest(std::make_unique<Test>("Equal test", std::function<bool()>([]() {
|
||||
HelpfulAssert<int>()(1, 1);
|
||||
|
||||
HelpfulAssert<std::string>()("hello", "hello");
|
||||
|
||||
try {
|
||||
HelpfulAssert<std::string>()("hello", "hello2");
|
||||
} catch (const Exception &e) {
|
||||
if (std::string_view(e.what()).find("Expected lhs to compare to hello2\nBut lhs is hello\n") == std::string_view::npos)
|
||||
throw Exception("HelpfulAssert text is wrong");
|
||||
} catch (...) {
|
||||
throw Exception("HelpfulAssert throws wrong exception");
|
||||
}
|
||||
|
||||
try {
|
||||
HelpfulAssert<int>()(1, 2);
|
||||
} catch (const Exception &e) {
|
||||
if (std::string_view(e.what()).find("Expected lhs to compare to 2\nBut lhs is 1\n") == std::string_view::npos)
|
||||
throw Exception("HelpfulAssert text is wrong");
|
||||
} catch (...) {
|
||||
throw Exception("HelpfulAssert throws wrong exception");
|
||||
}
|
||||
|
||||
return true;
|
||||
})));
|
||||
|
||||
tg->addTest(std::make_unique<Test>("Greater than test", std::function<bool()>([]() {
|
||||
HelpfulAssert<int, std::greater<>>()(2, 1);
|
||||
|
||||
try {
|
||||
HelpfulAssert<int, std::greater<>>()(1, 2);
|
||||
} catch (const Exception &e) {
|
||||
if (std::string_view(e.what()).find("Expected lhs to compare to 2\nBut lhs is 1\n") == std::string_view::npos)
|
||||
throw Exception("HelpfulAssert text is wrong");
|
||||
} catch (...) {
|
||||
throw Exception("HelpfulAssert throws wrong exception");
|
||||
}
|
||||
|
||||
return true;
|
||||
})));
|
||||
tg->addTest(std::make_unique<Test>("Less than test", std::function<bool()>([]() {
|
||||
HelpfulAssert<int, std::less<>>()(1, 2);
|
||||
|
||||
try {
|
||||
HelpfulAssert<int, std::less<>>()(2, 1);
|
||||
} catch (const Exception &e) {
|
||||
if (std::string_view(e.what()).find("Expected lhs to compare to 1\nBut lhs is 2\n") == std::string_view::npos)
|
||||
throw Exception("HelpfulAssert text is wrong");
|
||||
} catch (...) {
|
||||
throw Exception("HelpfulAssert throws wrong exception");
|
||||
}
|
||||
|
||||
return true;
|
||||
})));
|
||||
return tg;
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
//
|
||||
// Created by Stepan Usatiuk on 13.04.2023.
|
||||
//
|
||||
|
||||
#ifndef SEMBACKUP_HELPFULASSERTTEST_H
|
||||
#define SEMBACKUP_HELPFULASSERTTEST_H
|
||||
|
||||
#include "TestGroupGenerator.h"
|
||||
|
||||
class HelpfulAssertTest : public TestGroupGenerator {
|
||||
public:
|
||||
std::unique_ptr<TestGroup> operator()() override;
|
||||
};
|
||||
|
||||
|
||||
#endif//SEMBACKUP_HELPFULASSERTTEST_H
|
||||
@@ -1,13 +0,0 @@
|
||||
//
|
||||
// Created by Stepan Usatiuk on 13.04.2023.
|
||||
//
|
||||
|
||||
#include "Runnable.h"
|
||||
|
||||
Runnable::Runnable(std::string name) : name(std::move(name)) {}
|
||||
|
||||
std::string Runnable::getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
Runnable::~Runnable() = default;
|
||||
@@ -1,26 +0,0 @@
|
||||
//
|
||||
// Created by Stepan Usatiuk on 13.04.2023.
|
||||
//
|
||||
|
||||
#ifndef SEMBACKUP_RUNNABLE_H
|
||||
#define SEMBACKUP_RUNNABLE_H
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
class Runnable {
|
||||
public:
|
||||
Runnable(std::string name);
|
||||
|
||||
virtual bool run(std::ostream &out) = 0;
|
||||
|
||||
virtual ~Runnable();
|
||||
|
||||
std::string getName();
|
||||
|
||||
protected:
|
||||
std::string name;
|
||||
};
|
||||
|
||||
|
||||
#endif//SEMBACKUP_RUNNABLE_H
|
||||
@@ -1,16 +0,0 @@
|
||||
//
|
||||
// Created by Stepan Usatiuk on 13.04.2023.
|
||||
//
|
||||
|
||||
#include "Test.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
Test::Test(std::string name, std::function<bool()> test)
|
||||
: Runnable(std::move(name)), test(std::move(test)) {}
|
||||
|
||||
bool Test::run(std::ostream &out) {
|
||||
return test();
|
||||
}
|
||||
|
||||
Test::~Test() = default;
|
||||
@@ -1,25 +0,0 @@
|
||||
//
|
||||
// Created by Stepan Usatiuk on 13.04.2023.
|
||||
//
|
||||
|
||||
#ifndef SEMBACKUP_TEST_H
|
||||
#define SEMBACKUP_TEST_H
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include "Runnable.h"
|
||||
|
||||
class Test : public Runnable {
|
||||
public:
|
||||
Test(std::string name, std::function<bool()> test);
|
||||
|
||||
bool run(std::ostream &out) override;
|
||||
|
||||
~Test() override;
|
||||
|
||||
private:
|
||||
std::function<bool()> test;
|
||||
};
|
||||
|
||||
|
||||
#endif//SEMBACKUP_TEST_H
|
||||
@@ -1,31 +0,0 @@
|
||||
//
|
||||
// Created by Stepan Usatiuk on 13.04.2023.
|
||||
//
|
||||
|
||||
#include "TestGroup.h"
|
||||
|
||||
TestGroup::TestGroup(std::string name) : Runnable(std::move(name)) {}
|
||||
|
||||
bool TestGroup::run(std::ostream &out) {
|
||||
bool ok = true;
|
||||
out << "Running test group " << getName() << std::endl;
|
||||
for (auto const &p: tests) {
|
||||
out << " Running " << p->getName() << " ";
|
||||
try {
|
||||
p->run(out);
|
||||
out << "OK";
|
||||
} catch (const std::exception &e) {
|
||||
ok = false;
|
||||
out << "ERROR" << std::endl;
|
||||
out << e.what();
|
||||
}
|
||||
out << std::endl;
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
void TestGroup::addTest(std::unique_ptr<Runnable> &&test) {
|
||||
tests.emplace_back(std::move(test));
|
||||
}
|
||||
|
||||
TestGroup::~TestGroup() = default;
|
||||
@@ -1,28 +0,0 @@
|
||||
//
|
||||
// Created by Stepan Usatiuk on 13.04.2023.
|
||||
//
|
||||
|
||||
#ifndef SEMBACKUP_TESTGROUP_H
|
||||
#define SEMBACKUP_TESTGROUP_H
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "Runnable.h"
|
||||
|
||||
class TestGroup : public Runnable {
|
||||
public:
|
||||
TestGroup(std::string name);
|
||||
|
||||
bool run(std::ostream &out) override;
|
||||
|
||||
void addTest(std::unique_ptr<Runnable> &&test);
|
||||
|
||||
~TestGroup() override;
|
||||
|
||||
private:
|
||||
std::vector<std::unique_ptr<Runnable>> tests;
|
||||
};
|
||||
|
||||
|
||||
#endif//SEMBACKUP_TESTGROUP_H
|
||||
@@ -1,23 +0,0 @@
|
||||
//
|
||||
// Created by Stepan Usatiuk on 13.04.2023.
|
||||
//
|
||||
|
||||
#ifndef SEMBACKUP_TESTGROUPGENERATOR_H
|
||||
#define SEMBACKUP_TESTGROUPGENERATOR_H
|
||||
|
||||
#include <cassert>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
|
||||
#include "HelpfulAssert.h"
|
||||
#include "Runnable.h"
|
||||
#include "Test.h"
|
||||
#include "TestGroup.h"
|
||||
|
||||
class TestGroupGenerator {
|
||||
public:
|
||||
virtual std::unique_ptr<TestGroup> operator()() = 0;
|
||||
};
|
||||
|
||||
#endif//SEMBACKUP_TESTGROUPGENERATOR_H
|
||||
@@ -2,13 +2,14 @@
|
||||
// Created by Stepan Usatiuk on 14.04.2023.
|
||||
//
|
||||
|
||||
#include "Cleaner.h"
|
||||
#include "../includes/Cleaner.h"
|
||||
|
||||
Cleaner::Cleaner(std::vector<std::filesystem::path> toClean) : toClean(std::move(toClean)) {
|
||||
for (const auto &p: this->toClean) {
|
||||
std::filesystem::remove_all(p);
|
||||
}
|
||||
}
|
||||
|
||||
Cleaner::~Cleaner() {
|
||||
for (const auto &p: toClean) {
|
||||
std::filesystem::remove_all(p);
|
||||
Reference in New Issue
Block a user