+
+boost::filesystem::path
+subtitle_file (shared_ptr<Film> film)
+{
+ for (auto i: boost::filesystem::directory_iterator(film->directory().get() / film->dcp_name (false))) {
+ if (boost::filesystem::is_directory(i.path())) {
+ for (auto j: boost::filesystem::directory_iterator(i.path())) {
+ if (boost::algorithm::starts_with(j.path().leaf().string(), "sub_")) {
+ return j.path();
+ }
+ }
+ }
+ }
+
+ BOOST_REQUIRE (false);
+ /* Remove warning */
+ return boost::filesystem::path("/");
+}
+
+
+void
+make_random_file (boost::filesystem::path path, size_t size)
+{
+ dcp::File random_file(path, "wb");
+ BOOST_REQUIRE (random_file);
+
+ boost::random::mt19937 rng(1);
+ boost::random::uniform_int_distribution<uint64_t> dist(0);
+
+ while (size > 0) {
+ auto this_time = std::min(size, size_t(8));
+ uint64_t random = dist(rng);
+ random_file.write(&random, this_time, 1);
+ size -= this_time;
+ }
+}
+
+
+LogSwitcher::LogSwitcher (shared_ptr<Log> log)
+ : _old (dcpomatic_log)
+{
+ dcpomatic_log = log;
+}
+
+
+LogSwitcher::~LogSwitcher ()
+{
+ dcpomatic_log = _old;
+}
+
+std::ostream&
+dcp::operator<< (std::ostream& s, dcp::Size i)
+{
+ s << i.width << "x" << i.height;
+ return s;
+}
+
+std::ostream&
+dcp::operator<< (std::ostream& s, dcp::Standard t)
+{
+ switch (t) {
+ case Standard::INTEROP:
+ s << "interop";
+ break;
+ case Standard::SMPTE:
+ s << "smpte";
+ break;
+ }
+ return s;
+}
+
+std::ostream&
+operator<< (std::ostream&s, VideoFrameType f)
+{
+ s << video_frame_type_to_string(f);
+ return s;
+}
+
+
+void
+Cleanup::add (boost::filesystem::path path)
+{
+ _paths.push_back (path);
+}
+
+
+void
+Cleanup::run ()
+{
+ boost::system::error_code ec;
+ for (auto i: _paths) {
+ boost::filesystem::remove_all (i, ec);
+ }
+}
+
+
+void stage (string, boost::optional<boost::filesystem::path>) {}
+void progress (float) {}
+
+
+void
+make_and_verify_dcp (shared_ptr<Film> film, vector<dcp::VerificationNote::Code> ignore)
+{
+ film->write_metadata ();
+ make_dcp (film, TranscodeJob::ChangedBehaviour::IGNORE);
+ BOOST_REQUIRE (!wait_for_jobs());
+ auto notes = dcp::verify ({film->dir(film->dcp_name())}, &stage, &progress, TestPaths::xsd());
+ bool ok = true;
+ for (auto i: notes) {
+ if (find(ignore.begin(), ignore.end(), i.code()) == ignore.end()) {
+ std::cout << "\t" << dcp::note_to_string(i) << "\n";
+ ok = false;
+ }
+ }
+ BOOST_CHECK(ok);
+}
+
+
+void
+check_int_close (int a, int b, int d)
+{
+ BOOST_CHECK_MESSAGE (std::abs(a - b) < d, a << " differs from " << b << " by more than " << d);
+}
+
+
+void
+check_int_close (std::pair<int, int> a, std::pair<int, int> b, int d)
+{
+ check_int_close (a.first, b.first, d);
+ check_int_close (a.second, b.second, d);
+}
+
+
+ConfigRestorer::~ConfigRestorer()
+{
+ setup_test_config();
+}
+
+
+boost::filesystem::path
+find_file (boost::filesystem::path dir, string filename_part)
+{
+ boost::optional<boost::filesystem::path> found;
+ for (auto i: boost::filesystem::directory_iterator(dir)) {
+ if (i.path().filename().string().find(filename_part) != string::npos) {
+ BOOST_REQUIRE (!found);
+ found = i;
+ }
+ }
+ BOOST_REQUIRE (found);
+ return *found;
+}