Backup more than one config on failure to load.
authorCarl Hetherington <cth@carlh.net>
Fri, 5 Jan 2018 20:03:43 +0000 (20:03 +0000)
committerCarl Hetherington <cth@carlh.net>
Fri, 5 Jan 2018 20:03:43 +0000 (20:03 +0000)
src/lib/config.cc
src/lib/config.h
test/config_test.cc [new file with mode: 0644]
test/wscript

index 2a8a3cc..983fb69 100644 (file)
@@ -31,6 +31,7 @@
 #include "cross.h"
 #include "film.h"
 #include "dkdm_wrapper.h"
+#include "compose.hpp"
 #include <dcp/raw_convert.h>
 #include <dcp/name_format.h>
 #include <dcp/certificate_chain.h>
@@ -65,6 +66,7 @@ using dcp::raw_convert;
 Config* Config::_instance = 0;
 boost::signals2::signal<void ()> Config::FailedToLoad;
 boost::signals2::signal<void (string)> Config::Warning;
+boost::optional<boost::filesystem::path> Config::test_path;
 
 /** Construct default configuration */
 Config::Config ()
@@ -390,8 +392,13 @@ catch (...) {
 
                /* Make a copy of the configuration */
                try {
-                       boost::filesystem::copy_file (path ("config.xml", false), path ("config.xml.backup", false));
-                       boost::filesystem::copy_file (path ("cinemas.xml", false), path ("cinemas.xml.backup", false));
+                       int n = 1;
+                       while (n < 100 && boost::filesystem::exists(path(String::compose("config.xml.%1", n)))) {
+                               ++n;
+                       }
+
+                       boost::filesystem::copy_file(path("config.xml", false), path(String::compose("config.xml.%1", n), false));
+                       boost::filesystem::copy_file(path("cinemas.xml", false), path(String::compose("cinemas.xml.%1", n), false));
                } catch (...) {}
 
                /* We have a config file but it didn't load */
@@ -410,16 +417,20 @@ boost::filesystem::path
 Config::path (string file, bool create_directories)
 {
        boost::filesystem::path p;
+       if (test_path) {
+               p = test_path.get();
+       } else {
 #ifdef DCPOMATIC_OSX
-       p /= g_get_home_dir ();
-       p /= "Library";
-       p /= "Preferences";
-       p /= "com.dcpomatic";
-       p /= "2";
+               p /= g_get_home_dir ();
+               p /= "Library";
+               p /= "Preferences";
+               p /= "com.dcpomatic";
+               p /= "2";
 #else
-       p /= g_get_user_config_dir ();
-       p /= "dcpomatic2";
+               p /= g_get_user_config_dir ();
+               p /= "dcpomatic2";
 #endif
+       }
        boost::system::error_code ec;
        if (create_directories) {
                boost::filesystem::create_directories (p, ec);
index a57fbd5..61d9c64 100644 (file)
@@ -675,6 +675,8 @@ public:
        static bool have_existing (std::string);
        static boost::filesystem::path config_file ();
 
+       static boost::optional<boost::filesystem::path> test_path;
+
 private:
        Config ();
        static boost::filesystem::path path (std::string file, bool create_directories = true);
diff --git a/test/config_test.cc b/test/config_test.cc
new file mode 100644 (file)
index 0000000..25e8c7d
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+    Copyright (C) 2018 Carl Hetherington <cth@carlh.net>
+
+    This file is part of DCP-o-matic.
+
+    DCP-o-matic is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    DCP-o-matic 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 General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with DCP-o-matic.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "lib/config.h"
+#include <boost/test/unit_test.hpp>
+#include <fstream>
+
+using std::ofstream;
+
+static void
+rewrite_bad_config ()
+{
+       boost::system::error_code ec;
+       boost::filesystem::remove ("build/test/config.xml", ec);
+
+       Config::test_path = "build/test";
+       ofstream f ("build/test/config.xml");
+       f << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+         << "<Config>\n"
+         << "<Foo></Foo>\n"
+         << "</Config>\n";
+       f.close ();
+}
+
+
+BOOST_AUTO_TEST_CASE (config_backup_test)
+{
+       Config::drop();
+
+       boost::system::error_code ec;
+       boost::filesystem::remove ("build/test/config.xml.1", ec);
+       boost::filesystem::remove ("build/test/config.xml.2", ec);
+       boost::filesystem::remove ("build/test/config.xml.3", ec);
+       boost::filesystem::remove ("build/test/config.xml.4", ec);
+       boost::filesystem::remove ("build/test/config.xml.5", ec);
+       boost::filesystem::remove ("build/test/config.xml.5", ec);
+
+       rewrite_bad_config();
+
+       Config::instance();
+
+       BOOST_CHECK ( boost::filesystem::exists ("build/test/config.xml.1"));
+       BOOST_CHECK (!boost::filesystem::exists ("build/test/config.xml.2"));
+       BOOST_CHECK (!boost::filesystem::exists ("build/test/config.xml.3"));
+       BOOST_CHECK (!boost::filesystem::exists ("build/test/config.xml.4"));
+
+       Config::drop();
+       rewrite_bad_config();
+       Config::instance();
+
+       BOOST_CHECK ( boost::filesystem::exists ("build/test/config.xml.1"));
+       BOOST_CHECK ( boost::filesystem::exists ("build/test/config.xml.2"));
+       BOOST_CHECK (!boost::filesystem::exists ("build/test/config.xml.3"));
+       BOOST_CHECK (!boost::filesystem::exists ("build/test/config.xml.4"));
+
+       Config::drop();
+       rewrite_bad_config();
+       Config::instance();
+
+       BOOST_CHECK ( boost::filesystem::exists ("build/test/config.xml.1"));
+       BOOST_CHECK ( boost::filesystem::exists ("build/test/config.xml.2"));
+       BOOST_CHECK ( boost::filesystem::exists ("build/test/config.xml.3"));
+       BOOST_CHECK (!boost::filesystem::exists ("build/test/config.xml.4"));
+
+       Config::drop();
+       rewrite_bad_config();
+       Config::instance();
+
+       BOOST_CHECK (boost::filesystem::exists ("build/test/config.xml.1"));
+       BOOST_CHECK (boost::filesystem::exists ("build/test/config.xml.2"));
+       BOOST_CHECK (boost::filesystem::exists ("build/test/config.xml.3"));
+       BOOST_CHECK (boost::filesystem::exists ("build/test/config.xml.4"));
+}
index ecbc32f..f0533cf 100644 (file)
@@ -52,6 +52,7 @@ def build(bld):
                  butler_test.cc
                  client_server_test.cc
                  colour_conversion_test.cc
+                 config_test.cc
                  content_test.cc
                  dcpomatic_time_test.cc
                  dcp_subtitle_test.cc