2 Copyright (C) 2018-2021 Carl Hetherington <cth@carlh.net>
4 This file is part of DCP-o-matic.
6 DCP-o-matic is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 DCP-o-matic is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
22 #include "lib/cinema.h"
23 #include "lib/config.h"
25 #include <boost/test/unit_test.hpp>
29 using std::make_shared;
33 using boost::optional;
37 rewrite_bad_config (string filename, string extra_line)
39 using namespace boost::filesystem;
41 auto base = path("build/test/bad_config/2.18");
42 auto file = base / filename;
44 boost::system::error_code ec;
47 boost::filesystem::create_directories (base);
48 std::ofstream f (file.string().c_str());
49 f << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
56 return dcp::file_to_string (file);
60 BOOST_AUTO_TEST_CASE (config_backup_test)
64 Config::override_path = "build/test/bad_config";
66 boost::filesystem::remove_all ("build/test/bad_config");
68 /* Write an invalid config file to config.xml */
69 auto const first_write_xml = rewrite_bad_config("config.xml", "first write");
71 /* Load the config; this should fail, causing the bad config to be copied to config.xml.1
72 * and a new config.xml created in its place.
76 boost::filesystem::path const prefix = "build/test/bad_config/2.18";
78 BOOST_CHECK(boost::filesystem::exists(prefix / "config.xml.1"));
79 BOOST_CHECK(dcp::file_to_string(prefix / "config.xml.1") == first_write_xml);
80 BOOST_CHECK(!boost::filesystem::exists(prefix / "config.xml.2"));
81 BOOST_CHECK(!boost::filesystem::exists(prefix / "config.xml.3"));
82 BOOST_CHECK(!boost::filesystem::exists(prefix / "config.xml.4"));
85 auto const second_write_xml = rewrite_bad_config("config.xml", "second write");
88 BOOST_CHECK(boost::filesystem::exists(prefix / "config.xml.1"));
89 BOOST_CHECK(dcp::file_to_string(prefix / "config.xml.1") == first_write_xml);
90 BOOST_CHECK(boost::filesystem::exists(prefix / "config.xml.2"));
91 BOOST_CHECK(dcp::file_to_string(prefix / "config.xml.2") == second_write_xml);
92 BOOST_CHECK(!boost::filesystem::exists(prefix / "config.xml.3"));
93 BOOST_CHECK(!boost::filesystem::exists(prefix / "config.xml.4"));
96 auto const third_write_xml = rewrite_bad_config("config.xml", "third write");
99 BOOST_CHECK(boost::filesystem::exists(prefix / "config.xml.1"));
100 BOOST_CHECK(dcp::file_to_string(prefix / "config.xml.1") == first_write_xml);
101 BOOST_CHECK(boost::filesystem::exists(prefix / "config.xml.2"));
102 BOOST_CHECK(dcp::file_to_string(prefix / "config.xml.2") == second_write_xml);
103 BOOST_CHECK(boost::filesystem::exists(prefix / "config.xml.3"));
104 BOOST_CHECK(dcp::file_to_string(prefix / "config.xml.3") == third_write_xml);
105 BOOST_CHECK(!boost::filesystem::exists(prefix / "config.xml.4"));
108 auto const fourth_write_xml = rewrite_bad_config("config.xml", "fourth write");
111 BOOST_CHECK(boost::filesystem::exists(prefix / "config.xml.1"));
112 BOOST_CHECK(dcp::file_to_string(prefix / "config.xml.1") == first_write_xml);
113 BOOST_CHECK(boost::filesystem::exists(prefix / "config.xml.2"));
114 BOOST_CHECK(dcp::file_to_string(prefix / "config.xml.2") == second_write_xml);
115 BOOST_CHECK(boost::filesystem::exists(prefix / "config.xml.3"));
116 BOOST_CHECK(dcp::file_to_string(prefix / "config.xml.3") == third_write_xml);
117 BOOST_CHECK(boost::filesystem::exists(prefix / "config.xml.4"));
118 BOOST_CHECK(dcp::file_to_string(prefix / "config.xml.4") == fourth_write_xml);
122 BOOST_AUTO_TEST_CASE (config_backup_with_link_test)
124 using namespace boost::filesystem;
128 auto base = path("build/test/bad_config");
129 auto version = base / "2.18";
131 Config::override_path = base;
134 boost::filesystem::remove_all (base);
136 boost::filesystem::create_directories (version);
137 std::ofstream f (path(version / "config.xml").string().c_str());
138 f << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
140 << "<Link>" << path(version / "actual.xml").string() << "</Link>\n"
145 /* Cause actual.xml to be backed up */
146 rewrite_bad_config ("actual.xml", "first write");
149 /* Make sure actual.xml was backed up to the right place */
150 BOOST_CHECK (boost::filesystem::exists(version / "actual.xml.1"));
154 BOOST_AUTO_TEST_CASE (config_write_utf8_test)
158 boost::filesystem::remove_all ("build/test/config.xml");
159 boost::filesystem::copy_file ("test/data/utf8_config.xml", "build/test/config.xml");
160 Config::override_path = "build/test";
162 Config::instance()->write();
164 check_text_file ("test/data/utf8_config.xml", "build/test/config.xml");
169 BOOST_AUTO_TEST_CASE (config_upgrade_test1)
173 boost::filesystem::path dir = "build/test/config_upgrade_test";
174 Config::override_path = dir;
176 boost::filesystem::remove_all (dir);
177 boost::filesystem::create_directories (dir);
179 boost::filesystem::copy_file ("test/data/2.14.config.xml", dir / "config.xml");
180 boost::filesystem::copy_file ("test/data/2.14.cinemas.xml", dir / "cinemas.xml");
183 /* This will fail to write cinemas.xml since the link is to a non-existent directory */
184 Config::instance()->write();
187 check_xml (dir / "config.xml", "test/data/2.14.config.xml", {});
188 check_xml (dir / "cinemas.xml", "test/data/2.14.cinemas.xml", {});
189 #ifdef DCPOMATIC_WINDOWS
190 /* This file has the windows path for dkdm_recipients.xml (with backslashes) */
191 check_xml(dir / "2.18" / "config.xml", "test/data/2.18.config.windows.xml", {});
193 check_xml(dir / "2.18" / "config.xml", "test/data/2.18.config.xml", {});
195 /* cinemas.xml is not copied into 2.18 as its format has not changed */
196 BOOST_REQUIRE (!boost::filesystem::exists(dir / "2.18" / "cinemas.xml"));
201 BOOST_AUTO_TEST_CASE (config_upgrade_test2)
205 boost::filesystem::path dir = "build/test/config_upgrade_test";
206 Config::override_path = dir;
208 boost::filesystem::remove_all (dir);
209 boost::filesystem::create_directories (dir);
211 #ifdef DCPOMATIC_WINDOWS
212 boost::filesystem::copy_file("test/data/2.16.config.windows.xml", dir / "config.xml");
214 boost::filesystem::copy_file("test/data/2.16.config.xml", dir / "config.xml");
216 boost::filesystem::copy_file("test/data/2.14.cinemas.xml", dir / "cinemas.xml");
219 /* This will fail to write cinemas.xml since the link is to a non-existent directory */
220 Config::instance()->write();
223 check_xml(dir / "cinemas.xml", "test/data/2.14.cinemas.xml", {});
224 #ifdef DCPOMATIC_WINDOWS
225 /* This file has the windows path for dkdm_recipients.xml (with backslashes) */
226 check_xml(dir / "2.18" / "config.xml", "test/data/2.18.config.windows.xml", {});
227 check_xml(dir / "config.xml", "test/data/2.16.config.windows.xml", {});
229 check_xml(dir / "2.18" / "config.xml", "test/data/2.18.config.xml", {});
230 check_xml(dir / "config.xml", "test/data/2.16.config.xml", {});
232 /* cinemas.xml is not copied into 2.18 as its format has not changed */
233 BOOST_REQUIRE (!boost::filesystem::exists(dir / "2.18" / "cinemas.xml"));
237 BOOST_AUTO_TEST_CASE (config_keep_cinemas_if_making_new_config)
241 boost::filesystem::path dir = "build/test/config_keep_cinemas_if_making_new_config";
242 Config::override_path = dir;
244 boost::filesystem::remove_all (dir);
245 boost::filesystem::create_directories (dir);
247 Config::instance()->write();
249 Config::instance()->add_cinema(make_shared<Cinema>("My Great Cinema", vector<string>(), ""));
250 Config::instance()->write();
252 boost::filesystem::copy_file (dir / "cinemas.xml", dir / "backup_for_test.xml");
255 boost::filesystem::remove (dir / "2.18" / "config.xml");
258 check_text_file(dir / "backup_for_test.xml", dir / "cinemas.xml");
262 BOOST_AUTO_TEST_CASE(keep_config_if_cinemas_fail_to_load)
266 /* Make a new config */
267 boost::filesystem::path dir = "build/test/keep_config_if_cinemas_fail_to_load";
268 Config::override_path = dir;
270 boost::filesystem::remove_all(dir);
271 boost::filesystem::create_directories(dir);
272 Config::instance()->write();
274 auto const cinemas = dir / "cinemas.xml";
277 boost::filesystem::copy_file(dir / "2.18" / "config.xml", dir / "config_backup_for_test.xml");
278 boost::filesystem::copy_file(cinemas, dir / "cinemas_backup_for_test.xml");
280 /* Corrupt the cinemas */
282 std::ofstream corrupt(cinemas.string().c_str());
287 /* We should have a new cinemas.xml and the old config.xml */
288 check_text_file(dir / "2.18" / "config.xml", dir / "config_backup_for_test.xml");
289 check_text_file(cinemas, dir / "cinemas_backup_for_test.xml");