X-Git-Url: https://main.carlh.net/gitweb/?p=libdcp.git;a=blobdiff_plain;f=test%2Fverify_test.cc;h=f5a012a629f93ccd55ad26142640ccd851b3bbb8;hp=ddda7df0c180a291e15106f5cf2c1f3f4b4d64ea;hb=eac3cac07eb97a6bcf6accd1575af76cd6f59112;hpb=fb43b28f851cf4cfe1b7dfa79aec73b0ee8fe7e2 diff --git a/test/verify_test.cc b/test/verify_test.cc index ddda7df0..f5a012a6 100644 --- a/test/verify_test.cc +++ b/test/verify_test.cc @@ -31,28 +31,29 @@ files in the program, then also delete it here. */ -#include "verify.h" -#include "util.h" -#include "j2k.h" -#include "reel.h" -#include "reel_mono_picture_asset.h" -#include "reel_sound_asset.h" +#include "compose.hpp" #include "cpl.h" #include "dcp.h" -#include "openjpeg_image.h" +#include "interop_subtitle_asset.h" +#include "j2k_transcode.h" #include "mono_picture_asset.h" -#include "stereo_picture_asset.h" #include "mono_picture_asset_writer.h" -#include "interop_subtitle_asset.h" -#include "smpte_subtitle_asset.h" +#include "openjpeg_image.h" +#include "raw_convert.h" +#include "reel.h" #include "reel_closed_caption_asset.h" +#include "reel_markers_asset.h" +#include "reel_mono_picture_asset.h" +#include "reel_sound_asset.h" #include "reel_stereo_picture_asset.h" #include "reel_subtitle_asset.h" -#include "reel_markers_asset.h" -#include "compose.hpp" +#include "smpte_subtitle_asset.h" +#include "stereo_picture_asset.h" +#include "stream_operators.h" #include "test.h" +#include "util.h" +#include "verify.h" #include -#include #include #include #include @@ -64,15 +65,17 @@ using std::vector; using std::make_pair; using std::make_shared; using boost::optional; +using namespace boost::filesystem; using std::shared_ptr; -static list>> stages; +static list>> stages; static string const dcp_test1_pkl = "pkl_2b9b857f-ab4a-440e-a313-1ace0f1cfc95.xml"; -static string const dcp_test1_cpl = "cpl_81fb54df-e1bf-4647-8788-ea7ba154375b.xml"; +static string const dcp_test1_cpl_id = "81fb54df-e1bf-4647-8788-ea7ba154375b"; +static string const dcp_test1_cpl = "cpl_" + dcp_test1_cpl_id + ".xml"; static void -stage (string s, optional p) +stage (string s, optional p) { stages.push_back (make_pair (s, p)); } @@ -84,7 +87,7 @@ progress (float) } static void -prepare_directory (boost::filesystem::path path) +prepare_directory (path path) { using namespace boost::filesystem; remove_all (path); @@ -92,28 +95,28 @@ prepare_directory (boost::filesystem::path path) } -static vector -setup (int reference_number, int verify_test_number) +static path +setup (int reference_number, string verify_test_suffix) { - prepare_directory (dcp::String::compose("build/test/verify_test%1", verify_test_number)); - for (auto i: boost::filesystem::directory_iterator(dcp::String::compose("test/ref/DCP/dcp_test%1", reference_number))) { - boost::filesystem::copy_file (i.path(), dcp::String::compose("build/test/verify_test%1", verify_test_number) / i.path().filename()); + auto const dir = dcp::String::compose("build/test/verify_test%1", verify_test_suffix); + prepare_directory (dir); + for (auto i: directory_iterator(dcp::String::compose("test/ref/DCP/dcp_test%1", reference_number))) { + copy_file (i.path(), dir / i.path().filename()); } - return { dcp::String::compose("build/test/verify_test%1", verify_test_number) }; - + return dir; } static -void -write_dcp_with_single_asset (boost::filesystem::path dir, shared_ptr reel_asset, dcp::Standard standard = dcp::SMPTE) +shared_ptr +write_dcp_with_single_asset (path dir, shared_ptr reel_asset, dcp::Standard standard = dcp::Standard::SMPTE) { auto reel = make_shared(); reel->add (reel_asset); reel->add (simple_markers()); - auto cpl = make_shared("hello", dcp::TRAILER); + auto cpl = make_shared("hello", dcp::ContentKind::TRAILER); cpl->add (reel); auto dcp = make_shared(dir); dcp->add (cpl); @@ -124,6 +127,8 @@ write_dcp_with_single_asset (boost::filesystem::path dir, shared_ptr const & notes) static void -check_verify_result (vector dir, vector test_notes) +check_verify_result (vector dir, vector test_notes) { auto notes = dcp::verify ({dir}, &stage, &progress, xsd_test); - dump_notes (notes); BOOST_REQUIRE_EQUAL (notes.size(), test_notes.size()); + for (auto i = 0U; i < notes.size(); ++i) { + BOOST_REQUIRE_EQUAL (notes[i], test_notes[i]); + } } static void -check_verify_result_after_replace (int n, boost::function file, string from, string to, vector codes) +check_verify_result_after_replace (string suffix, boost::function file, string from, string to, vector codes) { - auto directories = setup (1, n); + auto dir = setup (1, suffix); { - Editor e (file(n)); + Editor e (file(suffix)); e.replace (from, to); } - auto notes = dcp::verify (directories, &stage, &progress, xsd_test); + auto notes = dcp::verify ({dir}, &stage, &progress, xsd_test); BOOST_REQUIRE_EQUAL (notes.size(), codes.size()); auto i = notes.begin(); @@ -225,71 +232,74 @@ check_verify_result_after_replace (int n, boost::functionfirst, "Checking DCP"); BOOST_REQUIRE (st->second); - BOOST_CHECK_EQUAL (st->second.get(), boost::filesystem::canonical("build/test/verify_test1")); + BOOST_CHECK_EQUAL (st->second.get(), canonical(dir)); ++st; BOOST_CHECK_EQUAL (st->first, "Checking CPL"); BOOST_REQUIRE (st->second); - BOOST_CHECK_EQUAL (st->second.get(), boost::filesystem::canonical(cpl_file)); + BOOST_CHECK_EQUAL (st->second.get(), canonical(cpl_file)); ++st; BOOST_CHECK_EQUAL (st->first, "Checking reel"); BOOST_REQUIRE (!st->second); ++st; BOOST_CHECK_EQUAL (st->first, "Checking picture asset hash"); BOOST_REQUIRE (st->second); - BOOST_CHECK_EQUAL (st->second.get(), boost::filesystem::canonical("build/test/verify_test1/video.mxf")); + BOOST_CHECK_EQUAL (st->second.get(), canonical(dir / "video.mxf")); ++st; BOOST_CHECK_EQUAL (st->first, "Checking picture frame sizes"); BOOST_REQUIRE (st->second); - BOOST_CHECK_EQUAL (st->second.get(), boost::filesystem::canonical("build/test/verify_test1/video.mxf")); + BOOST_CHECK_EQUAL (st->second.get(), canonical(dir / "video.mxf")); ++st; BOOST_CHECK_EQUAL (st->first, "Checking sound asset hash"); BOOST_REQUIRE (st->second); - BOOST_CHECK_EQUAL (st->second.get(), boost::filesystem::canonical("build/test/verify_test1/audio.mxf")); + BOOST_CHECK_EQUAL (st->second.get(), canonical(dir / "audio.mxf")); ++st; BOOST_CHECK_EQUAL (st->first, "Checking sound asset metadata"); BOOST_REQUIRE (st->second); - BOOST_CHECK_EQUAL (st->second.get(), boost::filesystem::canonical("build/test/verify_test1/audio.mxf")); + BOOST_CHECK_EQUAL (st->second.get(), canonical(dir / "audio.mxf")); ++st; BOOST_CHECK_EQUAL (st->first, "Checking PKL"); BOOST_REQUIRE (st->second); - BOOST_CHECK_EQUAL (st->second.get(), boost::filesystem::canonical(pkl_file)); + BOOST_CHECK_EQUAL (st->second.get(), canonical(pkl_file)); ++st; BOOST_CHECK_EQUAL (st->first, "Checking ASSETMAP"); BOOST_REQUIRE (st->second); - BOOST_CHECK_EQUAL (st->second.get(), boost::filesystem::canonical(assetmap_file)); + BOOST_CHECK_EQUAL (st->second.get(), canonical(assetmap_file)); ++st; BOOST_REQUIRE (st == stages.end()); BOOST_CHECK_EQUAL (notes.size(), 0); } -/* Corrupt the MXFs and check that this is spotted */ -BOOST_AUTO_TEST_CASE (verify_test2) + +BOOST_AUTO_TEST_CASE (verify_incorrect_picture_sound_hash) { - auto directories = setup (1, 2); + using namespace boost::filesystem; + + auto dir = setup (1, "incorrect_picture_sound_hash"); - auto mod = fopen("build/test/verify_test2/video.mxf", "r+b"); + auto video_path = path(dir / "video.mxf"); + auto mod = fopen(video_path.string().c_str(), "r+b"); BOOST_REQUIRE (mod); fseek (mod, 4096, SEEK_SET); int x = 42; fwrite (&x, sizeof(x), 1, mod); fclose (mod); - mod = fopen("build/test/verify_test2/audio.mxf", "r+b"); + auto audio_path = path(dir / "audio.mxf"); + mod = fopen(audio_path.string().c_str(), "r+b"); BOOST_REQUIRE (mod); BOOST_REQUIRE_EQUAL (fseek(mod, -64, SEEK_END), 0); BOOST_REQUIRE (fwrite (&x, sizeof(x), 1, mod) == 1); @@ -297,245 +307,244 @@ BOOST_AUTO_TEST_CASE (verify_test2) dcp::ASDCPErrorSuspender sus; check_verify_result ( - directories, + { dir }, { - { dcp::VerificationNote::VERIFY_ERROR, dcp::VerificationNote::PICTURE_HASH_INCORRECT }, - { dcp::VerificationNote::VERIFY_ERROR, dcp::VerificationNote::SOUND_HASH_INCORRECT } + { dcp::VerificationNote::Type::ERROR, dcp::VerificationNote::Code::INCORRECT_PICTURE_HASH, canonical(video_path) }, + { dcp::VerificationNote::Type::ERROR, dcp::VerificationNote::Code::INCORRECT_SOUND_HASH, canonical(audio_path) }, }); } -/* Corrupt the hashes in the PKL and check that the disagreement between CPL and PKL is spotted */ -BOOST_AUTO_TEST_CASE (verify_test3) + +BOOST_AUTO_TEST_CASE (verify_mismatched_picture_sound_hashes) { - auto directories = setup (1, 3); + using namespace boost::filesystem; + + auto dir = setup (1, "mismatched_picture_sound_hashes"); { - Editor e (boost::filesystem::path("build") / "test" / "verify_test3" / dcp_test1_pkl); + Editor e (dir / dcp_test1_pkl); e.replace ("", "x"); } check_verify_result ( - directories, + { dir }, { - { dcp::VerificationNote::VERIFY_ERROR, dcp::VerificationNote::CPL_HASH_INCORRECT }, - { dcp::VerificationNote::VERIFY_ERROR, dcp::VerificationNote::PKL_CPL_PICTURE_HASHES_DIFFER }, - { dcp::VerificationNote::VERIFY_ERROR, dcp::VerificationNote::PKL_CPL_SOUND_HASHES_DIFFER }, - { dcp::VerificationNote::VERIFY_ERROR, dcp::VerificationNote::XML_VALIDATION_ERROR }, - { dcp::VerificationNote::VERIFY_ERROR, dcp::VerificationNote::XML_VALIDATION_ERROR }, - { dcp::VerificationNote::VERIFY_ERROR, dcp::VerificationNote::XML_VALIDATION_ERROR } + { dcp::VerificationNote::Type::ERROR, dcp::VerificationNote::Code::MISMATCHED_CPL_HASHES, dcp_test1_cpl_id, canonical(dir / dcp_test1_cpl) }, + { dcp::VerificationNote::Type::ERROR, dcp::VerificationNote::Code::MISMATCHED_PICTURE_HASHES, canonical(dir / "video.mxf") }, + { dcp::VerificationNote::Type::ERROR, dcp::VerificationNote::Code::MISMATCHED_SOUND_HASHES, canonical(dir / "audio.mxf") }, + { dcp::VerificationNote::Type::ERROR, dcp::VerificationNote::Code::INVALID_XML, "value 'xX3bMCBdXEOYEpYmsConNWrWUAGs=' is invalid Base64-encoded binary", canonical(dir / dcp_test1_pkl), 12 }, + { dcp::VerificationNote::Type::ERROR, dcp::VerificationNote::Code::INVALID_XML, "value 'xaddO7je2lZSNQp55qjCWo5DLKFQ=' is invalid Base64-encoded binary", canonical(dir / dcp_test1_pkl), 19 }, + { dcp::VerificationNote::Type::ERROR, dcp::VerificationNote::Code::INVALID_XML, "value 'xqtXbkcwhUj/yqquVLmV+wbzbxQ8=' is invalid Base64-encoded binary", canonical(dir / dcp_test1_pkl), 26 } }); } -/* Corrupt the ContentKind in the CPL */ -BOOST_AUTO_TEST_CASE (verify_test4) + +BOOST_AUTO_TEST_CASE (verify_failed_read_content_kind) { - auto directories = setup (1, 4); + auto dir = setup (1, "failed_read_content_kind"); { - Editor e (boost::filesystem::path("build") / "test" / "verify_test4" / dcp_test1_cpl); + Editor e (dir / dcp_test1_cpl); e.replace ("", "x"); } check_verify_result ( - directories, - {{ dcp::VerificationNote::VERIFY_ERROR, dcp::VerificationNote::GENERAL_READ, string("Bad content kind 'xtrailer'")}} + { dir }, + {{ dcp::VerificationNote::Type::ERROR, dcp::VerificationNote::Code::FAILED_READ, string("Bad content kind 'xtrailer'")}} ); } + static -boost::filesystem::path -cpl (int n) +path +cpl (string suffix) { - return dcp::String::compose("build/test/verify_test%1/%2", n, dcp_test1_cpl); + return dcp::String::compose("build/test/verify_test%1/%2", suffix, dcp_test1_cpl); } + static -boost::filesystem::path -pkl (int n) +path +pkl (string suffix) { - return dcp::String::compose("build/test/verify_test%1/%2", n, dcp_test1_pkl); + return dcp::String::compose("build/test/verify_test%1/%2", suffix, dcp_test1_pkl); } + static -boost::filesystem::path -asset_map (int n) +path +asset_map (string suffix) { - return dcp::String::compose("build/test/verify_test%1/ASSETMAP.xml", n); + return dcp::String::compose("build/test/verify_test%1/ASSETMAP.xml", suffix); } -/* FrameRate */ -BOOST_AUTO_TEST_CASE (verify_test5) +BOOST_AUTO_TEST_CASE (verify_invalid_picture_frame_rate) { check_verify_result_after_replace ( - 5, &cpl, + "invalid_picture_frame_rate", &cpl, "24 1", "99 1", - { dcp::VerificationNote::CPL_HASH_INCORRECT, - dcp::VerificationNote::INVALID_PICTURE_FRAME_RATE } + { dcp::VerificationNote::Code::MISMATCHED_CPL_HASHES, + dcp::VerificationNote::Code::INVALID_PICTURE_FRAME_RATE } ); } -/* Missing asset */ -BOOST_AUTO_TEST_CASE (verify_test6) +BOOST_AUTO_TEST_CASE (verify_missing_asset) { - auto directories = setup (1, 6); - - boost::filesystem::remove ("build/test/verify_test6/video.mxf"); - check_verify_result (directories, {{ dcp::VerificationNote::VERIFY_ERROR, dcp::VerificationNote::MISSING_ASSET }}); + auto dir = setup (1, "missing_asset"); + remove (dir / "video.mxf"); + check_verify_result ( + { dir }, + { + { dcp::VerificationNote::Type::ERROR, dcp::VerificationNote::Code::MISSING_ASSET, canonical(dir) / "video.mxf" } + }); } -static -boost::filesystem::path -assetmap (int n) -{ - return dcp::String::compose("build/test/verify_test%1/ASSETMAP.xml", n); -} -/* Empty asset filename in ASSETMAP */ -BOOST_AUTO_TEST_CASE (verify_test7) +BOOST_AUTO_TEST_CASE (verify_empty_asset_path) { check_verify_result_after_replace ( - 7, &assetmap, + "empty_asset_path", &asset_map, "video.mxf", "", - { dcp::VerificationNote::EMPTY_ASSET_PATH } + { dcp::VerificationNote::Code::EMPTY_ASSET_PATH } ); } -/* Mismatched standard */ -BOOST_AUTO_TEST_CASE (verify_test8) + +BOOST_AUTO_TEST_CASE (verify_mismatched_standard) { check_verify_result_after_replace ( - 8, &cpl, + "mismatched_standard", &cpl, "http://www.smpte-ra.org/schemas/429-7/2006/CPL", "http://www.digicine.com/PROTO-ASDCP-CPL-20040511#", - { dcp::VerificationNote::MISMATCHED_STANDARD, - dcp::VerificationNote::XML_VALIDATION_ERROR, - dcp::VerificationNote::XML_VALIDATION_ERROR, - dcp::VerificationNote::XML_VALIDATION_ERROR, - dcp::VerificationNote::XML_VALIDATION_ERROR, - dcp::VerificationNote::XML_VALIDATION_ERROR, - dcp::VerificationNote::CPL_HASH_INCORRECT } + { dcp::VerificationNote::Code::MISMATCHED_STANDARD, + dcp::VerificationNote::Code::INVALID_XML, + dcp::VerificationNote::Code::INVALID_XML, + dcp::VerificationNote::Code::INVALID_XML, + dcp::VerificationNote::Code::INVALID_XML, + dcp::VerificationNote::Code::INVALID_XML, + dcp::VerificationNote::Code::MISMATCHED_CPL_HASHES } ); } -/* Badly formatted in CPL */ -BOOST_AUTO_TEST_CASE (verify_test9) + +BOOST_AUTO_TEST_CASE (verify_invalid_xml_cpl_id) { - /* There's no CPL_HASH_INCORRECT error here because it can't find the correct hash by ID (since the ID is wrong) */ + /* There's no MISMATCHED_CPL_HASHES error here because it can't find the correct hash by ID (since the ID is wrong) */ check_verify_result_after_replace ( - 9, &cpl, + "invalid_xml_cpl_id", &cpl, "urn:uuid:81fb54df-e1bf-4647-8788-ea7ba154375b", "urn:uuid:81fb54df-e1bf-4647-8788-ea7ba154375", - { dcp::VerificationNote::XML_VALIDATION_ERROR } + { dcp::VerificationNote::Code::INVALID_XML } ); } -/* Badly formatted in CPL */ -BOOST_AUTO_TEST_CASE (verify_test10) + +BOOST_AUTO_TEST_CASE (verify_invalid_xml_issue_date) { check_verify_result_after_replace ( - 10, &cpl, + "invalid_xml_issue_date", &cpl, "", "x", - { dcp::VerificationNote::XML_VALIDATION_ERROR, - dcp::VerificationNote::CPL_HASH_INCORRECT } + { dcp::VerificationNote::Code::INVALID_XML, + dcp::VerificationNote::Code::MISMATCHED_CPL_HASHES } ); } -/* Badly-formatted in PKL */ -BOOST_AUTO_TEST_CASE (verify_test11) + +BOOST_AUTO_TEST_CASE (verify_invalid_xml_pkl_id) { check_verify_result_after_replace ( - 11, &pkl, + "invalid_xml_pkl_id", &pkl, "urn:uuid:2b9", "urn:uuid:xb9", - { dcp::VerificationNote::XML_VALIDATION_ERROR } + { dcp::VerificationNote::Code::INVALID_XML } ); } -/* Badly-formatted in ASSETMAP */ -BOOST_AUTO_TEST_CASE (verify_test12) + +BOOST_AUTO_TEST_CASE (verify_invalid_xml_asset_map_id) { check_verify_result_after_replace ( - 12, &asset_map, + "invalix_xml_asset_map_id", &asset_map, "urn:uuid:07e", "urn:uuid:x7e", - { dcp::VerificationNote::XML_VALIDATION_ERROR } + { dcp::VerificationNote::Code::INVALID_XML } ); } -/* Basic test of an Interop DCP */ -BOOST_AUTO_TEST_CASE (verify_test13) + +BOOST_AUTO_TEST_CASE (verify_invalid_standard) { stages.clear (); - auto directories = setup (3, 13); - auto notes = dcp::verify (directories, &stage, &progress, xsd_test); + auto dir = setup (3, "verify_invalid_standard"); + auto notes = dcp::verify ({dir}, &stage, &progress, xsd_test); - boost::filesystem::path const cpl_file = boost::filesystem::path("build") / "test" / "verify_test13" / "cpl_cbfd2bc0-21cf-4a8f-95d8-9cddcbe51296.xml"; - boost::filesystem::path const pkl_file = boost::filesystem::path("build") / "test" / "verify_test13" / "pkl_d87a950c-bd6f-41f6-90cc-56ccd673e131.xml"; - boost::filesystem::path const assetmap_file = "build/test/verify_test13/ASSETMAP"; + path const cpl_file = dir / "cpl_cbfd2bc0-21cf-4a8f-95d8-9cddcbe51296.xml"; + path const pkl_file = dir / "pkl_d87a950c-bd6f-41f6-90cc-56ccd673e131.xml"; + path const assetmap_file = dir / "ASSETMAP"; auto st = stages.begin(); BOOST_CHECK_EQUAL (st->first, "Checking DCP"); BOOST_REQUIRE (st->second); - BOOST_CHECK_EQUAL (st->second.get(), boost::filesystem::canonical("build/test/verify_test13")); + BOOST_CHECK_EQUAL (st->second.get(), canonical(dir)); ++st; BOOST_CHECK_EQUAL (st->first, "Checking CPL"); BOOST_REQUIRE (st->second); - BOOST_CHECK_EQUAL (st->second.get(), boost::filesystem::canonical(cpl_file)); + BOOST_CHECK_EQUAL (st->second.get(), canonical(cpl_file)); ++st; BOOST_CHECK_EQUAL (st->first, "Checking reel"); BOOST_REQUIRE (!st->second); ++st; BOOST_CHECK_EQUAL (st->first, "Checking picture asset hash"); BOOST_REQUIRE (st->second); - BOOST_CHECK_EQUAL (st->second.get(), boost::filesystem::canonical("build/test/verify_test13/j2c_c6035f97-b07d-4e1c-944d-603fc2ddc242.mxf")); + BOOST_CHECK_EQUAL (st->second.get(), canonical(dir / "j2c_c6035f97-b07d-4e1c-944d-603fc2ddc242.mxf")); ++st; BOOST_CHECK_EQUAL (st->first, "Checking picture frame sizes"); BOOST_REQUIRE (st->second); - BOOST_CHECK_EQUAL (st->second.get(), boost::filesystem::canonical("build/test/verify_test13/j2c_c6035f97-b07d-4e1c-944d-603fc2ddc242.mxf")); + BOOST_CHECK_EQUAL (st->second.get(), canonical(dir / "j2c_c6035f97-b07d-4e1c-944d-603fc2ddc242.mxf")); ++st; BOOST_CHECK_EQUAL (st->first, "Checking sound asset hash"); BOOST_REQUIRE (st->second); - BOOST_CHECK_EQUAL (st->second.get(), boost::filesystem::canonical("build/test/verify_test13/pcm_69cf9eaf-9a99-4776-b022-6902208626c3.mxf")); + BOOST_CHECK_EQUAL (st->second.get(), canonical(dir / "pcm_69cf9eaf-9a99-4776-b022-6902208626c3.mxf")); ++st; BOOST_CHECK_EQUAL (st->first, "Checking sound asset metadata"); BOOST_REQUIRE (st->second); - BOOST_CHECK_EQUAL (st->second.get(), boost::filesystem::canonical("build/test/verify_test13/pcm_69cf9eaf-9a99-4776-b022-6902208626c3.mxf")); + BOOST_CHECK_EQUAL (st->second.get(), canonical(dir / "pcm_69cf9eaf-9a99-4776-b022-6902208626c3.mxf")); ++st; BOOST_CHECK_EQUAL (st->first, "Checking PKL"); BOOST_REQUIRE (st->second); - BOOST_CHECK_EQUAL (st->second.get(), boost::filesystem::canonical(pkl_file)); + BOOST_CHECK_EQUAL (st->second.get(), canonical(pkl_file)); ++st; BOOST_CHECK_EQUAL (st->first, "Checking ASSETMAP"); BOOST_REQUIRE (st->second); - BOOST_CHECK_EQUAL (st->second.get(), boost::filesystem::canonical(assetmap_file)); + BOOST_CHECK_EQUAL (st->second.get(), canonical(assetmap_file)); ++st; BOOST_REQUIRE (st == stages.end()); BOOST_REQUIRE_EQUAL (notes.size(), 1U); auto i = notes.begin (); - BOOST_CHECK_EQUAL (i->type(), dcp::VerificationNote::VERIFY_BV21_ERROR); - BOOST_CHECK_EQUAL (i->code(), dcp::VerificationNote::NOT_SMPTE); + BOOST_CHECK_EQUAL (i->type(), dcp::VerificationNote::Type::BV21_ERROR); + BOOST_CHECK_EQUAL (i->code(), dcp::VerificationNote::Code::INVALID_STANDARD); } /* DCP with a short asset */ -BOOST_AUTO_TEST_CASE (verify_test14) +BOOST_AUTO_TEST_CASE (verify_invalid_duration) { - auto directories = setup (8, 14); + auto dir = setup (8, "invalid_duration"); check_verify_result ( - directories, + { dir }, { - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::NOT_SMPTE }, - { dcp::VerificationNote::VERIFY_ERROR, dcp::VerificationNote::DURATION_TOO_SMALL }, - { dcp::VerificationNote::VERIFY_ERROR, dcp::VerificationNote::INTRINSIC_DURATION_TOO_SMALL }, - { dcp::VerificationNote::VERIFY_ERROR, dcp::VerificationNote::DURATION_TOO_SMALL }, - { dcp::VerificationNote::VERIFY_ERROR, dcp::VerificationNote::INTRINSIC_DURATION_TOO_SMALL } + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::INVALID_STANDARD }, + { dcp::VerificationNote::Type::ERROR, dcp::VerificationNote::Code::INVALID_DURATION, string("d7576dcb-a361-4139-96b8-267f5f8d7f91") }, + { dcp::VerificationNote::Type::ERROR, dcp::VerificationNote::Code::INVALID_INTRINSIC_DURATION, string("d7576dcb-a361-4139-96b8-267f5f8d7f91") }, + { dcp::VerificationNote::Type::ERROR, dcp::VerificationNote::Code::INVALID_DURATION, string("a2a87f5d-b749-4a7e-8d0c-9d48a4abf626") }, + { dcp::VerificationNote::Type::ERROR, dcp::VerificationNote::Code::INVALID_INTRINSIC_DURATION, string("a2a87f5d-b749-4a7e-8d0c-9d48a4abf626") } }); } static -void -dcp_from_frame (dcp::ArrayData const& frame, boost::filesystem::path dir) +shared_ptr +dcp_from_frame (dcp::ArrayData const& frame, path dir) { - auto asset = make_shared(dcp::Fraction(24, 1), dcp::SMPTE); - boost::filesystem::create_directories (dir); + auto asset = make_shared(dcp::Fraction(24, 1), dcp::Standard::SMPTE); + create_directories (dir); auto writer = asset->start_write (dir / "pic.mxf", true); for (int i = 0; i < 24; ++i) { writer->write (frame.data(), frame.size()); @@ -543,12 +552,11 @@ dcp_from_frame (dcp::ArrayData const& frame, boost::filesystem::path dir) writer->finalize (); auto reel_asset = make_shared(asset, 0); - write_dcp_with_single_asset (dir, reel_asset); + return write_dcp_with_single_asset (dir, reel_asset); } -/* DCP with an over-sized JPEG2000 frame */ -BOOST_AUTO_TEST_CASE (verify_test15) +BOOST_AUTO_TEST_CASE (verify_invalid_picture_frame_size_in_bytes) { int const too_big = 1302083 * 2; @@ -562,21 +570,20 @@ BOOST_AUTO_TEST_CASE (verify_test15) memcpy (oversized_frame.data(), frame.data(), frame.size()); memset (oversized_frame.data() + frame.size(), 0, too_big - frame.size()); - boost::filesystem::path const dir("build/test/verify_test15"); - boost::filesystem::remove_all (dir); - dcp_from_frame (oversized_frame, dir); + path const dir("build/test/verify_invalid_picture_frame_size_in_bytes"); + prepare_directory (dir); + auto cpl = dcp_from_frame (oversized_frame, dir); check_verify_result ( { dir }, { - { dcp::VerificationNote::VERIFY_ERROR, dcp::VerificationNote::PICTURE_FRAME_TOO_LARGE_IN_BYTES }, - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA } + { dcp::VerificationNote::Type::ERROR, dcp::VerificationNote::Code::INVALID_PICTURE_FRAME_SIZE_IN_BYTES, canonical(dir / "pic.mxf") }, + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_CPL_METADATA, cpl->id(), cpl->file().get() } }); } -/* DCP with a nearly over-sized JPEG2000 frame */ -BOOST_AUTO_TEST_CASE (verify_test16) +BOOST_AUTO_TEST_CASE (verify_nearly_invalid_picture_frame_size_in_bytes) { int const nearly_too_big = 1302083 * 0.98; @@ -590,58 +597,57 @@ BOOST_AUTO_TEST_CASE (verify_test16) memcpy (oversized_frame.data(), frame.data(), frame.size()); memset (oversized_frame.data() + frame.size(), 0, nearly_too_big - frame.size()); - boost::filesystem::path const dir("build/test/verify_test16"); - boost::filesystem::remove_all (dir); - dcp_from_frame (oversized_frame, dir); + path const dir("build/test/verify_nearly_invalid_picture_frame_size_in_bytes"); + prepare_directory (dir); + auto cpl = dcp_from_frame (oversized_frame, dir); check_verify_result ( { dir }, { - { dcp::VerificationNote::VERIFY_WARNING, dcp::VerificationNote::PICTURE_FRAME_NEARLY_TOO_LARGE_IN_BYTES }, - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA } + { dcp::VerificationNote::Type::WARNING, dcp::VerificationNote::Code::NEARLY_INVALID_PICTURE_FRAME_SIZE_IN_BYTES, canonical(dir / "pic.mxf") }, + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_CPL_METADATA, cpl->id(), cpl->file().get() } }); } -/* DCP with a within-range JPEG2000 frame */ -BOOST_AUTO_TEST_CASE (verify_test17) +BOOST_AUTO_TEST_CASE (verify_valid_picture_frame_size_in_bytes) { /* Compress a black image */ auto image = black_image (); auto frame = dcp::compress_j2k (image, 100000000, 24, false, false); BOOST_REQUIRE (frame.size() < 230000000 / (24 * 8)); - boost::filesystem::path const dir("build/test/verify_test17"); - boost::filesystem::remove_all (dir); - dcp_from_frame (frame, dir); + path const dir("build/test/verify_valid_picture_frame_size_in_bytes"); + prepare_directory (dir); + auto cpl = dcp_from_frame (frame, dir); - check_verify_result ({ dir }, {{ dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA }}); + check_verify_result ({ dir }, {{ dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_CPL_METADATA, cpl->id(), cpl->file().get() }}); } -/* DCP with valid Interop subtitles */ -BOOST_AUTO_TEST_CASE (verify_test18) +BOOST_AUTO_TEST_CASE (verify_valid_interop_subtitles) { - boost::filesystem::path const dir("build/test/verify_test18"); + path const dir("build/test/verify_valid_interop_subtitles"); prepare_directory (dir); - boost::filesystem::copy_file ("test/data/subs1.xml", dir / "subs.xml"); + copy_file ("test/data/subs1.xml", dir / "subs.xml"); auto asset = make_shared(dir / "subs.xml"); auto reel_asset = make_shared(asset, dcp::Fraction(24, 1), 16 * 24, 0); - write_dcp_with_single_asset (dir, reel_asset, dcp::INTEROP); + write_dcp_with_single_asset (dir, reel_asset, dcp::Standard::INTEROP); - check_verify_result ({dir}, {{ dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::NOT_SMPTE }}); + check_verify_result ({dir}, {{ dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::INVALID_STANDARD }}); } -/* DCP with broken Interop subtitles */ -BOOST_AUTO_TEST_CASE (verify_test19) +BOOST_AUTO_TEST_CASE (verify_invalid_interop_subtitles) { - boost::filesystem::path const dir("build/test/verify_test19"); + using namespace boost::filesystem; + + path const dir("build/test/verify_invalid_interop_subtitles"); prepare_directory (dir); - boost::filesystem::copy_file ("test/data/subs1.xml", dir / "subs.xml"); + copy_file ("test/data/subs1.xml", dir / "subs.xml"); auto asset = make_shared(dir / "subs.xml"); auto reel_asset = make_shared(asset, dcp::Fraction(24, 1), 16 * 24, 0); - write_dcp_with_single_asset (dir, reel_asset, dcp::INTEROP); + write_dcp_with_single_asset (dir, reel_asset, dcp::Standard::INTEROP); { Editor e (dir / "subs.xml"); @@ -651,52 +657,63 @@ BOOST_AUTO_TEST_CASE (verify_test19) check_verify_result ( { dir }, { - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::NOT_SMPTE }, - { dcp::VerificationNote::VERIFY_ERROR, dcp::VerificationNote::XML_VALIDATION_ERROR }, - { dcp::VerificationNote::VERIFY_ERROR, dcp::VerificationNote::XML_VALIDATION_ERROR } + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::INVALID_STANDARD }, + { dcp::VerificationNote::Type::ERROR, dcp::VerificationNote::Code::INVALID_XML, string("no declaration found for element 'Foo'"), path(), 5 }, + { + dcp::VerificationNote::Type::ERROR, + dcp::VerificationNote::Code::INVALID_XML, + string("element 'Foo' is not allowed for content model '(SubtitleID,MovieTitle,ReelNumber,Language,LoadFont*,Font*,Subtitle*)'"), + path(), + 29 + } }); } -/* DCP with valid SMPTE subtitles */ -BOOST_AUTO_TEST_CASE (verify_test20) +BOOST_AUTO_TEST_CASE (verify_valid_smpte_subtitles) { - boost::filesystem::path const dir("build/test/verify_test20"); + path const dir("build/test/verify_valid_smpte_subtitles"); prepare_directory (dir); - boost::filesystem::copy_file ("test/data/subs.mxf", dir / "subs.mxf"); + copy_file ("test/data/subs.mxf", dir / "subs.mxf"); auto asset = make_shared(dir / "subs.mxf"); auto reel_asset = make_shared(asset, dcp::Fraction(24, 1), 16 * 24, 0); - write_dcp_with_single_asset (dir, reel_asset); + auto cpl = write_dcp_with_single_asset (dir, reel_asset); - check_verify_result ({dir}, {{ dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA }}); + check_verify_result ({dir}, {{ dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_CPL_METADATA, cpl->id(), cpl->file().get() }}); } -/* DCP with broken SMPTE subtitles */ -BOOST_AUTO_TEST_CASE (verify_test21) +BOOST_AUTO_TEST_CASE (verify_invalid_smpte_subtitles) { - boost::filesystem::path const dir("build/test/verify_test21"); + using namespace boost::filesystem; + + path const dir("build/test/verify_invalid_smpte_subtitles"); prepare_directory (dir); - boost::filesystem::copy_file ("test/data/broken_smpte.mxf", dir / "subs.mxf"); + copy_file ("test/data/broken_smpte.mxf", dir / "subs.mxf"); auto asset = make_shared(dir / "subs.mxf"); auto reel_asset = make_shared(asset, dcp::Fraction(24, 1), 16 * 24, 0); - write_dcp_with_single_asset (dir, reel_asset); + auto cpl = write_dcp_with_single_asset (dir, reel_asset); check_verify_result ( { dir }, { - { dcp::VerificationNote::VERIFY_ERROR, dcp::VerificationNote::XML_VALIDATION_ERROR }, - { dcp::VerificationNote::VERIFY_ERROR, dcp::VerificationNote::XML_VALIDATION_ERROR }, - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_SUBTITLE_START_TIME }, - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA } + { dcp::VerificationNote::Type::ERROR, dcp::VerificationNote::Code::INVALID_XML, string("no declaration found for element 'Foo'"), path(), 2 }, + { + dcp::VerificationNote::Type::ERROR, + dcp::VerificationNote::Code::INVALID_XML, + string("element 'Foo' is not allowed for content model '(Id,ContentTitleText,AnnotationText?,IssueDate,ReelNumber?,Language?,EditRate,TimeCodeRate,StartTime?,DisplayType?,LoadFont*,SubtitleList)'"), + path(), + 2 + }, + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_SUBTITLE_START_TIME, canonical(dir / "subs.mxf") }, + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_CPL_METADATA, cpl->id(), cpl->file().get() }, }); } -/* VF */ -BOOST_AUTO_TEST_CASE (verify_test22) +BOOST_AUTO_TEST_CASE (verify_external_asset) { - boost::filesystem::path const ov_dir("build/test/verify_test22_ov"); + path const ov_dir("build/test/verify_external_asset"); prepare_directory (ov_dir); auto image = black_image (); @@ -707,59 +724,59 @@ BOOST_AUTO_TEST_CASE (verify_test22) dcp::DCP ov (ov_dir); ov.read (); - boost::filesystem::path const vf_dir("build/test/verify_test22_vf"); + path const vf_dir("build/test/verify_external_asset_vf"); prepare_directory (vf_dir); - write_dcp_with_single_asset (vf_dir, ov.cpls().front()->reels().front()->main_picture()); + auto picture = ov.cpls()[0]->reels()[0]->main_picture(); + auto cpl = write_dcp_with_single_asset (vf_dir, picture); check_verify_result ( { vf_dir }, { - { dcp::VerificationNote::VERIFY_WARNING, dcp::VerificationNote::EXTERNAL_ASSET }, - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA } + { dcp::VerificationNote::Type::WARNING, dcp::VerificationNote::Code::EXTERNAL_ASSET, picture->asset()->id() }, + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_CPL_METADATA, cpl->id(), cpl->file().get() } }); } -/* DCP with valid CompositionMetadataAsset */ -BOOST_AUTO_TEST_CASE (verify_test23) +BOOST_AUTO_TEST_CASE (verify_valid_cpl_metadata) { - boost::filesystem::path const dir("build/test/verify_test23"); + path const dir("build/test/verify_valid_cpl_metadata"); prepare_directory (dir); - boost::filesystem::copy_file ("test/data/subs.mxf", dir / "subs.mxf"); + copy_file ("test/data/subs.mxf", dir / "subs.mxf"); auto asset = make_shared(dir / "subs.mxf"); auto reel_asset = make_shared(asset, dcp::Fraction(24, 1), 16 * 24, 0); auto reel = make_shared(); reel->add (reel_asset); - reel->add (simple_markers(16 * 24 - 1)); + reel->add (make_shared(simple_picture(dir, "", 16 * 24), 0)); + reel->add (simple_markers(16 * 24)); - auto cpl = make_shared("hello", dcp::TRAILER); + auto cpl = make_shared("hello", dcp::ContentKind::TRAILER); cpl->add (reel); cpl->set_main_sound_configuration ("L,C,R,Lfe,-,-"); cpl->set_main_sound_sample_rate (48000); cpl->set_main_picture_stored_area (dcp::Size(1998, 1080)); cpl->set_main_picture_active_area (dcp::Size(1440, 1080)); + cpl->set_version_number (1); dcp::DCP dcp (dir); dcp.add (cpl); dcp.write_xml ( - dcp::SMPTE, + dcp::Standard::SMPTE, dcp::String::compose("libdcp %1", dcp::version), dcp::String::compose("libdcp %1", dcp::version), dcp::LocalTime().as_string(), "hello" ); - - check_verify_result ({dir}, {{ dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA }}); } -boost::filesystem::path find_cpl (boost::filesystem::path dir) +path find_cpl (path dir) { - for (auto i: boost::filesystem::directory_iterator(dir)) { + for (auto i: directory_iterator(dir)) { if (boost::starts_with(i.path().filename().string(), "cpl_")) { return i.path(); } @@ -771,14 +788,16 @@ boost::filesystem::path find_cpl (boost::filesystem::path dir) /* DCP with invalid CompositionMetadataAsset */ -BOOST_AUTO_TEST_CASE (verify_test24) +BOOST_AUTO_TEST_CASE (verify_invalid_cpl_metadata_bad_tag) { - boost::filesystem::path const dir("build/test/verify_test24"); + using namespace boost::filesystem; + + path const dir("build/test/verify_invalid_cpl_metadata_bad_tag"); prepare_directory (dir); auto reel = make_shared(); reel->add (black_picture_asset(dir)); - auto cpl = make_shared("hello", dcp::TRAILER); + auto cpl = make_shared("hello", dcp::ContentKind::TRAILER); cpl->add (reel); cpl->set_main_sound_configuration ("L,C,R,Lfe,-,-"); cpl->set_main_sound_sample_rate (48000); @@ -791,7 +810,7 @@ BOOST_AUTO_TEST_CASE (verify_test24) dcp::DCP dcp (dir); dcp.add (cpl); dcp.write_xml ( - dcp::SMPTE, + dcp::Standard::SMPTE, dcp::String::compose("libdcp %1", dcp::version), dcp::String::compose("libdcp %1", dcp::version), dcp::LocalTime().as_string(), @@ -799,30 +818,41 @@ BOOST_AUTO_TEST_CASE (verify_test24) ); { - Editor e (find_cpl("build/test/verify_test24")); + Editor e (find_cpl(dir)); e.replace ("MainSound", "MainSoundX"); } check_verify_result ( { dir }, { - { dcp::VerificationNote::VERIFY_ERROR, dcp::VerificationNote::XML_VALIDATION_ERROR }, - { dcp::VerificationNote::VERIFY_ERROR, dcp::VerificationNote::XML_VALIDATION_ERROR }, - { dcp::VerificationNote::VERIFY_ERROR, dcp::VerificationNote::XML_VALIDATION_ERROR }, - { dcp::VerificationNote::VERIFY_ERROR, dcp::VerificationNote::CPL_HASH_INCORRECT } + { dcp::VerificationNote::Type::ERROR, dcp::VerificationNote::Code::INVALID_XML, string("no declaration found for element 'meta:MainSoundXConfiguration'"), canonical(cpl->file().get()), 54 }, + { dcp::VerificationNote::Type::ERROR, dcp::VerificationNote::Code::INVALID_XML, string("no declaration found for element 'meta:MainSoundXSampleRate'"), canonical(cpl->file().get()), 55 }, + { + dcp::VerificationNote::Type::ERROR, + dcp::VerificationNote::Code::INVALID_XML, + string("element 'meta:MainSoundXConfiguration' is not allowed for content model " + "'(Id,AnnotationText?,EditRate,IntrinsicDuration,EntryPoint?,Duration?," + "FullContentTitleText,ReleaseTerritory?,VersionNumber?,Chain?,Distributor?," + "Facility?,AlternateContentVersionList?,Luminance?,MainSoundConfiguration," + "MainSoundSampleRate,MainPictureStoredArea,MainPictureActiveArea,MainSubtitleLanguageList?," + "ExtensionMetadataList?,)'"), + canonical(cpl->file().get()), + 75 + }, + { dcp::VerificationNote::Type::ERROR, dcp::VerificationNote::Code::MISMATCHED_CPL_HASHES, cpl->id(), canonical(cpl->file().get()) }, }); } /* DCP with invalid CompositionMetadataAsset */ -BOOST_AUTO_TEST_CASE (verify_test25) +BOOST_AUTO_TEST_CASE (verify_invalid_cpl_metadata_missing_tag) { - boost::filesystem::path const dir("build/test/verify_test25"); + path const dir("build/test/verify_invalid_cpl_metadata_missing_tag"); prepare_directory (dir); auto reel = make_shared(); reel->add (black_picture_asset(dir)); - auto cpl = make_shared("hello", dcp::TRAILER); + auto cpl = make_shared("hello", dcp::ContentKind::TRAILER); cpl->add (reel); cpl->set_main_sound_configuration ("L,C,R,Lfe,-,-"); cpl->set_main_sound_sample_rate (48000); @@ -832,7 +862,7 @@ BOOST_AUTO_TEST_CASE (verify_test25) dcp::DCP dcp (dir); dcp.add (cpl); dcp.write_xml ( - dcp::SMPTE, + dcp::Standard::SMPTE, dcp::String::compose("libdcp %1", dcp::version), dcp::String::compose("libdcp %1", dcp::version), dcp::LocalTime().as_string(), @@ -840,59 +870,58 @@ BOOST_AUTO_TEST_CASE (verify_test25) ); { - Editor e (find_cpl("build/test/verify_test25")); + Editor e (find_cpl(dir)); e.replace ("meta:Width", "meta:WidthX"); } check_verify_result ( { dir }, - {{ dcp::VerificationNote::VERIFY_ERROR, dcp::VerificationNote::GENERAL_READ }} + {{ dcp::VerificationNote::Type::ERROR, dcp::VerificationNote::Code::FAILED_READ, string("missing XML tag Width in MainPictureStoredArea") }} ); } -/* SMPTE DCP with invalid in the MainSubtitle reel and also in the XML within the MXF */ -BOOST_AUTO_TEST_CASE (verify_test26) +BOOST_AUTO_TEST_CASE (verify_invalid_language1) { - boost::filesystem::path const dir("build/test/verify_test26"); + path const dir("build/test/verify_invalid_language1"); prepare_directory (dir); - boost::filesystem::copy_file ("test/data/subs.mxf", dir / "subs.mxf"); + copy_file ("test/data/subs.mxf", dir / "subs.mxf"); auto asset = make_shared(dir / "subs.mxf"); asset->_language = "wrong-andbad"; asset->write (dir / "subs.mxf"); auto reel_asset = make_shared(asset, dcp::Fraction(24, 1), 16 * 24, 0); reel_asset->_language = "badlang"; - write_dcp_with_single_asset (dir, reel_asset); + auto cpl = write_dcp_with_single_asset (dir, reel_asset); check_verify_result ( { dir }, { - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::BAD_LANGUAGE, string("badlang") }, - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::BAD_LANGUAGE, string("wrong-andbad") }, - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA }, + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::INVALID_LANGUAGE, string("badlang") }, + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::INVALID_LANGUAGE, string("wrong-andbad") }, + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_CPL_METADATA, cpl->id(), cpl->file().get() }, }); } /* SMPTE DCP with invalid in the MainClosedCaption reel and also in the XML within the MXF */ -BOOST_AUTO_TEST_CASE (verify_invalid_closed_caption_languages) +BOOST_AUTO_TEST_CASE (verify_invalid_language2) { - boost::filesystem::path const dir("build/test/verify_invalid_closed_caption_languages"); + path const dir("build/test/verify_invalid_language2"); prepare_directory (dir); - boost::filesystem::copy_file ("test/data/subs.mxf", dir / "subs.mxf"); + copy_file ("test/data/subs.mxf", dir / "subs.mxf"); auto asset = make_shared(dir / "subs.mxf"); asset->_language = "wrong-andbad"; asset->write (dir / "subs.mxf"); auto reel_asset = make_shared(asset, dcp::Fraction(24, 1), 16 * 24, 0); reel_asset->_language = "badlang"; - write_dcp_with_single_asset (dir, reel_asset); + auto cpl = write_dcp_with_single_asset (dir, reel_asset); check_verify_result ( {dir}, { - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::BAD_LANGUAGE, string("badlang") }, - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::BAD_LANGUAGE, string("wrong-andbad") }, - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA } + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::INVALID_LANGUAGE, string("badlang") }, + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::INVALID_LANGUAGE, string("wrong-andbad") }, + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_CPL_METADATA, cpl->id(), cpl->file().get() } }); } @@ -900,9 +929,9 @@ BOOST_AUTO_TEST_CASE (verify_invalid_closed_caption_languages) /* SMPTE DCP with invalid in the MainSound reel, the CPL additional subtitles languages and * the release territory. */ -BOOST_AUTO_TEST_CASE (verify_various_invalid_languages) +BOOST_AUTO_TEST_CASE (verify_invalid_language3) { - boost::filesystem::path const dir("build/test/verify_various_invalid_languages"); + path const dir("build/test/verify_invalid_language3"); prepare_directory (dir); auto picture = simple_picture (dir, "foo"); @@ -914,7 +943,7 @@ BOOST_AUTO_TEST_CASE (verify_various_invalid_languages) reel->add (reel_sound); reel->add (simple_markers()); - auto cpl = make_shared("hello", dcp::TRAILER); + auto cpl = make_shared("hello", dcp::ContentKind::TRAILER); cpl->add (reel); cpl->_additional_subtitle_languages.push_back("this-is-wrong"); cpl->_additional_subtitle_languages.push_back("andso-is-this"); @@ -927,7 +956,7 @@ BOOST_AUTO_TEST_CASE (verify_various_invalid_languages) auto dcp = make_shared(dir); dcp->add (cpl); dcp->write_xml ( - dcp::SMPTE, + dcp::Standard::SMPTE, dcp::String::compose("libdcp %1", dcp::version), dcp::String::compose("libdcp %1", dcp::version), dcp::LocalTime().as_string(), @@ -937,10 +966,10 @@ BOOST_AUTO_TEST_CASE (verify_various_invalid_languages) check_verify_result ( { dir }, { - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::BAD_LANGUAGE, string("this-is-wrong") }, - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::BAD_LANGUAGE, string("andso-is-this") }, - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::BAD_LANGUAGE, string("fred-jim") }, - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::BAD_LANGUAGE, string("frobozz") }, + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::INVALID_LANGUAGE, string("this-is-wrong") }, + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::INVALID_LANGUAGE, string("andso-is-this") }, + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::INVALID_LANGUAGE, string("fred-jim") }, + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::INVALID_LANGUAGE, string("frobozz") }, }); } @@ -952,14 +981,13 @@ check_picture_size (int width, int height, int frame_rate, bool three_d) using namespace boost::filesystem; path dcp_path = "build/test/verify_picture_test"; - remove_all (dcp_path); - create_directories (dcp_path); + prepare_directory (dcp_path); shared_ptr mp; if (three_d) { - mp = make_shared(dcp::Fraction(frame_rate, 1), dcp::SMPTE); + mp = make_shared(dcp::Fraction(frame_rate, 1), dcp::Standard::SMPTE); } else { - mp = make_shared(dcp::Fraction(frame_rate, 1), dcp::SMPTE); + mp = make_shared(dcp::Fraction(frame_rate, 1), dcp::Standard::SMPTE); } auto picture_writer = mp->start_write (dcp_path / "video.mxf", false); @@ -972,7 +1000,7 @@ check_picture_size (int width, int height, int frame_rate, bool three_d) picture_writer->finalize (); auto d = make_shared(dcp_path); - auto cpl = make_shared("A Test DCP", dcp::TRAILER); + auto cpl = make_shared("A Test DCP", dcp::ContentKind::TRAILER); cpl->set_annotation_text ("A Test DCP"); cpl->set_issue_date ("2012-07-17T04:45:18+00:00"); cpl->set_main_sound_configuration ("L,C,R,Lfe,-,-"); @@ -995,7 +1023,7 @@ check_picture_size (int width, int height, int frame_rate, bool three_d) d->add (cpl); d->write_xml ( - dcp::SMPTE, + dcp::Standard::SMPTE, dcp::String::compose("libdcp %1", dcp::version), dcp::String::compose("libdcp %1", dcp::version), dcp::LocalTime().as_string(), @@ -1022,8 +1050,8 @@ check_picture_size_bad_frame_size (int width, int height, int frame_rate, bool t { auto notes = check_picture_size(width, height, frame_rate, three_d); BOOST_REQUIRE_EQUAL (notes.size(), 1U); - BOOST_CHECK_EQUAL (notes.front().type(), dcp::VerificationNote::VERIFY_BV21_ERROR); - BOOST_CHECK_EQUAL (notes.front().code(), dcp::VerificationNote::PICTURE_ASSET_INVALID_SIZE_IN_PIXELS); + BOOST_CHECK_EQUAL (notes.front().type(), dcp::VerificationNote::Type::BV21_ERROR); + BOOST_CHECK_EQUAL (notes.front().code(), dcp::VerificationNote::Code::INVALID_PICTURE_SIZE_IN_PIXELS); } @@ -1033,8 +1061,8 @@ check_picture_size_bad_2k_frame_rate (int width, int height, int frame_rate, boo { auto notes = check_picture_size(width, height, frame_rate, three_d); BOOST_REQUIRE_EQUAL (notes.size(), 2U); - BOOST_CHECK_EQUAL (notes.back().type(), dcp::VerificationNote::VERIFY_BV21_ERROR); - BOOST_CHECK_EQUAL (notes.back().code(), dcp::VerificationNote::PICTURE_ASSET_INVALID_FRAME_RATE_FOR_2K); + BOOST_CHECK_EQUAL (notes.back().type(), dcp::VerificationNote::Type::BV21_ERROR); + BOOST_CHECK_EQUAL (notes.back().code(), dcp::VerificationNote::Code::INVALID_PICTURE_FRAME_RATE_FOR_2K); } @@ -1044,8 +1072,8 @@ check_picture_size_bad_4k_frame_rate (int width, int height, int frame_rate, boo { auto notes = check_picture_size(width, height, frame_rate, three_d); BOOST_REQUIRE_EQUAL (notes.size(), 1U); - BOOST_CHECK_EQUAL (notes.front().type(), dcp::VerificationNote::VERIFY_BV21_ERROR); - BOOST_CHECK_EQUAL (notes.front().code(), dcp::VerificationNote::PICTURE_ASSET_INVALID_FRAME_RATE_FOR_4K); + BOOST_CHECK_EQUAL (notes.front().type(), dcp::VerificationNote::Type::BV21_ERROR); + BOOST_CHECK_EQUAL (notes.front().code(), dcp::VerificationNote::Code::INVALID_PICTURE_FRAME_RATE_FOR_4K); } @@ -1093,8 +1121,8 @@ BOOST_AUTO_TEST_CASE (verify_picture_size) /* No 4K 3D */ auto notes = check_picture_size(3996, 2160, 24, true); BOOST_REQUIRE_EQUAL (notes.size(), 1U); - BOOST_CHECK_EQUAL (notes.front().type(), dcp::VerificationNote::VERIFY_BV21_ERROR); - BOOST_CHECK_EQUAL (notes.front().code(), dcp::VerificationNote::PICTURE_ASSET_4K_3D); + BOOST_CHECK_EQUAL (notes.front().type(), dcp::VerificationNote::Type::BV21_ERROR); + BOOST_CHECK_EQUAL (notes.front().code(), dcp::VerificationNote::Code::INVALID_PICTURE_ASSET_RESOLUTION_FOR_3D); } @@ -1114,12 +1142,12 @@ add_test_subtitle (shared_ptr asset, int start_frame, int en dcp::Time(start_frame, 24, 24), dcp::Time(end_frame, 24, 24), 0, - dcp::HALIGN_CENTER, + dcp::HAlign::CENTER, v_position, - dcp::VALIGN_CENTER, - dcp::DIRECTION_LTR, + dcp::VAlign::CENTER, + dcp::Direction::LTR, text, - dcp::NONE, + dcp::Effect::NONE, dcp::Colour(), dcp::Time(), dcp::Time() @@ -1128,9 +1156,9 @@ add_test_subtitle (shared_ptr asset, int start_frame, int en } -BOOST_AUTO_TEST_CASE (verify_closed_caption_xml_too_large) +BOOST_AUTO_TEST_CASE (verify_invalid_closed_caption_xml_size_in_bytes) { - boost::filesystem::path const dir("build/test/verify_closed_caption_xml_too_large"); + path const dir("build/test/verify_invalid_closed_caption_xml_size_in_bytes"); prepare_directory (dir); auto asset = make_shared(); @@ -1140,22 +1168,27 @@ BOOST_AUTO_TEST_CASE (verify_closed_caption_xml_too_large) asset->set_language (dcp::LanguageTag("de-DE")); asset->write (dir / "subs.mxf"); auto reel_asset = make_shared(asset, dcp::Fraction(24, 1), 16 * 24, 0); - write_dcp_with_single_asset (dir, reel_asset); + auto cpl = write_dcp_with_single_asset (dir, reel_asset); check_verify_result ( { dir }, { - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_SUBTITLE_START_TIME }, - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::CLOSED_CAPTION_XML_TOO_LARGE_IN_BYTES }, - { dcp::VerificationNote::VERIFY_WARNING, dcp::VerificationNote::FIRST_TEXT_TOO_EARLY }, - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA }, + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_SUBTITLE_START_TIME, canonical(dir / "subs.mxf") }, + { + dcp::VerificationNote::Type::BV21_ERROR, + dcp::VerificationNote::Code::INVALID_CLOSED_CAPTION_XML_SIZE_IN_BYTES, + string("413262"), + canonical(dir / "subs.mxf") + }, + { dcp::VerificationNote::Type::WARNING, dcp::VerificationNote::Code::INVALID_SUBTITLE_FIRST_TEXT_TIME }, + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_CPL_METADATA, cpl->id(), cpl->file().get() }, }); } static shared_ptr -make_large_subtitle_asset (boost::filesystem::path font_file) +make_large_subtitle_asset (path font_file) { auto asset = make_shared(); dcp::ArrayData big_fake_font(1024 * 1024); @@ -1171,7 +1204,7 @@ template void verify_timed_text_asset_too_large (string name) { - auto const dir = boost::filesystem::path("build/test") / name; + auto const dir = path("build/test") / name; prepare_directory (dir); auto asset = make_large_subtitle_asset (dir / "font.ttf"); add_test_subtitle (asset, 0, 20); @@ -1179,16 +1212,16 @@ verify_timed_text_asset_too_large (string name) asset->write (dir / "subs.mxf"); auto reel_asset = make_shared(asset, dcp::Fraction(24, 1), 16 * 24, 0); - write_dcp_with_single_asset (dir, reel_asset); + auto cpl = write_dcp_with_single_asset (dir, reel_asset); check_verify_result ( { dir }, { - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::TIMED_TEXT_ASSET_TOO_LARGE_IN_BYTES }, - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::TIMED_TEXT_FONTS_TOO_LARGE_IN_BYTES }, - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_SUBTITLE_START_TIME }, - { dcp::VerificationNote::VERIFY_WARNING, dcp::VerificationNote::FIRST_TEXT_TOO_EARLY }, - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA }, + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::INVALID_TIMED_TEXT_SIZE_IN_BYTES, string("121696411"), canonical(dir / "subs.mxf") }, + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::INVALID_TIMED_TEXT_FONT_SIZE_IN_BYTES, string("121634816"), canonical(dir / "subs.mxf") }, + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_SUBTITLE_START_TIME, canonical(dir / "subs.mxf") }, + { dcp::VerificationNote::Type::WARNING, dcp::VerificationNote::Code::INVALID_SUBTITLE_FIRST_TEXT_TIME }, + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_CPL_METADATA, cpl->id(), cpl->file().get() }, }); } @@ -1200,9 +1233,9 @@ BOOST_AUTO_TEST_CASE (verify_subtitle_asset_too_large) } -BOOST_AUTO_TEST_CASE (verify_missing_language_tag_in_subtitle_xml) +BOOST_AUTO_TEST_CASE (verify_missing_subtitle_language) { - boost::filesystem::path dir = "build/test/verify_missing_language_tag_in_subtitle_xml"; + path dir = "build/test/verify_missing_subtitle_language"; prepare_directory (dir); auto dcp = make_simple (dir, 1, 240); @@ -1237,7 +1270,7 @@ BOOST_AUTO_TEST_CASE (verify_missing_language_tag_in_subtitle_xml) auto reel_subs = make_shared(subs, dcp::Fraction(24, 1), 240, 0); dcp->cpls().front()->reels().front()->add(reel_subs); dcp->write_xml ( - dcp::SMPTE, + dcp::Standard::SMPTE, dcp::String::compose("libdcp %1", dcp::version), dcp::String::compose("libdcp %1", dcp::version), dcp::LocalTime().as_string(), @@ -1247,15 +1280,15 @@ BOOST_AUTO_TEST_CASE (verify_missing_language_tag_in_subtitle_xml) check_verify_result ( { dir }, { - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_SUBTITLE_LANGUAGE }, - { dcp::VerificationNote::VERIFY_WARNING, dcp::VerificationNote::FIRST_TEXT_TOO_EARLY } + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_SUBTITLE_LANGUAGE, canonical(dir / "subs.mxf") }, + { dcp::VerificationNote::Type::WARNING, dcp::VerificationNote::Code::INVALID_SUBTITLE_FIRST_TEXT_TIME } }); } -BOOST_AUTO_TEST_CASE (verify_inconsistent_subtitle_languages) +BOOST_AUTO_TEST_CASE (verify_mismatched_subtitle_languages) { - boost::filesystem::path path ("build/test/verify_inconsistent_subtitle_languages"); + path path ("build/test/verify_mismatched_subtitle_languages"); auto dcp = make_simple (path, 2, 240); auto cpl = dcp->cpls()[0]; @@ -1278,7 +1311,7 @@ BOOST_AUTO_TEST_CASE (verify_inconsistent_subtitle_languages) } dcp->write_xml ( - dcp::SMPTE, + dcp::Standard::SMPTE, dcp::String::compose("libdcp %1", dcp::version), dcp::String::compose("libdcp %1", dcp::version), dcp::LocalTime().as_string(), @@ -1288,16 +1321,16 @@ BOOST_AUTO_TEST_CASE (verify_inconsistent_subtitle_languages) check_verify_result ( { path }, { - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_SUBTITLE_START_TIME }, - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::SUBTITLE_LANGUAGES_DIFFER }, - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_SUBTITLE_START_TIME } + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_SUBTITLE_START_TIME, canonical(path / "subs1.mxf") }, + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISMATCHED_SUBTITLE_LANGUAGES }, + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_SUBTITLE_START_TIME, canonical(path / "subs2.mxf") } }); } -BOOST_AUTO_TEST_CASE (verify_missing_start_time_tag_in_subtitle_xml) +BOOST_AUTO_TEST_CASE (verify_missing_subtitle_start_time) { - boost::filesystem::path dir = "build/test/verify_missing_start_time_tag_in_subtitle_xml"; + path dir = "build/test/verify_missing_subtitle_start_time"; prepare_directory (dir); auto dcp = make_simple (dir, 1, 240); @@ -1332,7 +1365,7 @@ BOOST_AUTO_TEST_CASE (verify_missing_start_time_tag_in_subtitle_xml) auto reel_subs = make_shared(subs, dcp::Fraction(24, 1), 240, 0); dcp->cpls().front()->reels().front()->add(reel_subs); dcp->write_xml ( - dcp::SMPTE, + dcp::Standard::SMPTE, dcp::String::compose("libdcp %1", dcp::version), dcp::String::compose("libdcp %1", dcp::version), dcp::LocalTime().as_string(), @@ -1342,15 +1375,15 @@ BOOST_AUTO_TEST_CASE (verify_missing_start_time_tag_in_subtitle_xml) check_verify_result ( { dir }, { - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_SUBTITLE_START_TIME }, - { dcp::VerificationNote::VERIFY_WARNING, dcp::VerificationNote::FIRST_TEXT_TOO_EARLY } + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_SUBTITLE_START_TIME, canonical(dir / "subs.mxf") }, + { dcp::VerificationNote::Type::WARNING, dcp::VerificationNote::Code::INVALID_SUBTITLE_FIRST_TEXT_TIME } }); } -BOOST_AUTO_TEST_CASE (verify_non_zero_start_time_tag_in_subtitle_xml) +BOOST_AUTO_TEST_CASE (verify_invalid_subtitle_start_time) { - boost::filesystem::path dir = "build/test/verify_non_zero_start_time_tag_in_subtitle_xml"; + path dir = "build/test/verify_invalid_subtitle_start_time"; prepare_directory (dir); auto dcp = make_simple (dir, 1, 240); @@ -1386,7 +1419,7 @@ BOOST_AUTO_TEST_CASE (verify_non_zero_start_time_tag_in_subtitle_xml) auto reel_subs = make_shared(subs, dcp::Fraction(24, 1), 240, 0); dcp->cpls().front()->reels().front()->add(reel_subs); dcp->write_xml ( - dcp::SMPTE, + dcp::Standard::SMPTE, dcp::String::compose("libdcp %1", dcp::version), dcp::String::compose("libdcp %1", dcp::version), dcp::LocalTime().as_string(), @@ -1396,8 +1429,8 @@ BOOST_AUTO_TEST_CASE (verify_non_zero_start_time_tag_in_subtitle_xml) check_verify_result ( { dir }, { - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::SUBTITLE_START_TIME_NON_ZERO }, - { dcp::VerificationNote::VERIFY_WARNING, dcp::VerificationNote::FIRST_TEXT_TOO_EARLY } + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::INVALID_SUBTITLE_START_TIME, canonical(dir / "subs.mxf") }, + { dcp::VerificationNote::Type::WARNING, dcp::VerificationNote::Code::INVALID_SUBTITLE_FIRST_TEXT_TIME } }); } @@ -1420,8 +1453,8 @@ public: template -void -dcp_with_text (boost::filesystem::path dir, vector subs) +shared_ptr +dcp_with_text (path dir, vector subs) { prepare_directory (dir); auto asset = make_shared(); @@ -1433,37 +1466,37 @@ dcp_with_text (boost::filesystem::path dir, vector subs) asset->write (dir / "subs.mxf"); auto reel_asset = make_shared(asset, dcp::Fraction(24, 1), 16 * 24, 0); - write_dcp_with_single_asset (dir, reel_asset); + return write_dcp_with_single_asset (dir, reel_asset); } -BOOST_AUTO_TEST_CASE (verify_text_too_early) +BOOST_AUTO_TEST_CASE (verify_invalid_subtitle_first_text_time) { - auto const dir = boost::filesystem::path("build/test/verify_text_too_early"); + auto const dir = path("build/test/verify_invalid_subtitle_first_text_time"); /* Just too early */ - dcp_with_text (dir, {{ 4 * 24 - 1, 5 * 24 }}); + auto cpl = dcp_with_text (dir, {{ 4 * 24 - 1, 5 * 24 }}); check_verify_result ( { dir }, { - { dcp::VerificationNote::VERIFY_WARNING, dcp::VerificationNote::FIRST_TEXT_TOO_EARLY }, - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA } + { dcp::VerificationNote::Type::WARNING, dcp::VerificationNote::Code::INVALID_SUBTITLE_FIRST_TEXT_TIME }, + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_CPL_METADATA, cpl->id(), cpl->file().get() } }); } -BOOST_AUTO_TEST_CASE (verify_text_not_too_early) +BOOST_AUTO_TEST_CASE (verify_valid_subtitle_first_text_time) { - auto const dir = boost::filesystem::path("build/test/verify_text_not_too_early"); + auto const dir = path("build/test/verify_valid_subtitle_first_text_time"); /* Just late enough */ - dcp_with_text (dir, {{ 4 * 24, 5 * 24 }}); - check_verify_result ({dir}, {{ dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA }}); + auto cpl = dcp_with_text (dir, {{ 4 * 24, 5 * 24 }}); + check_verify_result ({dir}, {{ dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_CPL_METADATA, cpl->id(), cpl->file().get() }}); } -BOOST_AUTO_TEST_CASE (verify_text_early_on_second_reel) +BOOST_AUTO_TEST_CASE (verify_valid_subtitle_first_text_time_on_second_reel) { - auto const dir = boost::filesystem::path("build/test/verify_text_early_on_second_reel"); + auto const dir = path("build/test/verify_valid_subtitle_first_text_time_on_second_reel"); prepare_directory (dir); auto asset1 = make_shared(); @@ -1492,13 +1525,13 @@ BOOST_AUTO_TEST_CASE (verify_text_early_on_second_reel) markers2->set (dcp::Marker::LFOC, dcp::Time(16 * 24 - 1, 24, 24)); reel2->add (markers2); - auto cpl = make_shared("hello", dcp::TRAILER); + auto cpl = make_shared("hello", dcp::ContentKind::TRAILER); cpl->add (reel1); cpl->add (reel2); auto dcp = make_shared(dir); dcp->add (cpl); dcp->write_xml ( - dcp::SMPTE, + dcp::Standard::SMPTE, dcp::String::compose("libdcp %1", dcp::version), dcp::String::compose("libdcp %1", dcp::version), dcp::LocalTime().as_string(), @@ -1506,14 +1539,14 @@ BOOST_AUTO_TEST_CASE (verify_text_early_on_second_reel) ); - check_verify_result ({dir}, {{ dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA }}); + check_verify_result ({dir}, {{ dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_CPL_METADATA, cpl->id(), cpl->file().get() }}); } -BOOST_AUTO_TEST_CASE (verify_text_too_close) +BOOST_AUTO_TEST_CASE (verify_invalid_subtitle_spacing) { - auto const dir = boost::filesystem::path("build/test/verify_text_too_close"); - dcp_with_text ( + auto const dir = path("build/test/verify_invalid_subtitle_spacing"); + auto cpl = dcp_with_text ( dir, { { 4 * 24, 5 * 24 }, @@ -1522,50 +1555,50 @@ BOOST_AUTO_TEST_CASE (verify_text_too_close) check_verify_result ( {dir}, { - { dcp::VerificationNote::VERIFY_WARNING, dcp::VerificationNote::SUBTITLE_TOO_CLOSE }, - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA } + { dcp::VerificationNote::Type::WARNING, dcp::VerificationNote::Code::INVALID_SUBTITLE_SPACING }, + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_CPL_METADATA, cpl->id(), cpl->file().get() } }); } -BOOST_AUTO_TEST_CASE (verify_text_not_too_close) +BOOST_AUTO_TEST_CASE (verify_valid_subtitle_spacing) { - auto const dir = boost::filesystem::path("build/test/verify_text_not_too_close"); - dcp_with_text ( + auto const dir = path("build/test/verify_valid_subtitle_spacing"); + auto cpl = dcp_with_text ( dir, { { 4 * 24, 5 * 24 }, { 5 * 24 + 16, 8 * 24 }, }); - check_verify_result ({dir}, {{ dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA }}); + check_verify_result ({dir}, {{ dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_CPL_METADATA, cpl->id(), cpl->file().get() }}); } -BOOST_AUTO_TEST_CASE (verify_text_too_short) +BOOST_AUTO_TEST_CASE (verify_invalid_subtitle_duration) { - auto const dir = boost::filesystem::path("build/test/verify_text_too_short"); - dcp_with_text (dir, {{ 4 * 24, 4 * 24 + 1 }}); + auto const dir = path("build/test/verify_invalid_subtitle_duration"); + auto cpl = dcp_with_text (dir, {{ 4 * 24, 4 * 24 + 1 }}); check_verify_result ( {dir}, { - { dcp::VerificationNote::VERIFY_WARNING, dcp::VerificationNote::SUBTITLE_TOO_SHORT }, - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA } + { dcp::VerificationNote::Type::WARNING, dcp::VerificationNote::Code::INVALID_SUBTITLE_DURATION }, + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_CPL_METADATA, cpl->id(), cpl->file().get() } }); } -BOOST_AUTO_TEST_CASE (verify_text_not_too_short) +BOOST_AUTO_TEST_CASE (verify_valid_subtitle_duration) { - auto const dir = boost::filesystem::path("build/test/verify_text_not_too_short"); - dcp_with_text (dir, {{ 4 * 24, 4 * 24 + 17 }}); - check_verify_result ({dir}, {{ dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA }}); + auto const dir = path("build/test/verify_valid_subtitle_duration"); + auto cpl = dcp_with_text (dir, {{ 4 * 24, 4 * 24 + 17 }}); + check_verify_result ({dir}, {{ dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_CPL_METADATA, cpl->id(), cpl->file().get() }}); } -BOOST_AUTO_TEST_CASE (verify_too_many_subtitle_lines1) +BOOST_AUTO_TEST_CASE (verify_invalid_subtitle_line_count1) { - auto const dir = boost::filesystem::path ("build/test/verify_too_many_subtitle_lines1"); - dcp_with_text ( + auto const dir = path ("build/test/invalid_subtitle_line_count1"); + auto cpl = dcp_with_text ( dir, { { 96, 200, 0.0, "We" }, @@ -1576,30 +1609,30 @@ BOOST_AUTO_TEST_CASE (verify_too_many_subtitle_lines1) check_verify_result ( {dir}, { - { dcp::VerificationNote::VERIFY_WARNING, dcp::VerificationNote::TOO_MANY_SUBTITLE_LINES }, - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA } + { dcp::VerificationNote::Type::WARNING, dcp::VerificationNote::Code::INVALID_SUBTITLE_LINE_COUNT }, + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_CPL_METADATA, cpl->id(), cpl->file().get() } }); } -BOOST_AUTO_TEST_CASE (verify_not_too_many_subtitle_lines1) +BOOST_AUTO_TEST_CASE (verify_valid_subtitle_line_count1) { - auto const dir = boost::filesystem::path ("build/test/verify_not_too_many_subtitle_lines1"); - dcp_with_text ( + auto const dir = path ("build/test/verify_valid_subtitle_line_count1"); + auto cpl = dcp_with_text ( dir, { { 96, 200, 0.0, "We" }, { 96, 200, 0.1, "have" }, { 96, 200, 0.2, "four" }, }); - check_verify_result ({dir}, {{ dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA }}); + check_verify_result ({dir}, {{ dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_CPL_METADATA, cpl->id(), cpl->file().get() }}); } -BOOST_AUTO_TEST_CASE (verify_too_many_subtitle_lines2) +BOOST_AUTO_TEST_CASE (verify_invalid_subtitle_line_count2) { - auto const dir = boost::filesystem::path ("build/test/verify_too_many_subtitle_lines2"); - dcp_with_text ( + auto const dir = path ("build/test/verify_invalid_subtitle_line_count2"); + auto cpl = dcp_with_text ( dir, { { 96, 300, 0.0, "We" }, @@ -1610,16 +1643,16 @@ BOOST_AUTO_TEST_CASE (verify_too_many_subtitle_lines2) check_verify_result ( {dir}, { - { dcp::VerificationNote::VERIFY_WARNING, dcp::VerificationNote::TOO_MANY_SUBTITLE_LINES }, - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA } + { dcp::VerificationNote::Type::WARNING, dcp::VerificationNote::Code::INVALID_SUBTITLE_LINE_COUNT }, + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_CPL_METADATA, cpl->id(), cpl->file().get() } }); } -BOOST_AUTO_TEST_CASE (verify_not_too_many_subtitle_lines2) +BOOST_AUTO_TEST_CASE (verify_valid_subtitle_line_count2) { - auto const dir = boost::filesystem::path ("build/test/verify_not_too_many_subtitle_lines2"); - dcp_with_text ( + auto const dir = path ("build/test/verify_valid_subtitle_line_count2"); + auto cpl = dcp_with_text ( dir, { { 96, 300, 0.0, "We" }, @@ -1627,14 +1660,14 @@ BOOST_AUTO_TEST_CASE (verify_not_too_many_subtitle_lines2) { 150, 180, 0.2, "four" }, { 190, 250, 0.3, "lines" } }); - check_verify_result ({dir}, {{ dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA }}); + check_verify_result ({dir}, {{ dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_CPL_METADATA, cpl->id(), cpl->file().get() }}); } -BOOST_AUTO_TEST_CASE (verify_subtitle_lines_too_long1) +BOOST_AUTO_TEST_CASE (verify_invalid_subtitle_line_length1) { - auto const dir = boost::filesystem::path ("build/test/verify_subtitle_lines_too_long1"); - dcp_with_text ( + auto const dir = path ("build/test/verify_invalid_subtitle_line_length1"); + auto cpl = dcp_with_text ( dir, { { 96, 300, 0.0, "012345678901234567890123456789012345678901234567890123" } @@ -1642,16 +1675,16 @@ BOOST_AUTO_TEST_CASE (verify_subtitle_lines_too_long1) check_verify_result ( {dir}, { - { dcp::VerificationNote::VERIFY_WARNING, dcp::VerificationNote::SUBTITLE_LINE_LONGER_THAN_RECOMMENDED }, - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA } + { dcp::VerificationNote::Type::WARNING, dcp::VerificationNote::Code::NEARLY_INVALID_SUBTITLE_LINE_LENGTH }, + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_CPL_METADATA, cpl->id(), cpl->file().get() } }); } -BOOST_AUTO_TEST_CASE (verify_subtitle_lines_too_long2) +BOOST_AUTO_TEST_CASE (verify_invalid_subtitle_line_length2) { - auto const dir = boost::filesystem::path ("build/test/verify_subtitle_lines_too_long2"); - dcp_with_text ( + auto const dir = path ("build/test/verify_invalid_subtitle_line_length2"); + auto cpl = dcp_with_text ( dir, { { 96, 300, 0.0, "012345678901234567890123456789012345678901234567890123456789012345678901234567890" } @@ -1659,16 +1692,16 @@ BOOST_AUTO_TEST_CASE (verify_subtitle_lines_too_long2) check_verify_result ( {dir}, { - { dcp::VerificationNote::VERIFY_WARNING, dcp::VerificationNote::SUBTITLE_LINE_TOO_LONG }, - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA } + { dcp::VerificationNote::Type::WARNING, dcp::VerificationNote::Code::INVALID_SUBTITLE_LINE_LENGTH }, + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_CPL_METADATA, cpl->id(), cpl->file().get() } }); } -BOOST_AUTO_TEST_CASE (verify_too_many_closed_caption_lines1) +BOOST_AUTO_TEST_CASE (verify_valid_closed_caption_line_count1) { - auto const dir = boost::filesystem::path ("build/test/verify_too_many_closed_caption_lines1"); - dcp_with_text ( + auto const dir = path ("build/test/verify_valid_closed_caption_line_count1"); + auto cpl = dcp_with_text ( dir, { { 96, 200, 0.0, "We" }, @@ -1679,30 +1712,30 @@ BOOST_AUTO_TEST_CASE (verify_too_many_closed_caption_lines1) check_verify_result ( {dir}, { - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::TOO_MANY_CLOSED_CAPTION_LINES}, - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA } + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::INVALID_CLOSED_CAPTION_LINE_COUNT}, + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_CPL_METADATA, cpl->id(), cpl->file().get() } }); } -BOOST_AUTO_TEST_CASE (verify_not_too_many_closed_caption_lines1) +BOOST_AUTO_TEST_CASE (verify_valid_closed_caption_line_count2) { - auto const dir = boost::filesystem::path ("build/test/verify_not_too_many_closed_caption_lines1"); - dcp_with_text ( + auto const dir = path ("build/test/verify_valid_closed_caption_line_count2"); + auto cpl = dcp_with_text ( dir, { { 96, 200, 0.0, "We" }, { 96, 200, 0.1, "have" }, { 96, 200, 0.2, "four" }, }); - check_verify_result ({dir}, {{ dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA }}); + check_verify_result ({dir}, {{ dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_CPL_METADATA, cpl->id(), cpl->file().get() }}); } -BOOST_AUTO_TEST_CASE (verify_too_many_closed_caption_lines2) +BOOST_AUTO_TEST_CASE (verify_invalid_closed_caption_line_count3) { - auto const dir = boost::filesystem::path ("build/test/verify_too_many_closed_caption_lines2"); - dcp_with_text ( + auto const dir = path ("build/test/verify_invalid_closed_caption_line_count3"); + auto cpl = dcp_with_text ( dir, { { 96, 300, 0.0, "We" }, @@ -1713,16 +1746,16 @@ BOOST_AUTO_TEST_CASE (verify_too_many_closed_caption_lines2) check_verify_result ( {dir}, { - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::TOO_MANY_CLOSED_CAPTION_LINES}, - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA } + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::INVALID_CLOSED_CAPTION_LINE_COUNT}, + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_CPL_METADATA, cpl->id(), cpl->file().get() } }); } -BOOST_AUTO_TEST_CASE (verify_not_too_many_closed_caption_lines2) +BOOST_AUTO_TEST_CASE (verify_valid_closed_caption_line_count4) { - auto const dir = boost::filesystem::path ("build/test/verify_not_too_many_closed_caption_lines2"); - dcp_with_text ( + auto const dir = path ("build/test/verify_valid_closed_caption_line_count4"); + auto cpl = dcp_with_text ( dir, { { 96, 300, 0.0, "We" }, @@ -1730,14 +1763,14 @@ BOOST_AUTO_TEST_CASE (verify_not_too_many_closed_caption_lines2) { 150, 180, 0.2, "four" }, { 190, 250, 0.3, "lines" } }); - check_verify_result ({dir}, {{ dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA }}); + check_verify_result ({dir}, {{ dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_CPL_METADATA, cpl->id(), cpl->file().get() }}); } -BOOST_AUTO_TEST_CASE (verify_closed_caption_lines_too_long1) +BOOST_AUTO_TEST_CASE (verify_invalid_closed_caption_line_length) { - auto const dir = boost::filesystem::path ("build/test/verify_closed_caption_lines_too_long1"); - dcp_with_text ( + auto const dir = path ("build/test/verify_invalid_closed_caption_line_length"); + auto cpl = dcp_with_text ( dir, { { 96, 300, 0.0, "0123456789012345678901234567890123" } @@ -1745,15 +1778,15 @@ BOOST_AUTO_TEST_CASE (verify_closed_caption_lines_too_long1) check_verify_result ( {dir}, { - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::CLOSED_CAPTION_LINE_TOO_LONG }, - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA } + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::INVALID_CLOSED_CAPTION_LINE_LENGTH }, + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_CPL_METADATA, cpl->id(), cpl->file().get() } }); } -BOOST_AUTO_TEST_CASE (verify_sound_sampling_rate_must_be_48k) +BOOST_AUTO_TEST_CASE (verify_invalid_sound_frame_rate) { - boost::filesystem::path const dir("build/test/verify_sound_sampling_rate_must_be_48k"); + path const dir("build/test/verify_invalid_sound_frame_rate"); prepare_directory (dir); auto picture = simple_picture (dir, "foo"); @@ -1764,12 +1797,12 @@ BOOST_AUTO_TEST_CASE (verify_sound_sampling_rate_must_be_48k) auto reel_sound = make_shared(sound, 0); reel->add (reel_sound); reel->add (simple_markers()); - auto cpl = make_shared("hello", dcp::TRAILER); + auto cpl = make_shared("hello", dcp::ContentKind::TRAILER); cpl->add (reel); auto dcp = make_shared(dir); dcp->add (cpl); dcp->write_xml ( - dcp::SMPTE, + dcp::Standard::SMPTE, dcp::String::compose("libdcp %1", dcp::version), dcp::String::compose("libdcp %1", dcp::version), dcp::LocalTime().as_string(), @@ -1779,18 +1812,18 @@ BOOST_AUTO_TEST_CASE (verify_sound_sampling_rate_must_be_48k) check_verify_result ( {dir}, { - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::INVALID_SOUND_FRAME_RATE }, - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA } + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::INVALID_SOUND_FRAME_RATE, string("96000"), canonical(dir / "audiofoo.mxf") }, + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_CPL_METADATA, cpl->id(), cpl->file().get() }, }); } -BOOST_AUTO_TEST_CASE (verify_cpl_must_have_annotation_text) +BOOST_AUTO_TEST_CASE (verify_missing_cpl_annotation_text) { - boost::filesystem::path const dir("build/test/verify_cpl_must_have_annotation_text"); + path const dir("build/test/verify_missing_cpl_annotation_text"); auto dcp = make_simple (dir); dcp->write_xml ( - dcp::SMPTE, + dcp::Standard::SMPTE, dcp::String::compose("libdcp %1", dcp::version), dcp::String::compose("libdcp %1", dcp::version), dcp::LocalTime().as_string(), @@ -1799,27 +1832,29 @@ BOOST_AUTO_TEST_CASE (verify_cpl_must_have_annotation_text) BOOST_REQUIRE_EQUAL (dcp->cpls().size(), 1U); + auto const cpl = dcp->cpls()[0]; + { - BOOST_REQUIRE (dcp->cpls()[0]->file()); - Editor e(dcp->cpls()[0]->file().get()); + BOOST_REQUIRE (cpl->file()); + Editor e(cpl->file().get()); e.replace("A Test DCP", ""); } check_verify_result ( {dir}, { - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_ANNOTATION_TEXT_IN_CPL }, - { dcp::VerificationNote::VERIFY_ERROR, dcp::VerificationNote::CPL_HASH_INCORRECT } + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_CPL_ANNOTATION_TEXT, cpl->id(), canonical(cpl->file().get()) }, + { dcp::VerificationNote::Type::ERROR, dcp::VerificationNote::Code::MISMATCHED_CPL_HASHES, cpl->id(), canonical(cpl->file().get()) } }); } -BOOST_AUTO_TEST_CASE (verify_cpl_annotation_text_should_be_same_as_content_title_text) +BOOST_AUTO_TEST_CASE (verify_mismatched_cpl_annotation_text) { - boost::filesystem::path const dir("build/test/verify_cpl_annotation_text_should_be_same_as_content_title_text"); + path const dir("build/test/verify_mismatched_cpl_annotation_text"); auto dcp = make_simple (dir); dcp->write_xml ( - dcp::SMPTE, + dcp::Standard::SMPTE, dcp::String::compose("libdcp %1", dcp::version), dcp::String::compose("libdcp %1", dcp::version), dcp::LocalTime().as_string(), @@ -1827,29 +1862,29 @@ BOOST_AUTO_TEST_CASE (verify_cpl_annotation_text_should_be_same_as_content_title ); BOOST_REQUIRE_EQUAL (dcp->cpls().size(), 1U); + auto const cpl = dcp->cpls()[0]; { - BOOST_REQUIRE (dcp->cpls()[0]->file()); - Editor e(dcp->cpls()[0]->file().get()); + BOOST_REQUIRE (cpl->file()); + Editor e(cpl->file().get()); e.replace("A Test DCP", "A Test DCP 1"); } check_verify_result ( {dir}, { - { dcp::VerificationNote::VERIFY_WARNING, dcp::VerificationNote::CPL_ANNOTATION_TEXT_DIFFERS_FROM_CONTENT_TITLE_TEXT }, - { dcp::VerificationNote::VERIFY_ERROR, dcp::VerificationNote::CPL_HASH_INCORRECT } + { dcp::VerificationNote::Type::WARNING, dcp::VerificationNote::Code::MISMATCHED_CPL_ANNOTATION_TEXT, cpl->id(), canonical(cpl->file().get()) }, + { dcp::VerificationNote::Type::ERROR, dcp::VerificationNote::Code::MISMATCHED_CPL_HASHES, cpl->id(), canonical(cpl->file().get()) } }); } -BOOST_AUTO_TEST_CASE (verify_reel_assets_durations_must_match) +BOOST_AUTO_TEST_CASE (verify_mismatched_asset_duration) { - boost::filesystem::path const dir("build/test/verify_reel_assets_durations_must_match"); - boost::filesystem::remove_all (dir); - boost::filesystem::create_directories (dir); + path const dir("build/test/verify_mismatched_asset_duration"); + prepare_directory (dir); shared_ptr dcp (new dcp::DCP(dir)); - shared_ptr cpl (new dcp::CPL("A Test DCP", dcp::TRAILER)); + shared_ptr cpl (new dcp::CPL("A Test DCP", dcp::ContentKind::TRAILER)); shared_ptr mp = simple_picture (dir, "", 24); shared_ptr ms = simple_sound (dir, "", dcp::MXFMetadata(), "en-US", 25); @@ -1864,7 +1899,7 @@ BOOST_AUTO_TEST_CASE (verify_reel_assets_durations_must_match) dcp->add (cpl); dcp->write_xml ( - dcp::SMPTE, + dcp::Standard::SMPTE, dcp::String::compose("libdcp %1", dcp::version), dcp::String::compose("libdcp %1", dcp::version), dcp::LocalTime().as_string(), @@ -1874,21 +1909,20 @@ BOOST_AUTO_TEST_CASE (verify_reel_assets_durations_must_match) check_verify_result ( {dir}, { - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISMATCHED_ASSET_DURATION }, - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA } + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISMATCHED_ASSET_DURATION }, + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_CPL_METADATA, cpl->id(), canonical(cpl->file().get()) } }); } static -void -verify_subtitles_must_be_in_all_reels_check (boost::filesystem::path dir, bool add_to_reel1, bool add_to_reel2) +shared_ptr +verify_subtitles_must_be_in_all_reels_check (path dir, bool add_to_reel1, bool add_to_reel2) { - boost::filesystem::remove_all (dir); - boost::filesystem::create_directories (dir); + prepare_directory (dir); auto dcp = make_shared(dir); - auto cpl = make_shared("A Test DCP", dcp::TRAILER); + auto cpl = make_shared("A Test DCP", dcp::ContentKind::TRAILER); auto subs = make_shared(); subs->set_language (dcp::LanguageTag("de-DE")); @@ -1929,51 +1963,52 @@ verify_subtitles_must_be_in_all_reels_check (boost::filesystem::path dir, bool a dcp->add (cpl); dcp->write_xml ( - dcp::SMPTE, + dcp::Standard::SMPTE, dcp::String::compose("libdcp %1", dcp::version), dcp::String::compose("libdcp %1", dcp::version), dcp::LocalTime().as_string(), "A Test DCP" ); + + return cpl; } -BOOST_AUTO_TEST_CASE (verify_subtitles_must_be_in_all_reels) +BOOST_AUTO_TEST_CASE (verify_missing_main_subtitle_from_some_reels) { { - boost::filesystem::path dir ("build/test/verify_subtitles_must_be_in_all_reels1"); - verify_subtitles_must_be_in_all_reels_check (dir, true, false); + path dir ("build/test/missing_main_subtitle_from_some_reels"); + auto cpl = verify_subtitles_must_be_in_all_reels_check (dir, true, false); check_verify_result ( { dir }, { - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MAIN_SUBTITLE_NOT_IN_ALL_REELS }, - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA } + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_MAIN_SUBTITLE_FROM_SOME_REELS }, + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_CPL_METADATA, cpl->id(), cpl->file().get() } }); } { - boost::filesystem::path dir ("build/test/verify_subtitles_must_be_in_all_reels2"); - verify_subtitles_must_be_in_all_reels_check (dir, true, true); - check_verify_result ({dir}, {{ dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA }}); + path dir ("build/test/verify_subtitles_must_be_in_all_reels2"); + auto cpl = verify_subtitles_must_be_in_all_reels_check (dir, true, true); + check_verify_result ({dir}, {{ dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_CPL_METADATA, cpl->id(), cpl->file().get() }}); } { - boost::filesystem::path dir ("build/test/verify_subtitles_must_be_in_all_reels1"); - verify_subtitles_must_be_in_all_reels_check (dir, false, false); - check_verify_result ({dir}, {{ dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA }}); + path dir ("build/test/verify_subtitles_must_be_in_all_reels1"); + auto cpl = verify_subtitles_must_be_in_all_reels_check (dir, false, false); + check_verify_result ({dir}, {{ dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_CPL_METADATA, cpl->id(), cpl->file().get() }}); } } static -void -verify_closed_captions_must_be_in_all_reels_check (boost::filesystem::path dir, int caps_in_reel1, int caps_in_reel2) +shared_ptr +verify_closed_captions_must_be_in_all_reels_check (path dir, int caps_in_reel1, int caps_in_reel2) { - boost::filesystem::remove_all (dir); - boost::filesystem::create_directories (dir); + prepare_directory (dir); auto dcp = make_shared(dir); - auto cpl = make_shared("A Test DCP", dcp::TRAILER); + auto cpl = make_shared("A Test DCP", dcp::ContentKind::TRAILER); auto subs = make_shared(); subs->set_language (dcp::LanguageTag("de-DE")); @@ -2013,50 +2048,51 @@ verify_closed_captions_must_be_in_all_reels_check (boost::filesystem::path dir, dcp->add (cpl); dcp->write_xml ( - dcp::SMPTE, + dcp::Standard::SMPTE, dcp::String::compose("libdcp %1", dcp::version), dcp::String::compose("libdcp %1", dcp::version), dcp::LocalTime().as_string(), "A Test DCP" ); + + return cpl; } -BOOST_AUTO_TEST_CASE (verify_closed_captions_must_be_in_all_reels) +BOOST_AUTO_TEST_CASE (verify_mismatched_closed_caption_asset_counts) { { - boost::filesystem::path dir ("build/test/verify_closed_captions_must_be_in_all_reels1"); - verify_closed_captions_must_be_in_all_reels_check (dir, 3, 4); + path dir ("build/test/mismatched_closed_caption_asset_counts"); + auto cpl = verify_closed_captions_must_be_in_all_reels_check (dir, 3, 4); check_verify_result ( {dir}, { - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::CLOSED_CAPTION_ASSET_COUNTS_DIFFER }, - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA } + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISMATCHED_CLOSED_CAPTION_ASSET_COUNTS }, + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_CPL_METADATA, cpl->id(), cpl->file().get() } }); } { - boost::filesystem::path dir ("build/test/verify_closed_captions_must_be_in_all_reels2"); - verify_closed_captions_must_be_in_all_reels_check (dir, 4, 4); - check_verify_result ({dir}, {{ dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA }}); + path dir ("build/test/verify_closed_captions_must_be_in_all_reels2"); + auto cpl = verify_closed_captions_must_be_in_all_reels_check (dir, 4, 4); + check_verify_result ({dir}, {{ dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_CPL_METADATA, cpl->id(), cpl->file().get() }}); } { - boost::filesystem::path dir ("build/test/verify_closed_captions_must_be_in_all_reels3"); - verify_closed_captions_must_be_in_all_reels_check (dir, 0, 0); - check_verify_result ({dir}, {{ dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA }}); + path dir ("build/test/verify_closed_captions_must_be_in_all_reels3"); + auto cpl = verify_closed_captions_must_be_in_all_reels_check (dir, 0, 0); + check_verify_result ({dir}, {{ dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_CPL_METADATA, cpl->id(), cpl->file().get() }}); } } template void -verify_text_entry_point_check (boost::filesystem::path dir, dcp::VerificationNote::Code code, boost::function)> adjust) +verify_text_entry_point_check (path dir, dcp::VerificationNote::Code code, boost::function)> adjust) { - boost::filesystem::remove_all (dir); - boost::filesystem::create_directories (dir); + prepare_directory (dir); auto dcp = make_shared(dir); - auto cpl = make_shared("A Test DCP", dcp::TRAILER); + auto cpl = make_shared("A Test DCP", dcp::ContentKind::TRAILER); auto subs = make_shared(); subs->set_language (dcp::LanguageTag("de-DE")); @@ -2079,7 +2115,7 @@ verify_text_entry_point_check (boost::filesystem::path dir, dcp::VerificationNot dcp->add (cpl); dcp->write_xml ( - dcp::SMPTE, + dcp::Standard::SMPTE, dcp::String::compose("libdcp %1", dcp::version), dcp::String::compose("libdcp %1", dcp::version), dcp::LocalTime().as_string(), @@ -2089,8 +2125,8 @@ verify_text_entry_point_check (boost::filesystem::path dir, dcp::VerificationNot check_verify_result ( {dir}, { - { dcp::VerificationNote::VERIFY_BV21_ERROR, code }, - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA } + { dcp::VerificationNote::Type::BV21_ERROR, code, subs->id() }, + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_CPL_METADATA, cpl->id(), cpl->file().get() } }); } @@ -2099,7 +2135,7 @@ BOOST_AUTO_TEST_CASE (verify_text_entry_point) { verify_text_entry_point_check ( "build/test/verify_subtitle_entry_point_must_be_present", - dcp::VerificationNote::MISSING_SUBTITLE_ENTRY_POINT, + dcp::VerificationNote::Code::MISSING_SUBTITLE_ENTRY_POINT, [](shared_ptr asset) { asset->unset_entry_point (); } @@ -2107,7 +2143,7 @@ BOOST_AUTO_TEST_CASE (verify_text_entry_point) verify_text_entry_point_check ( "build/test/verify_subtitle_entry_point_must_be_zero", - dcp::VerificationNote::SUBTITLE_ENTRY_POINT_NON_ZERO, + dcp::VerificationNote::Code::INCORRECT_SUBTITLE_ENTRY_POINT, [](shared_ptr asset) { asset->set_entry_point (4); } @@ -2115,7 +2151,7 @@ BOOST_AUTO_TEST_CASE (verify_text_entry_point) verify_text_entry_point_check ( "build/test/verify_closed_caption_entry_point_must_be_present", - dcp::VerificationNote::MISSING_CLOSED_CAPTION_ENTRY_POINT, + dcp::VerificationNote::Code::MISSING_CLOSED_CAPTION_ENTRY_POINT, [](shared_ptr asset) { asset->unset_entry_point (); } @@ -2123,7 +2159,7 @@ BOOST_AUTO_TEST_CASE (verify_text_entry_point) verify_text_entry_point_check ( "build/test/verify_closed_caption_entry_point_must_be_zero", - dcp::VerificationNote::CLOSED_CAPTION_ENTRY_POINT_NON_ZERO, + dcp::VerificationNote::Code::INCORRECT_CLOSED_CAPTION_ENTRY_POINT, [](shared_ptr asset) { asset->set_entry_point (9); } @@ -2131,14 +2167,14 @@ BOOST_AUTO_TEST_CASE (verify_text_entry_point) } -BOOST_AUTO_TEST_CASE (verify_assets_must_have_hashes) +BOOST_AUTO_TEST_CASE (verify_missing_hash) { RNGFixer fix; - boost::filesystem::path const dir("build/test/verify_assets_must_have_hashes"); + path const dir("build/test/verify_missing_hash"); auto dcp = make_simple (dir); dcp->write_xml ( - dcp::SMPTE, + dcp::Standard::SMPTE, dcp::String::compose("libdcp %1", dcp::version), dcp::String::compose("libdcp %1", dcp::version), dcp::LocalTime().as_string(), @@ -2146,18 +2182,19 @@ BOOST_AUTO_TEST_CASE (verify_assets_must_have_hashes) ); BOOST_REQUIRE_EQUAL (dcp->cpls().size(), 1U); + auto const cpl = dcp->cpls()[0]; { - BOOST_REQUIRE (dcp->cpls()[0]->file()); - Editor e(dcp->cpls()[0]->file().get()); - e.replace("XGhFVrqZqapOJx5Fh2SLjj48Yjg=", ""); + BOOST_REQUIRE (cpl->file()); + Editor e(cpl->file().get()); + e.replace("addO7je2lZSNQp55qjCWo5DLKFQ=", ""); } check_verify_result ( {dir}, { - { dcp::VerificationNote::VERIFY_ERROR, dcp::VerificationNote::CPL_HASH_INCORRECT }, - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_HASH } + { dcp::VerificationNote::Type::ERROR, dcp::VerificationNote::Code::MISMATCHED_CPL_HASHES, cpl->id(), cpl->file().get() }, + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_HASH, string("1fab8bb0-cfaf-4225-ad6d-01768bc10470") } }); } @@ -2165,20 +2202,20 @@ BOOST_AUTO_TEST_CASE (verify_assets_must_have_hashes) static void verify_markers_test ( - boost::filesystem::path dir, + path dir, vector> markers, vector test_notes ) { auto dcp = make_simple (dir); - dcp->cpls()[0]->set_content_kind (dcp::FEATURE); + dcp->cpls()[0]->set_content_kind (dcp::ContentKind::FEATURE); auto markers_asset = make_shared(dcp::Fraction(24, 1), 24, 0); for (auto const& i: markers) { markers_asset->set (i.first, i.second); } dcp->cpls()[0]->reels()[0]->add(markers_asset); dcp->write_xml ( - dcp::SMPTE, + dcp::Standard::SMPTE, dcp::String::compose("libdcp %1", dcp::version), dcp::String::compose("libdcp %1", dcp::version), dcp::LocalTime().as_string(), @@ -2210,7 +2247,7 @@ BOOST_AUTO_TEST_CASE (verify_markers) { dcp::Marker::LFOC, dcp::Time(23, 24, 24) } }, { - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_FFEC_IN_FEATURE } + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_FFEC_IN_FEATURE } }); verify_markers_test ( @@ -2221,7 +2258,7 @@ BOOST_AUTO_TEST_CASE (verify_markers) { dcp::Marker::LFOC, dcp::Time(23, 24, 24) } }, { - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_FFMC_IN_FEATURE } + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_FFMC_IN_FEATURE } }); verify_markers_test ( @@ -2232,7 +2269,7 @@ BOOST_AUTO_TEST_CASE (verify_markers) { dcp::Marker::LFOC, dcp::Time(23, 24, 24) } }, { - { dcp::VerificationNote::VERIFY_WARNING, dcp::VerificationNote::MISSING_FFOC} + { dcp::VerificationNote::Type::WARNING, dcp::VerificationNote::Code::MISSING_FFOC} }); verify_markers_test ( @@ -2243,7 +2280,7 @@ BOOST_AUTO_TEST_CASE (verify_markers) { dcp::Marker::FFOC, dcp::Time(1, 24, 24) } }, { - { dcp::VerificationNote::VERIFY_WARNING, dcp::VerificationNote::MISSING_LFOC } + { dcp::VerificationNote::Type::WARNING, dcp::VerificationNote::Code::MISSING_LFOC } }); verify_markers_test ( @@ -2255,7 +2292,7 @@ BOOST_AUTO_TEST_CASE (verify_markers) { dcp::Marker::LFOC, dcp::Time(23, 24, 24) } }, { - { dcp::VerificationNote::VERIFY_WARNING, dcp::VerificationNote::INCORRECT_FFOC } + { dcp::VerificationNote::Type::WARNING, dcp::VerificationNote::Code::INCORRECT_FFOC, string("3") } }); verify_markers_test ( @@ -2267,95 +2304,102 @@ BOOST_AUTO_TEST_CASE (verify_markers) { dcp::Marker::LFOC, dcp::Time(18, 24, 24) } }, { - { dcp::VerificationNote::VERIFY_WARNING, dcp::VerificationNote::INCORRECT_LFOC } + { dcp::VerificationNote::Type::WARNING, dcp::VerificationNote::Code::INCORRECT_LFOC, string("18") } }); } -BOOST_AUTO_TEST_CASE (verify_cpl_metadata_version) +BOOST_AUTO_TEST_CASE (verify_missing_cpl_metadata_version_number) { - boost::filesystem::path dir = "build/test/verify_cpl_metadata_version"; + path dir = "build/test/verify_missing_cpl_metadata_version_number"; prepare_directory (dir); auto dcp = make_simple (dir); - dcp->cpls()[0]->unset_version_number(); + auto cpl = dcp->cpls()[0]; + cpl->unset_version_number(); dcp->write_xml ( - dcp::SMPTE, + dcp::Standard::SMPTE, dcp::String::compose("libdcp %1", dcp::version), dcp::String::compose("libdcp %1", dcp::version), dcp::LocalTime().as_string(), "A Test DCP" ); - check_verify_result ({dir}, {{ dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_CPL_METADATA_VERSION_NUMBER }}); + check_verify_result ({dir}, {{ dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_CPL_METADATA_VERSION_NUMBER, cpl->id(), cpl->file().get() }}); } -BOOST_AUTO_TEST_CASE (verify_cpl_extension_metadata1) +BOOST_AUTO_TEST_CASE (verify_missing_extension_metadata1) { - boost::filesystem::path dir = "build/test/verify_cpl_extension_metadata1"; + path dir = "build/test/verify_missing_extension_metadata1"; auto dcp = make_simple (dir); dcp->write_xml ( - dcp::SMPTE, + dcp::Standard::SMPTE, dcp::String::compose("libdcp %1", dcp::version), dcp::String::compose("libdcp %1", dcp::version), dcp::LocalTime().as_string(), "A Test DCP" ); + auto cpl = dcp->cpls()[0]; + { - Editor e (dcp->cpls()[0]->file().get()); + Editor e (cpl->file().get()); e.delete_lines ("", ""); } check_verify_result ( {dir}, { - { dcp::VerificationNote::VERIFY_ERROR, dcp::VerificationNote::CPL_HASH_INCORRECT }, - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_EXTENSION_METADATA } + { dcp::VerificationNote::Type::ERROR, dcp::VerificationNote::Code::MISMATCHED_CPL_HASHES, cpl->id(), cpl->file().get() }, + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_EXTENSION_METADATA, cpl->id(), cpl->file().get() } }); } -BOOST_AUTO_TEST_CASE (verify_cpl_extension_metadata2) +BOOST_AUTO_TEST_CASE (verify_missing_extension_metadata2) { - boost::filesystem::path dir = "build/test/verify_cpl_extension_metadata2"; + path dir = "build/test/verify_missing_extension_metadata2"; auto dcp = make_simple (dir); dcp->write_xml ( - dcp::SMPTE, + dcp::Standard::SMPTE, dcp::String::compose("libdcp %1", dcp::version), dcp::String::compose("libdcp %1", dcp::version), dcp::LocalTime().as_string(), "A Test DCP" ); + auto cpl = dcp->cpls()[0]; + { - Editor e (dcp->cpls()[0]->file().get()); + Editor e (cpl->file().get()); e.delete_lines ("", ""); } check_verify_result ( {dir}, { - { dcp::VerificationNote::VERIFY_ERROR, dcp::VerificationNote::CPL_HASH_INCORRECT }, - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::MISSING_EXTENSION_METADATA } + { dcp::VerificationNote::Type::ERROR, dcp::VerificationNote::Code::MISMATCHED_CPL_HASHES, cpl->id(), cpl->file().get() }, + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_EXTENSION_METADATA, cpl->id(), cpl->file().get() } }); } -BOOST_AUTO_TEST_CASE (verify_cpl_extension_metadata3) +BOOST_AUTO_TEST_CASE (verify_invalid_xml_cpl_extension_metadata3) { - boost::filesystem::path dir = "build/test/verify_cpl_extension_metadata3"; + path dir = "build/test/verify_invalid_xml_cpl_extension_metadata3"; auto dcp = make_simple (dir); dcp->write_xml ( - dcp::SMPTE, + dcp::Standard::SMPTE, dcp::String::compose("libdcp %1", dcp::version), dcp::String::compose("libdcp %1", dcp::version), dcp::LocalTime().as_string(), "A Test DCP" ); + auto const cpl = dcp->cpls()[0]; + { - Editor e (dcp->cpls()[0]->file().get()); + Editor e (cpl->file().get()); e.replace ("A", "A"); e.replace ("n", "n"); } @@ -2363,78 +2407,85 @@ BOOST_AUTO_TEST_CASE (verify_cpl_extension_metadata3) check_verify_result ( {dir}, { - { dcp::VerificationNote::VERIFY_ERROR, dcp::VerificationNote::XML_VALIDATION_ERROR }, - { dcp::VerificationNote::VERIFY_ERROR, dcp::VerificationNote::XML_VALIDATION_ERROR }, - { dcp::VerificationNote::VERIFY_ERROR, dcp::VerificationNote::CPL_HASH_INCORRECT }, + { dcp::VerificationNote::Type::ERROR, dcp::VerificationNote::Code::INVALID_XML, string("no declaration found for element 'meta:NameX'"), cpl->file().get(), 75 }, + { dcp::VerificationNote::Type::ERROR, dcp::VerificationNote::Code::INVALID_XML, string("element 'meta:NameX' is not allowed for content model '(Name,PropertyList?,)'"), cpl->file().get(), 82 }, + { dcp::VerificationNote::Type::ERROR, dcp::VerificationNote::Code::MISMATCHED_CPL_HASHES, cpl->id(), cpl->file().get() }, }); } -BOOST_AUTO_TEST_CASE (verify_cpl_extension_metadata4) +BOOST_AUTO_TEST_CASE (verify_invalid_extension_metadata1) { - boost::filesystem::path dir = "build/test/verify_cpl_extension_metadata4"; + path dir = "build/test/verify_invalid_extension_metadata1"; auto dcp = make_simple (dir); dcp->write_xml ( - dcp::SMPTE, + dcp::Standard::SMPTE, dcp::String::compose("libdcp %1", dcp::version), dcp::String::compose("libdcp %1", dcp::version), dcp::LocalTime().as_string(), "A Test DCP" ); + auto cpl = dcp->cpls()[0]; + { - Editor e (dcp->cpls()[0]->file().get()); + Editor e (cpl->file().get()); e.replace ("Application", "Fred"); } check_verify_result ( {dir}, { - { dcp::VerificationNote::VERIFY_ERROR, dcp::VerificationNote::CPL_HASH_INCORRECT }, - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::INVALID_EXTENSION_METADATA, string(" property should be 'Application'") }, + { dcp::VerificationNote::Type::ERROR, dcp::VerificationNote::Code::MISMATCHED_CPL_HASHES, cpl->id(), cpl->file().get() }, + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::INVALID_EXTENSION_METADATA, string(" should be 'Application'"), cpl->file().get() }, }); } -BOOST_AUTO_TEST_CASE (verify_cpl_extension_metadata5) +BOOST_AUTO_TEST_CASE (verify_invalid_extension_metadata2) { - boost::filesystem::path dir = "build/test/verify_cpl_extension_metadata5"; + path dir = "build/test/verify_invalid_extension_metadata2"; auto dcp = make_simple (dir); dcp->write_xml ( - dcp::SMPTE, + dcp::Standard::SMPTE, dcp::String::compose("libdcp %1", dcp::version), dcp::String::compose("libdcp %1", dcp::version), dcp::LocalTime().as_string(), "A Test DCP" ); + + auto cpl = dcp->cpls()[0]; + { - Editor e (dcp->cpls()[0]->file().get()); + Editor e (cpl->file().get()); e.replace ("DCP Constraints Profile", "Fred"); } check_verify_result ( {dir}, { - { dcp::VerificationNote::VERIFY_ERROR, dcp::VerificationNote::CPL_HASH_INCORRECT }, - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::INVALID_EXTENSION_METADATA, string(" property should be 'DCP Constraints Profile'") }, + { dcp::VerificationNote::Type::ERROR, dcp::VerificationNote::Code::MISMATCHED_CPL_HASHES, cpl->id(), cpl->file().get() }, + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::INVALID_EXTENSION_METADATA, string(" property should be 'DCP Constraints Profile'"), cpl->file().get() }, }); } -BOOST_AUTO_TEST_CASE (verify_cpl_extension_metadata6) +BOOST_AUTO_TEST_CASE (verify_invalid_xml_cpl_extension_metadata6) { - boost::filesystem::path dir = "build/test/verify_cpl_extension_metadata6"; + path dir = "build/test/verify_invalid_xml_cpl_extension_metadata6"; auto dcp = make_simple (dir); dcp->write_xml ( - dcp::SMPTE, + dcp::Standard::SMPTE, dcp::String::compose("libdcp %1", dcp::version), dcp::String::compose("libdcp %1", dcp::version), dcp::LocalTime().as_string(), "A Test DCP" ); + auto const cpl = dcp->cpls()[0]; + { - Editor e (dcp->cpls()[0]->file().get()); + Editor e (cpl->file().get()); e.replace ("", ""); e.replace ("", ""); } @@ -2442,51 +2493,57 @@ BOOST_AUTO_TEST_CASE (verify_cpl_extension_metadata6) check_verify_result ( {dir}, { - { dcp::VerificationNote::VERIFY_ERROR, dcp::VerificationNote::XML_VALIDATION_ERROR }, - { dcp::VerificationNote::VERIFY_ERROR, dcp::VerificationNote::XML_VALIDATION_ERROR }, - { dcp::VerificationNote::VERIFY_ERROR, dcp::VerificationNote::CPL_HASH_INCORRECT }, + { dcp::VerificationNote::Type::ERROR, dcp::VerificationNote::Code::INVALID_XML, string("no declaration found for element 'meta:ValueX'"), cpl->file().get(), 79 }, + { dcp::VerificationNote::Type::ERROR, dcp::VerificationNote::Code::INVALID_XML, string("element 'meta:ValueX' is not allowed for content model '(Name,Value)'"), cpl->file().get(), 80 }, + { dcp::VerificationNote::Type::ERROR, dcp::VerificationNote::Code::MISMATCHED_CPL_HASHES, cpl->id(), cpl->file().get() }, }); } -BOOST_AUTO_TEST_CASE (verify_cpl_extension_metadata7) +BOOST_AUTO_TEST_CASE (verify_invalid_xml_cpl_extension_metadata7) { - boost::filesystem::path dir = "build/test/verify_cpl_extension_metadata7"; + path dir = "build/test/verify_invalid_xml_cpl_extension_metadata7"; auto dcp = make_simple (dir); dcp->write_xml ( - dcp::SMPTE, + dcp::Standard::SMPTE, dcp::String::compose("libdcp %1", dcp::version), dcp::String::compose("libdcp %1", dcp::version), dcp::LocalTime().as_string(), "A Test DCP" ); + + auto const cpl = dcp->cpls()[0]; + { - Editor e (dcp->cpls()[0]->file().get()); + Editor e (cpl->file().get()); e.replace ("SMPTE-RDD-52:2020-Bv2.1", "Fred"); } check_verify_result ( {dir}, { - { dcp::VerificationNote::VERIFY_ERROR, dcp::VerificationNote::CPL_HASH_INCORRECT }, - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::INVALID_EXTENSION_METADATA, string(" property should be 'SMPTE-RDD-52:2020-Bv2.1'") }, + { dcp::VerificationNote::Type::ERROR, dcp::VerificationNote::Code::MISMATCHED_CPL_HASHES, cpl->id(), cpl->file().get() }, + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::INVALID_EXTENSION_METADATA, string(" property should be 'SMPTE-RDD-52:2020-Bv2.1'"), cpl->file().get() }, }); } -BOOST_AUTO_TEST_CASE (verify_cpl_extension_metadata8) +BOOST_AUTO_TEST_CASE (verify_invalid_xml_cpl_extension_metadata8) { - boost::filesystem::path dir = "build/test/verify_cpl_extension_metadata8"; + path dir = "build/test/verify_invalid_xml_cpl_extension_metadata8"; auto dcp = make_simple (dir); dcp->write_xml ( - dcp::SMPTE, + dcp::Standard::SMPTE, dcp::String::compose("libdcp %1", dcp::version), dcp::String::compose("libdcp %1", dcp::version), dcp::LocalTime().as_string(), "A Test DCP" ); + + auto const cpl = dcp->cpls()[0]; + { - Editor e (dcp->cpls()[0]->file().get()); + Editor e (cpl->file().get()); e.replace ("", ""); e.replace ("", ""); } @@ -2494,26 +2551,29 @@ BOOST_AUTO_TEST_CASE (verify_cpl_extension_metadata8) check_verify_result ( {dir}, { - { dcp::VerificationNote::VERIFY_ERROR, dcp::VerificationNote::XML_VALIDATION_ERROR }, - { dcp::VerificationNote::VERIFY_ERROR, dcp::VerificationNote::XML_VALIDATION_ERROR }, - { dcp::VerificationNote::VERIFY_ERROR, dcp::VerificationNote::CPL_HASH_INCORRECT }, + { dcp::VerificationNote::Type::ERROR, dcp::VerificationNote::Code::INVALID_XML, string("no declaration found for element 'meta:PropertyX'"), cpl->file().get(), 77 }, + { dcp::VerificationNote::Type::ERROR, dcp::VerificationNote::Code::INVALID_XML, string("element 'meta:PropertyX' is not allowed for content model '(Property+)'"), cpl->file().get(), 81 }, + { dcp::VerificationNote::Type::ERROR, dcp::VerificationNote::Code::MISMATCHED_CPL_HASHES, cpl->id(), cpl->file().get() }, }); } -BOOST_AUTO_TEST_CASE (verify_cpl_extension_metadata9) +BOOST_AUTO_TEST_CASE (verify_invalid_xml_cpl_extension_metadata9) { - boost::filesystem::path dir = "build/test/verify_cpl_extension_metadata9"; + path dir = "build/test/verify_invalid_xml_cpl_extension_metadata9"; auto dcp = make_simple (dir); dcp->write_xml ( - dcp::SMPTE, + dcp::Standard::SMPTE, dcp::String::compose("libdcp %1", dcp::version), dcp::String::compose("libdcp %1", dcp::version), dcp::LocalTime().as_string(), "A Test DCP" ); + + auto const cpl = dcp->cpls()[0]; + { - Editor e (dcp->cpls()[0]->file().get()); + Editor e (cpl->file().get()); e.replace ("", ""); e.replace ("", ""); } @@ -2521,75 +2581,84 @@ BOOST_AUTO_TEST_CASE (verify_cpl_extension_metadata9) check_verify_result ( {dir}, { - { dcp::VerificationNote::VERIFY_ERROR, dcp::VerificationNote::XML_VALIDATION_ERROR }, - { dcp::VerificationNote::VERIFY_ERROR, dcp::VerificationNote::XML_VALIDATION_ERROR }, - { dcp::VerificationNote::VERIFY_ERROR, dcp::VerificationNote::CPL_HASH_INCORRECT }, + { dcp::VerificationNote::Type::ERROR, dcp::VerificationNote::Code::INVALID_XML, string("no declaration found for element 'meta:PropertyListX'"), cpl->file().get(), 76 }, + { dcp::VerificationNote::Type::ERROR, dcp::VerificationNote::Code::INVALID_XML, string("element 'meta:PropertyListX' is not allowed for content model '(Name,PropertyList?,)'"), cpl->file().get(), 82 }, + { dcp::VerificationNote::Type::ERROR, dcp::VerificationNote::Code::MISMATCHED_CPL_HASHES, cpl->id(), cpl->file().get() }, }); } -BOOST_AUTO_TEST_CASE (verify_encrypted_cpl_is_signed) +BOOST_AUTO_TEST_CASE (verify_unsigned_cpl_with_encrypted_content) { - boost::filesystem::path dir = "build/test/verify_encrypted_cpl_is_signed"; + path dir = "build/test/verify_unsigned_cpl_with_encrypted_content"; prepare_directory (dir); - for (auto i: boost::filesystem::directory_iterator("test/ref/DCP/encryption_test")) { - boost::filesystem::copy_file (i.path(), dir / i.path().filename()); + for (auto i: directory_iterator("test/ref/DCP/encryption_test")) { + copy_file (i.path(), dir / i.path().filename()); } + string const pkl_id = "93182bd2-b1e8-41a3-b5c8-6e6564273bff"; + path const pkl = dir / ( "pkl_" + pkl_id + ".xml" ); + string const cpl_id = "81fb54df-e1bf-4647-8788-ea7ba154375b"; + path const cpl = dir / ( "cpl_" + cpl_id + ".xml"); + { - Editor e (dir / "cpl_81fb54df-e1bf-4647-8788-ea7ba154375b.xml"); + Editor e (cpl); e.delete_lines (""); } check_verify_result ( {dir}, { - { dcp::VerificationNote::VERIFY_ERROR, dcp::VerificationNote::CPL_HASH_INCORRECT }, - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::PKL_ANNOTATION_TEXT_DOES_NOT_MATCH_CPL_CONTENT_TITLE_TEXT }, - { dcp::VerificationNote::VERIFY_ERROR, dcp::VerificationNote::MISSING_FFEC_IN_FEATURE }, - { dcp::VerificationNote::VERIFY_ERROR, dcp::VerificationNote::MISSING_FFMC_IN_FEATURE }, - { dcp::VerificationNote::VERIFY_WARNING, dcp::VerificationNote::MISSING_FFOC }, - { dcp::VerificationNote::VERIFY_WARNING, dcp::VerificationNote::MISSING_LFOC }, - { dcp::VerificationNote::VERIFY_WARNING, dcp::VerificationNote::MISSING_CPL_METADATA }, - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::CPL_WITH_ENCRYPTED_CONTENT_NOT_SIGNED } + { dcp::VerificationNote::Type::ERROR, dcp::VerificationNote::Code::MISMATCHED_CPL_HASHES, cpl_id, canonical(cpl) }, + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISMATCHED_PKL_ANNOTATION_TEXT_WITH_CPL, pkl_id, canonical(pkl), }, + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_FFEC_IN_FEATURE }, + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_FFMC_IN_FEATURE }, + { dcp::VerificationNote::Type::WARNING, dcp::VerificationNote::Code::MISSING_FFOC }, + { dcp::VerificationNote::Type::WARNING, dcp::VerificationNote::Code::MISSING_LFOC }, + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_CPL_METADATA, cpl_id, canonical(cpl) }, + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::UNSIGNED_CPL_WITH_ENCRYPTED_CONTENT, cpl_id, canonical(cpl) } }); } -BOOST_AUTO_TEST_CASE (verify_encrypted_pkl_is_signed) +BOOST_AUTO_TEST_CASE (verify_unsigned_pkl_with_encrypted_content) { - boost::filesystem::path dir = "build/test/verify_encrypted_pkl_is_signed"; + path dir = "build/test/unsigned_pkl_with_encrypted_content"; prepare_directory (dir); - for (auto i: boost::filesystem::directory_iterator("test/ref/DCP/encryption_test")) { - boost::filesystem::copy_file (i.path(), dir / i.path().filename()); + for (auto i: directory_iterator("test/ref/DCP/encryption_test")) { + copy_file (i.path(), dir / i.path().filename()); } + string const cpl_id = "81fb54df-e1bf-4647-8788-ea7ba154375b"; + path const cpl = dir / ("cpl_" + cpl_id + ".xml"); + string const pkl_id = "93182bd2-b1e8-41a3-b5c8-6e6564273bff"; + path const pkl = dir / ("pkl_" + pkl_id + ".xml"); { - Editor e (dir / "pkl_93182bd2-b1e8-41a3-b5c8-6e6564273bff.xml"); + Editor e (pkl); e.delete_lines (""); } check_verify_result ( {dir}, { - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::PKL_ANNOTATION_TEXT_DOES_NOT_MATCH_CPL_CONTENT_TITLE_TEXT }, - { dcp::VerificationNote::VERIFY_ERROR, dcp::VerificationNote::MISSING_FFEC_IN_FEATURE }, - { dcp::VerificationNote::VERIFY_ERROR, dcp::VerificationNote::MISSING_FFMC_IN_FEATURE }, - { dcp::VerificationNote::VERIFY_WARNING, dcp::VerificationNote::MISSING_FFOC }, - { dcp::VerificationNote::VERIFY_WARNING, dcp::VerificationNote::MISSING_LFOC }, - { dcp::VerificationNote::VERIFY_WARNING, dcp::VerificationNote::MISSING_CPL_METADATA }, - { dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::PKL_WITH_ENCRYPTED_CONTENT_NOT_SIGNED } + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISMATCHED_PKL_ANNOTATION_TEXT_WITH_CPL, pkl_id, canonical(pkl) }, + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_FFEC_IN_FEATURE }, + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_FFMC_IN_FEATURE }, + { dcp::VerificationNote::Type::WARNING, dcp::VerificationNote::Code::MISSING_FFOC }, + { dcp::VerificationNote::Type::WARNING, dcp::VerificationNote::Code::MISSING_LFOC }, + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::MISSING_CPL_METADATA, cpl_id, canonical(cpl) }, + { dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::UNSIGNED_PKL_WITH_ENCRYPTED_CONTENT, pkl_id, canonical(pkl) }, }); } -BOOST_AUTO_TEST_CASE (verify_unencrypted_pkl_can_be_unsigned) +BOOST_AUTO_TEST_CASE (verify_unsigned_pkl_with_unencrypted_content) { - boost::filesystem::path dir = "build/test/verify_unencrypted_pkl_can_be_unsigned"; + path dir = "build/test/verify_unsigned_pkl_with_unencrypted_content"; prepare_directory (dir); - for (auto i: boost::filesystem::directory_iterator("test/ref/DCP/dcp_test1")) { - boost::filesystem::copy_file (i.path(), dir / i.path().filename()); + for (auto i: directory_iterator("test/ref/DCP/dcp_test1")) { + copy_file (i.path(), dir / i.path().filename()); } { @@ -2601,9 +2670,9 @@ BOOST_AUTO_TEST_CASE (verify_unencrypted_pkl_can_be_unsigned) } -BOOST_AUTO_TEST_CASE (verify_must_not_be_partially_encrypted) +BOOST_AUTO_TEST_CASE (verify_partially_encrypted) { - boost::filesystem::path dir ("build/test/verify_must_not_be_partially_encrypted"); + path dir ("build/test/verify_must_not_be_partially_encrypted"); prepare_directory (dir); dcp::DCP d (dir); @@ -2614,11 +2683,11 @@ BOOST_AUTO_TEST_CASE (verify_must_not_be_partially_encrypted) signer->add (dcp::Certificate(dcp::file_to_string("test/ref/crypt/leaf.signed.pem"))); signer->set_key (dcp::file_to_string("test/ref/crypt/leaf.key")); - auto cpl = make_shared("A Test DCP", dcp::TRAILER); + auto cpl = make_shared("A Test DCP", dcp::ContentKind::TRAILER); dcp::Key key; - auto mp = make_shared(dcp::Fraction (24, 1), dcp::SMPTE); + auto mp = make_shared(dcp::Fraction (24, 1), dcp::Standard::SMPTE); mp->set_key (key); auto writer = mp->start_write (dir / "video.mxf", false); @@ -2654,8 +2723,8 @@ BOOST_AUTO_TEST_CASE (verify_must_not_be_partially_encrypted) d.add (cpl); - d.write_xml (dcp::SMPTE, "OpenDCP 0.0.25", "OpenDCP 0.0.25", "2012-07-17T04:45:18+00:00", "A Test DCP", signer); + d.write_xml (dcp::Standard::SMPTE, "OpenDCP 0.0.25", "OpenDCP 0.0.25", "2012-07-17T04:45:18+00:00", "A Test DCP", signer); - check_verify_result ({dir}, {{dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::PARTIALLY_ENCRYPTED}}); + check_verify_result ({dir}, {{dcp::VerificationNote::Type::BV21_ERROR, dcp::VerificationNote::Code::PARTIALLY_ENCRYPTED}}); }