2 Copyright (C) 2018 Carl Hetherington <cth@carlh.net>
4 This file is part of libdcp.
6 libdcp is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 libdcp is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with libdcp. If not, see <http://www.gnu.org/licenses/>.
19 In addition, as a special exception, the copyright holders give
20 permission to link the code of portions of this program with the
21 OpenSSL library under certain conditions as described in each
22 individual source file, and distribute linked combinations
25 You must obey the GNU General Public License in all respects
26 for all of the code used other than OpenSSL. If you modify
27 file(s) with this exception, you may extend this exception to your
28 version of the file(s), but you are not obligated to do so. If you
29 do not wish to do so, delete this exception statement from your
30 version. If you delete this exception statement from all source
31 files in the program, then also delete it here.
36 #include <boost/test/unit_test.hpp>
45 using boost::optional;
47 static list<pair<string, optional<boost::filesystem::path> > > stages;
50 stage (string s, optional<boost::filesystem::path> p)
52 stages.push_back (make_pair (s, p));
61 BOOST_AUTO_TEST_CASE (verify_test1)
63 boost::filesystem::remove_all ("build/test/verify_test1");
64 boost::filesystem::create_directory ("build/test/verify_test1");
65 for (boost::filesystem::directory_iterator i("test/ref/DCP/dcp_test1"); i != boost::filesystem::directory_iterator(); ++i) {
66 boost::filesystem::copy_file (i->path(), "build/test/verify_test1" / i->path().filename());
69 /* Check DCP as-is (should be OK) */
71 vector<boost::filesystem::path> directories;
72 directories.push_back ("build/test/verify_test1");
73 list<dcp::VerificationNote> notes = dcp::verify (directories, &stage, &progress);
75 boost::filesystem::path const cpl_file = "build/test/verify_test1/cpl_81fb54df-e1bf-4647-8788-ea7ba154375b.xml";
76 boost::filesystem::path const pkl_file = "build/test/verify_test1/pkl_74e205d0-d145-42d2-8c49-7b55d058ca55.xml";
78 list<pair<string, optional<boost::filesystem::path> > >::const_iterator st = stages.begin();
79 BOOST_CHECK_EQUAL (st->first, "Checking DCP");
80 BOOST_REQUIRE (st->second);
81 BOOST_CHECK_EQUAL (st->second.get(), boost::filesystem::canonical("build/test/verify_test1"));
83 BOOST_CHECK_EQUAL (st->first, "Checking CPL");
84 BOOST_REQUIRE (st->second);
85 BOOST_CHECK_EQUAL (st->second.get(), boost::filesystem::canonical(cpl_file));
87 BOOST_CHECK_EQUAL (st->first, "Checking reel");
88 BOOST_REQUIRE (!st->second);
90 BOOST_CHECK_EQUAL (st->first, "Checking picture asset hash");
91 BOOST_REQUIRE (st->second);
92 BOOST_CHECK_EQUAL (st->second.get(), boost::filesystem::canonical("build/test/verify_test1/video.mxf"));
94 BOOST_CHECK_EQUAL (st->first, "Checking sound asset hash");
95 BOOST_REQUIRE (st->second);
96 BOOST_CHECK_EQUAL (st->second.get(), boost::filesystem::canonical("build/test/verify_test1/audio.mxf"));
98 BOOST_REQUIRE (st == stages.end());
100 BOOST_CHECK_EQUAL (notes.size(), 0);
102 /* Corrupt the MXFs and check that this is spotted */
104 FILE* mod = fopen("build/test/verify_test1/video.mxf", "r+b");
106 fseek (mod, 4096, SEEK_SET);
108 fwrite (&x, sizeof(x), 1, mod);
111 mod = fopen("build/test/verify_test1/audio.mxf", "r+b");
113 fseek (mod, 4096, SEEK_SET);
114 BOOST_REQUIRE (fwrite (&x, sizeof(x), 1, mod) == 1);
117 notes = dcp::verify (directories, &stage, &progress);
118 BOOST_CHECK_EQUAL (notes.size(), 2);
119 BOOST_CHECK_EQUAL (notes.front().type(), dcp::VerificationNote::VERIFY_ERROR);
120 BOOST_CHECK_EQUAL (notes.front().note(), "Picture asset hash is incorrect.");
121 BOOST_CHECK_EQUAL (notes.back().type(), dcp::VerificationNote::VERIFY_ERROR);
122 BOOST_CHECK_EQUAL (notes.back().note(), "Sound asset hash is incorrect.");
124 /* Corrupt the hashes in the PKL and check that the disagreement between CPL and PKL is spotted */
125 string const pkl = dcp::file_to_string (pkl_file);
126 string hacked_pkl = "";
127 for (size_t i = 0; i < pkl.length(); ++i) {
128 if (pkl.substr(i, 6) == "<Hash>") {
129 hacked_pkl += "<Hash>x";
132 hacked_pkl += pkl[i];
136 FILE* f = fopen(pkl_file.string().c_str(), "w");
137 fwrite(hacked_pkl.c_str(), hacked_pkl.length(), 1, f);
140 notes = dcp::verify (directories, &stage, &progress);
141 BOOST_CHECK_EQUAL (notes.size(), 3);
142 list<dcp::VerificationNote>::const_iterator i = notes.begin();
143 BOOST_CHECK_EQUAL (i->type(), dcp::VerificationNote::VERIFY_ERROR);
144 BOOST_CHECK_EQUAL (i->note(), "CPL hash is incorrect.");
146 BOOST_CHECK_EQUAL (i->type(), dcp::VerificationNote::VERIFY_ERROR);
147 BOOST_CHECK_EQUAL (i->note(), "PKL and CPL hashes differ for picture asset.");
149 BOOST_CHECK_EQUAL (i->type(), dcp::VerificationNote::VERIFY_ERROR);
150 BOOST_CHECK_EQUAL (i->note(), "PKL and CPL hashes differ for sound asset.");