Use sqlite for cinema and DKDM recipient lists.
[dcpomatic.git] / test / kdm_naming_test.cc
1 /*
2     Copyright (C) 2020-2021 Carl Hetherington <cth@carlh.net>
3
4     This file is part of DCP-o-matic.
5
6     DCP-o-matic 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.
10
11     DCP-o-matic 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.
15
16     You should have received a copy of the GNU General Public License
17     along with DCP-o-matic.  If not, see <http://www.gnu.org/licenses/>.
18
19 */
20
21
22 #include "lib/cinema.h"
23 #include "lib/cinema_list.h"
24 #include "lib/config.h"
25 #include "lib/content_factory.h"
26 #include "lib/film.h"
27 #include "lib/kdm_with_metadata.h"
28 #include "lib/screen.h"
29 #include "test.h"
30 #include <boost/test/unit_test.hpp>
31
32
33 using std::dynamic_pointer_cast;
34 using std::list;
35 using std::make_shared;
36 using std::pair;
37 using std::shared_ptr;
38 using std::string;
39 using std::vector;
40 using boost::optional;
41
42
43 static
44 bool
45 confirm_overwrite (boost::filesystem::path)
46 {
47         return true;
48 }
49
50
51 struct Context
52 {
53         Context()
54         {
55                 CinemaList cinemas;
56
57                 auto crypt_cert = Config::instance()->decryption_chain()->leaf();
58
59                 cinema_a = cinemas.add_cinema({"Cinema A", {}, "", dcp::UTCOffset(4, 30)});
60                 cinema_a_screen_1 = cinemas.add_screen(cinema_a, {"Screen 1", "", crypt_cert, boost::none, {}});
61                 cinema_a_screen_2 = cinemas.add_screen(cinema_a, {"Screen 2", "", crypt_cert, boost::none, {}});
62
63                 cinema_b = cinemas.add_cinema({"Cinema B", {}, "", dcp::UTCOffset(-1, 0)});
64                 cinema_b_screen_x = cinemas.add_screen(cinema_b, {"Screen X", "", crypt_cert, boost::none, {}});
65                 cinema_b_screen_y = cinemas.add_screen(cinema_b, {"Screen Y", "", crypt_cert, boost::none, {}});
66                 cinema_b_screen_z = cinemas.add_screen(cinema_b, {"Screen Z", "", crypt_cert, boost::none, {}});
67         }
68
69         CinemaID cinema_a = 0;
70         CinemaID cinema_b = 0;
71         ScreenID cinema_a_screen_1 = 0;
72         ScreenID cinema_a_screen_2 = 0;
73         ScreenID cinema_b_screen_x = 0;
74         ScreenID cinema_b_screen_y = 0;
75         ScreenID cinema_b_screen_z = 0;
76 };
77
78
79 BOOST_AUTO_TEST_CASE (single_kdm_naming_test)
80 {
81         auto c = Config::instance();
82
83         Context context;
84         CinemaList cinemas;
85
86         /* Film */
87         boost::filesystem::remove_all ("build/test/single_kdm_naming_test");
88         auto film = new_test_film2 ("single_kdm_naming_test");
89         film->set_name ("my_great_film");
90         film->examine_and_add_content (content_factory("test/data/flat_black.png")[0]);
91         BOOST_REQUIRE (!wait_for_jobs());
92         film->set_encrypted (true);
93         make_and_verify_dcp (film);
94         auto cpls = film->cpls ();
95         BOOST_REQUIRE(cpls.size() == 1);
96
97         auto sign_cert = c->signer_chain()->leaf();
98
99         dcp::LocalTime from = sign_cert.not_before();
100         from.add_months (2);
101         dcp::LocalTime until = sign_cert.not_after();
102         until.add_months (-2);
103
104         std::vector<KDMCertificatePeriod> period_checks;
105
106         auto cpl = cpls.front().cpl_file;
107         std::function<dcp::DecryptedKDM (dcp::LocalTime, dcp::LocalTime)> make_kdm = [film, cpl](dcp::LocalTime begin, dcp::LocalTime end) {
108                 return film->make_kdm(cpl, begin, end);
109         };
110         auto kdm = kdm_for_screen (
111                         make_kdm,
112                         context.cinema_a,
113                         *cinemas.cinema(context.cinema_a),
114                         *cinemas.screen(context.cinema_a_screen_1),
115                         from,
116                         until,
117                         dcp::Formulation::MODIFIED_TRANSITIONAL_1,
118                         false,
119                         optional<int>(),
120                         period_checks
121                         );
122
123         write_files (
124                 { kdm },
125                 boost::filesystem::path("build/test/single_kdm_naming_test"),
126                 dcp::NameFormat("KDM %c - %s - %f - %b - %e"),
127                 &confirm_overwrite
128                 );
129
130         auto from_time = from.time_of_day (true, false);
131         boost::algorithm::replace_all (from_time, ":", "-");
132         auto until_time = until.time_of_day (true, false);
133         boost::algorithm::replace_all (until_time, ":", "-");
134
135         auto const dcp_date = boost::gregorian::to_iso_string(film->isdcf_date());
136         auto const ref = String::compose("KDM_Cinema_A_-_Screen_1_-_MyGreatFilm_TST-1_F_XX-XX_MOS_2K_%1_SMPTE_OV_-_%2_%3_-_%4_%5.xml", dcp_date, from.date(), from_time, until.date(), until_time);
137         BOOST_CHECK_MESSAGE (boost::filesystem::exists("build/test/single_kdm_naming_test/" + ref), "File " << ref << " not found");
138 }
139
140
141 BOOST_AUTO_TEST_CASE(directory_kdm_naming_test)
142 {
143         using boost::filesystem::path;
144
145         Context context;
146         CinemaList cinemas;
147
148         /* Film */
149         boost::filesystem::remove_all ("build/test/directory_kdm_naming_test");
150         auto film = new_test_film2 (
151                 "directory_kdm_naming_test",
152                 { content_factory("test/data/flat_black.png")[0] }
153                 );
154
155         film->set_name ("my_great_film");
156         film->set_encrypted (true);
157         make_and_verify_dcp (film);
158         auto cpls = film->cpls ();
159         BOOST_REQUIRE(cpls.size() == 1);
160
161         auto sign_cert = Config::instance()->signer_chain()->leaf();
162
163         dcp::LocalTime from (sign_cert.not_before());
164         from.add_months (2);
165         dcp::LocalTime until (sign_cert.not_after());
166         until.add_months (-2);
167
168         vector<pair<CinemaID, ScreenID>> screens = {
169                 { context.cinema_a, context.cinema_a_screen_2 },
170                 { context.cinema_b, context.cinema_b_screen_x },
171                 { context.cinema_a, context.cinema_a_screen_1 },
172                 { context.cinema_b, context.cinema_b_screen_z }
173         };
174
175         auto const cpl = cpls.front().cpl_file;
176         auto const cpl_id = cpls.front().cpl_id;
177
178         std::vector<KDMCertificatePeriod> period_checks;
179         list<KDMWithMetadataPtr> kdms;
180
181         std::function<dcp::DecryptedKDM (dcp::LocalTime, dcp::LocalTime)> make_kdm = [film, cpls](dcp::LocalTime begin, dcp::LocalTime end) {
182                 return film->make_kdm(cpls.front().cpl_file, begin, end);
183         };
184
185         for (auto screen: screens) {
186                 auto kdm = kdm_for_screen (
187                                 make_kdm,
188                                 screen.first,
189                                 *cinemas.cinema(screen.first),
190                                 *cinemas.screen(screen.second),
191                                 from,
192                                 until,
193                                 dcp::Formulation::MODIFIED_TRANSITIONAL_1,
194                                 false,
195                                 optional<int>(),
196                                 period_checks
197                                 );
198
199                 kdms.push_back (kdm);
200         }
201
202         write_directories (
203                 collect(kdms),
204                 path("build/test/directory_kdm_naming_test"),
205                 dcp::NameFormat("%c - %s - %f - %b - %e"),
206 #ifdef DCPOMATIC_WINDOWS
207                 /* Use a shorter name on Windows so that the paths aren't too long */
208                 dcp::NameFormat("KDM %f"),
209 #else
210                 dcp::NameFormat("KDM %c - %s - %f - %b - %e - %i"),
211 #endif
212                 &confirm_overwrite
213                 );
214
215         auto from_time = from.time_of_day (true, false);
216         boost::algorithm::replace_all (from_time, ":", "-");
217         auto until_time = until.time_of_day (true, false);
218         boost::algorithm::replace_all (until_time, ":", "-");
219
220         auto const dcp_date = boost::gregorian::to_iso_string(film->isdcf_date());
221         auto const dcp_name = String::compose("MyGreatFilm_TST-1_F_XX-XX_MOS_2K_%1_SMPTE_OV", dcp_date);
222         auto const common = String::compose("%1_-_%2_%3_-_%4_%5", dcp_name, from.date(), from_time, until.date(), until_time);
223
224         path const base = "build/test/directory_kdm_naming_test";
225
226         path dir_a = String::compose("Cinema_A_-_%s_-_%1", common);
227         BOOST_CHECK_MESSAGE (boost::filesystem::exists(base / dir_a), "Directory " << dir_a << " not found");
228         path dir_b = String::compose("Cinema_B_-_%s_-_%1", common);
229         BOOST_CHECK_MESSAGE (boost::filesystem::exists(base / dir_b), "Directory " << dir_b << " not found");
230
231 #ifdef DCPOMATIC_WINDOWS
232         path ref = String::compose("KDM_%1.xml", dcp_name);
233 #else
234         path ref = String::compose("KDM_Cinema_A_-_Screen_2_-_%1_-_%2.xml", common, cpl_id);
235 #endif
236         BOOST_CHECK_MESSAGE (boost::filesystem::exists(base / dir_a / ref), "File " << ref << " not found");
237
238 #ifdef DCPOMATIC_WINDOWS
239         ref = String::compose("KDM_%1.xml", dcp_name);
240 #else
241         ref = String::compose("KDM_Cinema_B_-_Screen_X_-_%1_-_%2.xml", common, cpl_id);
242 #endif
243         BOOST_CHECK_MESSAGE (boost::filesystem::exists(base / dir_b / ref), "File " << ref << " not found");
244
245 #ifdef DCPOMATIC_WINDOWS
246         ref = String::compose("KDM_%1.xml", dcp_name);
247 #else
248         ref = String::compose("KDM_Cinema_A_-_Screen_1_-_%1_-_%2.xml", common, cpl_id);
249 #endif
250         BOOST_CHECK_MESSAGE (boost::filesystem::exists(base / dir_a / ref), "File " << ref << " not found");
251
252 #ifdef DCPOMATIC_WINDOWS
253         ref = String::compose("KDM_%1.xml", dcp_name);
254 #else
255         ref = String::compose("KDM_Cinema_B_-_Screen_Z_-_%1_-_%2.xml", common, cpl_id);
256 #endif
257         BOOST_CHECK_MESSAGE (boost::filesystem::exists(base / dir_b / ref), "File " << ref << " not found");
258 }
259