diff options
Diffstat (limited to 'test')
43 files changed, 1315 insertions, 404 deletions
diff --git a/test/burnt_subtitle_test.cc b/test/burnt_subtitle_test.cc index 8d7dcd143..e8ecc0048 100644 --- a/test/burnt_subtitle_test.cc +++ b/test/burnt_subtitle_test.cc @@ -30,7 +30,7 @@ #include "lib/dcp_content.h" #include "lib/dcp_content_type.h" #include "lib/film.h" -#include "lib/ffmpeg_encoder.h" +#include "lib/ffmpeg_film_encoder.h" #include "lib/log_entry.h" #include "lib/ratio.h" #include "lib/text_content.h" @@ -39,9 +39,9 @@ #include <dcp/cpl.h> #include <dcp/reel.h> #include <dcp/j2k_transcode.h> -#include <dcp/mono_picture_asset.h> -#include <dcp/mono_picture_asset_reader.h> -#include <dcp/mono_picture_frame.h> +#include <dcp/mono_j2k_picture_asset.h> +#include <dcp/mono_j2k_picture_asset_reader.h> +#include <dcp/mono_j2k_picture_frame.h> #include <dcp/openjpeg_image.h> #include <dcp/reel_picture_asset.h> #include <dcp/reel_mono_picture_asset.h> @@ -137,7 +137,7 @@ BOOST_AUTO_TEST_CASE (burnt_subtitle_test_onto_dcp) BOOST_REQUIRE (dcp.cpls().front()->reels().front()->main_picture()->asset()); auto pic = dynamic_pointer_cast<dcp::ReelMonoPictureAsset> ( dcp.cpls().front()->reels().front()->main_picture() - )->mono_asset(); + )->mono_j2k_asset(); BOOST_REQUIRE (pic); auto frame = pic->start_read()->get_frame(12); auto xyz = frame->xyz_image (); @@ -199,7 +199,7 @@ BOOST_AUTO_TEST_CASE(burn_empty_subtitle_test) auto job = make_shared<TranscodeJob>(film, TranscodeJob::ChangedBehaviour::IGNORE); auto file = boost::filesystem::path("build") / "test" / "burnt_empty_subtitle_test.mov"; cl.add(file); - FFmpegEncoder encoder(film, job, file, ExportFormat::PRORES_4444, false, false, false, 23); + FFmpegFilmEncoder encoder(film, job, file, ExportFormat::PRORES_4444, false, false, false, 23); encoder.go(); cl.run(); diff --git a/test/bv20_test.cc b/test/bv20_test.cc index 5530a05d0..7f4e98aa7 100644 --- a/test/bv20_test.cc +++ b/test/bv20_test.cc @@ -49,7 +49,8 @@ has_mxf_mca_subdescriptors(shared_ptr<const Film> film) * whether they exist. */ - ASDCP::PCM::MXFReader reader; + Kumu::FileReaderFactory factory; + ASDCP::PCM::MXFReader reader(factory); auto r = reader.OpenRead(find_file(film->dir(film->dcp_name()), "pcm_").string()); BOOST_REQUIRE(!ASDCP_FAILURE(r)); diff --git a/test/cinema_list_test.cc b/test/cinema_list_test.cc new file mode 100644 index 000000000..4aa9fa4ed --- /dev/null +++ b/test/cinema_list_test.cc @@ -0,0 +1,225 @@ +/* + Copyright (C) 2023 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/cinema.h" +#include "lib/cinema_list.h" +#include "lib/config.h" +#include "lib/screen.h" +#include <dcp/certificate.h> +#include <dcp/filesystem.h> +#include <dcp/util.h> +#include <boost/filesystem.hpp> +#include <boost/test/unit_test.hpp> +#include <list> +#include <string> + + +using std::pair; +using std::string; +using std::vector; + + +static +boost::filesystem::path +setup(string name) +{ + boost::filesystem::path db = boost::filesystem::path("build") / "test" / (name + ".db"); + boost::system::error_code ec; + boost::filesystem::remove(db, ec); + return db; +} + + +BOOST_AUTO_TEST_CASE(add_cinema_test) +{ + auto const db = setup("add_cinema_test"); + + auto const name = "Bob's Zero-G Cinema"; + auto const emails = vector<string>{"zerogbob@hotmail.com"}; + auto const notes = "Nice enough place but the popcorn keeps floating away"; + auto const utc_offset = dcp::UTCOffset{5, 0}; + + CinemaList cinemas(db); + cinemas.add_cinema({name, emails, notes, utc_offset}); + + CinemaList cinemas2(db); + auto const check = cinemas2.cinemas(); + BOOST_REQUIRE_EQUAL(check.size(), 1U); + BOOST_CHECK(check[0].second.name == name); + BOOST_CHECK(check[0].second.emails == emails); + BOOST_CHECK_EQUAL(check[0].second.notes, notes); + BOOST_CHECK(check[0].second.utc_offset == utc_offset); +} + + +BOOST_AUTO_TEST_CASE(remove_cinema_test) +{ + auto const db = setup("remove_cinema_test"); + + auto const name1 = "Bob's Zero-G Cinema"; + auto const emails1 = vector<string>{"zerogbob@hotmail.com"}; + auto const notes1 = "Nice enough place but the popcorn keeps floating away"; + auto const utc_offset1 = dcp::UTCOffset{-4, -30}; + + auto const name2 = "Angie's Infinite-Screen Cinema"; + auto const emails2 = vector<string>{"angie@infinitium.com", "projection-screen912341235@infinitium.com"}; + auto const notes2 = "Nice enough place but it's very hard to find the right screen"; + auto const utc_offset2 = dcp::UTCOffset{9, 0}; + + CinemaList cinemas(db); + auto const id1 = cinemas.add_cinema({name1, emails1, notes1, utc_offset1}); + cinemas.add_cinema({name2, emails2, notes2, utc_offset2}); + + auto const check = cinemas.cinemas(); + BOOST_REQUIRE_EQUAL(check.size(), 2U); + BOOST_CHECK(check[0].second.name == name2); + BOOST_CHECK(check[0].second.emails == emails2); + BOOST_CHECK_EQUAL(check[0].second.notes, notes2); + BOOST_CHECK(check[0].second.utc_offset == utc_offset2); + BOOST_CHECK(check[1].second.name == name1); + BOOST_CHECK(check[1].second.emails == emails1); + BOOST_CHECK_EQUAL(check[1].second.notes, notes1); + BOOST_CHECK(check[1].second.utc_offset == utc_offset1); + + cinemas.remove_cinema(id1); + + auto const check2 = cinemas.cinemas(); + BOOST_REQUIRE_EQUAL(check2.size(), 1U); + BOOST_CHECK(check2[0].second.name == name2); + BOOST_CHECK(check2[0].second.emails == emails2); + BOOST_CHECK_EQUAL(check2[0].second.notes, notes2); +} + + +BOOST_AUTO_TEST_CASE(update_cinema_test) +{ + auto const db = setup("update_cinema_test"); + + auto const name1 = "Bob's Zero-G Cinema"; + auto const emails1 = vector<string>{"zerogbob@hotmail.com"}; + auto const notes1 = "Nice enough place but the popcorn keeps floating away"; + auto const utc_offset1 = dcp::UTCOffset{-4, -30}; + + auto const name2 = "Angie's Infinite-Screen Cinema"; + auto const emails2 = vector<string>{"angie@infinitium.com", "projection-screen912341235@infinitium.com"}; + auto const notes2 = "Nice enough place but it's very hard to find the right screen"; + auto const utc_offset2 = dcp::UTCOffset{9, 0}; + + CinemaList cinemas(db); + auto const id = cinemas.add_cinema({name1, emails1, notes1, utc_offset1}); + cinemas.add_cinema({name2, emails2, notes2, utc_offset2}); + + auto check = cinemas.cinemas(); + BOOST_REQUIRE_EQUAL(check.size(), 2U); + /* Alphabetically ordered so first is 2 */ + BOOST_CHECK_EQUAL(check[0].second.name, name2); + BOOST_CHECK(check[0].second.emails == emails2); + BOOST_CHECK_EQUAL(check[0].second.notes, notes2); + BOOST_CHECK(check[0].second.utc_offset == utc_offset2); + /* Then 1 */ + BOOST_CHECK_EQUAL(check[1].second.name, name1); + BOOST_CHECK(check[1].second.emails == emails1); + BOOST_CHECK_EQUAL(check[1].second.notes, notes1); + BOOST_CHECK(check[1].second.utc_offset == utc_offset1); + + cinemas.update_cinema(id, Cinema{name1, vector<string>{"bob@zerogkino.com"}, notes1, utc_offset1}); + + check = cinemas.cinemas(); + BOOST_REQUIRE_EQUAL(check.size(), 2U); + BOOST_CHECK_EQUAL(check[0].second.name, name2); + BOOST_CHECK(check[0].second.emails == emails2); + BOOST_CHECK_EQUAL(check[0].second.notes, notes2); + BOOST_CHECK(check[0].second.utc_offset == utc_offset2); + BOOST_CHECK_EQUAL(check[1].second.name, name1); + BOOST_CHECK(check[1].second.emails == vector<string>{"bob@zerogkino.com"}); + BOOST_CHECK_EQUAL(check[1].second.notes, notes1); + BOOST_CHECK(check[1].second.utc_offset == utc_offset1); +} + + +BOOST_AUTO_TEST_CASE(add_screen_test) +{ + auto const db = setup("add_screen_test"); + + CinemaList cinemas(db); + auto const cinema_id = cinemas.add_cinema({"Name", { "foo@bar.com" }, "", dcp::UTCOffset()}); + auto const screen_id = cinemas.add_screen( + cinema_id, + dcpomatic::Screen( + "Screen 1", + "Smells of popcorn", + dcp::Certificate(dcp::file_to_string("test/data/cert.pem")), + string("test/data/cert.pem"), + vector<TrustedDevice>{} + )); + + auto check = cinemas.screens(cinema_id); + BOOST_REQUIRE_EQUAL(check.size(), 1U); + BOOST_CHECK(check[0].first == screen_id); + BOOST_CHECK_EQUAL(check[0].second.name, "Screen 1"); + BOOST_CHECK_EQUAL(check[0].second.notes, "Smells of popcorn"); + BOOST_CHECK(check[0].second.recipient == dcp::Certificate(dcp::file_to_string("test/data/cert.pem"))); + BOOST_CHECK(check[0].second.recipient_file == string("test/data/cert.pem")); +} + + +BOOST_AUTO_TEST_CASE(cinemas_list_copy_from_xml_test) +{ + Config::override_path = "build/test/cinemas_list_copy_config"; + dcp::filesystem::remove_all(*Config::override_path); + dcp::filesystem::create_directories(*Config::override_path); + dcp::filesystem::copy_file("test/data/cinemas2.xml", *Config::override_path / "cinemas2.xml"); + Config::drop(); + + CinemaList cinema_list; + cinema_list.read_legacy_file(Config::instance()->read_path("cinemas2.xml")); + auto cinemas = cinema_list.cinemas(); + BOOST_REQUIRE_EQUAL(cinemas.size(), 3U); + + auto cinema_iter = cinemas.begin(); + BOOST_CHECK_EQUAL(cinema_iter->second.name, "Great"); + BOOST_CHECK_EQUAL(cinema_iter->second.emails.size(), 1U); + BOOST_CHECK_EQUAL(cinema_iter->second.emails[0], "julie@tinyscreen.com"); + BOOST_CHECK(cinema_iter->second.utc_offset == dcp::UTCOffset(1, 0)); + ++cinema_iter; + + BOOST_CHECK_EQUAL(cinema_iter->second.name, "classy joint"); + BOOST_CHECK_EQUAL(cinema_iter->second.notes, "Can't stand this place"); + ++cinema_iter; + + BOOST_CHECK_EQUAL(cinema_iter->second.name, "stinking dump"); + BOOST_CHECK_EQUAL(cinema_iter->second.emails.size(), 2U); + BOOST_CHECK_EQUAL(cinema_iter->second.emails[0], "bob@odourscreen.com"); + BOOST_CHECK_EQUAL(cinema_iter->second.emails[1], "alice@whiff.com"); + BOOST_CHECK_EQUAL(cinema_iter->second.notes, "Great cinema, smells of roses"); + BOOST_CHECK(cinema_iter->second.utc_offset == dcp::UTCOffset(-7, 0)); + auto screens = cinema_list.screens(cinema_iter->first); + BOOST_CHECK_EQUAL(screens.size(), 2U); + auto screen_iter = screens.begin(); + BOOST_CHECK_EQUAL(screen_iter->second.name, "1"); + BOOST_CHECK(screen_iter->second.recipient); + BOOST_CHECK_EQUAL(screen_iter->second.recipient->subject_dn_qualifier(), "CVsuuv9eYsQZSl8U4fDpvOmzZhI="); + ++screen_iter; + BOOST_CHECK_EQUAL(screen_iter->second.name, "2"); + BOOST_CHECK(screen_iter->second.recipient); + BOOST_CHECK_EQUAL(screen_iter->second.recipient->subject_dn_qualifier(), "CVsuuv9eYsQZSl8U4fDpvOmzZhI="); +} + diff --git a/test/client_server_test.cc b/test/client_server_test.cc index 596668aae..64a77415a 100644 --- a/test/client_server_test.cc +++ b/test/client_server_test.cc @@ -20,20 +20,18 @@ /** @file test/client_server_test.cc - * @brief Test the server class. + * @brief Test the remote encoding code. * @ingroup feature - * - * Create a test image and then encode it using the standard mechanism - * and also using a EncodeServer object running on localhost. Compare the resulting - * encoded data to check that they are the same. */ +#include "lib/content_factory.h" #include "lib/cross.h" #include "lib/dcp_video.h" #include "lib/dcpomatic_log.h" #include "lib/encode_server.h" #include "lib/encode_server_description.h" +#include "lib/encode_server_finder.h" #include "lib/file_log.h" #include "lib/image.h" #include "lib/j2k_image_proxy.h" @@ -51,6 +49,7 @@ using std::weak_ptr; using boost::thread; using boost::optional; using dcp::ArrayData; +using namespace dcpomatic; void @@ -105,7 +104,7 @@ BOOST_AUTO_TEST_CASE (client_server_test_rgb) ColourConversion(), VideoRange::FULL, weak_ptr<Content>(), - optional<Frame>(), + optional<ContentTime>(), false ); @@ -184,7 +183,7 @@ BOOST_AUTO_TEST_CASE (client_server_test_yuv) ColourConversion(), VideoRange::FULL, weak_ptr<Content>(), - optional<Frame>(), + optional<ContentTime>(), false ); @@ -250,7 +249,7 @@ BOOST_AUTO_TEST_CASE (client_server_test_j2k) ColourConversion(), VideoRange::FULL, weak_ptr<Content>(), - optional<Frame>(), + optional<ContentTime>(), false ); @@ -275,7 +274,7 @@ BOOST_AUTO_TEST_CASE (client_server_test_j2k) PresetColourConversion::all().front().conversion, VideoRange::FULL, weak_ptr<Content>(), - optional<Frame>(), + optional<ContentTime>(), false ); @@ -312,6 +311,27 @@ BOOST_AUTO_TEST_CASE (client_server_test_j2k) server->stop (); server_thread.join(); + + EncodeServerFinder::drop(); } +BOOST_AUTO_TEST_CASE(real_encode_with_server) +{ + auto content = content_factory(TestPaths::private_data() / "dolby_aurora.vob"); + auto film = new_test_film2("real_encode_with_server", content); + + EncodeServerFinder::instance(); + + EncodeServer server(true, 4); + thread server_thread(boost::bind(&EncodeServer::run, &server)); + + make_and_verify_dcp(film); + + server.stop(); + server_thread.join(); + + BOOST_CHECK(server.frames_encoded() > 0); + EncodeServerFinder::drop(); +} + diff --git a/test/config_test.cc b/test/config_test.cc index 103a6a585..1c35f0a78 100644 --- a/test/config_test.cc +++ b/test/config_test.cc @@ -20,7 +20,12 @@ #include "lib/cinema.h" +#include "lib/cinema_list.h" #include "lib/config.h" +#include "lib/dkdm_recipient.h" +#include "lib/dkdm_recipient_list.h" +#include "lib/unzipper.h" +#include "lib/zipper.h" #include "test.h" #include <boost/test/unit_test.hpp> #include <fstream> @@ -38,7 +43,7 @@ rewrite_bad_config (string filename, string extra_line) { using namespace boost::filesystem; - auto base = path("build/test/bad_config/2.16"); + auto base = path("build/test/bad_config/2.18"); auto file = base / filename; boost::system::error_code ec; @@ -73,47 +78,49 @@ BOOST_AUTO_TEST_CASE (config_backup_test) */ Config::instance(); - BOOST_CHECK ( boost::filesystem::exists("build/test/bad_config/2.16/config.xml.1")); - BOOST_CHECK (dcp::file_to_string("build/test/bad_config/2.16/config.xml.1") == first_write_xml); - BOOST_CHECK (!boost::filesystem::exists("build/test/bad_config/2.16/config.xml.2")); - BOOST_CHECK (!boost::filesystem::exists("build/test/bad_config/2.16/config.xml.3")); - BOOST_CHECK (!boost::filesystem::exists("build/test/bad_config/2.16/config.xml.4")); + boost::filesystem::path const prefix = "build/test/bad_config/2.18"; + + BOOST_CHECK(boost::filesystem::exists(prefix / "config.xml.1")); + BOOST_CHECK(dcp::file_to_string(prefix / "config.xml.1") == first_write_xml); + BOOST_CHECK(!boost::filesystem::exists(prefix / "config.xml.2")); + BOOST_CHECK(!boost::filesystem::exists(prefix / "config.xml.3")); + BOOST_CHECK(!boost::filesystem::exists(prefix / "config.xml.4")); Config::drop(); auto const second_write_xml = rewrite_bad_config("config.xml", "second write"); Config::instance(); - BOOST_CHECK ( boost::filesystem::exists("build/test/bad_config/2.16/config.xml.1")); - BOOST_CHECK (dcp::file_to_string("build/test/bad_config/2.16/config.xml.1") == first_write_xml); - BOOST_CHECK ( boost::filesystem::exists("build/test/bad_config/2.16/config.xml.2")); - BOOST_CHECK (dcp::file_to_string("build/test/bad_config/2.16/config.xml.2") == second_write_xml); - BOOST_CHECK (!boost::filesystem::exists("build/test/bad_config/2.16/config.xml.3")); - BOOST_CHECK (!boost::filesystem::exists("build/test/bad_config/2.16/config.xml.4")); + BOOST_CHECK(boost::filesystem::exists(prefix / "config.xml.1")); + BOOST_CHECK(dcp::file_to_string(prefix / "config.xml.1") == first_write_xml); + BOOST_CHECK(boost::filesystem::exists(prefix / "config.xml.2")); + BOOST_CHECK(dcp::file_to_string(prefix / "config.xml.2") == second_write_xml); + BOOST_CHECK(!boost::filesystem::exists(prefix / "config.xml.3")); + BOOST_CHECK(!boost::filesystem::exists(prefix / "config.xml.4")); Config::drop(); auto const third_write_xml = rewrite_bad_config("config.xml", "third write"); Config::instance(); - BOOST_CHECK ( boost::filesystem::exists("build/test/bad_config/2.16/config.xml.1")); - BOOST_CHECK (dcp::file_to_string("build/test/bad_config/2.16/config.xml.1") == first_write_xml); - BOOST_CHECK ( boost::filesystem::exists("build/test/bad_config/2.16/config.xml.2")); - BOOST_CHECK (dcp::file_to_string("build/test/bad_config/2.16/config.xml.2") == second_write_xml); - BOOST_CHECK ( boost::filesystem::exists("build/test/bad_config/2.16/config.xml.3")); - BOOST_CHECK (dcp::file_to_string("build/test/bad_config/2.16/config.xml.3") == third_write_xml); - BOOST_CHECK (!boost::filesystem::exists("build/test/bad_config/2.16/config.xml.4")); + BOOST_CHECK(boost::filesystem::exists(prefix / "config.xml.1")); + BOOST_CHECK(dcp::file_to_string(prefix / "config.xml.1") == first_write_xml); + BOOST_CHECK(boost::filesystem::exists(prefix / "config.xml.2")); + BOOST_CHECK(dcp::file_to_string(prefix / "config.xml.2") == second_write_xml); + BOOST_CHECK(boost::filesystem::exists(prefix / "config.xml.3")); + BOOST_CHECK(dcp::file_to_string(prefix / "config.xml.3") == third_write_xml); + BOOST_CHECK(!boost::filesystem::exists(prefix / "config.xml.4")); Config::drop(); auto const fourth_write_xml = rewrite_bad_config("config.xml", "fourth write"); Config::instance(); - BOOST_CHECK (boost::filesystem::exists("build/test/bad_config/2.16/config.xml.1")); - BOOST_CHECK (dcp::file_to_string("build/test/bad_config/2.16/config.xml.1") == first_write_xml); - BOOST_CHECK (boost::filesystem::exists("build/test/bad_config/2.16/config.xml.2")); - BOOST_CHECK (dcp::file_to_string("build/test/bad_config/2.16/config.xml.2") == second_write_xml); - BOOST_CHECK (boost::filesystem::exists("build/test/bad_config/2.16/config.xml.3")); - BOOST_CHECK (dcp::file_to_string("build/test/bad_config/2.16/config.xml.3") == third_write_xml); - BOOST_CHECK (boost::filesystem::exists("build/test/bad_config/2.16/config.xml.4")); - BOOST_CHECK (dcp::file_to_string("build/test/bad_config/2.16/config.xml.4") == fourth_write_xml); + BOOST_CHECK(boost::filesystem::exists(prefix / "config.xml.1")); + BOOST_CHECK(dcp::file_to_string(prefix / "config.xml.1") == first_write_xml); + BOOST_CHECK(boost::filesystem::exists(prefix / "config.xml.2")); + BOOST_CHECK(dcp::file_to_string(prefix / "config.xml.2") == second_write_xml); + BOOST_CHECK(boost::filesystem::exists(prefix / "config.xml.3")); + BOOST_CHECK(dcp::file_to_string(prefix / "config.xml.3") == third_write_xml); + BOOST_CHECK(boost::filesystem::exists(prefix / "config.xml.4")); + BOOST_CHECK(dcp::file_to_string(prefix / "config.xml.4") == fourth_write_xml); } @@ -124,7 +131,7 @@ BOOST_AUTO_TEST_CASE (config_backup_with_link_test) ConfigRestorer cr; auto base = path("build/test/bad_config"); - auto version = base / "2.16"; + auto version = base / "2.18"; Config::override_path = base; Config::drop(); @@ -163,7 +170,8 @@ BOOST_AUTO_TEST_CASE (config_write_utf8_test) } -BOOST_AUTO_TEST_CASE (config_upgrade_test) +/* 2.14 -> 2.18 */ +BOOST_AUTO_TEST_CASE (config_upgrade_test1) { ConfigRestorer cr; @@ -175,22 +183,61 @@ BOOST_AUTO_TEST_CASE (config_upgrade_test) boost::filesystem::copy_file ("test/data/2.14.config.xml", dir / "config.xml"); boost::filesystem::copy_file ("test/data/2.14.cinemas.xml", dir / "cinemas.xml"); - Config::instance(); try { - /* This will fail to write cinemas.xml since the link is to a non-existent directory */ - Config::instance()->write(); + /* This will fail to read cinemas.xml since the link is to a non-existent directory */ + Config::instance(); } catch (...) {} + Config::instance()->write(); + check_xml (dir / "config.xml", "test/data/2.14.config.xml", {}); check_xml (dir / "cinemas.xml", "test/data/2.14.cinemas.xml", {}); #ifdef DCPOMATIC_WINDOWS /* This file has the windows path for dkdm_recipients.xml (with backslashes) */ - check_xml (dir / "2.16" / "config.xml", "test/data/2.16.config.windows.xml", {}); + check_xml(dir / "2.18" / "config.xml", "test/data/2.18.config.windows.sqlite.xml", {}); #else - check_xml (dir / "2.16" / "config.xml", "test/data/2.16.config.xml", {}); + check_xml(dir / "2.18" / "config.xml", "test/data/2.18.config.sqlite.xml", {}); #endif - /* cinemas.xml is not copied into 2.16 as its format has not changed */ - BOOST_REQUIRE (!boost::filesystem::exists(dir / "2.16" / "cinemas.xml")); + /* cinemas.xml is not copied into 2.18 as its format has not changed */ + BOOST_REQUIRE (!boost::filesystem::exists(dir / "2.18" / "cinemas.xml")); +} + + +/* 2.16 -> 2.18 */ +BOOST_AUTO_TEST_CASE (config_upgrade_test2) +{ + ConfigRestorer cr; + + boost::filesystem::path dir = "build/test/config_upgrade_test"; + Config::override_path = dir; + Config::drop (); + boost::filesystem::remove_all (dir); + boost::filesystem::create_directories (dir); + +#ifdef DCPOMATIC_WINDOWS + boost::filesystem::copy_file("test/data/2.16.config.windows.xml", dir / "config.xml"); +#else + boost::filesystem::copy_file("test/data/2.16.config.xml", dir / "config.xml"); +#endif + boost::filesystem::copy_file("test/data/2.14.cinemas.xml", dir / "cinemas.xml"); + try { + /* This will fail to read cinemas.xml since the link is to a non-existent directory */ + Config::instance(); + } catch (...) {} + + Config::instance()->write(); + + check_xml(dir / "cinemas.xml", "test/data/2.14.cinemas.xml", {}); +#ifdef DCPOMATIC_WINDOWS + /* This file has the windows path for dkdm_recipients.xml (with backslashes) */ + check_xml(dir / "2.18" / "config.xml", "test/data/2.18.config.windows.xml", {}); + check_xml(dir / "config.xml", "test/data/2.16.config.windows.xml", {}); +#else + check_xml(dir / "2.18" / "config.xml", "test/data/2.18.config.xml", {}); + check_xml(dir / "config.xml", "test/data/2.16.config.xml", {}); +#endif + /* cinemas.xml is not copied into 2.18 as its format has not changed */ + BOOST_REQUIRE (!boost::filesystem::exists(dir / "2.18" / "cinemas.xml")); } @@ -206,16 +253,16 @@ BOOST_AUTO_TEST_CASE (config_keep_cinemas_if_making_new_config) Config::instance()->write(); - Config::instance()->add_cinema(make_shared<Cinema>("My Great Cinema", vector<string>(), "", 0, 0)); - Config::instance()->write(); + CinemaList cinemas; + cinemas.add_cinema({"My Great Cinema", {}, "", dcp::UTCOffset()}); - boost::filesystem::copy_file (dir / "cinemas.xml", dir / "backup_for_test.xml"); + boost::filesystem::copy_file(dir / "cinemas.sqlite3", dir / "backup_for_test.sqlite3"); Config::drop (); - boost::filesystem::remove (dir / "2.16" / "config.xml"); + boost::filesystem::remove (dir / "2.18" / "config.xml"); Config::instance(); - check_text_file(dir / "backup_for_test.xml", dir / "cinemas.xml"); + check_file(dir / "backup_for_test.sqlite3", dir / "cinemas.sqlite3"); } @@ -231,11 +278,14 @@ BOOST_AUTO_TEST_CASE(keep_config_if_cinemas_fail_to_load) boost::filesystem::create_directories(dir); Config::instance()->write(); - auto const cinemas = dir / "cinemas.xml"; + CinemaList cinema_list; + cinema_list.add_cinema(Cinema("Foo", {}, "Bar", dcp::UTCOffset())); + + auto const cinemas = dir / "cinemas.sqlite3"; /* Back things up */ - boost::filesystem::copy_file(dir / "2.16" / "config.xml", dir / "config_backup_for_test.xml"); - boost::filesystem::copy_file(cinemas, dir / "cinemas_backup_for_test.xml"); + boost::filesystem::copy_file(dir / "2.18" / "config.xml", dir / "config_backup_for_test.xml"); + boost::filesystem::copy_file(cinemas, dir / "cinemas_backup_for_test.sqlite3"); /* Corrupt the cinemas */ Config::drop(); @@ -244,8 +294,241 @@ BOOST_AUTO_TEST_CASE(keep_config_if_cinemas_fail_to_load) corrupt.close(); Config::instance(); - /* We should have a new cinemas.xml and the old config.xml */ - check_text_file(dir / "2.16" / "config.xml", dir / "config_backup_for_test.xml"); - check_text_file(cinemas, dir / "cinemas_backup_for_test.xml"); + /* We should have the old config.xml */ + check_text_file(dir / "2.18" / "config.xml", dir / "config_backup_for_test.xml"); +} + + +BOOST_AUTO_TEST_CASE(read_cinemas_xml_and_write_sqlite) +{ + ConfigRestorer cr; + + /* Set up a config with an XML cinemas file */ + boost::filesystem::path dir = "build/test/read_cinemas_xml_and_write_sqlite"; + boost::filesystem::remove_all(dir); + boost::filesystem::create_directories(dir); + boost::filesystem::create_directories(dir / "2.18"); + + boost::filesystem::copy_file("test/data/cinemas.xml", dir / "cinemas.xml"); + boost::filesystem::copy_file("test/data/2.18.config.xml", dir / "2.18" / "config.xml"); + { + Editor editor(dir / "2.18" / "config.xml"); + editor.replace( + "/home/realldoesnt/exist/this/path/is/nonsense.xml", + boost::filesystem::canonical(dir / "cinemas.xml").string() + ); + } + + Config::override_path = dir; + Config::drop(); + + /* This should make a sqlite3 file containing the recipients from cinemas.xml */ + Config::instance(); + + { + CinemaList test(dir / "cinemas.sqlite3"); + + /* The detailed creation of sqlite3 from XML is tested in cinema_list_test.cc */ + auto cinemas = test.cinemas(); + BOOST_REQUIRE_EQUAL(cinemas.size(), 3U); + BOOST_CHECK_EQUAL(cinemas[0].second.name, "Great"); + BOOST_CHECK_EQUAL(cinemas[1].second.name, "classy joint"); + BOOST_CHECK_EQUAL(cinemas[2].second.name, "stinking dump"); + + /* Add another recipient to the sqlite */ + test.add_cinema({"The ol' 1-seater", {}, "Quiet but lonely", dcp::UTCOffset()}); + } + + /* Reload the config; the old XML should not clobber the new sqlite3 */ + Config::drop(); + Config::instance(); + + { + CinemaList test(dir / "cinemas.sqlite3"); + + auto cinemas = test.cinemas(); + BOOST_REQUIRE_EQUAL(cinemas.size(), 4U); + BOOST_CHECK_EQUAL(cinemas[0].second.name, "Great"); + BOOST_CHECK_EQUAL(cinemas[1].second.name, "The ol' 1-seater"); + BOOST_CHECK_EQUAL(cinemas[2].second.name, "classy joint"); + BOOST_CHECK_EQUAL(cinemas[3].second.name, "stinking dump"); + } +} + + +BOOST_AUTO_TEST_CASE(read_dkdm_recipients_xml_and_write_sqlite) +{ + ConfigRestorer cr; + + /* Set up a config with an XML cinemas file */ + boost::filesystem::path dir = "build/test/read_dkdm_recipients_xml_and_write_sqlite"; + boost::filesystem::remove_all(dir); + boost::filesystem::create_directories(dir); + boost::filesystem::create_directories(dir / "2.18"); + + boost::filesystem::copy_file("test/data/dkdm_recipients.xml", dir / "dkdm_recipients.xml"); + boost::filesystem::copy_file("test/data/2.18.config.xml", dir / "2.18" / "config.xml"); + { + Editor editor(dir / "2.18" / "config.xml"); + editor.replace( + "build/test/config_upgrade_test/dkdm_recipients.xml", + boost::filesystem::canonical(dir / "dkdm_recipients.xml").string() + ); + } + + Config::override_path = dir; + Config::drop(); + + /* This should make a sqlite3 file containing the recipients from dkdm_recipients.xml */ + Config::instance(); + + { + DKDMRecipientList test(dir / "dkdm_recipients.sqlite3"); + + /* The detailed creation of sqlite3 from XML is tested in dkdm_recipient_list_test.cc */ + auto recipients = test.dkdm_recipients(); + BOOST_REQUIRE_EQUAL(recipients.size(), 2U); + BOOST_CHECK_EQUAL(recipients[0].second.name, "Bob's Epics"); + BOOST_CHECK_EQUAL(recipients[1].second.name, "Sharon's Shorts"); + + /* Add another recipient to the sqlite */ + test.add_dkdm_recipient({"Carl's Classics", "Oldies but goodies", {}, {}}); + } + + /* Reload the config; the old XML should not clobber the new sqlite3 */ + Config::drop(); + Config::instance(); + + { + DKDMRecipientList test(dir / "dkdm_recipients.sqlite3"); + + auto recipients = test.dkdm_recipients(); + BOOST_REQUIRE_EQUAL(recipients.size(), 3U); + BOOST_CHECK_EQUAL(recipients[0].second.name, "Bob's Epics"); + BOOST_CHECK_EQUAL(recipients[1].second.name, "Carl's Classics"); + BOOST_CHECK_EQUAL(recipients[2].second.name, "Sharon's Shorts"); + } } + +BOOST_AUTO_TEST_CASE(save_config_as_zip_test) +{ + ConfigRestorer cr; + + CinemaList cinemas; + cinemas.add_cinema({"My Great Cinema", {}, "", dcp::UTCOffset()}); + DKDMRecipientList recipients; + recipients.add_dkdm_recipient({"Carl's Classics", "Oldies but goodies", {}, {}}); + + boost::filesystem::path const zip = "build/test/save.zip"; + boost::system::error_code ec; + boost::filesystem::remove(zip, ec); + save_all_config_as_zip(zip); + Unzipper unzipper(zip); + + BOOST_CHECK(unzipper.contains("config.xml")); + BOOST_CHECK(unzipper.contains("cinemas.sqlite3")); + BOOST_CHECK(unzipper.contains("dkdm_recipients.sqlite3")); +} + + +/** Load a config ZIP file, which contains an XML cinemas file, and ask to overwrite + * the existing cinemas file that we had. + */ +BOOST_AUTO_TEST_CASE(load_config_from_zip_with_only_xml_current) +{ + ConfigRestorer cr; + + auto cinemas_file = Config::instance()->cinemas_file(); + + boost::filesystem::path const zip = "build/test/load.zip"; + boost::system::error_code ec; + boost::filesystem::remove(zip, ec); + + Zipper zipper(zip); + zipper.add( + "config.xml", + boost::algorithm::replace_all_copy( + dcp::file_to_string("test/data/2.18.config.xml"), + "/home/realldoesnt/exist/this/path/is/nonsense.xml", + "" + ) + ); + + zipper.add("cinemas.xml", dcp::file_to_string("test/data/cinemas.xml")); + zipper.close(); + + Config::instance()->load_from_zip(zip, Config::CinemasAction::WRITE_TO_CURRENT_PATH); + + CinemaList cinema_list(cinemas_file); + auto cinemas = cinema_list.cinemas(); + BOOST_REQUIRE_EQUAL(cinemas.size(), 3U); + BOOST_CHECK_EQUAL(cinemas[0].second.name, "Great"); + BOOST_CHECK_EQUAL(cinemas[1].second.name, "classy joint"); + BOOST_CHECK_EQUAL(cinemas[2].second.name, "stinking dump"); +} + + +/** Load a config ZIP file, which contains an XML cinemas file, and ask to write it to + * the location specified by the zipped config.xml. + */ +BOOST_AUTO_TEST_CASE(load_config_from_zip_with_only_xml_zip) +{ + ConfigRestorer cr; + + boost::filesystem::path const zip = "build/test/load.zip"; + boost::system::error_code ec; + boost::filesystem::remove(zip, ec); + + Zipper zipper(zip); + zipper.add( + "config.xml", + boost::algorithm::replace_all_copy( + dcp::file_to_string("test/data/2.18.config.xml"), + "/home/realldoesnt/exist/this/path/is/nonsense.xml", + "build/test/hide/it/here/cinemas.sqlite3" + ) + ); + + zipper.add("cinemas.xml", dcp::file_to_string("test/data/cinemas.xml")); + zipper.close(); + + Config::instance()->load_from_zip(zip, Config::CinemasAction::WRITE_TO_PATH_IN_ZIPPED_CONFIG); + + CinemaList cinema_list("build/test/hide/it/here/cinemas.sqlite3"); + auto cinemas = cinema_list.cinemas(); + BOOST_REQUIRE_EQUAL(cinemas.size(), 3U); + BOOST_CHECK_EQUAL(cinemas[0].second.name, "Great"); + BOOST_CHECK_EQUAL(cinemas[1].second.name, "classy joint"); + BOOST_CHECK_EQUAL(cinemas[2].second.name, "stinking dump"); +} + + +/** Load a config ZIP file, which contains an XML cinemas file, and ask to ignore it */ +BOOST_AUTO_TEST_CASE(load_config_from_zip_with_only_xml_ignore) +{ + ConfigRestorer cr; + + boost::filesystem::path const zip = "build/test/load.zip"; + boost::system::error_code ec; + boost::filesystem::remove(zip, ec); + + Zipper zipper(zip); + zipper.add( + "config.xml", + boost::algorithm::replace_all_copy( + dcp::file_to_string("test/data/2.18.config.xml"), + "/home/realldoesnt/exist/this/path/is/nonsense.xml", + "build/test/hide/it/here/cinemas.sqlite3" + ) + ); + + zipper.add("cinemas.xml", "<?xml version=\"1.0\" encoding=\"UTF-8\"?><Cinemas/>"); + zipper.close(); + + Config::instance()->load_from_zip(zip, Config::CinemasAction::IGNORE); + + CinemaList cinema_list("build/test/hide/it/here/cinemas.sqlite3"); + auto cinemas = cinema_list.cinemas(); + BOOST_CHECK(!cinemas.empty()); +} diff --git a/test/content_test.cc b/test/content_test.cc index 5ab714b47..dce7643dc 100644 --- a/test/content_test.cc +++ b/test/content_test.cc @@ -154,7 +154,7 @@ BOOST_AUTO_TEST_CASE (content_test6) film->set_audio_channels(16); make_and_verify_dcp (film); - check_dcp (TestPaths::private_data() / "fha", film); + check_dcp (TestPaths::private_data() / "v2.18.x" / "fha", film); cl.run (); } diff --git a/test/create_cli_test.cc b/test/create_cli_test.cc index aae5fb6de..09f1a4538 100644 --- a/test/create_cli_test.cc +++ b/test/create_cli_test.cc @@ -179,11 +179,11 @@ BOOST_AUTO_TEST_CASE (create_cli_test) BOOST_CHECK_EQUAL(cc._fourk, true); BOOST_CHECK (!cc.error); - cc = run ("dcpomatic2_create --j2k-bandwidth 120 foo.mp4"); + cc = run ("dcpomatic2_create --video-bit-rate 120 foo.mp4"); BOOST_REQUIRE_EQUAL (cc.content.size(), 1U); BOOST_CHECK_EQUAL (cc.content[0].path, "foo.mp4"); - BOOST_REQUIRE(cc._j2k_bandwidth); - BOOST_CHECK_EQUAL(*cc._j2k_bandwidth, 120000000); + BOOST_REQUIRE(cc._video_bit_rate); + BOOST_CHECK_EQUAL(*cc._video_bit_rate, 120000000); BOOST_CHECK (!cc.error); cc = run ("dcpomatic2_create --channel L fred.wav --channel R jim.wav sheila.wav"); diff --git a/test/data b/test/data -Subproject 4cb08962ba07e99c442cb12091c0347d84d8fd8 +Subproject b4fe926644bb49e442a3a920cb4601be8959bfb diff --git a/test/dcp_subtitle_test.cc b/test/dcp_subtitle_test.cc index 837362e84..e62bd70ba 100644 --- a/test/dcp_subtitle_test.cc +++ b/test/dcp_subtitle_test.cc @@ -37,7 +37,7 @@ #include "lib/text_content.h" #include "lib/text_decoder.h" #include "test.h" -#include <dcp/mono_picture_asset.h> +#include <dcp/mono_j2k_picture_asset.h> #include <dcp/openjpeg_image.h> #include <dcp/smpte_subtitle_asset.h> #include <boost/test/unit_test.hpp> @@ -327,7 +327,7 @@ BOOST_AUTO_TEST_CASE(entity_from_dcp_source) dcp::VerificationNote::Code::INVALID_SUBTITLE_SPACING, }); - dcp::MonoPictureAsset burnt(dcp_file(film, "j2c_")); + dcp::MonoJ2KPictureAsset burnt(dcp_file(film, "j2c_")); auto frame = burnt.start_read()->get_frame(12)->xyz_image(); auto const size = frame->size(); int max_X = 0; diff --git a/test/disk_writer_test.cc b/test/disk_writer_test.cc index 553adcae7..ff39eaaea 100644 --- a/test/disk_writer_test.cc +++ b/test/disk_writer_test.cc @@ -228,110 +228,3 @@ BOOST_AUTO_TEST_CASE (disk_writer_test3) cl.run(); } - - -BOOST_AUTO_TEST_CASE (osx_drive_identification_test) -{ - vector<OSXDisk> disks; - - auto disk = [&disks](string mount_point, string media_path, bool whole, std::vector<boost::filesystem::path> mount_points) - { - auto mp = analyse_osx_media_path (media_path); - if (mp) { - disks.push_back({mount_point, {}, {}, *mp, whole, mount_points, 0}); - } - }; - - auto find_unmounted = [](vector<OSXDisk> disks) { - auto drives = osx_disks_to_drives (disks); - vector<Drive> unmounted; - std::copy_if (drives.begin(), drives.end(), std::back_inserter(unmounted), [](Drive const& drive) { return !drive.mounted(); }); - return unmounted; - }; - - disk("/dev/disk4s1", "IODeviceTree:/arm-io@10F00000/apcie@90000000/pci-bridge1@1/pcie-xhci@0/@7:1", false, {}); - disk("/dev/disk4", "IODeviceTree:/arm-io@10F00000/apcie@90000000/pci-bridge1@1/pcie-xhci@0/@7:0", true, {}); - disk("/dev/disk0", "IODeviceTree:/arm-io@10F00000/ans@77400000/iop-ans-nub/AppleANS3NVMeController/@1:0", true, {}); - disk("/dev/disk0s1", "IODeviceTree:/arm-io@10F00000/ans@77400000/iop-ans-nub/AppleANS3NVMeController/@1:1", false, {}); - disk("/dev/disk0s2", "IODeviceTree:/arm-io@10F00000/ans@77400000/iop-ans-nub/AppleANS3NVMeController/@1:2", false, {}); - disk("/dev/disk0s3", "IODeviceTree:/arm-io@10F00000/ans@77400000/iop-ans-nub/AppleANS3NVMeController/@1:3", false, {}); - disk("/dev/disk1", "IOService:/AppleARMPE/arm-io@10F00000/AppleT810xIO/ans@77400000/AppleASCWrapV4/iop-ans-nub/RTBuddyV2/RTBuddyService/AppleANS3NVMeController/NS_01@1/IOBlockStorageDriver/APPLE SSD AP0512Q Media/IOGUIDPartitionScheme/iBootSystemContainer@1/AppleAPFSContainerScheme/AppleAPFSMedia", true, {}); - disk("/dev/disk2", "IOService:/AppleARMPE/arm-io@10F00000/AppleT810xIO/ans@77400000/AppleASCWrapV4/iop-ans-nub/RTBuddyV2/RTBuddyService/AppleANS3NVMeController/NS_01@1/IOBlockStorageDriver/APPLE SSD AP0512Q Media/IOGUIDPartitionScheme/RecoveryOSContainer@3/AppleAPFSContainerScheme/AppleAPFSMedia", true, {}); - disk("/dev/disk3", "IOService:/AppleARMPE/arm-io@10F00000/AppleT810xIO/ans@77400000/AppleASCWrapV4/iop-ans-nub/RTBuddyV2/RTBuddyService/AppleANS3NVMeController/NS_01@1/IOBlockStorageDriver/APPLE SSD AP0512Q Media/IOGUIDPartitionScheme/Container@2/AppleAPFSContainerScheme/AppleAPFSMedia", false, {}); - disk("/dev/disk1s1", "IOService:/AppleARMPE/arm-io@10F00000/AppleT810xIO/ans@77400000/AppleASCWrapV4/iop-ans-nub/RTBuddyV2/RTBuddyService/AppleANS3NVMeController/NS_01@1/IOBlockStorageDriver/APPLE SSD AP0512Q Media/IOGUIDPartitionScheme/iBootSystemContainer@1/AppleAPFSContainerScheme/AppleAPFSMedia/AppleAPFSContainer/iSCPreboot@1", false, {}); - disk("/dev/disk1s2", "IOService:/AppleARMPE/arm-io@10F00000/AppleT810xIO/ans@77400000/AppleASCWrapV4/iop-ans-nub/RTBuddyV2/RTBuddyService/AppleANS3NVMeController/NS_01@1/IOBlockStorageDriver/APPLE SSD AP0512Q Media/IOGUIDPartitionScheme/iBootSystemContainer@1/AppleAPFSContainerScheme/AppleAPFSMedia/AppleAPFSContainer/xART@2", false, {}); - disk("/dev/disk1s3", "IOService:/AppleARMPE/arm-io@10F00000/AppleT810xIO/ans@77400000/AppleASCWrapV4/iop-ans-nub/RTBuddyV2/RTBuddyService/AppleANS3NVMeController/NS_01@1/IOBlockStorageDriver/APPLE SSD AP0512Q Media/IOGUIDPartitionScheme/iBootSystemContainer@1/AppleAPFSContainerScheme/AppleAPFSMedia/AppleAPFSContainer/Hardware@3", false, {}); - disk("/dev/disk1s4", "IOService:/AppleARMPE/arm-io@10F00000/AppleT810xIO/ans@77400000/AppleASCWrapV4/iop-ans-nub/RTBuddyV2/RTBuddyService/AppleANS3NVMeController/NS_01@1/IOBlockStorageDriver/APPLE SSD AP0512Q Media/IOGUIDPartitionScheme/iBootSystemContainer@1/AppleAPFSContainerScheme/AppleAPFSMedia/AppleAPFSContainer/Recovery@4", false, {}); - disk("/dev/disk2s1", "IOService:/AppleARMPE/arm-io@10F00000/AppleT810xIO/ans@77400000/AppleASCWrapV4/iop-ans-nub/RTBuddyV2/RTBuddyService/AppleANS3NVMeController/NS_01@1/IOBlockStorageDriver/APPLE SSD AP0512Q Media/IOGUIDPartitionScheme/RecoveryOSContainer@3/AppleAPFSContainerScheme/AppleAPFSMedia/AppleAPFSContainer/Recovery@1", false, {}); - disk("/dev/disk2s2", "IOService:/AppleARMPE/arm-io@10F00000/AppleT810xIO/ans@77400000/AppleASCWrapV4/iop-ans-nub/RTBuddyV2/RTBuddyService/AppleANS3NVMeController/NS_01@1/IOBlockStorageDriver/APPLE SSD AP0512Q Media/IOGUIDPartitionScheme/RecoveryOSContainer@3/AppleAPFSContainerScheme/AppleAPFSMedia/AppleAPFSContainer/Update@2", false, {}); - disk("/dev/disk3s1", "IOService:/AppleARMPE/arm-io@10F00000/AppleT810xIO/ans@77400000/AppleASCWrapV4/iop-ans-nub/RTBuddyV2/RTBuddyService/AppleANS3NVMeController/NS_01@1/IOBlockStorageDriver/APPLE SSD AP0512Q Media/IOGUIDPartitionScheme/Container@2/AppleAPFSContainerScheme/AppleAPFSMedia/AppleAPFSContainer/Macintosh HD@1", false, {}); - disk("/dev/disk3s4", "IOService:/AppleARMPE/arm-io@10F00000/AppleT810xIO/ans@77400000/AppleASCWrapV4/iop-ans-nub/RTBuddyV2/RTBuddyService/AppleANS3NVMeController/NS_01@1/IOBlockStorageDriver/APPLE SSD AP0512Q Media/IOGUIDPartitionScheme/Container@2/AppleAPFSContainerScheme/AppleAPFSMedia/AppleAPFSContainer/Update@4", false, {"/System/Volumes/Update"}); - disk("/dev/disk3s5", "IOService:/AppleARMPE/arm-io@10F00000/AppleT810xIO/ans@77400000/AppleASCWrapV4/iop-ans-nub/RTBuddyV2/RTBuddyService/AppleANS3NVMeController/NS_01@1/IOBlockStorageDriver/APPLE SSD AP0512Q Media/IOGUIDPartitionScheme/Container@2/AppleAPFSContainerScheme/AppleAPFSMedia/AppleAPFSContainer/Data@5", false, {"/System/Volumes/Data"}); - disk("/dev/disk3s2", "IOService:/AppleARMPE/arm-io@10F00000/AppleT810xIO/ans@77400000/AppleASCWrapV4/iop-ans-nub/RTBuddyV2/RTBuddyService/AppleANS3NVMeController/NS_01@1/IOBlockStorageDriver/APPLE SSD AP0512Q Media/IOGUIDPartitionScheme/Container@2/AppleAPFSContainerScheme/AppleAPFSMedia/AppleAPFSContainer/Preboot@2", false, {"/System/Volumes/Preboot"}); - disk("/dev/disk3s3", "IOService:/AppleARMPE/arm-io@10F00000/AppleT810xIO/ans@77400000/AppleASCWrapV4/iop-ans-nub/RTBuddyV2/RTBuddyService/AppleANS3NVMeController/NS_01@1/IOBlockStorageDriver/APPLE SSD AP0512Q Media/IOGUIDPartitionScheme/Container@2/AppleAPFSContainerScheme/AppleAPFSMedia/AppleAPFSContainer/Recovery@3", false, {}); - disk("/dev/disk3s6", "IOService:/AppleARMPE/arm-io@10F00000/AppleT810xIO/ans@77400000/AppleASCWrapV4/iop-ans-nub/RTBuddyV2/RTBuddyService/AppleANS3NVMeController/NS_01@1/IOBlockStorageDriver/APPLE SSD AP0512Q Media/IOGUIDPartitionScheme/Container@2/AppleAPFSContainerScheme/AppleAPFSMedia/AppleAPFSContainer/VM@6", false, {"/System/Volumes/VM"}); - disk("/dev/disk3s1s1", "IOService:/AppleARMPE/arm-io@10F00000/AppleT810xIO/ans@77400000/AppleASCWrapV4/iop-ans-nub/RTBuddyV2/RTBuddyService/AppleANS3NVMeController/NS_01@1/IOBlockStorageDriver/APPLE SSD AP0512Q Media/IOGUIDPartitionScheme/Container@2/AppleAPFSContainerScheme/AppleAPFSMedia/AppleAPFSContainer/Macintosh HD@1/com.apple.os.update-EA882DCA7A28EBA0A6E94689836BB10D77D84D1AEE2468E17775A447AA815278@1", false, {"/"}); - - vector<Drive> writeable = find_unmounted (disks); - BOOST_REQUIRE_EQUAL (writeable.size(), 1U); - BOOST_CHECK_EQUAL (writeable[0].device(), "/dev/disk4"); - - disks.clear (); - disk("/dev/disk4s1", "IOService:/IOResources/IOHDIXController/IOHDIXHDDriveOutKernel@0/IODiskImageBlockStorageDeviceOutKernel/IOBlockStorageDriver/Apple UDIF read-only compressed (zlib) Media/IOGUIDPartitionScheme/disk image@1", false, {}); - disk("/dev/disk4", "IOService:/IOResources/IOHDIXController/IOHDIXHDDriveOutKernel@0/IODiskImageBlockStorageDeviceOutKernel/IOBlockStorageDriver/Apple UDIF read-only compressed (zlib) Media", true, {}); - disk("/dev/disk3s1", "IODeviceTree:/PCI0@0/XHC1@14/@2:1", false, {}); - disk("/dev/disk3", "IODeviceTree:/PCI0@0/XHC1@14/@2:0", true, {}); - disk("/dev/disk0", "IODeviceTree:/PCI0@0/SATA@1F,2/PRT1@1/PMP@0/@0:0", true, {}); - disk("/dev/disk0s1", "IODeviceTree:/PCI0@0/SATA@1F,2/PRT1@1/PMP@0/@0:1", false, {}); - disk("/dev/disk0s2", "IODeviceTree:/PCI0@0/SATA@1F,2/PRT1@1/PMP@0/@0:2", false, {"/Volumes/Macintosh HD"}); - disk("/dev/disk0s3", "IODeviceTree:/PCI0@0/SATA@1F,2/PRT1@1/PMP@0/@0:3", false, {}); - disk("/dev/disk0s4", "IODeviceTree:/PCI0@0/SATA@1F,2/PRT1@1/PMP@0/@0:4", false, {}); - disk("/dev/disk0s5", "IODeviceTree:/PCI0@0/SATA@1F,2/PRT1@1/PMP@0/@0:5", false, {"/Volumes/High Sierra"}); - disk("/dev/disk0s6", "IODeviceTree:/PCI0@0/SATA@1F,2/PRT1@1/PMP@0/@0:6", false, {}); - disk("/dev/disk0s7", "IODeviceTree:/PCI0@0/SATA@1F,2/PRT1@1/PMP@0/@0:7", false, {"/Volumes/Recovery HD"}); - disk("/dev/disk1", "IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/SATA@1F,2/AppleIntelPchSeriesAHCI/PRT1@1/IOAHCIDevice@0/AppleAHCIDiskDriver/IOAHCIBlockStorageDevice/IOBlockStorageDriver/APPLE HDD ST500LM012 Media/IOGUIDPartitionScheme/Untitled 3@3/AppleAPFSContainerScheme/AppleAPFSMedia", true, {}); - disk("/dev/disk", "IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/SATA@1F,2/AppleIntelPchSeriesAHCI/PRT1@1/IOAHCIDevice@0/AppleAHCIDiskDriver/IOAHCIBlockStorageDevice/IOBlockStorageDriver/APPLE HDD ST500LM012 Media/IOGUIDPartitionScheme/Untitled 4@4/AppleAPFSContainerScheme/AppleAPFSMedia", true, {}); - disk("/dev/disk1s1", "IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/SATA@1F,2/AppleIntelPchSeriesAHCI/PRT1@1/IOAHCIDevice@0/AppleAHCIDiskDriver/IOAHCIBlockStorageDevice/IOBlockStorageDriver/APPLE HDD ST500LM012 Media/IOGUIDPartitionScheme/Untitled 3@3/AppleAPFSContainerScheme/AppleAPFSMedia/AppleAPFSContainer/Untitled - Data@1", false, {"/Volumes/Untitled - Data"}); - disk("/dev/disk1s2", "IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/SATA@1F,2/AppleIntelPchSeriesAHCI/PRT1@1/IOAHCIDevice@0/AppleAHCIDiskDriver/IOAHCIBlockStorageDevice/IOBlockStorageDriver/APPLE HDD ST500LM012 Media/IOGUIDPartitionScheme/Untitled 3@3/AppleAPFSContainerScheme/AppleAPFSMedia/AppleAPFSContainer/Preboot@2", false, {}); - disk("/dev/disk1s3", "IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/SATA@1F,2/AppleIntelPchSeriesAHCI/PRT1@1/IOAHCIDevice@0/AppleAHCIDiskDriver/IOAHCIBlockStorageDevice/IOBlockStorageDriver/APPLE HDD ST500LM012 Media/IOGUIDPartitionScheme/Untitled 3@3/AppleAPFSContainerScheme/AppleAPFSMedia/AppleAPFSContainer/Recovery@3", false, {}); - disk("/dev/disk1s4", "IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/SATA@1F,2/AppleIntelPchSeriesAHCI/PRT1@1/IOAHCIDevice@0/AppleAHCIDiskDriver/IOAHCIBlockStorageDevice/IOBlockStorageDriver/APPLE HDD ST500LM012 Media/IOGUIDPartitionScheme/Untitled 3@3/AppleAPFSContainerScheme/AppleAPFSMedia/AppleAPFSContainer/VM@4", false, {}); - disk("/dev/disk1s5", "IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/SATA@1F,2/AppleIntelPchSeriesAHCI/PRT1@1/IOAHCIDevice@0/AppleAHCIDiskDriver/IOAHCIBlockStorageDevice/IOBlockStorageDriver/APPLE HDD ST500LM012 Media/IOGUIDPartitionScheme/Untitled 3@3/AppleAPFSContainerScheme/AppleAPFSMedia/AppleAPFSContainer/Untitled@5", false, {"/Volumes/Untitled"}); - disk("/dev/disk2s1", "IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/SATA@1F,2/AppleIntelPchSeriesAHCI/PRT1@1/IOAHCIDevice@0/AppleAHCIDiskDriver/IOAHCIBlockStorageDevice/IOBlockStorageDriver/APPLE HDD ST500LM012 Media/IOGUIDPartitionScheme/Untitled 4@4/AppleAPFSContainerScheme/AppleAPFSMedia/AppleAPFSContainer/Catalina - Data@1", false, {}); - disk("/dev/disk2s2", "IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/SATA@1F,2/AppleIntelPchSeriesAHCI/PRT1@1/IOAHCIDevice@0/AppleAHCIDiskDriver/IOAHCIBlockStorageDevice/IOBlockStorageDriver/APPLE HDD ST500LM012 Media/IOGUIDPartitionScheme/Untitled 4@4/AppleAPFSContainerScheme/AppleAPFSMedia/AppleAPFSContainer/Preboot@2", false, {}); - disk("/dev/disk2s3", "IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/SATA@1F,2/AppleIntelPchSeriesAHCI/PRT1@1/IOAHCIDevice@0/AppleAHCIDiskDriver/IOAHCIBlockStorageDevice/IOBlockStorageDriver/APPLE HDD ST500LM012 Media/IOGUIDPartitionScheme/Untitled 4@4/AppleAPFSContainerScheme/AppleAPFSMedia/AppleAPFSContainer/Recovery@3", false, {}); - disk("/dev/disk2s4", "IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/SATA@1F,2/AppleIntelPchSeriesAHCI/PRT1@1/IOAHCIDevice@0/AppleAHCIDiskDriver/IOAHCIBlockStorageDevice/IOBlockStorageDriver/APPLE HDD ST500LM012 Media/IOGUIDPartitionScheme/Untitled 4@4/AppleAPFSContainerScheme/AppleAPFSMedia/AppleAPFSContainer/VM@4", false, {"/private/var/vm"}); - disk("/dev/disk2s5", "IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/SATA@1F,2/AppleIntelPchSeriesAHCI/PRT1@1/IOAHCIDevice@0/AppleAHCIDiskDriver/IOAHCIBlockStorageDevice/IOBlockStorageDriver/APPLE HDD ST500LM012 Media/IOGUIDPartitionScheme/Untitled 4@4/AppleAPFSContainerScheme/AppleAPFSMedia/AppleAPFSContainer/Catalina@5", false, {"/"}); - - writeable = find_unmounted (disks); - BOOST_REQUIRE_EQUAL (writeable.size(), 1U); - BOOST_CHECK_EQUAL (writeable[0].device(), "/dev/disk3"); - - disks.clear (); - disk("/dev/disk7", "IOService:/IOResources/IOHDIXController/IOHDIXHDDriveOutKernel@3/IODiskImageBlockStorageDeviceOutKernel/IOBlockStorageDriver/Apple UDIF read-only compressed (zlib) Media", true, {}); - disk("/dev/disk7s1", "IOService:/IOResources/IOHDIXController/IOHDIXHDDriveOutKernel@3/IODiskImageBlockStorageDeviceOutKernel/IOBlockStorageDriver/Apple UDIF read-only compressed (zlib) Media/IOGUIDPartitionScheme/disk image@1", false, {}); - disk("/dev/disk6s1", "MediaPathKey is IOService:/IOResources/IOHDIXController/IOHDIXHDDriveOutKernel@2/IODiskImageBlockStorageDeviceOutKernel/IOBlockStorageDriver/Apple UDIF read-only compressed (zlib) Media/IOGUIDPartitionScheme/disk image@1", false, {}); - disk("/dev/disk6", "IOService:/IOResources/IOHDIXController/IOHDIXHDDriveOutKernel@2/IODiskImageBlockStorageDeviceOutKernel/IOBlockStorageDriver/Apple UDIF read-only compressed (zlib) Media", true, {}); - disk("/dev/disk5s1", "IOService:/IOResources/IOHDIXController/IOHDIXHDDriveOutKernel@1/IODiskImageBlockStorageDeviceOutKernel/IOBlockStorageDriver/Apple UDIF read-only compressed (zlib) Media/IOGUIDPartitionScheme/disk image@1", false, {}); - disk("/dev/disk5", "IOService:/IOResources/IOHDIXController/IOHDIXHDDriveOutKernel@1/IODiskImageBlockStorageDeviceOutKernel/IOBlockStorageDriver/Apple UDIF read-only compressed (zlib) Media", true, {}); - disk("/dev/disk4s1", "IOService:/IOResources/IOHDIXController/IOHDIXHDDriveOutKernel@0/IODiskImageBlockStorageDeviceOutKernel/IOBlockStorageDriver/Apple UDIF read-only compressed (zlib) Media/IOGUIDPartitionScheme/disk image@1", false, {}); - disk("/dev/disk4", "IOService:/IOResources/IOHDIXController/IOHDIXHDDriveOutKernel@0/IODiskImageBlockStorageDeviceOutKernel/IOBlockStorageDriver/Apple UDIF read-only compressed (zlib) Media", true, {}); - disk("/dev/disk0", "IODeviceTree:/PCI0@1e0000/pci8086,2829@1F,2/PRT3@3/PMP@0/@0:0", true, {}); - disk("/dev/disk2", "IODeviceTree:/PCI0@1e0000/pci8086,2829@1F,2/PRT1@1/PMP@0/@0:0", true, {}); - disk("/dev/disk1", "IODeviceTree:/PCI0@1e0000/pci8086,2829@1F,2/PRT0@0/PMP@0/@0:0", true, {}); - disk("/dev/disk1s1", "IODeviceTree:/PCI0@1e0000/pci8086,2829@1F,2/PRT0@0/PMP@0/@0:1", false, {"/Volumes/EFI"}); - disk("/dev/disk2s1", "IODeviceTree:/PCI0@1e0000/pci8086,2829@1F,2/PRT1@1/PMP@0/@0:1", false, {}); - disk("/dev/disk2s2", "IODeviceTree:/PCI0@1e0000/pci8086,2829@1F,2/PRT1@1/PMP@0/@0:2", false, {}); - disk("/dev/disk3", "IOService:/AppleACPIPlatformExpert/PCI0@1e0000/AppleACPIPCI/pci8086,2829@1F,2/AppleAHCI/PRT1@1/IOAHCIDevice@0/AppleAHCIDiskDriver/IOAHCIBlockStorageDevice/IOBlockStorageDriver/VBOX HARDDISK Media/IOGUIDPartitionScheme/disk image@2/AppleAPFSContainerScheme/AppleAPFSMedia", false, {}); - disk("/dev/disk3s1", "IOService:/AppleACPIPlatformExpert/PCI0@1e0000/AppleACPIPCI/pci8086,2829@1F,2/AppleAHCI/PRT1@1/IOAHCIDevice@0/AppleAHCIDiskDriver/IOAHCIBlockStorageDevice/IOBlockStorageDriver/VBOX HARDDISK Media/IOGUIDPartitionScheme/disk image@2/AppleAPFSContainerScheme/AppleAPFSMedia/AppleAPFSContainer/macOS - Data@1", false, {"/System/Volumes/Data"}); - disk("/dev/disk3s2", "IOService:/AppleACPIPlatformExpert/PCI0@1e0000/AppleACPIPCI/pci8086,2829@1F,2/AppleAHCI/PRT1@1/IOAHCIDevice@0/AppleAHCIDiskDriver/IOAHCIBlockStorageDevice/IOBlockStorageDriver/VBOX HARDDISK Media/IOGUIDPartitionScheme/disk image@2/AppleAPFSContainerScheme/AppleAPFSMedia/AppleAPFSContainer/Preboot@2", false, {"/System/Volumes/Preboot"}); - disk("/dev/disk3s3", "IOService:/AppleACPIPlatformExpert/PCI0@1e0000/AppleACPIPCI/pci8086,2829@1F,2/AppleAHCI/PRT1@1/IOAHCIDevice@0/AppleAHCIDiskDriver/IOAHCIBlockStorageDevice/IOBlockStorageDriver/VBOX HARDDISK Media/IOGUIDPartitionScheme/disk image@2/AppleAPFSContainerScheme/AppleAPFSMedia/AppleAPFSContainer/Recovery@3", false, {}); - disk("/dev/disk3s4", "IOService:/AppleACPIPlatformExpert/PCI0@1e0000/AppleACPIPCI/pci8086,2829@1F,2/AppleAHCI/PRT1@1/IOAHCIDevice@0/AppleAHCIDiskDriver/IOAHCIBlockStorageDevice/IOBlockStorageDriver/VBOX HARDDISK Media/IOGUIDPartitionScheme/disk image@2/AppleAPFSContainerScheme/AppleAPFSMedia/AppleAPFSContainer/VM@4", false, {"/System/Volumes/VM"}); - disk("/dev/disk3s5", "IOService:/AppleACPIPlatformExpert/PCI0@1e0000/AppleACPIPCI/pci8086,2829@1F,2/AppleAHCI/PRT1@1/IOAHCIDevice@0/AppleAHCIDiskDriver/IOAHCIBlockStorageDevice/IOBlockStorageDriver/VBOX HARDDISK Media/IOGUIDPartitionScheme/disk image@2/AppleAPFSContainerScheme/AppleAPFSMedia/AppleAPFSContainer/macOS@5", false, {}); - disk("/dev/disk3s6", "IOService:/AppleACPIPlatformExpert/PCI0@1e0000/AppleACPIPCI/pci8086,2829@1F,2/AppleAHCI/PRT1@1/IOAHCIDevice@0/AppleAHCIDiskDriver/IOAHCIBlockStorageDevice/IOBlockStorageDriver/VBOX HARDDISK Media/IOGUIDPartitionScheme/disk image@2/AppleAPFSContainerScheme/AppleAPFSMedia/AppleAPFSContainer/Update@6", false, {"/System/Volumes/Update"}); - disk("/dev/disk3s5s1", "IOService:/AppleACPIPlatformExpert/PCI0@1e0000/AppleACPIPCI/pci8086,2829@1F,2/AppleAHCI/PRT1@1/IOAHCIDevice@0/AppleAHCIDiskDriver/IOAHCIBlockStorageDevice/IOBlockStorageDriver/VBOX HARDDISK Media/IOGUIDPartitionScheme/disk image@2/AppleAPFSContainerScheme/AppleAPFSMedia/AppleAPFSContainer/macOS@5/com.apple.os.update-5523D8E63431315F9F949CCDD0274BF797F5CEE4EAF616D4C66A01B8D6A83C7B@1", false, {"/"}); - - writeable = find_unmounted (disks); - BOOST_REQUIRE_EQUAL (writeable.size(), 1U); - BOOST_CHECK_EQUAL (writeable[0].device(), "/dev/disk0"); -} - diff --git a/test/dkdm_recipient_list_test.cc b/test/dkdm_recipient_list_test.cc new file mode 100644 index 000000000..20f669e76 --- /dev/null +++ b/test/dkdm_recipient_list_test.cc @@ -0,0 +1,56 @@ +/* + Copyright (C) 2024 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 "lib/dkdm_recipient.h" +#include "lib/dkdm_recipient_list.h" +#include <dcp/filesystem.h> +#include <boost/test/unit_test.hpp> + + +BOOST_AUTO_TEST_CASE(dkdm_receipient_list_copy_from_xml_test) +{ + Config::override_path = "build/test/dkdm_recipient_list_copy_config"; + dcp::filesystem::remove_all(*Config::override_path); + dcp::filesystem::create_directories(*Config::override_path); + dcp::filesystem::copy_file("test/data/dkdm_recipients.xml", *Config::override_path / "dkdm_recipients.xml"); + Config::drop(); + + DKDMRecipientList dkdm_recipient_list; + dkdm_recipient_list.read_legacy_file(Config::instance()->read_path("dkdm_recipients.xml")); + auto dkdm_recipients = dkdm_recipient_list.dkdm_recipients(); + BOOST_REQUIRE_EQUAL(dkdm_recipients.size(), 2U); + + auto dkdm_recipient_iter = dkdm_recipients.begin(); + BOOST_CHECK_EQUAL(dkdm_recipient_iter->second.name, "Bob's Epics"); + BOOST_CHECK_EQUAL(dkdm_recipient_iter->second.emails.size(), 2U); + BOOST_CHECK_EQUAL(dkdm_recipient_iter->second.emails[0], "epicbob@gmail.com"); + BOOST_CHECK_EQUAL(dkdm_recipient_iter->second.emails[1], "boblikesemlong@cinema-bob.com"); + BOOST_CHECK_EQUAL(dkdm_recipient_iter->second.recipient->subject_dn_qualifier(), "r5/Q5f3UTm7qzoF5QzNZP6aEuvI="); + ++dkdm_recipient_iter; + + BOOST_CHECK_EQUAL(dkdm_recipient_iter->second.name, "Sharon's Shorts"); + BOOST_CHECK_EQUAL(dkdm_recipient_iter->second.notes, "Even if it sucks, at least it's over quickly"); + BOOST_CHECK_EQUAL(dkdm_recipient_iter->second.recipient->subject_dn_qualifier(), "FHerM3Us/DWuqD1MnztStSlFJO0="); + ++dkdm_recipient_iter; +} + + diff --git a/test/ffmpeg_decoder_seek_test.cc b/test/ffmpeg_decoder_seek_test.cc index 4dceae86b..f38ef3564 100644 --- a/test/ffmpeg_decoder_seek_test.cc +++ b/test/ffmpeg_decoder_seek_test.cc @@ -64,18 +64,18 @@ store (ContentVideo v) static void -check (shared_ptr<FFmpegDecoder> decoder, int frame) +check (shared_ptr<FFmpegDecoder> decoder, ContentTime time) { BOOST_REQUIRE (decoder->ffmpeg_content()->video_frame_rate ()); - decoder->seek (ContentTime::from_frames (frame, decoder->ffmpeg_content()->video_frame_rate().get()), true); + decoder->seek(time, true); stored = optional<ContentVideo> (); while (!decoder->pass() && !stored) {} - BOOST_CHECK (stored->frame <= frame); + BOOST_CHECK(stored->time <= time); } static void -test (boost::filesystem::path file, vector<int> frames) +test (boost::filesystem::path file, vector<ContentTime> times) { auto path = TestPaths::private_data() / file; BOOST_REQUIRE (boost::filesystem::exists (path)); @@ -87,7 +87,7 @@ test (boost::filesystem::path file, vector<int> frames) auto decoder = make_shared<FFmpegDecoder>(film, content, false); decoder->video->Data.connect (bind (&store, _1)); - for (auto i: frames) { + for (auto i: times) { check (decoder, i); } } @@ -95,10 +95,43 @@ test (boost::filesystem::path file, vector<int> frames) BOOST_AUTO_TEST_CASE (ffmpeg_decoder_seek_test) { - vector<int> frames = { 0, 42, 999, 0 }; - - test ("boon_telly.mkv", frames); - test ("Sintel_Trailer1.480p.DivX_Plus_HD.mkv", frames); - test ("prophet_long_clip.mkv", { 15, 42, 999, 15 }); - test ("dolby_aurora.vob", { 0, 125, 250, 41 }); + test( + "boon_telly.mkv", + { + ContentTime::from_frames(0, 29.97), + ContentTime::from_frames(42, 29.97), + ContentTime::from_frames(999, 29.97), + ContentTime::from_frames(0, 29.97), + } + ); + + test( + "Sintel_Trailer1.480p.DivX_Plus_HD.mkv", + { + ContentTime::from_frames(0, 24), + ContentTime::from_frames(42, 24), + ContentTime::from_frames(999, 24), + ContentTime::from_frames(0, 24), + } + ); + + test( + "prophet_long_clip.mkv", + { + ContentTime::from_frames(15, 23.976), + ContentTime::from_frames(42, 23.976), + ContentTime::from_frames(999, 23.976), + ContentTime::from_frames(15, 23.976) + } + ); + + test( + "dolby_aurora.vob", + { + ContentTime::from_frames(0, 25), + ContentTime::from_frames(125, 25), + ContentTime::from_frames(250, 25), + ContentTime::from_frames(41, 25) + } + ); } diff --git a/test/ffmpeg_encoder_test.cc b/test/ffmpeg_encoder_test.cc index dc57b473b..67bc0ce1e 100644 --- a/test/ffmpeg_encoder_test.cc +++ b/test/ffmpeg_encoder_test.cc @@ -28,8 +28,8 @@ #include "lib/dcp_content.h" #include "lib/dcpomatic_log.h" #include "lib/ffmpeg_content.h" -#include "lib/ffmpeg_encoder.h" #include "lib/ffmpeg_examiner.h" +#include "lib/ffmpeg_film_encoder.h" #include "lib/film.h" #include "lib/image_content.h" #include "lib/ratio.h" @@ -84,7 +84,7 @@ ffmpeg_content_test (int number, boost::filesystem::path content, ExportFormat f auto job = make_shared<TranscodeJob>(film, TranscodeJob::ChangedBehaviour::IGNORE); auto file = boost::filesystem::path("build") / "test" / String::compose("%1.%2", name, extension); cl.add (file); - FFmpegEncoder encoder (film, job, file, format, false, false, false, 23); + FFmpegFilmEncoder encoder(film, job, file, format, false, false, false, 23); encoder.go (); cl.run (); @@ -135,7 +135,7 @@ BOOST_AUTO_TEST_CASE (ffmpeg_encoder_prores_test5) film->write_metadata (); auto job = make_shared<TranscodeJob>(film, TranscodeJob::ChangedBehaviour::IGNORE); - FFmpegEncoder encoder (film, job, "build/test/ffmpeg_encoder_prores_test5.mov", ExportFormat::PRORES_HQ, false, false, false, 23); + FFmpegFilmEncoder encoder(film, job, "build/test/ffmpeg_encoder_prores_test5.mov", ExportFormat::PRORES_HQ, false, false, false, 23); encoder.go (); } @@ -157,7 +157,7 @@ BOOST_AUTO_TEST_CASE (ffmpeg_encoder_prores_test6) film->write_metadata(); auto job = make_shared<TranscodeJob> (film, TranscodeJob::ChangedBehaviour::IGNORE); - FFmpegEncoder encoder (film, job, "build/test/ffmpeg_encoder_prores_test6.mov", ExportFormat::PRORES_HQ, false, false, false, 23); + FFmpegFilmEncoder encoder(film, job, "build/test/ffmpeg_encoder_prores_test6.mov", ExportFormat::PRORES_HQ, false, false, false, 23); encoder.go (); } @@ -182,7 +182,7 @@ BOOST_AUTO_TEST_CASE (ffmpeg_encoder_prores_test7) s->only_text()->set_effect_colour (dcp::Colour (0, 255, 255)); auto job = make_shared<TranscodeJob>(film, TranscodeJob::ChangedBehaviour::IGNORE); - FFmpegEncoder encoder (film, job, "build/test/ffmpeg_encoder_prores_test7.mov", ExportFormat::PRORES_HQ, false, false, false, 23); + FFmpegFilmEncoder encoder(film, job, "build/test/ffmpeg_encoder_prores_test7.mov", ExportFormat::PRORES_HQ, false, false, false, 23); encoder.go (); } @@ -211,7 +211,7 @@ BOOST_AUTO_TEST_CASE (ffmpeg_encoder_h264_test2) film->write_metadata(); auto job = make_shared<TranscodeJob>(film, TranscodeJob::ChangedBehaviour::IGNORE); - FFmpegEncoder encoder (film, job, "build/test/ffmpeg_encoder_h264_test2.mp4", ExportFormat::H264_AAC, false, false, false, 23); + FFmpegFilmEncoder encoder(film, job, "build/test/ffmpeg_encoder_h264_test2.mp4", ExportFormat::H264_AAC, false, false, false, 23); encoder.go (); } @@ -237,7 +237,7 @@ BOOST_AUTO_TEST_CASE (ffmpeg_encoder_h264_test3) film->write_metadata(); auto job = make_shared<TranscodeJob> (film, TranscodeJob::ChangedBehaviour::IGNORE); - FFmpegEncoder encoder (film, job, "build/test/ffmpeg_encoder_h264_test3.mp4", ExportFormat::H264_AAC, false, false, false, 23); + FFmpegFilmEncoder encoder(film, job, "build/test/ffmpeg_encoder_h264_test3.mp4", ExportFormat::H264_AAC, false, false, false, 23); encoder.go (); } @@ -251,7 +251,7 @@ BOOST_AUTO_TEST_CASE (ffmpeg_encoder_h264_test4) film->set_container(Ratio::from_id("185")); auto job = make_shared<TranscodeJob>(film, TranscodeJob::ChangedBehaviour::IGNORE); - FFmpegEncoder encoder(film, job, "build/test/ffmpeg_encoder_h264_test4.mp4", ExportFormat::H264_AAC, false, false, false, 23); + FFmpegFilmEncoder encoder(film, job, "build/test/ffmpeg_encoder_h264_test4.mp4", ExportFormat::H264_AAC, false, false, false, 23); encoder.go(); } @@ -259,8 +259,8 @@ BOOST_AUTO_TEST_CASE (ffmpeg_encoder_h264_test4) /** Test mixdown from 5.1 to stereo */ BOOST_AUTO_TEST_CASE (ffmpeg_encoder_h264_test5) { - auto film = new_test_film ("ffmpeg_transcoder_h264_test5"); - film->set_name ("ffmpeg_transcoder_h264_test5"); + auto film = new_test_film("ffmpeg_encoder_h264_test5"); + film->set_name("ffmpeg_encoder_h264_test5"); film->set_container (Ratio::from_id ("185")); film->set_audio_channels (6); @@ -306,7 +306,7 @@ BOOST_AUTO_TEST_CASE (ffmpeg_encoder_h264_test5) Rs->audio->set_mapping (map); auto job = make_shared<TranscodeJob>(film, TranscodeJob::ChangedBehaviour::IGNORE); - FFmpegEncoder encoder (film, job, "build/test/ffmpeg_encoder_h264_test5.mp4", ExportFormat::H264_AAC, true, false, false, 23); + FFmpegFilmEncoder encoder(film, job, "build/test/ffmpeg_encoder_h264_test5.mp4", ExportFormat::H264_AAC, true, false, false, 23); encoder.go (); check_ffmpeg ("build/test/ffmpeg_encoder_h264_test5.mp4", "test/data/ffmpeg_encoder_h264_test5.mp4", 1); @@ -334,7 +334,7 @@ BOOST_AUTO_TEST_CASE (ffmpeg_encoder_h264_test6) } auto job = make_shared<TranscodeJob>(film2, TranscodeJob::ChangedBehaviour::IGNORE); - FFmpegEncoder encoder (film2, job, "build/test/ffmpeg_encoder_h264_test6_vf.mp4", ExportFormat::H264_AAC, true, false, false, 23); + FFmpegFilmEncoder encoder(film2, job, "build/test/ffmpeg_encoder_h264_test6_vf.mp4", ExportFormat::H264_AAC, true, false, false, 23); encoder.go (); } @@ -346,7 +346,7 @@ BOOST_AUTO_TEST_CASE (ffmpeg_encoder_3d_dcp_to_h264) auto film2 = new_test_film2 ("ffmpeg_encoder_3d_dcp_to_h264_export", {dcp}); auto job = make_shared<TranscodeJob>(film2, TranscodeJob::ChangedBehaviour::IGNORE); - FFmpegEncoder encoder (film2, job, "build/test/ffmpeg_encoder_3d_dcp_to_h264.mp4", ExportFormat::H264_AAC, true, false, false, 23); + FFmpegFilmEncoder encoder(film2, job, "build/test/ffmpeg_encoder_3d_dcp_to_h264.mp4", ExportFormat::H264_AAC, true, false, false, 23); encoder.go (); } @@ -368,7 +368,7 @@ BOOST_AUTO_TEST_CASE (ffmpeg_encoder_h264_test7) auto film2 = new_test_film2 ("ffmpeg_encoder_h264_test7_export", {dcp}); auto job = make_shared<TranscodeJob> (film2, TranscodeJob::ChangedBehaviour::IGNORE); - FFmpegEncoder encoder (film2, job, "build/test/ffmpeg_encoder_h264_test7.mp4", ExportFormat::H264_AAC, true, false, false, 23); + FFmpegFilmEncoder encoder(film2, job, "build/test/ffmpeg_encoder_h264_test7.mp4", ExportFormat::H264_AAC, true, false, false, 23); encoder.go (); } @@ -380,7 +380,7 @@ BOOST_AUTO_TEST_CASE(ffmpeg_encoder_2d_content_in_3d_project) film->set_three_d(true); auto job = make_shared<TranscodeJob>(film, TranscodeJob::ChangedBehaviour::IGNORE); - FFmpegEncoder encoder(film, job, "build/test/ffmpeg_encoder_2d_content_in_3d_project.mp4", ExportFormat::H264_AAC, true, false, false, 23); + FFmpegFilmEncoder encoder(film, job, "build/test/ffmpeg_encoder_2d_content_in_3d_project.mp4", ExportFormat::H264_AAC, true, false, false, 23); encoder.go(); } @@ -394,7 +394,7 @@ BOOST_AUTO_TEST_CASE (ffmpeg_encoder_h264_test8) film->set_audio_channels (2); auto job = make_shared<TranscodeJob>(film, TranscodeJob::ChangedBehaviour::IGNORE); - FFmpegEncoder encoder(film, job, "build/test/ffmpeg_encoder_h264_test8.mp4", ExportFormat::H264_AAC, true, false, false, 23); + FFmpegFilmEncoder encoder(film, job, "build/test/ffmpeg_encoder_h264_test8.mp4", ExportFormat::H264_AAC, true, false, false, 23); encoder.go(); } @@ -415,7 +415,7 @@ BOOST_AUTO_TEST_CASE (ffmpeg_encoder_h264_test9) film->write_metadata (); auto job = make_shared<TranscodeJob>(film, TranscodeJob::ChangedBehaviour::IGNORE); - FFmpegEncoder encoder (film, job, "build/test/ffmpeg_encoder_prores_test9.mov", ExportFormat::H264_AAC, false, false, false, 23); + FFmpegFilmEncoder encoder (film, job, "build/test/ffmpeg_encoder_prores_test9.mov", ExportFormat::H264_AAC, false, false, false, 23); encoder.go (); } @@ -430,7 +430,7 @@ BOOST_AUTO_TEST_CASE (ffmpeg_encoder_prores_from_dcp_with_crop) film->write_metadata (); auto job = make_shared<TranscodeJob>(film, TranscodeJob::ChangedBehaviour::IGNORE); - FFmpegEncoder encoder (film, job, "build/test/ffmpeg_encoder_prores_from_dcp_with_crop.mov", ExportFormat::PRORES_HQ, false, false, false, 23); + FFmpegFilmEncoder encoder (film, job, "build/test/ffmpeg_encoder_prores_from_dcp_with_crop.mov", ExportFormat::PRORES_HQ, false, false, false, 23); encoder.go (); } @@ -445,7 +445,7 @@ BOOST_AUTO_TEST_CASE (ffmpeg_encoder_h264_from_dcp_with_crop) film->write_metadata (); auto job = make_shared<TranscodeJob>(film, TranscodeJob::ChangedBehaviour::IGNORE); - FFmpegEncoder encoder (film, job, "build/test/ffmpeg_encoder_prores_from_dcp_with_crop.mov", ExportFormat::H264_AAC, false, false, false, 23); + FFmpegFilmEncoder encoder (film, job, "build/test/ffmpeg_encoder_prores_from_dcp_with_crop.mov", ExportFormat::H264_AAC, false, false, false, 23); encoder.go (); } @@ -461,7 +461,7 @@ BOOST_AUTO_TEST_CASE (ffmpeg_encoder_h264_with_reels) content2->video->set_length (240); auto job = make_shared<TranscodeJob>(film, TranscodeJob::ChangedBehaviour::IGNORE); - FFmpegEncoder encoder (film, job, "build/test/ffmpeg_encoder_h264_with_reels.mov", ExportFormat::H264_AAC, false, true, false, 23); + FFmpegFilmEncoder encoder (film, job, "build/test/ffmpeg_encoder_h264_with_reels.mov", ExportFormat::H264_AAC, false, true, false, 23); encoder.go (); auto check = [](boost::filesystem::path path) { @@ -485,7 +485,7 @@ BOOST_AUTO_TEST_CASE (ffmpeg_encoder_prores_regression_1) auto film = new_test_film2 ("ffmpeg_encoder_prores_regression_1", { content }); auto job = make_shared<TranscodeJob>(film, TranscodeJob::ChangedBehaviour::IGNORE); - FFmpegEncoder encoder (film, job, "build/test/ffmpeg_encoder_prores_regression_1.mov", ExportFormat::PRORES_HQ, false, true, false, 23); + FFmpegFilmEncoder encoder (film, job, "build/test/ffmpeg_encoder_prores_regression_1.mov", ExportFormat::PRORES_HQ, false, true, false, 23); encoder.go (); cl.add("build/test/ffmpeg_encoder_prores_regression_1.mov"); @@ -505,7 +505,7 @@ BOOST_AUTO_TEST_CASE (ffmpeg_encoder_prores_regression_2) auto film = new_test_film2 ("ffmpeg_encoder_prores_regression_2", { content }); auto job = make_shared<TranscodeJob>(film, TranscodeJob::ChangedBehaviour::IGNORE); - FFmpegEncoder encoder (film, job, "build/test/ffmpeg_encoder_prores_regression_2.mov", ExportFormat::PRORES_HQ, false, true, false, 23); + FFmpegFilmEncoder encoder (film, job, "build/test/ffmpeg_encoder_prores_regression_2.mov", ExportFormat::PRORES_HQ, false, true, false, 23); encoder.go (); dcpomatic_log->set_types(logs); @@ -524,7 +524,7 @@ BOOST_AUTO_TEST_CASE(ffmpeg_encoder_missing_frame_at_end) boost::filesystem::path log("build/test/ffmpeg_encoder_missing_frame_at_end.log"); auto job = make_shared<TranscodeJob>(film, TranscodeJob::ChangedBehaviour::IGNORE); - FFmpegEncoder encoder(film, job, output, ExportFormat::PRORES_HQ, false, true, false, 23); + FFmpegFilmEncoder encoder(film, job, output, ExportFormat::PRORES_HQ, false, true, false, 23); encoder.go(); run_ffprobe(output, log, false, "-show_frames -show_format -show_streams -select_streams v:0"); diff --git a/test/ffmpeg_examiner_test.cc b/test/ffmpeg_examiner_test.cc index c745335ae..231bd16e0 100644 --- a/test/ffmpeg_examiner_test.cc +++ b/test/ffmpeg_examiner_test.cc @@ -64,7 +64,7 @@ BOOST_AUTO_TEST_CASE (ffmpeg_examiner_probesize_test) BOOST_CHECK_EQUAL (examiner->audio_streams()[0]->frame_rate(), 48000); BOOST_CHECK_EQUAL (examiner->audio_streams()[0]->channels(), 2); BOOST_CHECK_EQUAL (examiner->audio_streams()[1]->frame_rate(), 48000); - BOOST_CHECK_EQUAL (examiner->audio_streams()[1]->channels(), 5); + BOOST_CHECK_EQUAL (examiner->audio_streams()[1]->channels(), 6); } diff --git a/test/film_metadata_test.cc b/test/film_metadata_test.cc index 878e60254..c52df6d72 100644 --- a/test/film_metadata_test.cc +++ b/test/film_metadata_test.cc @@ -57,7 +57,7 @@ BOOST_AUTO_TEST_CASE (film_metadata_test) film->set_name ("fred"); film->set_dcp_content_type (DCPContentType::from_isdcf_name ("SHR")); film->set_container (Ratio::from_id ("185")); - film->set_j2k_bandwidth (200000000); + film->set_video_bit_rate(VideoEncoding::JPEG2000, 200000000); film->set_interop (false); film->set_chain (string("")); film->set_distributor (string("")); @@ -66,7 +66,7 @@ BOOST_AUTO_TEST_CASE (film_metadata_test) film->set_audio_channels(6); film->write_metadata (); - list<string> ignore = { "Key", "ContextID", "LastWrittenBy" }; + list<Glib::ustring> ignore = { "Key", "ContextID", "LastWrittenBy" }; check_xml ("test/data/metadata.xml.ref", dir.string() + "/metadata.xml", ignore); auto g = make_shared<Film>(dir); diff --git a/test/image_filename_sorter_test.cc b/test/image_filename_sorter_test.cc index eb662a120..29b550753 100644 --- a/test/image_filename_sorter_test.cc +++ b/test/image_filename_sorter_test.cc @@ -28,9 +28,10 @@ #include "lib/image_filename_sorter.h" #include "lib/compose.hpp" #include <boost/test/unit_test.hpp> +#include <algorithm> +#include <random> -using std::random_shuffle; using std::sort; using std::vector; @@ -69,7 +70,11 @@ BOOST_AUTO_TEST_CASE (image_filename_sorter_test2) for (int i = 0; i < 100000; ++i) { paths.push_back(String::compose("some.filename.with.%1.number.tiff", i)); } - random_shuffle (paths.begin(), paths.end()); + + std::random_device rd; + std::mt19937 generator(rd()); + std::shuffle(paths.begin(), paths.end(), generator); + sort (paths.begin(), paths.end(), ImageFilenameSorter()); for (int i = 0; i < 100000; ++i) { BOOST_CHECK_EQUAL(paths[i].string(), String::compose("some.filename.with.%1.number.tiff", i)); diff --git a/test/j2k_encode_threading_test.cc b/test/j2k_encode_threading_test.cc new file mode 100644 index 000000000..ee219fbe0 --- /dev/null +++ b/test/j2k_encode_threading_test.cc @@ -0,0 +1,117 @@ +/* + Copyright (C) 2023 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 "lib/content_factory.h" +#include "lib/dcp_film_encoder.h" +#include "lib/dcp_transcode_job.h" +#include "lib/encode_server_description.h" +#include "lib/film.h" +#include "lib/j2k_encoder.h" +#include "lib/job_manager.h" +#include "lib/make_dcp.h" +#include "lib/transcode_job.h" +#include "test.h" +#include <dcp/cpl.h> +#include <dcp/dcp.h> +#include <dcp/reel.h> +#include <dcp/reel_picture_asset.h> +#include <boost/test/unit_test.hpp> + + +using std::dynamic_pointer_cast; +using std::list; + + +BOOST_AUTO_TEST_CASE(local_threads_created_and_destroyed) +{ + auto film = new_test_film2("local_threads_created_and_destroyed", {}); + Writer writer(film, {}); + J2KEncoder encoder(film, writer); + + encoder.remake_threads(32, 0, {}); + BOOST_CHECK_EQUAL(encoder._threads.size(), 32U); + + encoder.remake_threads(9, 0, {}); + BOOST_CHECK_EQUAL(encoder._threads.size(), 9U); + + encoder.end(); + BOOST_CHECK_EQUAL(encoder._threads.size(), 0U); +} + + +BOOST_AUTO_TEST_CASE(remote_threads_created_and_destroyed) +{ + auto film = new_test_film2("remote_threads_created_and_destroyed", {}); + Writer writer(film, {}); + J2KEncoder encoder(film, writer); + + list<EncodeServerDescription> servers = { + { "fred", 7, SERVER_LINK_VERSION }, + { "jim", 2, SERVER_LINK_VERSION }, + { "sheila", 14, SERVER_LINK_VERSION }, + }; + + encoder.remake_threads(0, 0, servers); + BOOST_CHECK_EQUAL(encoder._threads.size(), 7U + 2U + 14U); + + servers = { + { "fred", 7, SERVER_LINK_VERSION }, + { "jim", 5, SERVER_LINK_VERSION }, + { "sheila", 14, SERVER_LINK_VERSION }, + }; + + encoder.remake_threads(0, 0, servers); + BOOST_CHECK_EQUAL(encoder._threads.size(), 7U + 5U + 14U); + + servers = { + { "fred", 0, SERVER_LINK_VERSION }, + { "jim", 0, SERVER_LINK_VERSION }, + { "sheila", 11, SERVER_LINK_VERSION }, + }; + + encoder.remake_threads(0, 0, servers); + BOOST_CHECK_EQUAL(encoder._threads.size(), 11U); +} + + +BOOST_AUTO_TEST_CASE(frames_not_lost_when_threads_disappear) +{ + auto content = content_factory(TestPaths::private_data() / "clapperboard.mp4"); + auto film = new_test_film2("frames_not_lost", content); + film->write_metadata(); + auto job = make_dcp(film, TranscodeJob::ChangedBehaviour::IGNORE); + auto encoder = dynamic_cast<J2KEncoder*>(dynamic_pointer_cast<DCPFilmEncoder>(job->_encoder)->_encoder.get()); + + while (JobManager::instance()->work_to_do()) { + encoder->remake_threads(rand() % 8, 0, {}); + dcpomatic_sleep_seconds(1); + } + + BOOST_CHECK(!JobManager::instance()->errors()); + + dcp::DCP dcp(film->dir(film->dcp_name())); + dcp.read(); + BOOST_REQUIRE_EQUAL(dcp.cpls().size(), 1U); + BOOST_REQUIRE_EQUAL(dcp.cpls()[0]->reels().size(), 1U); + BOOST_REQUIRE_EQUAL(dcp.cpls()[0]->reels()[0]->main_picture()->intrinsic_duration(), 423U); +} + diff --git a/test/j2k_bandwidth_test.cc b/test/j2k_video_bit_rate_test.cc index f9e47c4b9..ab4c4271e 100644 --- a/test/j2k_bandwidth_test.cc +++ b/test/j2k_video_bit_rate_test.cc @@ -47,7 +47,7 @@ check (int target_bits_per_second) auto film = new_test_film (name); film->set_name (name); film->set_dcp_content_type (DCPContentType::from_isdcf_name ("FTR")); - film->set_j2k_bandwidth (target_bits_per_second); + film->set_video_bit_rate(VideoEncoding::JPEG2000, target_bits_per_second); auto content = make_shared<ImageContent>(TestPaths::private_data() / "prophet_frame.tiff"); film->examine_and_add_content (content); BOOST_REQUIRE (!wait_for_jobs()); diff --git a/test/kdm_cli_test.cc b/test/kdm_cli_test.cc index e79e37b2d..3fd20d478 100644 --- a/test/kdm_cli_test.cc +++ b/test/kdm_cli_test.cc @@ -20,8 +20,11 @@ #include "lib/cinema.h" +#include "lib/cinema_list.h" #include "lib/config.h" #include "lib/content_factory.h" +#include "lib/cross.h" +#include "lib/dkdm_wrapper.h" #include "lib/film.h" #include "lib/kdm_cli.h" #include "lib/screen.h" @@ -33,13 +36,14 @@ #include <iostream> +using std::dynamic_pointer_cast; using std::string; using std::vector; using boost::optional; optional<string> -run(vector<string> const& args, vector<string>& output) +run(vector<string> const& args, vector<string>& output, bool dump_errors = true) { std::vector<char*> argv(args.size()); for (auto i = 0U; i < args.size(); ++i) { @@ -47,7 +51,7 @@ run(vector<string> const& args, vector<string>& output) } auto error = kdm_cli(args.size(), argv.data(), [&output](string s) { output.push_back(s); }); - if (error) { + if (error && dump_errors) { std::cout << *error << "\n"; } @@ -62,7 +66,7 @@ BOOST_AUTO_TEST_CASE (kdm_cli_test_certificate) "--verbose", "--valid-from", "now", "--valid-duration", "2 weeks", - "--certificate", "test/data/cert.pem", + "--projector-certificate", "test/data/cert.pem", "-S", "my great screen", "-o", "build/test", "test/data/dkdm.xml" @@ -80,6 +84,70 @@ BOOST_AUTO_TEST_CASE (kdm_cli_test_certificate) } +BOOST_AUTO_TEST_CASE(kdm_cli_specify_decryption_key_test) +{ + using boost::filesystem::path; + + ConfigRestorer cr; + + path const dir = "build/test/kdm_cli_specify_decryption_key_test"; + + boost::system::error_code ec; + boost::filesystem::remove_all(dir, ec); + boost::filesystem::create_directories(dir); + + dcp::CertificateChain chain(openssl_path(), 365); + dcp::write_string_to_file(chain.leaf().certificate(true), dir / "cert.pem"); + dcp::write_string_to_file(*chain.key(), dir / "key.pem"); + + vector<string> make_args = { + "kdm_cli", + "--valid-from", "now", + "--valid-duration", "2 weeks", + "--projector-certificate", path(dir / "cert.pem").string(), + "-S", "base", + "-o", dir.string(), + "test/data/dkdm.xml" + }; + + vector<string> output; + auto error = run(make_args, output); + BOOST_CHECK(!error); + + vector<string> bad_args = { + "kdm_cli", + "--valid-from", "now", + "--valid-duration", "2 weeks", + "--projector-certificate", path(dir / "cert.pem").string(), + "-S", "bad", + "-o", dir.string(), + path(dir / "KDM_Test_FTR-1_F-133_XX-XX_MOS_2K_20220109_SMPTE_OV__base.xml").string() + }; + + /* This should fail because we're using the wrong decryption certificate */ + output.clear(); + error = run(bad_args, output, false); + BOOST_REQUIRE(error); + BOOST_CHECK_MESSAGE(error->find("Could not decrypt KDM") != string::npos, "Error was " << *error); + + vector<string> good_args = { + "kdm_cli", + "--valid-from", "now", + "--valid-duration", "2 weeks", + "--projector-certificate", path(dir / "cert.pem").string(), + "--decryption-key", path(dir / "key.pem").string(), + "-S", "good", + "-o", dir.string(), + path(dir / "KDM_Test_FTR-1_F-133_XX-XX_MOS_2K_20220109_SMPTE_OV__base.xml").string() + }; + + /* This should succeed */ + output.clear(); + error = run(good_args, output); + BOOST_CHECK(!error); +} + + static void setup_test_config() @@ -87,16 +155,16 @@ setup_test_config() auto config = Config::instance(); auto const cert = dcp::Certificate(dcp::file_to_string("test/data/cert.pem")); - auto cinema_a = std::make_shared<Cinema>("Dean's Screens", vector<string>(), "", 0, 0); - cinema_a->add_screen(std::make_shared<dcpomatic::Screen>("Screen 1", "", cert, boost::none, std::vector<TrustedDevice>())); - cinema_a->add_screen(std::make_shared<dcpomatic::Screen>("Screen 2", "", cert, boost::none, std::vector<TrustedDevice>())); - cinema_a->add_screen(std::make_shared<dcpomatic::Screen>("Screen 3", "", cert, boost::none, std::vector<TrustedDevice>())); - config->add_cinema(cinema_a); + CinemaList cinemas(config->cinemas_file()); - auto cinema_b = std::make_shared<Cinema>("Floyd's Celluloid", vector<string>(), "", 0, 0); - cinema_b->add_screen(std::make_shared<dcpomatic::Screen>("Foo", "", cert, boost::none, std::vector<TrustedDevice>())); - cinema_b->add_screen(std::make_shared<dcpomatic::Screen>("Bar", "", cert, boost::none, std::vector<TrustedDevice>())); - config->add_cinema(cinema_b); + auto cinema_a = cinemas.add_cinema({"Dean's Screens", {}, "", dcp::UTCOffset()}); + cinemas.add_screen(cinema_a, {"Screen 1", "", cert, boost::none, {}}); + cinemas.add_screen(cinema_a, {"Screen 2", "", cert, boost::none, {}}); + cinemas.add_screen(cinema_a, {"Screen 3", "", cert, boost::none, {}}); + + auto cinema_b = cinemas.add_cinema({"Floyd's Celluloid", {}, "", dcp::UTCOffset()}); + cinemas.add_screen(cinema_b, {"Foo", "", cert, boost::none, std::vector<TrustedDevice>()}); + cinemas.add_screen(cinema_b, {"Bar", "", cert, boost::none, std::vector<TrustedDevice>()}); } @@ -183,8 +251,8 @@ BOOST_AUTO_TEST_CASE(kdm_cli_specify_cinemas_file) vector<string> args = { "kdm_cli", "--cinemas-file", - "test/data/cinemas.xml", - "--list-cinemas" + "test/data/cinemas.sqlite3", + "list-cinemas" }; vector<string> output; @@ -192,9 +260,9 @@ BOOST_AUTO_TEST_CASE(kdm_cli_specify_cinemas_file) BOOST_CHECK(!error); BOOST_REQUIRE_EQUAL(output.size(), 3U); - BOOST_CHECK_EQUAL(output[0], "stinking dump ()"); + BOOST_CHECK_EQUAL(output[0], "Great (julie@tinyscreen.com)"); BOOST_CHECK_EQUAL(output[1], "classy joint ()"); - BOOST_CHECK_EQUAL(output[2], "Great ()"); + BOOST_CHECK_EQUAL(output[2], "stinking dump (bob@odourscreen.com, alice@whiff.com)"); } @@ -217,6 +285,7 @@ BOOST_AUTO_TEST_CASE(kdm_cli_specify_cert) "--valid-duration", "2 weeks", "-C", "test/data/cert.pem", "-o", "build/test", + "create", "build/test/kdm_cli_specify_cert" }; @@ -228,3 +297,66 @@ BOOST_AUTO_TEST_CASE(kdm_cli_specify_cert) BOOST_CHECK(boost::filesystem::exists(kdm_filename)); } + +BOOST_AUTO_TEST_CASE(kdm_cli_time) +{ + ConfigRestorer cr; + + setup_test_config(); + + boost::filesystem::path kdm_filename = "build/test/KDM_Test_FTR-1_F-133_XX-XX_MOS_2K_20220109_SMPTE_OV_Deans_Screens_Screen_2.xml"; + + boost::system::error_code ec; + boost::filesystem::remove(kdm_filename, ec); + + dcp::LocalTime now; + now.add_days(2); + + vector<string> args = { + "kdm_cli", + "--verbose", + "--valid-from", now.as_string(), + "--valid-duration", "2 weeks", + "-c", "Dean's Screens", + "-S", "Screen 2", + "-o", "build/test", + "test/data/dkdm.xml" + }; + + vector<string> output; + auto error = run(args, output); + BOOST_CHECK(!error); + + BOOST_REQUIRE_EQUAL(output.size(), 2U); + BOOST_CHECK(boost::algorithm::starts_with(output[0], "Making KDMs valid from")); + BOOST_CHECK_EQUAL(output[1], "Wrote 1 KDM files to build/test"); + + BOOST_CHECK(boost::filesystem::exists(kdm_filename)); +} + + +BOOST_AUTO_TEST_CASE(kdm_cli_add_dkdm) +{ + ConfigRestorer cr; + + setup_test_config(); + + BOOST_CHECK_EQUAL(Config::instance()->dkdms()->children().size(), 0U); + + vector<string> args = { + "kdm_cli", + "add-dkdm", + "test/data/dkdm.xml" + }; + + vector<string> output; + auto error = run(args, output); + BOOST_CHECK(!error); + + auto dkdms = Config::instance()->dkdms()->children(); + BOOST_CHECK_EQUAL(dkdms.size(), 1U); + auto dkdm = dynamic_pointer_cast<DKDM>(dkdms.front()); + BOOST_CHECK(dkdm); + BOOST_CHECK_EQUAL(dkdm->dkdm().as_xml(), dcp::file_to_string("test/data/dkdm.xml")); +} + diff --git a/test/kdm_naming_test.cc b/test/kdm_naming_test.cc index 32500553e..c5c7c2678 100644 --- a/test/kdm_naming_test.cc +++ b/test/kdm_naming_test.cc @@ -20,6 +20,7 @@ #include "lib/cinema.h" +#include "lib/cinema_list.h" #include "lib/config.h" #include "lib/content_factory.h" #include "lib/film.h" @@ -32,6 +33,7 @@ using std::dynamic_pointer_cast; using std::list; using std::make_shared; +using std::pair; using std::shared_ptr; using std::string; using std::vector; @@ -46,36 +48,40 @@ confirm_overwrite (boost::filesystem::path) } -static shared_ptr<dcpomatic::Screen> cinema_a_screen_1; -static shared_ptr<dcpomatic::Screen> cinema_a_screen_2; -static shared_ptr<dcpomatic::Screen> cinema_b_screen_x; -static shared_ptr<dcpomatic::Screen> cinema_b_screen_y; -static shared_ptr<dcpomatic::Screen> cinema_b_screen_z; +struct Context +{ + Context() + { + CinemaList cinemas; + + auto crypt_cert = Config::instance()->decryption_chain()->leaf(); + + cinema_a = cinemas.add_cinema({"Cinema A", {}, "", dcp::UTCOffset(4, 30)}); + cinema_a_screen_1 = cinemas.add_screen(cinema_a, {"Screen 1", "", crypt_cert, boost::none, {}}); + cinema_a_screen_2 = cinemas.add_screen(cinema_a, {"Screen 2", "", crypt_cert, boost::none, {}}); + + cinema_b = cinemas.add_cinema({"Cinema B", {}, "", dcp::UTCOffset(-1, 0)}); + cinema_b_screen_x = cinemas.add_screen(cinema_b, {"Screen X", "", crypt_cert, boost::none, {}}); + cinema_b_screen_y = cinemas.add_screen(cinema_b, {"Screen Y", "", crypt_cert, boost::none, {}}); + cinema_b_screen_z = cinemas.add_screen(cinema_b, {"Screen Z", "", crypt_cert, boost::none, {}}); + } + + CinemaID cinema_a = 0; + CinemaID cinema_b = 0; + ScreenID cinema_a_screen_1 = 0; + ScreenID cinema_a_screen_2 = 0; + ScreenID cinema_b_screen_x = 0; + ScreenID cinema_b_screen_y = 0; + ScreenID cinema_b_screen_z = 0; +}; BOOST_AUTO_TEST_CASE (single_kdm_naming_test) { auto c = Config::instance(); - auto crypt_cert = c->decryption_chain()->leaf(); - - /* Cinema A: UTC +4:30 */ - auto cinema_a = make_shared<Cinema>("Cinema A", vector<string>(), "", 4, 30); - cinema_a_screen_1 = std::make_shared<dcpomatic::Screen>("Screen 1", "", crypt_cert, boost::none, vector<TrustedDevice>()); - cinema_a->add_screen (cinema_a_screen_1); - cinema_a_screen_2 = std::make_shared<dcpomatic::Screen>("Screen 2", "", crypt_cert, boost::none, vector<TrustedDevice>()); - cinema_a->add_screen (cinema_a_screen_2); - c->add_cinema (cinema_a); - - /* Cinema B: UTC -1:00 */ - auto cinema_b = make_shared<Cinema>("Cinema B", vector<string>(), "", -1, 0); - cinema_b_screen_x = std::make_shared<dcpomatic::Screen>("Screen X", "", crypt_cert, boost::none, vector<TrustedDevice>()); - cinema_b->add_screen (cinema_b_screen_x); - cinema_b_screen_y = std::make_shared<dcpomatic::Screen>("Screen Y", "", crypt_cert, boost::none, vector<TrustedDevice>()); - cinema_b->add_screen (cinema_b_screen_y); - cinema_b_screen_z = std::make_shared<dcpomatic::Screen>("Screen Z", "", crypt_cert, boost::none, vector<TrustedDevice>()); - cinema_b->add_screen (cinema_b_screen_z); - c->add_cinema (cinema_a); + Context context; + CinemaList cinemas; /* Film */ boost::filesystem::remove_all ("build/test/single_kdm_naming_test"); @@ -90,14 +96,11 @@ BOOST_AUTO_TEST_CASE (single_kdm_naming_test) auto sign_cert = c->signer_chain()->leaf(); - dcp::LocalTime from (sign_cert.not_before()); + dcp::LocalTime from = sign_cert.not_before(); from.add_months (2); - dcp::LocalTime until (sign_cert.not_after()); + dcp::LocalTime until = sign_cert.not_after(); until.add_months (-2); - auto const from_string = from.date() + " " + from.time_of_day(true, false); - auto const until_string = until.date() + " " + until.time_of_day(true, false); - std::vector<KDMCertificatePeriod> period_checks; auto cpl = cpls.front().cpl_file; @@ -106,9 +109,11 @@ BOOST_AUTO_TEST_CASE (single_kdm_naming_test) }; auto kdm = kdm_for_screen ( make_kdm, - cinema_a_screen_1, - boost::posix_time::time_from_string(from_string), - boost::posix_time::time_from_string(until_string), + context.cinema_a, + *cinemas.cinema(context.cinema_a), + *cinemas.screen(context.cinema_a_screen_1), + from, + until, dcp::Formulation::MODIFIED_TRANSITIONAL_1, false, optional<int>(), @@ -133,10 +138,13 @@ BOOST_AUTO_TEST_CASE (single_kdm_naming_test) } -BOOST_AUTO_TEST_CASE (directory_kdm_naming_test, * boost::unit_test::depends_on("single_kdm_naming_test")) +BOOST_AUTO_TEST_CASE(directory_kdm_naming_test) { using boost::filesystem::path; + Context context; + CinemaList cinemas; + /* Film */ boost::filesystem::remove_all ("build/test/directory_kdm_naming_test"); auto film = new_test_film2 ( @@ -157,11 +165,11 @@ BOOST_AUTO_TEST_CASE (directory_kdm_naming_test, * boost::unit_test::depends_on( dcp::LocalTime until (sign_cert.not_after()); until.add_months (-2); - string const from_string = from.date() + " " + from.time_of_day(true, false); - string const until_string = until.date() + " " + until.time_of_day(true, false); - - vector<shared_ptr<dcpomatic::Screen>> screens = { - cinema_a_screen_2, cinema_b_screen_x, cinema_a_screen_1, (cinema_b_screen_z) + vector<pair<CinemaID, ScreenID>> screens = { + { context.cinema_a, context.cinema_a_screen_2 }, + { context.cinema_b, context.cinema_b_screen_x }, + { context.cinema_a, context.cinema_a_screen_1 }, + { context.cinema_b, context.cinema_b_screen_z } }; auto const cpl = cpls.front().cpl_file; @@ -174,12 +182,14 @@ BOOST_AUTO_TEST_CASE (directory_kdm_naming_test, * boost::unit_test::depends_on( return film->make_kdm(cpls.front().cpl_file, begin, end); }; - for (auto i: screens) { + for (auto screen: screens) { auto kdm = kdm_for_screen ( make_kdm, - i, - boost::posix_time::time_from_string(from_string), - boost::posix_time::time_from_string(until_string), + screen.first, + *cinemas.cinema(screen.first), + *cinemas.screen(screen.second), + from, + until, dcp::Formulation::MODIFIED_TRANSITIONAL_1, false, optional<int>(), diff --git a/test/low_bitrate_test.cc b/test/low_bitrate_test.cc index 7050dd771..52b8d54be 100644 --- a/test/low_bitrate_test.cc +++ b/test/low_bitrate_test.cc @@ -31,6 +31,7 @@ extern "C" { using std::make_shared; +using namespace dcpomatic; BOOST_AUTO_TEST_CASE (low_bitrate_test) @@ -51,7 +52,7 @@ BOOST_AUTO_TEST_CASE (low_bitrate_test) boost::optional<ColourConversion>(), VideoRange::FULL, std::weak_ptr<Content>(), - boost::optional<Frame>(), + boost::optional<ContentTime>(), false ); diff --git a/test/map_cli_test.cc b/test/map_cli_test.cc index ed2a7e5ec..0600de31e 100644 --- a/test/map_cli_test.cc +++ b/test/map_cli_test.cc @@ -466,6 +466,7 @@ BOOST_AUTO_TEST_CASE(map_with_given_config) }; boost::filesystem::remove_all(out); + boost::filesystem::remove_all("test/data/map_with_given_config/2.18"); Config::instance()->drop(); vector<string> output_messages; diff --git a/test/optimise_stills_test.cc b/test/optimise_stills_test.cc index cad7d7d26..50514041b 100644 --- a/test/optimise_stills_test.cc +++ b/test/optimise_stills_test.cc @@ -22,7 +22,6 @@ #include "lib/content.h" #include "lib/content_factory.h" #include "lib/dcp_content_type.h" -#include "lib/dcp_encoder.h" #include "lib/dcpomatic_log.h" #include "lib/film.h" #include "lib/job_manager.h" diff --git a/test/overlap_video_test.cc b/test/overlap_video_test.cc index cb5fcb430..638f606d3 100644 --- a/test/overlap_video_test.cc +++ b/test/overlap_video_test.cc @@ -30,8 +30,8 @@ #include <dcp/cpl.h> #include <dcp/dcp.h> #include <dcp/j2k_transcode.h> -#include <dcp/mono_picture_asset.h> -#include <dcp/mono_picture_frame.h> +#include <dcp/mono_j2k_picture_asset.h> +#include <dcp/mono_j2k_picture_frame.h> #include <dcp/openjpeg_image.h> #include <dcp/reel.h> #include <dcp/reel_mono_picture_asset.h> @@ -89,7 +89,7 @@ BOOST_AUTO_TEST_CASE (overlap_video_test1) BOOST_REQUIRE (reel->main_picture()); auto mono_picture = dynamic_pointer_cast<dcp::ReelMonoPictureAsset>(reel->main_picture()); BOOST_REQUIRE (mono_picture); - auto asset = mono_picture->mono_asset(); + auto asset = mono_picture->mono_j2k_asset(); BOOST_REQUIRE (asset); BOOST_CHECK_EQUAL (asset->intrinsic_duration(), fps * 5); auto reader = asset->start_read (); diff --git a/test/player_test.cc b/test/player_test.cc index 5120c0180..530dfc770 100644 --- a/test/player_test.cc +++ b/test/player_test.cc @@ -54,6 +54,7 @@ using std::cout; using std::list; using std::shared_ptr; using std::make_shared; +using std::vector; using boost::bind; using boost::optional; #if BOOST_VERSION >= 106100 @@ -710,3 +711,31 @@ BOOST_AUTO_TEST_CASE(three_d_in_two_d_chooses_left) while (!player->pass()) {} } + +BOOST_AUTO_TEST_CASE(check_seek_with_no_video) +{ + auto content = content_factory(TestPaths::private_data() / "Fight.Club.1999.720p.BRRip.x264-x0r.srt")[0]; + auto film = new_test_film2("check_seek_with_no_video", { content }); + auto player = std::make_shared<Player>(film, film->playlist()); + + boost::signals2::signal<void (std::shared_ptr<PlayerVideo>, dcpomatic::DCPTime)> Video; + + optional<dcpomatic::DCPTime> earliest; + + player->Video.connect( + [&earliest](shared_ptr<PlayerVideo>, dcpomatic::DCPTime time) { + if (!earliest || time < *earliest) { + earliest = time; + } + }); + + player->seek(dcpomatic::DCPTime::from_seconds(60 * 60), false); + + for (int i = 0; i < 10; ++i) { + player->pass(); + } + + BOOST_REQUIRE(earliest); + BOOST_CHECK(*earliest >= dcpomatic::DCPTime(60 * 60)); +} + diff --git a/test/recover_test.cc b/test/recover_test.cc index 63c611831..696a2c36a 100644 --- a/test/recover_test.cc +++ b/test/recover_test.cc @@ -33,8 +33,8 @@ #include "lib/video_content.h" #include "lib/ratio.h" #include <dcp/equality_options.h> -#include <dcp/mono_picture_asset.h> -#include <dcp/stereo_picture_asset.h> +#include <dcp/mono_j2k_picture_asset.h> +#include <dcp/stereo_j2k_picture_asset.h> #include <boost/test/unit_test.hpp> #include <iostream> @@ -63,6 +63,7 @@ BOOST_AUTO_TEST_CASE (recover_test_2d) film->set_dcp_content_type (DCPContentType::from_isdcf_name ("FTR")); film->set_container (Ratio::from_id ("185")); film->set_name ("recover_test"); + film->set_video_bit_rate(VideoEncoding::JPEG2000, 100000000); auto content = make_shared<FFmpegContent>("test/data/count300bd24.m2ts"); film->examine_and_add_content (content); @@ -94,8 +95,8 @@ BOOST_AUTO_TEST_CASE (recover_test_2d) false ); - auto A = make_shared<dcp::MonoPictureAsset>("build/test/recover_test_2d/original.mxf"); - auto B = make_shared<dcp::MonoPictureAsset>(video); + auto A = make_shared<dcp::MonoJ2KPictureAsset>("build/test/recover_test_2d/original.mxf"); + auto B = make_shared<dcp::MonoJ2KPictureAsset>(video); dcp::EqualityOptions eq; BOOST_CHECK (A->equals (B, eq, boost::bind (¬e, _1, _2))); @@ -110,6 +111,7 @@ BOOST_AUTO_TEST_CASE (recover_test_3d, * boost::unit_test::depends_on("recover_t film->set_container (Ratio::from_id ("185")); film->set_name ("recover_test"); film->set_three_d (true); + film->set_video_bit_rate(VideoEncoding::JPEG2000, 100000000); auto content = make_shared<ImageContent>("test/data/3d_test"); content->video->set_frame_type (VideoFrameType::THREE_D_LEFT_RIGHT); @@ -137,8 +139,8 @@ BOOST_AUTO_TEST_CASE (recover_test_3d, * boost::unit_test::depends_on("recover_t false ); - auto A = make_shared<dcp::StereoPictureAsset>("build/test/recover_test_3d/original.mxf"); - auto B = make_shared<dcp::StereoPictureAsset>(video); + auto A = make_shared<dcp::StereoJ2KPictureAsset>("build/test/recover_test_3d/original.mxf"); + auto B = make_shared<dcp::StereoJ2KPictureAsset>(video); dcp::EqualityOptions eq; BOOST_CHECK (A->equals (B, eq, boost::bind (¬e, _1, _2))); @@ -154,6 +156,7 @@ BOOST_AUTO_TEST_CASE (recover_test_2d_encrypted, * boost::unit_test::depends_on( film->set_name ("recover_test"); film->set_encrypted (true); film->_key = dcp::Key("eafcb91c9f5472edf01f3a2404c57258"); + film->set_video_bit_rate(VideoEncoding::JPEG2000, 100000000); auto content = make_shared<FFmpegContent>("test/data/count300bd24.m2ts"); film->examine_and_add_content (content); @@ -181,9 +184,9 @@ BOOST_AUTO_TEST_CASE (recover_test_2d_encrypted, * boost::unit_test::depends_on( false ); - auto A = make_shared<dcp::MonoPictureAsset>("build/test/recover_test_2d_encrypted/original.mxf"); + auto A = make_shared<dcp::MonoJ2KPictureAsset>("build/test/recover_test_2d_encrypted/original.mxf"); A->set_key (film->key ()); - auto B = make_shared<dcp::MonoPictureAsset>(video); + auto B = make_shared<dcp::MonoJ2KPictureAsset>(video); B->set_key (film->key ()); dcp::EqualityOptions eq; diff --git a/test/reel_writer_test.cc b/test/reel_writer_test.cc index ec2469898..f81e8e333 100644 --- a/test/reel_writer_test.cc +++ b/test/reel_writer_test.cc @@ -30,6 +30,7 @@ #include "lib/content_factory.h" #include "lib/cross.h" #include "lib/film.h" +#include "lib/frame_info.h" #include "lib/reel_writer.h" #include "lib/video_content.h" #include "test.h" @@ -46,9 +47,9 @@ using std::string; using boost::optional; -static bool equal (dcp::FrameInfo a, ReelWriter const & writer, shared_ptr<InfoFileHandle> file, Frame frame, Eyes eyes) +static bool equal(J2KFrameInfo a, shared_ptr<InfoFileHandle> file, Frame frame, Eyes eyes) { - auto b = writer.read_frame_info(file, frame, eyes); + auto b = J2KFrameInfo(file, frame, eyes); return a.offset == b.offset && a.size == b.size && a.hash == b.hash; } @@ -61,44 +62,44 @@ BOOST_AUTO_TEST_CASE (write_frame_info_test) /* Write the first one */ - dcp::FrameInfo info1(0, 123, "12345678901234567890123456789012"); - writer.write_frame_info (0, Eyes::LEFT, info1); + J2KFrameInfo info1(0, 123, "12345678901234567890123456789012"); + info1.write(film->info_file_handle(period, false), 0, Eyes::LEFT); { auto file = film->info_file_handle(period, true); - BOOST_CHECK (equal(info1, writer, file, 0, Eyes::LEFT)); + BOOST_CHECK(equal(info1, file, 0, Eyes::LEFT)); } /* Write some more */ - dcp::FrameInfo info2(596, 14921, "123acb789f1234ae782012n456339522"); - writer.write_frame_info (5, Eyes::RIGHT, info2); + J2KFrameInfo info2(596, 14921, "123acb789f1234ae782012n456339522"); + info2.write(film->info_file_handle(period, false), 5, Eyes::RIGHT); { auto file = film->info_file_handle(period, true); - BOOST_CHECK (equal(info1, writer, file, 0, Eyes::LEFT)); - BOOST_CHECK (equal(info2, writer, file, 5, Eyes::RIGHT)); + BOOST_CHECK(equal(info1, file, 0, Eyes::LEFT)); + BOOST_CHECK(equal(info2, file, 5, Eyes::RIGHT)); } - dcp::FrameInfo info3(12494, 99157123, "xxxxyyyyabc12356ffsfdsf456339522"); - writer.write_frame_info (10, Eyes::LEFT, info3); + J2KFrameInfo info3(12494, 99157123, "xxxxyyyyabc12356ffsfdsf456339522"); + info3.write(film->info_file_handle(period, false), 10, Eyes::LEFT); { auto file = film->info_file_handle(period, true); - BOOST_CHECK (equal(info1, writer, file, 0, Eyes::LEFT)); - BOOST_CHECK (equal(info2, writer, file, 5, Eyes::RIGHT)); - BOOST_CHECK (equal(info3, writer, file, 10, Eyes::LEFT)); + BOOST_CHECK(equal(info1, file, 0, Eyes::LEFT)); + BOOST_CHECK(equal(info2, file, 5, Eyes::RIGHT)); + BOOST_CHECK(equal(info3, file, 10, Eyes::LEFT)); } /* Overwrite one */ - dcp::FrameInfo info4(55512494, 123599157123, "ABCDEFGyabc12356ffsfdsf4563395ZZ"); - writer.write_frame_info (5, Eyes::RIGHT, info4); + J2KFrameInfo info4(55512494, 123599157123, "ABCDEFGyabc12356ffsfdsf4563395ZZ"); + info4.write(film->info_file_handle(period, false), 5, Eyes::RIGHT); { auto file = film->info_file_handle(period, true); - BOOST_CHECK (equal(info1, writer, file, 0, Eyes::LEFT)); - BOOST_CHECK (equal(info4, writer, file, 5, Eyes::RIGHT)); - BOOST_CHECK (equal(info3, writer, file, 10, Eyes::LEFT)); + BOOST_CHECK(equal(info1, file, 0, Eyes::LEFT)); + BOOST_CHECK(equal(info4, file, 5, Eyes::RIGHT)); + BOOST_CHECK(equal(info3, file, 10, Eyes::LEFT)); } } diff --git a/test/reels_test.cc b/test/reels_test.cc index d4a783f91..e6d8cf9c6 100644 --- a/test/reels_test.cc +++ b/test/reels_test.cc @@ -54,6 +54,14 @@ using std::vector; using namespace dcpomatic; +static +void +filter_ok(std::vector<dcp::VerificationNote>& notes) +{ + notes.erase(std::remove_if(notes.begin(), notes.end(), [](dcp::VerificationNote const& note) { return note.type() == dcp::VerificationNote::Type::OK; }), notes.end()); +} + + /** Test Film::reels() */ BOOST_AUTO_TEST_CASE (reels_test1) { @@ -80,7 +88,7 @@ BOOST_AUTO_TEST_CASE (reels_test1) BOOST_CHECK_EQUAL (r.back().from.get(), 288000); BOOST_CHECK_EQUAL (r.back().to.get(), 288000 * 2); - film->set_j2k_bandwidth (100000000); + film->set_video_bit_rate(VideoEncoding::JPEG2000, 100000000); film->set_reel_type (ReelType::BY_LENGTH); /* This is just over 2.5s at 100Mbit/s; should correspond to 60 frames */ film->set_reel_length (31253154); @@ -302,7 +310,7 @@ BOOST_AUTO_TEST_CASE (reels_test6) auto A = make_shared<FFmpegContent>("test/data/test2.mp4"); auto film = new_test_film2 ("reels_test6", {A}); - film->set_j2k_bandwidth (100000000); + film->set_video_bit_rate(VideoEncoding::JPEG2000, 100000000); film->set_reel_type (ReelType::BY_LENGTH); /* This is just over 2.5s at 100Mbit/s; should correspond to 60 frames */ film->set_reel_length (31253154); @@ -508,9 +516,10 @@ BOOST_AUTO_TEST_CASE (reels_should_not_be_short1) make_and_verify_dcp (film); vector<boost::filesystem::path> dirs = { film->dir(film->dcp_name(false)) }; - auto notes = dcp::verify(dirs, {}, boost::bind(&no_op), boost::bind(&no_op), {}, TestPaths::xsd()); - dump_notes (notes); - BOOST_REQUIRE (notes.empty()); + auto result = dcp::verify(dirs, {}, boost::bind(&no_op), boost::bind(&no_op), {}, TestPaths::xsd()); + filter_ok(result.notes); + dump_notes(result.notes); + BOOST_REQUIRE(result.notes.empty()); } @@ -533,9 +542,10 @@ BOOST_AUTO_TEST_CASE (reels_should_not_be_short2) make_and_verify_dcp (film); vector<boost::filesystem::path> dirs = { film->dir(film->dcp_name(false)) }; - auto const notes = dcp::verify(dirs, {}, boost::bind(&no_op), boost::bind(&no_op), {}, TestPaths::xsd()); - dump_notes (notes); - BOOST_REQUIRE (notes.empty()); + auto result = dcp::verify(dirs, {}, boost::bind(&no_op), boost::bind(&no_op), {}, TestPaths::xsd()); + filter_ok(result.notes); + dump_notes(result.notes); + BOOST_REQUIRE(result.notes.empty()); } @@ -554,9 +564,10 @@ BOOST_AUTO_TEST_CASE (reels_should_not_be_short3) make_and_verify_dcp (film); - auto const notes = dcp::verify({}, {}, boost::bind(&no_op), boost::bind(&no_op), {}, TestPaths::xsd()); - dump_notes (notes); - BOOST_REQUIRE (notes.empty()); + auto result = dcp::verify({}, {}, boost::bind(&no_op), boost::bind(&no_op), {}, TestPaths::xsd()); + filter_ok(result.notes); + dump_notes(result.notes); + BOOST_REQUIRE(result.notes.empty()); } @@ -584,9 +595,10 @@ BOOST_AUTO_TEST_CASE (reels_should_not_be_short4) BOOST_REQUIRE (!wait_for_jobs()); vector<boost::filesystem::path> dirs = { film->dir(film->dcp_name(false)) }; - auto const notes = dcp::verify(dirs, {}, boost::bind(&no_op), boost::bind(&no_op), {}, TestPaths::xsd()); - dump_notes (notes); - BOOST_REQUIRE (notes.empty()); + auto result = dcp::verify(dirs, {}, boost::bind(&no_op), boost::bind(&no_op), {}, TestPaths::xsd()); + filter_ok(result.notes); + dump_notes(result.notes); + BOOST_REQUIRE(result.notes.empty()); } diff --git a/test/remake_video_test.cc b/test/remake_video_test.cc index a07659844..2afe90b63 100644 --- a/test/remake_video_test.cc +++ b/test/remake_video_test.cc @@ -26,7 +26,7 @@ #include <dcp/colour_conversion.h> #include <dcp/cpl.h> #include <dcp/dcp.h> -#include <dcp/mono_picture_asset_reader.h> +#include <dcp/mono_j2k_picture_asset_reader.h> #include <dcp/reel.h> #include <dcp/reel_mono_picture_asset.h> #include <boost/test/unit_test.hpp> @@ -58,7 +58,7 @@ BOOST_AUTO_TEST_CASE(remake_video_after_yub_rgb_matrix_changed) BOOST_REQUIRE(!cpl->reels().empty()); auto reel = cpl->reels()[0]; BOOST_REQUIRE(reel->main_picture()); - auto mono = dynamic_pointer_cast<dcp::MonoPictureAsset>(reel->main_picture()->asset()); + auto mono = dynamic_pointer_cast<dcp::MonoJ2KPictureAsset>(reel->main_picture()->asset()); BOOST_REQUIRE(mono); auto reader = mono->start_read(); diff --git a/test/remake_with_subtitle_test.cc b/test/remake_with_subtitle_test.cc index 57322d3ac..70d38c1eb 100644 --- a/test/remake_with_subtitle_test.cc +++ b/test/remake_with_subtitle_test.cc @@ -48,5 +48,9 @@ BOOST_AUTO_TEST_CASE (remake_with_subtitle_test) content->only_text()->set_use (false); make_and_verify_dcp (film); - check_one_frame (film->dir(film->dcp_name()), 325, TestPaths::private_data() / "prophet_frame_325_no_subs.j2c"); +#ifdef DCPOMATIC_OSX + check_one_frame(film->dir(film->dcp_name()), 325, TestPaths::private_data() / "v2.18.x" / "prophet_frame_325_no_subs_mac.j2c"); +#else + check_one_frame(film->dir(film->dcp_name()), 325, TestPaths::private_data() / "v2.18.x" / "prophet_frame_325_no_subs.j2c"); +#endif } diff --git a/test/required_disk_space_test.cc b/test/required_disk_space_test.cc index b704ccef2..e26a09169 100644 --- a/test/required_disk_space_test.cc +++ b/test/required_disk_space_test.cc @@ -45,7 +45,7 @@ void check_within_n (int64_t a, int64_t b, int64_t n) BOOST_AUTO_TEST_CASE (required_disk_space_test) { auto film = new_test_film ("required_disk_space_test"); - film->set_j2k_bandwidth (100000000); + film->set_video_bit_rate(VideoEncoding::JPEG2000, 100000000); film->set_audio_channels(8); film->set_reel_type (ReelType::BY_VIDEO_CONTENT); auto content_a = content_factory("test/data/flat_blue.png")[0]; diff --git a/test/shuffler_test.cc b/test/shuffler_test.cc index 2099a0923..37d6749c3 100644 --- a/test/shuffler_test.cc +++ b/test/shuffler_test.cc @@ -33,14 +33,15 @@ using boost::optional; #if BOOST_VERSION >= 106100 using namespace boost::placeholders; #endif +using namespace dcpomatic; static void -push (Shuffler& s, int frame, Eyes eyes) +push(Shuffler& s, int frame, Eyes eyes) { auto piece = make_shared<Piece>(shared_ptr<Content>(), shared_ptr<Decoder>(), FrameRateChange(24, 24)); ContentVideo cv; - cv.frame = frame; + cv.time = ContentTime::from_frames(frame, 24); cv.eyes = eyes; s.video (piece, cv); } @@ -56,8 +57,9 @@ receive (weak_ptr<Piece>, ContentVideo cv) static void check (int frame, Eyes eyes, int line) { + auto const time = ContentTime::from_frames(frame, 24); BOOST_REQUIRE_MESSAGE (!pending_cv.empty(), "Check at " << line << " failed."); - BOOST_CHECK_MESSAGE (pending_cv.front().frame == frame, "Check at " << line << " failed."); + BOOST_CHECK_MESSAGE (pending_cv.front().time == time, "Check at " << line << " failed."); BOOST_CHECK_MESSAGE (pending_cv.front().eyes == eyes, "Check at " << line << " failed."); pending_cv.pop_front(); } diff --git a/test/stream_test.cc b/test/stream_test.cc index a180739ab..ecd2deac8 100644 --- a/test/stream_test.cc +++ b/test/stream_test.cc @@ -43,38 +43,38 @@ BOOST_AUTO_TEST_CASE (stream_test) { xmlpp::Document doc; auto root = doc.create_root_node("FFmpegAudioStream"); - root->add_child("Name")->add_child_text ("hello there world"); - root->add_child("Id")->add_child_text ("4"); - root->add_child("FrameRate")->add_child_text ("44100"); - root->add_child("Channels")->add_child_text ("2"); + cxml::add_text_child(root, "Name", "hello there world"); + cxml::add_text_child(root, "Id", "4"); + cxml::add_text_child(root, "FrameRate", "44100"); + cxml::add_text_child(root, "Channels", "2"); /* This is the state file version 5 description of the mapping */ - auto mapping = root->add_child("Mapping"); - mapping->add_child("ContentChannels")->add_child_text ("2"); + auto mapping = cxml::add_child(root, "Mapping"); + cxml::add_text_child(mapping, "ContentChannels", "2"); { /* L -> L */ - auto map = mapping->add_child("Map"); - map->add_child("ContentIndex")->add_child_text ("0"); - map->add_child("DCP")->add_child_text ("0"); + auto map = cxml::add_child(mapping, "Map"); + cxml::add_text_child(map, "ContentIndex", "0"); + cxml::add_text_child(map, "DCP", "0"); } { /* L -> C */ - auto map = mapping->add_child("Map"); - map->add_child("ContentIndex")->add_child_text ("0"); - map->add_child("DCP")->add_child_text ("2"); + auto map = cxml::add_child(mapping, "Map"); + cxml::add_text_child(map, "ContentIndex", "0"); + cxml::add_text_child(map, "DCP", "2"); } { /* R -> R */ - auto map = mapping->add_child("Map"); - map->add_child("ContentIndex")->add_child_text ("1"); - map->add_child("DCP")->add_child_text ("1"); + auto map = cxml::add_child(mapping, "Map"); + cxml::add_text_child(map, "ContentIndex", "1"); + cxml::add_text_child(map, "DCP", "1"); } { /* R -> C */ - auto map = mapping->add_child("Map"); - map->add_child("ContentIndex")->add_child_text ("1"); - map->add_child("DCP")->add_child_text ("2"); + auto map = cxml::add_child(mapping, "Map"); + cxml::add_text_child(map, "ContentIndex", "1"); + cxml::add_text_child(map, "DCP", "2"); } FFmpegAudioStream a (cxml::NodePtr (new cxml::Node (root)), 5); diff --git a/test/test.cc b/test/test.cc index fc5d9dc83..d214f1d39 100644 --- a/test/test.cc +++ b/test/test.cc @@ -47,8 +47,8 @@ #include <dcp/dcp.h> #include <dcp/equality_options.h> #include <dcp/filesystem.h> -#include <dcp/mono_picture_asset.h> -#include <dcp/mono_picture_frame.h> +#include <dcp/mono_j2k_picture_asset.h> +#include <dcp/mono_j2k_picture_frame.h> #include <dcp/openjpeg_image.h> #include <dcp/reel.h> #include <dcp/reel_picture_asset.h> @@ -122,7 +122,7 @@ setup_test_config () Config::instance()->set_server_port_base (61921); Config::instance()->set_default_dcp_content_type (static_cast<DCPContentType*> (0)); Config::instance()->set_default_audio_delay (0); - Config::instance()->set_default_j2k_bandwidth (100000000); + Config::instance()->set_default_video_bit_rate(VideoEncoding::JPEG2000, 100000000); Config::instance()->set_default_interop (false); Config::instance()->set_default_still_length (10); Config::instance()->set_default_dcp_audio_channels(8); @@ -138,7 +138,8 @@ setup_test_config () decryption->set_key(dcp::file_to_string("test/data/decryption_key")); Config::instance()->set_decryption_chain (decryption); Config::instance()->set_dcp_asset_filename_format(dcp::NameFormat("%t")); - Config::instance()->set_cinemas_file("test/data/empty_cinemas.xml"); + Config::instance()->set_cinemas_file("build/test/cinemas.sqlite3"); + Config::instance()->set_dkdm_recipients_file("build/test/dkdm_recipients.sqlite3"); } @@ -163,11 +164,21 @@ struct TestConfig setup_test_config (); capture_ffmpeg_logs(); - EncodeServerFinder::instance()->stop (); + EncodeServerFinder::drop(); signal_manager = new TestSignalManager (); dcpomatic_log.reset (new FileLog("build/test/log")); + + auto const& suite = boost::unit_test::framework::master_test_suite(); + int types = LogEntry::TYPE_GENERAL | LogEntry::TYPE_WARNING | LogEntry::TYPE_ERROR; + for (int i = 1; i < suite.argc; ++i) { + if (string(suite.argv[i]) == "--log=debug-player") { + types |= LogEntry::TYPE_DEBUG_PLAYER; + } + } + + dcpomatic_log->set_types(types); } ~TestConfig () @@ -277,13 +288,14 @@ check_wav_file (boost::filesystem::path ref, boost::filesystem::path check) void check_mxf_audio_file (boost::filesystem::path ref, boost::filesystem::path check) { - ASDCP::PCM::MXFReader ref_reader; + Kumu::FileReaderFactory factory; + ASDCP::PCM::MXFReader ref_reader(factory); BOOST_REQUIRE (!ASDCP_FAILURE (ref_reader.OpenRead (ref.string().c_str()))); ASDCP::PCM::AudioDescriptor ref_desc; BOOST_REQUIRE (!ASDCP_FAILURE (ref_reader.FillAudioDescriptor (ref_desc))); - ASDCP::PCM::MXFReader check_reader; + ASDCP::PCM::MXFReader check_reader(factory); BOOST_REQUIRE (!ASDCP_FAILURE (check_reader.OpenRead (check.string().c_str()))); ASDCP::PCM::AudioDescriptor check_desc; @@ -306,13 +318,14 @@ check_mxf_audio_file (boost::filesystem::path ref, boost::filesystem::path check bool mxf_atmos_files_same (boost::filesystem::path ref, boost::filesystem::path check, bool verbose) { - ASDCP::ATMOS::MXFReader ref_reader; + Kumu::FileReaderFactory factory; + ASDCP::ATMOS::MXFReader ref_reader(factory); BOOST_REQUIRE (!ASDCP_FAILURE(ref_reader.OpenRead(ref.string().c_str()))); ASDCP::ATMOS::AtmosDescriptor ref_desc; BOOST_REQUIRE (!ASDCP_FAILURE(ref_reader.FillAtmosDescriptor(ref_desc))); - ASDCP::ATMOS::MXFReader check_reader; + ASDCP::ATMOS::MXFReader check_reader(factory); BOOST_REQUIRE (!ASDCP_FAILURE(check_reader.OpenRead(check.string().c_str()))); ASDCP::ATMOS::AtmosDescriptor check_desc; @@ -574,7 +587,7 @@ check_dcp(boost::filesystem::path ref, boost::filesystem::path check, bool sound } void -check_xml (xmlpp::Element* ref, xmlpp::Element* test, list<string> ignore) +check_xml(xmlpp::Element* ref, xmlpp::Element* test, list<Glib::ustring> ignore) { BOOST_CHECK_EQUAL (ref->get_name (), test->get_name ()); BOOST_CHECK_EQUAL (ref->get_namespace_prefix (), test->get_namespace_prefix ()); @@ -630,7 +643,7 @@ check_xml (xmlpp::Element* ref, xmlpp::Element* test, list<string> ignore) } void -check_xml (boost::filesystem::path ref, boost::filesystem::path test, list<string> ignore) +check_xml(boost::filesystem::path ref, boost::filesystem::path test, list<Glib::ustring> ignore) { auto ref_parser = new xmlpp::DomParser(ref.string()); auto ref_root = ref_parser->get_document()->get_root_node(); @@ -817,22 +830,25 @@ check_one_frame (boost::filesystem::path dcp_dir, int64_t index, boost::filesyst { dcp::DCP dcp (dcp_dir); dcp.read (); - auto asset = dynamic_pointer_cast<dcp::MonoPictureAsset> (dcp.cpls().front()->reels().front()->main_picture()->asset()); + auto asset = dynamic_pointer_cast<dcp::MonoJ2KPictureAsset>(dcp.cpls().front()->reels().front()->main_picture()->asset()); BOOST_REQUIRE (asset); auto frame = asset->start_read()->get_frame(index); - auto ref_frame (new dcp::MonoPictureFrame (ref)); + dcp::MonoJ2KPictureFrame ref_frame(ref); auto image = frame->xyz_image (); - auto ref_image = ref_frame->xyz_image (); + auto ref_image = ref_frame.xyz_image(); BOOST_REQUIRE (image->size() == ref_image->size()); int off = 0; for (int y = 0; y < ref_image->size().height; ++y) { for (int x = 0; x < ref_image->size().width; ++x) { - BOOST_REQUIRE_EQUAL (ref_image->data(0)[off], image->data(0)[off]); - BOOST_REQUIRE_EQUAL (ref_image->data(1)[off], image->data(1)[off]); - BOOST_REQUIRE_EQUAL (ref_image->data(2)[off], image->data(2)[off]); + auto x_error = std::abs(ref_image->data(0)[off] - image->data(0)[off]); + BOOST_REQUIRE_MESSAGE(x_error == 0, "x component at " << x << "," << y << " differs by " << x_error); + auto y_error = std::abs(ref_image->data(1)[off] - image->data(1)[off]); + BOOST_REQUIRE_MESSAGE(y_error == 0, "y component at " << x << "," << y << " differs by " << y_error); + auto z_error = std::abs(ref_image->data(2)[off] - image->data(2)[off]); + BOOST_REQUIRE_MESSAGE(z_error == 0, "z component at " << x << "," << y << " differs by " << z_error); ++off; } } @@ -950,10 +966,10 @@ void progress (float) {} void verify_dcp(boost::filesystem::path dir, vector<dcp::VerificationNote::Code> ignore) { - auto notes = dcp::verify({dir}, {}, &stage, &progress, {}, TestPaths::xsd()); + auto result = dcp::verify({dir}, {}, &stage, &progress, {}, TestPaths::xsd()); bool ok = true; - for (auto i: notes) { - if (find(ignore.begin(), ignore.end(), i.code()) == ignore.end()) { + for (auto i: result.notes) { + if (i.type() != dcp::VerificationNote::Type::OK && find(ignore.begin(), ignore.end(), i.code()) == ignore.end()) { std::cout << "\t" << dcp::note_to_string(i) << "\n"; ok = false; } diff --git a/test/test.h b/test/test.h index 6687affea..0776d6e5a 100644 --- a/test/test.h +++ b/test/test.h @@ -22,6 +22,7 @@ #include "lib/video_frame_type.h" #include <dcp/types.h> #include <dcp/verify.h> +#include <glibmm.h> #include <boost/filesystem.hpp> #include <vector> @@ -66,7 +67,7 @@ extern void check_text_file (boost::filesystem::path ref, boost::filesystem::pat extern void check_wav_file (boost::filesystem::path ref, boost::filesystem::path check); extern void check_mxf_audio_file (boost::filesystem::path ref, boost::filesystem::path check); extern bool mxf_atmos_files_same (boost::filesystem::path ref, boost::filesystem::path check, bool verbose = false); -extern void check_xml (boost::filesystem::path, boost::filesystem::path, std::list<std::string>); +extern void check_xml(boost::filesystem::path, boost::filesystem::path, std::list<Glib::ustring>); extern void check_ffmpeg (boost::filesystem::path, boost::filesystem::path, int audio_tolerance); extern void check_image (boost::filesystem::path, boost::filesystem::path, double threshold = 4); extern boost::filesystem::path test_film_dir (std::string); diff --git a/test/text_entry_point_test.cc b/test/text_entry_point_test.cc new file mode 100644 index 000000000..ce4f6148e --- /dev/null +++ b/test/text_entry_point_test.cc @@ -0,0 +1,70 @@ +/* + Copyright (C) 2024 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 "test.h" +#include "lib/dcp_content.h" +#include "lib/film.h" +#include <dcp/cpl.h> +#include <dcp/dcp.h> +#include <dcp/reel.h> +#include <dcp/reel_smpte_subtitle_asset.h> +#include <dcp/smpte_subtitle_asset.h> +#include <boost/test/unit_test.hpp> + + +using std::make_shared; +using std::string; + + +BOOST_AUTO_TEST_CASE(test_text_entry_point) +{ + auto const path = boost::filesystem::path("build/test/test_text_entry_point"); + boost::filesystem::remove_all(path); + boost::filesystem::create_directories(path); + + /* Make a "bad" DCP with a non-zero text entry point */ + dcp::DCP bad_dcp(path / "dcp"); + auto sub = make_shared<dcp::SMPTESubtitleAsset>(); + sub->write(path / "dcp" / "subs.mxf"); + auto reel_sub = make_shared<dcp::ReelSMPTESubtitleAsset>(sub, dcp::Fraction{24, 1}, 42, 6); + auto reel = make_shared<dcp::Reel>(); + reel->add(reel_sub); + + auto cpl = make_shared<dcp::CPL>("foo", dcp::ContentKind::FEATURE, dcp::Standard::SMPTE); + bad_dcp.add(cpl); + cpl->add(reel); + + bad_dcp.write_xml(); + + /* Make a film and add the bad DCP, so that the examiner spots the problem */ + auto dcp_content = make_shared<DCPContent>(path / "dcp"); + auto film = new_test_film2("test_text_entry_point/film", { dcp_content }); + film->write_metadata(); + + /* Reload the film to check that the examiner's output is saved and recovered */ + auto film2 = make_shared<Film>(path / "film"); + film2->read_metadata(); + + string why_not; + BOOST_CHECK(!dcp_content->can_reference_text(film2, TextType::OPEN_SUBTITLE, why_not)); + BOOST_CHECK_EQUAL(why_not, "one of its subtitle reels has a non-zero entry point so it must be re-written."); +} + diff --git a/test/threed_test.cc b/test/threed_test.cc index 78d74add4..38b8f36d4 100644 --- a/test/threed_test.cc +++ b/test/threed_test.cc @@ -42,8 +42,8 @@ #include "lib/util.h" #include "lib/video_content.h" #include "test.h" -#include <dcp/mono_picture_asset.h> -#include <dcp/stereo_picture_asset.h> +#include <dcp/mono_j2k_picture_asset.h> +#include <dcp/stereo_j2k_picture_asset.h> #include <boost/test/unit_test.hpp> #include <iostream> @@ -330,10 +330,10 @@ BOOST_AUTO_TEST_CASE(threed_passthrough_test, * boost::unit_test::depends_on("th BOOST_REQUIRE_EQUAL(matches.size(), 1U); - auto stereo = dcp::StereoPictureAsset(matches[0]); + auto stereo = dcp::StereoJ2KPictureAsset(matches[0]); auto stereo_reader = stereo.start_read(); - auto mono = dcp::MonoPictureAsset(dcp_file(film, "j2c")); + auto mono = dcp::MonoJ2KPictureAsset(dcp_file(film, "j2c")); auto mono_reader = mono.start_read(); BOOST_REQUIRE_EQUAL(stereo.intrinsic_duration(), mono.intrinsic_duration()); diff --git a/test/torture_test.cc b/test/torture_test.cc index 0c781fdb1..e5ce694ce 100644 --- a/test/torture_test.cc +++ b/test/torture_test.cc @@ -35,8 +35,8 @@ #include "lib/video_content.h" #include "test.h" #include <dcp/cpl.h> -#include <dcp/mono_picture_asset.h> -#include <dcp/mono_picture_frame.h> +#include <dcp/mono_j2k_picture_asset.h> +#include <dcp/mono_j2k_picture_frame.h> #include <dcp/openjpeg_image.h> #include <dcp/reel.h> #include <dcp/reel_picture_asset.h> @@ -230,7 +230,7 @@ BOOST_AUTO_TEST_CASE (torture_test1) auto reel_picture = reels.front()->main_picture(); BOOST_REQUIRE (reel_picture); - auto picture = dynamic_pointer_cast<dcp::MonoPictureAsset> (reel_picture->asset()); + auto picture = dynamic_pointer_cast<dcp::MonoJ2KPictureAsset>(reel_picture->asset()); BOOST_REQUIRE (picture); BOOST_CHECK_EQUAL (picture->intrinsic_duration(), 144); @@ -248,7 +248,7 @@ BOOST_AUTO_TEST_CASE (torture_test1) for (int c = 0; c < 3; ++c) { for (int y = 0; y < size.height; ++y) { for (int x = 0; x < size.width; ++x) { - BOOST_REQUIRE (image->data(c)[y * size.height + x] <= 3); + BOOST_REQUIRE (image->data(c)[y * size.height + x] <= 5); } } } diff --git a/test/vf_test.cc b/test/vf_test.cc index ca987b22d..051712deb 100644 --- a/test/vf_test.cc +++ b/test/vf_test.cc @@ -40,8 +40,8 @@ #include "lib/video_content.h" #include "test.h" #include <dcp/cpl.h> -#include <dcp/mono_picture_asset.h> -#include <dcp/picture_asset_writer.h> +#include <dcp/mono_j2k_picture_asset.h> +#include <dcp/j2k_picture_asset_writer.h> #include <dcp/reel.h> #include <dcp/reel_mono_picture_asset.h> #include <dcp/reel_sound_asset.h> @@ -492,8 +492,8 @@ BOOST_AUTO_TEST_CASE(test_referencing_ov_with_missing_subtitle_in_some_reels) dcp::DCP ov(path / "ov"); auto make_picture = [path](string filename) { - auto pic = make_shared<dcp::MonoPictureAsset>(dcp::Fraction(24, 1), dcp::Standard::SMPTE); - auto writer = pic->start_write(path / "ov" / filename, dcp::PictureAsset::Behaviour::MAKE_NEW); + auto pic = make_shared<dcp::MonoJ2KPictureAsset>(dcp::Fraction(24, 1), dcp::Standard::SMPTE); + auto writer = pic->start_write(path / "ov" / filename, dcp::Behaviour::MAKE_NEW); auto frame = dcp::ArrayData("test/data/picture.j2c"); for (int i = 0; i < 240; ++i) { writer->write(frame); diff --git a/test/video_level_test.cc b/test/video_level_test.cc index e2419d8e7..bb2c1b7fa 100644 --- a/test/video_level_test.cc +++ b/test/video_level_test.cc @@ -36,7 +36,7 @@ #include "lib/image.h" #include "lib/image_content.h" #include "lib/image_decoder.h" -#include "lib/ffmpeg_encoder.h" +#include "lib/ffmpeg_film_encoder.h" #include "lib/job_manager.h" #include "lib/player.h" #include "lib/player_video.h" @@ -45,8 +45,8 @@ #include "test.h" #include <dcp/cpl.h> #include <dcp/dcp.h> -#include <dcp/mono_picture_asset.h> -#include <dcp/mono_picture_frame.h> +#include <dcp/mono_j2k_picture_asset.h> +#include <dcp/mono_j2k_picture_frame.h> #include <dcp/openjpeg_image.h> #include <dcp/reel.h> #include <dcp/reel_picture_asset.h> @@ -275,7 +275,7 @@ pixel_range (boost::filesystem::path dcp_path) dcp::DCP dcp (dcp_path); dcp.read (); - auto picture = dynamic_pointer_cast<dcp::MonoPictureAsset>(dcp.cpls().front()->reels().front()->main_picture()->asset()); + auto picture = dynamic_pointer_cast<dcp::MonoJ2KPictureAsset>(dcp.cpls().front()->reels().front()->main_picture()->asset()); BOOST_REQUIRE (picture); auto frame = picture->start_read()->get_frame(0)->xyz_image(); @@ -459,7 +459,7 @@ V_movie_range (shared_ptr<Film> film) { auto job = make_shared<TranscodeJob>(film, TranscodeJob::ChangedBehaviour::IGNORE); job->set_encoder ( - make_shared<FFmpegEncoder>(film, job, film->file("export.mov"), ExportFormat::PRORES_HQ, true, false, false, 23) + make_shared<FFmpegFilmEncoder>(film, job, film->file("export.mov"), ExportFormat::PRORES_HQ, true, false, false, 23) ); JobManager::instance()->add (job); BOOST_REQUIRE (!wait_for_jobs()); @@ -480,7 +480,7 @@ BOOST_AUTO_TEST_CASE (movie_V_to_dcp) { auto range = dcp_range (movie_V("movie_V_to_dcp")); /* Video range has been correctly expanded to full for the DCP */ - check_int_close (range, {0, 4083}, 2); + check_int_close(range, {0, 4081}, 2); } @@ -498,7 +498,7 @@ BOOST_AUTO_TEST_CASE (movie_F_to_dcp) { auto range = dcp_range (movie_F("movie_F_to_dcp")); /* The nearly-full-range of the input has been preserved */ - check_int_close (range, {0, 4083}, 2); + check_int_close(range, {0, 4080}, 2); } @@ -506,14 +506,14 @@ BOOST_AUTO_TEST_CASE (video_FoV_to_dcp) { auto range = dcp_range (movie_FoV("video_FoV_to_dcp")); /* The nearly-full-range of the input has become even more full, and clipped */ - check_int_close (range, {0, 4095}, 2); + check_int_close(range, {0, 4093}, 2); } BOOST_AUTO_TEST_CASE (image_F_to_dcp) { auto range = dcp_range (image_F("image_F_to_dcp")); - check_int_close (range, {0, 4083}, 3); + check_int_close(range, {0, 4080}, 3); } diff --git a/test/video_mxf_content_test.cc b/test/video_mxf_content_test.cc index f3766e4af..3497772a2 100644 --- a/test/video_mxf_content_test.cc +++ b/test/video_mxf_content_test.cc @@ -33,7 +33,7 @@ #include "lib/video_mxf_content.h" #include "test.h" #include <dcp/equality_options.h> -#include <dcp/mono_picture_asset.h> +#include <dcp/mono_j2k_picture_asset.h> #include <boost/test/unit_test.hpp> @@ -50,18 +50,10 @@ static void note (dcp::NoteType, std::string) /** Basic test of using video MXF content */ BOOST_AUTO_TEST_CASE (video_mxf_content_test) { - auto film = new_test_film ("video_mxf_content_test"); - film->set_dcp_content_type (DCPContentType::from_isdcf_name ("FTR")); - film->set_container (Ratio::from_id ("185")); - film->set_name ("video_mxf_content_test"); - auto const ref_mxf = find_file("test/data/scaling_test_185_185", "j2c"); + auto content = content_factory(ref_mxf); - auto content = content_factory(ref_mxf)[0]; - auto check = dynamic_pointer_cast<VideoMXFContent> (content); - BOOST_REQUIRE (check); - film->examine_and_add_content (content); - BOOST_REQUIRE (!wait_for_jobs()); + auto film = new_test_film2("video_mxf_content_test", content); make_and_verify_dcp ( film, { @@ -70,9 +62,9 @@ BOOST_AUTO_TEST_CASE (video_mxf_content_test) dcp::VerificationNote::Code::INVALID_JPEG2000_GUARD_BITS_FOR_2K }); - auto ref = make_shared<dcp::MonoPictureAsset>(ref_mxf); - boost::filesystem::directory_iterator i ("build/test/video_mxf_content_test/video"); - auto comp = make_shared<dcp::MonoPictureAsset>(*i); + auto ref = make_shared<dcp::MonoJ2KPictureAsset>(ref_mxf); + auto comp_mxf = find_file("build/test/video_mxf_content_test/video", ".mxf"); + auto comp = make_shared<dcp::MonoJ2KPictureAsset>(comp_mxf); dcp::EqualityOptions op; BOOST_CHECK (ref->equals (comp, op, note)); } diff --git a/test/writer_test.cc b/test/writer_test.cc index 86b60818f..2d4da570f 100644 --- a/test/writer_test.cc +++ b/test/writer_test.cc @@ -23,7 +23,7 @@ #include "lib/content.h" #include "lib/content_factory.h" #include "lib/cross.h" -#include "lib/dcp_encoder.h" +#include "lib/dcp_film_encoder.h" #include "lib/film.h" #include "lib/job.h" #include "lib/video_content.h" @@ -149,7 +149,7 @@ BOOST_AUTO_TEST_CASE(writer_progress_test) last_sub_name = job->sub_name(); }); - DCPEncoder encoder(film, job); + DCPFilmEncoder encoder(film, job); encoder.go(); } diff --git a/test/wscript b/test/wscript index cd23badc0..52b909b52 100644 --- a/test/wscript +++ b/test/wscript @@ -37,7 +37,7 @@ def build(bld): obj.name = 'unit-tests' obj.uselib = 'BOOST_TEST BOOST_THREAD BOOST_FILESYSTEM BOOST_DATETIME SNDFILE SAMPLERATE DCP FONTCONFIG CAIROMM PANGOMM XMLPP ' obj.uselib += 'AVFORMAT AVFILTER AVCODEC AVUTIL SWSCALE SWRESAMPLE POSTPROC CXML SUB GLIB CURL SSH XMLSEC BOOST_REGEX ICU NETTLE PNG JPEG ' - obj.uselib += 'LEQM_NRT ZIP ' + obj.uselib += 'LEQM_NRT ZIP SQLITE3 ' if bld.env.TARGET_WINDOWS_64 or bld.env.TARGET_WINDOWS_32: obj.uselib += 'WINSOCK2 DBGHELP SHLWAPI MSWSOCK BOOST_LOCALE ' if bld.env.TARGET_LINUX: @@ -60,6 +60,7 @@ def build(bld): burnt_subtitle_test.cc butler_test.cc bv20_test.cc + cinema_list_test.cc cinema_sound_processor_test.cc client_server_test.cc closed_caption_test.cc @@ -78,6 +79,7 @@ def build(bld): dcp_playback_test.cc dcp_subtitle_test.cc digest_test.cc + dkdm_recipient_list_test.cc empty_caption_test.cc empty_test.cc encryption_test.cc @@ -112,8 +114,10 @@ def build(bld): interrupt_encoder_test.cc isdcf_name_test.cc j2k_bandwidth_test.cc + j2k_encode_threading_test.cc j2k_encoder_test.cc job_manager_test.cc + j2k_video_bit_rate_test.cc kdm_cli_test.cc kdm_naming_test.cc kdm_util_test.cc @@ -162,6 +166,7 @@ def build(bld): template_test.cc test.cc text_decoder_test.cc + text_entry_point_test.cc threed_test.cc time_calculation_test.cc torture_test.cc |
