Tidy up backing up of config files, improve the tests a little and fix it for the
[dcpomatic.git] / test / config_test.cc
1 /*
2     Copyright (C) 2018-2021 Carl Hetherington <cth@carlh.net>
3
4     This file is part of DCP-o-matic.
5
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.
10
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.
15
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/>.
18
19 */
20
21
22 #include "lib/config.h"
23 #include "test.h"
24 #include <boost/test/unit_test.hpp>
25 #include <fstream>
26
27
28 using std::ofstream;
29 using std::string;
30 using boost::optional;
31
32
33 static string
34 rewrite_bad_config (string filename, string extra_line)
35 {
36         using namespace boost::filesystem;
37
38         auto base = path("build/test/bad_config/2.16");
39         auto file = base / filename;
40
41         boost::system::error_code ec;
42         remove (file, ec);
43
44         boost::filesystem::create_directories (base);
45         std::ofstream f (file.string().c_str());
46         f << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
47           << "<Config>\n"
48           << "<Foo></Foo>\n"
49           << extra_line << "\n"
50           << "</Config>\n";
51         f.close ();
52
53         return dcp::file_to_string (file);
54 }
55
56
57 BOOST_AUTO_TEST_CASE (config_backup_test)
58 {
59         ConfigRestorer cr;
60
61         Config::override_path = "build/test/bad_config";
62         Config::drop();
63         boost::filesystem::remove_all ("build/test/bad_config");
64
65         /* Write an invalid config file to config.xml */
66         auto const first_write_xml = rewrite_bad_config("config.xml", "first write");
67
68         /* Load the config; this should fail, causing the bad config to be copied to config.xml.1
69          * and a new config.xml created in its place.
70          */
71         Config::instance();
72
73         BOOST_CHECK ( boost::filesystem::exists("build/test/bad_config/2.16/config.xml.1"));
74         BOOST_CHECK (dcp::file_to_string("build/test/bad_config/2.16/config.xml.1") == first_write_xml);
75         BOOST_CHECK (!boost::filesystem::exists("build/test/bad_config/2.16/config.xml.2"));
76         BOOST_CHECK (!boost::filesystem::exists("build/test/bad_config/2.16/config.xml.3"));
77         BOOST_CHECK (!boost::filesystem::exists("build/test/bad_config/2.16/config.xml.4"));
78
79         Config::drop();
80         auto const second_write_xml = rewrite_bad_config("config.xml", "second write");
81         Config::instance();
82
83         BOOST_CHECK ( boost::filesystem::exists("build/test/bad_config/2.16/config.xml.1"));
84         BOOST_CHECK (dcp::file_to_string("build/test/bad_config/2.16/config.xml.1") == first_write_xml);
85         BOOST_CHECK ( boost::filesystem::exists("build/test/bad_config/2.16/config.xml.2"));
86         BOOST_CHECK (dcp::file_to_string("build/test/bad_config/2.16/config.xml.2") == second_write_xml);
87         BOOST_CHECK (!boost::filesystem::exists("build/test/bad_config/2.16/config.xml.3"));
88         BOOST_CHECK (!boost::filesystem::exists("build/test/bad_config/2.16/config.xml.4"));
89
90         Config::drop();
91         auto const third_write_xml = rewrite_bad_config("config.xml", "third write");
92         Config::instance();
93
94         BOOST_CHECK ( boost::filesystem::exists("build/test/bad_config/2.16/config.xml.1"));
95         BOOST_CHECK (dcp::file_to_string("build/test/bad_config/2.16/config.xml.1") == first_write_xml);
96         BOOST_CHECK ( boost::filesystem::exists("build/test/bad_config/2.16/config.xml.2"));
97         BOOST_CHECK (dcp::file_to_string("build/test/bad_config/2.16/config.xml.2") == second_write_xml);
98         BOOST_CHECK ( boost::filesystem::exists("build/test/bad_config/2.16/config.xml.3"));
99         BOOST_CHECK (dcp::file_to_string("build/test/bad_config/2.16/config.xml.3") == third_write_xml);
100         BOOST_CHECK (!boost::filesystem::exists("build/test/bad_config/2.16/config.xml.4"));
101
102         Config::drop();
103         auto const fourth_write_xml = rewrite_bad_config("config.xml", "fourth write");
104         Config::instance();
105
106         BOOST_CHECK (boost::filesystem::exists("build/test/bad_config/2.16/config.xml.1"));
107         BOOST_CHECK (dcp::file_to_string("build/test/bad_config/2.16/config.xml.1") == first_write_xml);
108         BOOST_CHECK (boost::filesystem::exists("build/test/bad_config/2.16/config.xml.2"));
109         BOOST_CHECK (dcp::file_to_string("build/test/bad_config/2.16/config.xml.2") == second_write_xml);
110         BOOST_CHECK (boost::filesystem::exists("build/test/bad_config/2.16/config.xml.3"));
111         BOOST_CHECK (dcp::file_to_string("build/test/bad_config/2.16/config.xml.3") == third_write_xml);
112         BOOST_CHECK (boost::filesystem::exists("build/test/bad_config/2.16/config.xml.4"));
113         BOOST_CHECK (dcp::file_to_string("build/test/bad_config/2.16/config.xml.4") == fourth_write_xml);
114 }
115
116
117 BOOST_AUTO_TEST_CASE (config_backup_with_link_test)
118 {
119         using namespace boost::filesystem;
120
121         ConfigRestorer cr;
122
123         auto base = path("build/test/bad_config");
124         auto version = base / "2.16";
125
126         Config::override_path = base;
127         Config::drop();
128
129         boost::filesystem::remove_all (base);
130
131         boost::filesystem::create_directories (version);
132         std::ofstream f (path(version / "config.xml").string().c_str());
133         f << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
134           << "<Config>\n"
135           << "<Link>" << path(version / "actual.xml").string() << "</Link>\n"
136           << "</Config>\n";
137         f.close ();
138
139         Config::drop ();
140         /* Cause actual.xml to be backed up */
141         rewrite_bad_config ("actual.xml", "first write");
142         Config::instance ();
143
144         /* Make sure actual.xml was backed up to the right place */
145         BOOST_CHECK (boost::filesystem::exists(version / "actual.xml.1"));
146 }
147
148
149 BOOST_AUTO_TEST_CASE (config_write_utf8_test)
150 {
151         ConfigRestorer cr;
152
153         boost::filesystem::remove_all ("build/test/config.xml");
154         boost::filesystem::copy_file ("test/data/utf8_config.xml", "build/test/config.xml");
155         Config::override_path = "build/test";
156         Config::drop ();
157         Config::instance()->write();
158
159         check_text_file ("test/data/utf8_config.xml", "build/test/config.xml");
160 }
161
162
163 BOOST_AUTO_TEST_CASE (config_upgrade_test)
164 {
165         ConfigRestorer cr;
166
167         boost::filesystem::path dir = "build/test/config_upgrade_test";
168         Config::override_path = dir;
169         Config::drop ();
170         boost::filesystem::remove_all (dir);
171         boost::filesystem::create_directories (dir);
172
173         boost::filesystem::copy_file ("test/data/2.14.config.xml", dir / "config.xml");
174         boost::filesystem::copy_file ("test/data/2.14.cinemas.xml", dir / "cinemas.xml");
175         Config::instance();
176         try {
177                 /* This will fail to write cinemas.xml since the link is to a non-existant directory */
178                 Config::instance()->write();
179         } catch (...) {}
180
181         check_xml (dir / "config.xml", "test/data/2.14.config.xml", {});
182         check_xml (dir / "cinemas.xml", "test/data/2.14.cinemas.xml", {});
183 #ifdef DCPOMATIC_WINDOWS
184         /* This file has the windows path for dkdm_recipients.xml (with backslashes) */
185         check_xml (dir / "2.16" / "config.xml", "test/data/2.16.config.windows.xml", {});
186 #else
187         check_xml (dir / "2.16" / "config.xml", "test/data/2.16.config.xml", {});
188 #endif
189         /* cinemas.xml is not copied into 2.16 as its format has not changed */
190         BOOST_REQUIRE (!boost::filesystem::exists(dir / "2.16" / "cinemas.xml"));
191 }
192