diff options
author | Andreas Rogge <andreas.rogge@bareos.com> | 2022-10-10 16:16:54 +0300 |
---|---|---|
committer | Andreas Rogge <andreas.rogge@bareos.com> | 2022-11-07 19:37:29 +0300 |
commit | 9b4883a8d2b2c2621e275bf68d102cd266a8afff (patch) | |
tree | c7a23bbbda517d397ab1abcfa7211f26005e9fb6 | |
parent | 0a346707d3feb60d6beb8c547a641eb8c5c53911 (diff) |
tests: refactor droplet test into own program
Previously the droplet tests were integrated into the sd_backend tests.
With the new backend loading, we cannot configure a droplet backend if
we did not build it, thus we need to extract the droplet tests so we can
disable them completely.
-rw-r--r-- | .gitignore | 5 | ||||
-rw-r--r-- | core/src/tests/CMakeLists.txt | 2 | ||||
-rw-r--r-- | core/src/tests/configs/droplet_backend/bareos-sd.d/device/droplet.conf.in (renamed from core/src/tests/configs/sd_backend/bareos-sd.d/device/droplet.conf.in) | 2 | ||||
-rw-r--r-- | core/src/tests/configs/droplet_backend/bareos-sd.d/storage/myself.conf.in | 5 | ||||
-rw-r--r-- | core/src/tests/configs/droplet_backend/droplet.profile.in (renamed from core/src/tests/configs/sd_backend/droplet.profile.in) | 0 | ||||
-rw-r--r-- | core/src/tests/droplet_backend.cc | 192 | ||||
-rw-r--r-- | core/src/tests/sd_backend.cc | 230 | ||||
-rw-r--r-- | core/src/tests/sd_backend_tests.h | 75 |
8 files changed, 281 insertions, 230 deletions
diff --git a/.gitignore b/.gitignore index c604efe10..773072ed6 100644 --- a/.gitignore +++ b/.gitignore @@ -128,9 +128,10 @@ core/src/tests/configs/console-director/tls_psk_default_enabled/bareos-dir.d/job core/src/tests/configs/console-director/tls_psk_default_enabled/bareos-dir.d/jobdefs/DefaultJob.conf core/src/tests/configs/console-director/tls_psk_default_enabled/bareos-dir.d/messages/Daemon.conf core/src/tests/configs/console-director/tls_psk_default_enabled/bareos-dir.d/messages/Standard.conf -core/src/tests/configs/sd_backend/bareos-sd.d/device/droplet.conf +core/src/tests/configs/droplet_backend/bareos-sd.d/device/droplet.conf +core/src/tests/configs/droplet_backend/bareos-sd.d/storage/myself.conf +core/src/tests/configs/droplet_backend/droplet.profile core/src/tests/configs/sd_backend/bareos-sd.d/storage/myself.conf -core/src/tests/configs/sd_backend/droplet.profile core/src/tests/configs/sd_reservation/bareos-sd.d/storage/myself.conf core/src/tests/configs/statistics_thread/sd_statistics_thread/default_config/bareos-sd.d/storage/myself.conf core/src/tests/configs/statistics_thread/sd_statistics_thread/only_collect_set/bareos-sd.d/storage/myself.conf diff --git a/core/src/tests/CMakeLists.txt b/core/src/tests/CMakeLists.txt index ccd063f8a..80b6f2836 100644 --- a/core/src/tests/CMakeLists.txt +++ b/core/src/tests/CMakeLists.txt @@ -249,7 +249,7 @@ if(NOT client-only) ) bareos_add_test(sd_backend LINK_LIBRARIES ${LINK_LIBRARIES}) if(TARGET droplet) - target_compile_definitions(sd_backend PRIVATE HAVE_DROPLET) + bareos_add_test(droplet_backend LINK_LIBRARIES ${LINK_LIBRARIES}) endif() if(${CMAKE_SYSTEM_NAME} MATCHES "SunOS") # disable on solaris set(disable "DISABLE") diff --git a/core/src/tests/configs/sd_backend/bareos-sd.d/device/droplet.conf.in b/core/src/tests/configs/droplet_backend/bareos-sd.d/device/droplet.conf.in index b93c0b119..9fb80a40c 100644 --- a/core/src/tests/configs/sd_backend/bareos-sd.d/device/droplet.conf.in +++ b/core/src/tests/configs/droplet_backend/bareos-sd.d/device/droplet.conf.in @@ -2,7 +2,7 @@ Device { Name = droplet Media Type = S3 Device Type = droplet - Device Options = "profile=@CMAKE_CURRENT_SOURCE_DIR@/src/tests/configs/sd_backend/droplet.profile,bucket=bareos-test,chunksize=10M" + Device Options = "profile=@CMAKE_CURRENT_SOURCE_DIR@/src/tests/configs/droplet_backend/droplet.profile,bucket=bareos-test,chunksize=10M" Maximum Concurrent Jobs = 1 Archive Device = "Cloud Storage" LabelMedia = yes diff --git a/core/src/tests/configs/droplet_backend/bareos-sd.d/storage/myself.conf.in b/core/src/tests/configs/droplet_backend/bareos-sd.d/storage/myself.conf.in new file mode 100644 index 000000000..bc16b3bda --- /dev/null +++ b/core/src/tests/configs/droplet_backend/bareos-sd.d/storage/myself.conf.in @@ -0,0 +1,5 @@ +Storage { + Name = test-sd + @UNCOMMENT_SD_BACKEND_DIRECTORY@Backend Directory = @PROJECT_BINARY_DIR@/src/stored/backends + Working Directory = @PROJECT_BINARY_DIR@/ +} diff --git a/core/src/tests/configs/sd_backend/droplet.profile.in b/core/src/tests/configs/droplet_backend/droplet.profile.in index 9d161c8cf..9d161c8cf 100644 --- a/core/src/tests/configs/sd_backend/droplet.profile.in +++ b/core/src/tests/configs/droplet_backend/droplet.profile.in diff --git a/core/src/tests/droplet_backend.cc b/core/src/tests/droplet_backend.cc new file mode 100644 index 000000000..261e12a0d --- /dev/null +++ b/core/src/tests/droplet_backend.cc @@ -0,0 +1,192 @@ +/* + BAREOSĀ® - Backup Archiving REcovery Open Sourced + + Copyright (C) 2021-2022 Bareos GmbH & Co. KG + + This program is Free Software; you can redistribute it and/or + modify it under the terms of version three of the GNU Affero General Public + License as published by the Free Software Foundation, which is + listed in the file LICENSE. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. +*/ + +#if defined(HAVE_MINGW) +# include "include/bareos.h" +# include "gtest/gtest.h" +#else +# include "gtest/gtest.h" +# include "include/bareos.h" +#endif + + +#include <chrono> +#include <future> + +#define STORAGE_DAEMON 1 +#include "include/jcr.h" +#include "lib/crypto_cache.h" +#include "lib/edit.h" +#include "lib/parse_conf.h" +#include "stored/butil.h" +#include "stored/device_control_record.h" +#include "stored/jcr_private.h" +#include "stored/job.h" +#include "stored/sd_plugins.h" +#include "stored/sd_stats.h" +#include "stored/stored.h" +#include "stored/stored_globals.h" +#include "stored/wait.h" +#include "stored/sd_backends.h" + +#define CONFIG_SUBDIR "droplet_backend" +#include "sd_backend_tests.h" + +using namespace storagedaemon; + +void droplet_write_reread_testdata(std::vector<std::vector<char>>& test_data) +{ + const char* name = "sd_backend_test"; + const char* dev_name = "droplet"; + const char* volname + = ::testing::UnitTest::GetInstance()->current_test_info()->name(); + + JobControlRecord* jcr = SetupDummyJcr(name, nullptr, nullptr); + ASSERT_TRUE(jcr); + + DeviceResource* device_resource + = (DeviceResource*)my_config->GetResWithName(R_DEVICE, dev_name); + + Device* dev = FactoryCreateDevice(jcr, device_resource); + ASSERT_TRUE(dev); + + // write to device + { + dev->setVolCatName(volname); + auto fd = dev->d_open(volname, O_CREAT | O_RDWR | O_BINARY, 0640); + dev->d_truncate( + nullptr); // dcr parameter is unused, so nullptr should be fine + + for (auto& buf : test_data) { dev->d_write(fd, buf.data(), buf.size()); } + dev->d_close(fd); + } + + // read from device + { + dev->setVolCatName(volname); + auto fd = dev->d_open(volname, O_CREAT | O_RDWR | O_BINARY, 0640); + + for (auto& buf : test_data) { + std::vector<char> tmp(buf.size()); + dev->d_read(fd, tmp.data(), buf.size()); + ASSERT_EQ(buf, tmp); + } + dev->d_close(fd); + } + delete dev; + FreeJcr(jcr); +} + +// write-request writing 1 byte to this chunk and rest to next chunk +TEST_F(sd, droplet_off_by_one_short) +{ + using namespace std::string_literals; + std::vector<std::vector<char>> test_data; + + { + std::vector<char> tmp(1024 * 1024 - 1); + std::fill(tmp.begin(), tmp.end(), '0'); + test_data.push_back(tmp); + } + for (char& c : "123456789abcdefghijklmnopqrstuvwxyz"s) { + std::vector<char> tmp(1024 * 1024); + std::fill(tmp.begin(), tmp.end(), c); + test_data.push_back(tmp); + } + + droplet_write_reread_testdata(test_data); +} + +// write-request crossing the chunk-border by exactly 1 byte +TEST_F(sd, droplet_off_by_one_long) +{ + using namespace std::string_literals; + std::vector<std::vector<char>> test_data; + + { + std::vector<char> tmp(1024 * 1024 + 1); + std::fill(tmp.begin(), tmp.end(), '0'); + test_data.push_back(tmp); + } + for (char& c : "123456789abcdefghijklmnopqrstuvwxyz"s) { + std::vector<char> tmp(1024 * 1024); + std::fill(tmp.begin(), tmp.end(), c); + test_data.push_back(tmp); + } + + droplet_write_reread_testdata(test_data); +} + +// write-request hitting chunk-border exactly +TEST_F(sd, droplet_aligned) +{ + using namespace std::string_literals; + std::vector<std::vector<char>> test_data; + for (char& c : "0123456789abcdefghijklmnopqrstuvwxyz"s) { + std::vector<char> tmp(1024 * 1024); + std::fill(tmp.begin(), tmp.end(), c); + test_data.push_back(tmp); + } + + droplet_write_reread_testdata(test_data); +} + +// write-request same size as chunk +TEST_F(sd, droplet_fullchunk) +{ + using namespace std::string_literals; + std::vector<std::vector<char>> test_data; + for (char& c : "0123"s) { + std::vector<char> tmp(10 * 1024 * 1024); + std::fill(tmp.begin(), tmp.end(), c); + test_data.push_back(tmp); + } + + droplet_write_reread_testdata(test_data); +} + +// write-request larger than chunk +TEST_F(sd, droplet_oversized_write) +{ + using namespace std::string_literals; + std::vector<std::vector<char>> test_data; + for (char& c : "0123"s) { + std::vector<char> tmp(11 * 1024 * 1024); + std::fill(tmp.begin(), tmp.end(), c); + test_data.push_back(tmp); + } + + droplet_write_reread_testdata(test_data); +} + +// write-request larger than two chunks +TEST_F(sd, droplet_double_oversized_write) +{ + using namespace std::string_literals; + std::vector<std::vector<char>> test_data; + for (char& c : "0123"s) { + std::vector<char> tmp(21 * 1024 * 1024); + std::fill(tmp.begin(), tmp.end(), c); + test_data.push_back(tmp); + } + + droplet_write_reread_testdata(test_data); +} diff --git a/core/src/tests/sd_backend.cc b/core/src/tests/sd_backend.cc index 454fe7333..89b6c6365 100644 --- a/core/src/tests/sd_backend.cc +++ b/core/src/tests/sd_backend.cc @@ -45,60 +45,13 @@ #include "stored/stored.h" #include "stored/stored_globals.h" #include "stored/wait.h" -#if defined(HAVE_DYNAMIC_SD_BACKENDS) -# include "stored/sd_backends.h" -#endif - -using namespace storagedaemon; - -namespace storagedaemon { -/* import this to parse the config */ -extern bool ParseSdConfig(const char* configfile, int exit_code); -} // namespace storagedaemon - -class sd : public ::testing::Test { - protected: - void SetUp() override; - void TearDown() override; -}; - -void sd::SetUp() -{ - OSDependentInit(); - - debug_level = 900; - - /* configfile is a global char* from stored_globals.h */ - configfile = strdup(RELATIVE_PROJECT_SOURCE_DIR "/configs/sd_backend/"); - my_config = InitSdConfig(configfile, M_ERROR_TERM); - ParseSdConfig(configfile, M_ERROR_TERM); - /* - * we do not run CheckResources() here, so take care the test configration - * is not broken. Also autochangers will not work. - */ -} -void sd::TearDown() -{ - Dmsg0(100, "TearDown start\n"); +#include "stored/sd_backends.h" - { - DeviceResource* d = nullptr; - foreach_res (d, R_DEVICE) { - Dmsg1(10, "Term device %s (%s)\n", d->resource_name_, - d->archive_device_string); - if (d->dev) { - d->dev->ClearVolhdr(); - delete d->dev; - d->dev = nullptr; - } - } - } +#define CONFIG_SUBDIR "sd_backend" +#include "sd_backend_tests.h" - if (configfile) { free(configfile); } - if (my_config) { delete my_config; } +using namespace storagedaemon; - TermReservationsLock(); -} // Test that load and unloads a tape device. TEST_F(sd, backend_load_unload) @@ -137,178 +90,3 @@ TEST_F(sd, backend_load_unload) Dmsg0(100, "cleanup\n"); FreeJcr(jcr); } - -void droplet_write_reread_testdata(std::vector<std::vector<char>>& test_data) -{ - const char* name = "sd_backend_test"; - const char* dev_name = "droplet"; - const char* volname - = ::testing::UnitTest::GetInstance()->current_test_info()->name(); - - JobControlRecord* jcr = SetupDummyJcr(name, nullptr, nullptr); - ASSERT_TRUE(jcr); - - DeviceResource* device_resource - = (DeviceResource*)my_config->GetResWithName(R_DEVICE, dev_name); - - Device* dev = FactoryCreateDevice(jcr, device_resource); - ASSERT_TRUE(dev); - - // write to device - { - dev->setVolCatName(volname); - auto fd = dev->d_open(volname, O_CREAT | O_RDWR | O_BINARY, 0640); - dev->d_truncate( - nullptr); // dcr parameter is unused, so nullptr should be fine - - for (auto& buf : test_data) { dev->d_write(fd, buf.data(), buf.size()); } - dev->d_close(fd); - } - - // read from device - { - dev->setVolCatName(volname); - auto fd = dev->d_open(volname, O_CREAT | O_RDWR | O_BINARY, 0640); - - for (auto& buf : test_data) { - std::vector<char> tmp(buf.size()); - dev->d_read(fd, tmp.data(), buf.size()); - ASSERT_EQ(buf, tmp); - } - dev->d_close(fd); - } - delete dev; - FreeJcr(jcr); -} - -// write-request writing 1 byte to this chunk and rest to next chunk -TEST_F(sd, droplet_off_by_one_short) -{ -#if !defined HAVE_DROPLET - std::cerr << "\nThis test requires droplet backend, which has not been " - "built. Skipping.\n"; - exit(77); -#else - using namespace std::string_literals; - std::vector<std::vector<char>> test_data; - - { - std::vector<char> tmp(1024 * 1024 - 1); - std::fill(tmp.begin(), tmp.end(), '0'); - test_data.push_back(tmp); - } - for (char& c : "123456789abcdefghijklmnopqrstuvwxyz"s) { - std::vector<char> tmp(1024 * 1024); - std::fill(tmp.begin(), tmp.end(), c); - test_data.push_back(tmp); - } - - droplet_write_reread_testdata(test_data); -#endif -} - -// write-request crossing the chunk-border by exactly 1 byte -TEST_F(sd, droplet_off_by_one_long) -{ -#if !defined HAVE_DROPLET - std::cerr << "\nThis test requires droplet backend, which has not been " - "built. Skipping.\n"; - exit(77); -#else - using namespace std::string_literals; - std::vector<std::vector<char>> test_data; - - { - std::vector<char> tmp(1024 * 1024 + 1); - std::fill(tmp.begin(), tmp.end(), '0'); - test_data.push_back(tmp); - } - for (char& c : "123456789abcdefghijklmnopqrstuvwxyz"s) { - std::vector<char> tmp(1024 * 1024); - std::fill(tmp.begin(), tmp.end(), c); - test_data.push_back(tmp); - } - - droplet_write_reread_testdata(test_data); -#endif -} - -// write-request hitting chunk-border exactly -TEST_F(sd, droplet_aligned) -{ -#if !defined HAVE_DROPLET - std::cerr << "\nThis test requires droplet backend, which has not been " - "built. Skipping.\n"; - exit(77); -#else - using namespace std::string_literals; - std::vector<std::vector<char>> test_data; - for (char& c : "0123456789abcdefghijklmnopqrstuvwxyz"s) { - std::vector<char> tmp(1024 * 1024); - std::fill(tmp.begin(), tmp.end(), c); - test_data.push_back(tmp); - } - - droplet_write_reread_testdata(test_data); -#endif -} - -// write-request same size as chunk -TEST_F(sd, droplet_fullchunk) -{ -#if !defined HAVE_DROPLET - std::cerr << "\nThis test requires droplet backend, which has not been " - "built. Skipping.\n"; - exit(77); -#else - using namespace std::string_literals; - std::vector<std::vector<char>> test_data; - for (char& c : "0123"s) { - std::vector<char> tmp(10 * 1024 * 1024); - std::fill(tmp.begin(), tmp.end(), c); - test_data.push_back(tmp); - } - - droplet_write_reread_testdata(test_data); -#endif -} - -// write-request larger than chunk -TEST_F(sd, droplet_oversized_write) -{ -#if !defined HAVE_DROPLET - std::cerr << "\nThis test requires droplet backend, which has not been " - "built. Skipping.\n"; - exit(77); -#else - using namespace std::string_literals; - std::vector<std::vector<char>> test_data; - for (char& c : "0123"s) { - std::vector<char> tmp(11 * 1024 * 1024); - std::fill(tmp.begin(), tmp.end(), c); - test_data.push_back(tmp); - } - - droplet_write_reread_testdata(test_data); -#endif -} - -// write-request larger than two chunks -TEST_F(sd, droplet_double_oversized_write) -{ -#if !defined HAVE_DROPLET - std::cerr << "\nThis test requires droplet backend, which has not been " - "built. Skipping.\n"; - exit(77); -#else - using namespace std::string_literals; - std::vector<std::vector<char>> test_data; - for (char& c : "0123"s) { - std::vector<char> tmp(21 * 1024 * 1024); - std::fill(tmp.begin(), tmp.end(), c); - test_data.push_back(tmp); - } - - droplet_write_reread_testdata(test_data); -#endif -} diff --git a/core/src/tests/sd_backend_tests.h b/core/src/tests/sd_backend_tests.h new file mode 100644 index 000000000..c47fe75f7 --- /dev/null +++ b/core/src/tests/sd_backend_tests.h @@ -0,0 +1,75 @@ +/* + BAREOSĀ® - Backup Archiving REcovery Open Sourced + + Copyright (C) 2022-2022 Bareos GmbH & Co. KG + + This program is Free Software; you can redistribute it and/or + modify it under the terms of version three of the GNU Affero General Public + License as published by the Free Software Foundation and included + in the file LICENSE. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. +*/ + +#ifndef BAREOS_TESTS_SD_BACKEND_TESTS_H_ +#define BAREOS_TESTS_SD_BACKEND_TESTS_H_ +namespace storagedaemon { +/* import this to parse the config */ +extern bool ParseSdConfig(const char* configfile, int exit_code); +} // namespace storagedaemon + +class sd : public ::testing::Test { + protected: + void SetUp() override; + void TearDown() override; +}; + +void sd::SetUp() +{ + using namespace storagedaemon; + OSDependentInit(); + + debug_level = 900; + + /* configfile is a global char* from stored_globals.h */ + configfile + = strdup(RELATIVE_PROJECT_SOURCE_DIR "/configs/" CONFIG_SUBDIR "/"); + my_config = InitSdConfig(configfile, M_ERROR_TERM); + ParseSdConfig(configfile, M_ERROR_TERM); + /* + * we do not run CheckResources() here, so take care the test configration + * is not broken. Also autochangers will not work. + */ +} +void sd::TearDown() +{ + using namespace storagedaemon; + Dmsg0(100, "TearDown start\n"); + + { + DeviceResource* d = nullptr; + foreach_res (d, R_DEVICE) { + Dmsg1(10, "Term device %s (%s)\n", d->resource_name_, + d->archive_device_string); + if (d->dev) { + d->dev->ClearVolhdr(); + delete d->dev; + d->dev = nullptr; + } + } + } + + if (configfile) { free(configfile); } + if (my_config) { delete my_config; } + + TermReservationsLock(); +} +#endif // BAREOS_TESTS_SD_BACKEND_TESTS_H_ |