1 /*
2    BAREOS® - Backup Archiving REcovery Open Sourced
3 
4    Copyright (C) 2019-2020 Bareos GmbH & Co. KG
5 
6    This program is Free Software; you can redistribute it and/or
7    modify it under the terms of version three of the GNU Affero General Public
8    License as published by the Free Software Foundation, which is
9    listed in the file LICENSE.
10 
11    This program is distributed in the hope that it will be useful, but
12    WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14    Affero General Public License for more details.
15 
16    You should have received a copy of the GNU Affero General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19    02110-1301, USA.
20 */
21 
22 #include "include/bareos.h"
23 #include "cats/cats.h"
24 #include "cats/cats_backends.h"
25 #include "cats/sql_pooling.h"
26 #include "dird/get_database_connection.h"
27 #include "dird/dird_conf.h"
28 #include "dird/dird_globals.h"
29 #include "dird/jcr_private.h"
30 #include "dird/job.h"
31 #include "gmock/gmock.h"
32 #include "gtest/gtest.h"
33 #include "include/bareos.h"
34 #include "lib/parse_conf.h"
35 #include "lib/util.h"
36 
37 #include <string>
38 #include <vector>
39 
40 namespace directordaemon {
DoReloadConfig()41 bool DoReloadConfig() { return false; }
42 }  // namespace directordaemon
43 
44 using directordaemon::InitDirConfig;
45 using directordaemon::my_config;
46 
main(int argc,char ** argv)47 int main(int argc, char** argv)
48 {
49   testing::InitGoogleTest(&argc, argv);
50 
51   return RUN_ALL_TESTS();
52 }
53 
54 class CatalogTest : public ::testing::Test {
55  protected:
56   std::set<std::string> testable_catalog_backends{"postgresql", "sqlite3",
57                                                   "mysql"};
58   std::string catalog_backend_name;
59   std::string backend_dir;
60   std::string config_dir;
61   std::string working_dir;
62 
63   JobControlRecord* jcr{};
64   BareosDb* db{};
65 
66   void SetUp() override;
67   void TearDown() override;
68 };
69 
SetUp()70 void CatalogTest::SetUp()
71 {
72   InitMsg(nullptr, nullptr);
73 
74   // get environment
75   {
76     catalog_backend_name = getenv_std_string("DBTYPE");
77     backend_dir = getenv_std_string("backenddir");
78     config_dir = getenv_std_string("BAREOS_CONFIG_DIR");
79     working_dir = getenv_std_string("BAREOS_WORKING_DIR");
80 
81     ASSERT_NE(testable_catalog_backends.find(catalog_backend_name),
82               testable_catalog_backends.end())
83         << "Environment variable DBTYPE does not contain a name for a "
84            "testable catalog backend: "
85         << "<" << catalog_backend_name << ">";
86     ASSERT_FALSE(backend_dir.empty())
87         << "Environment variable backenddir not set.";
88     ASSERT_FALSE(config_dir.empty())
89         << "Environment variable BAREOS_CONFIG_DIR not set.";
90     ASSERT_FALSE(working_dir.empty())
91         << "Environment variable BAREOS_WORKING_DIR not set.";
92 
93     SetWorkingDirectory(working_dir.c_str());
94   }
95 
96   // parse config
97   {
98     std::string path_to_config_file
99         = std::string(RELATIVE_PROJECT_SOURCE_DIR "/configs/catalog");
100     my_config = InitDirConfig(path_to_config_file.c_str(), M_ERROR_TERM);
101 
102     ASSERT_TRUE(my_config->ParseConfig());
103   }
104 
105   // connect to database
106   {
107     jcr = directordaemon::NewDirectorJcr();
108     jcr->impl->res.catalog
109         = (directordaemon::CatalogResource*)my_config->GetResWithName(
110             directordaemon::R_CATALOG, catalog_backend_name.c_str());
111 
112     ASSERT_NE(jcr->impl->res.catalog, nullptr);
113 
114     auto backenddir = std::vector<std::string>{backend_dir};
115     DbSetBackendDirs(backenddir);
116 
117     db = directordaemon::GetDatabaseConnection(jcr);
118 
119     ASSERT_NE(db, nullptr);
120   }
121 }
122 
TearDown()123 void CatalogTest::TearDown()
124 {
125   DbSqlPoolDestroy();
126   DbFlushBackends();
127 
128   if (jcr) {
129     FreeJcr(jcr);
130     jcr = nullptr;
131   }
132 
133   if (my_config) {
134     delete my_config;
135     my_config = nullptr;
136   }
137 }
138 
TEST_F(CatalogTest,database)139 TEST_F(CatalogTest, database)
140 {
141   std::vector<char> stime;
142   auto jcr = directordaemon::NewDirectorJcr();
143 
144   auto result = db->FindLastJobStartTimeForJobAndClient(jcr, "backup-bareos-fd",
145                                                         "bareos-fd", stime);
146 
147   EXPECT_EQ(result, BareosDb::SqlFindResult::kEmptyResultSet)
148       << "Resultset should be empty.";
149 
150   std::string client_query{
151       "INSERT INTO Client "
152       " (Name, Uname)"
153       " VALUES( "
154       "  'bareos-fd',"
155       "  '19.2.4~pre1035.d5f227724 (22Nov19) "
156       "Linux-5.3.11-200.fc30.x86_64,redhat,Fedora release 30 (Thirty)')"};
157 
158   ASSERT_TRUE(db->SqlQuery(client_query.c_str(), 0));
159 
160   std::string job_query{
161       "INSERT INTO Job "
162       " (Job, Name, Type, Level, ClientId, JobStatus, StartTime, SchedTime)"
163       " VALUES( "
164       "  'backup-bareos-fd.2019-11-27_15.04.49_04', "
165       "  'backup-bareos-fd', "
166       "  'B', "
167       "  'F', "
168       "   1,  "
169       "  'T', "
170       "  '2019-11-27 15:04:49', "
171       "  '2019-11-27 15:04:48') "};
172 
173   ASSERT_TRUE(db->SqlQuery(job_query.c_str(), 0));
174 
175   result = db->FindLastJobStartTimeForJobAndClient(jcr, "backup-bareos-fd",
176                                                    "bareos-fd", stime);
177 
178   ASSERT_EQ(result, BareosDb::SqlFindResult::kSuccess)
179       << "Preset database entries not found.";
180 
181   time_t time_converted = static_cast<time_t>(StrToUtime(stime.data()));
182 
183   EXPECT_EQ(time_converted, StrToUtime("2019-11-27 15:04:49"));
184 }
185