spec: remove pkg_initdb in post script
[profile/ivi/rygel.git] / tests / rygel-http-time-seek-test.vala
1 /*
2  * Copyright (C) 2010 Nokia Corporation.
3  *
4  * Author: Zeeshan Ali (Khattak) <zeeshan.ali@nokia.com>
5  *                               <zeeshanak@gnome.org>
6  *
7  * This file is part of Rygel.
8  *
9  * Rygel is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU Lesser General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Rygel is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22  */
23
24 private errordomain Rygel.TestError {
25     SKIP
26 }
27
28 private class Rygel.HTTPTranscodeHandler : GLib.Object {}
29
30 public class Rygel.MediaObject : GLib.Object {
31     public int64 size = -1;
32 }
33
34 public class Rygel.MediaContainer : MediaObject {
35 }
36
37 private abstract class Rygel.MediaItem : MediaObject {
38     public bool is_live_stream () {
39         return true;
40     }
41 }
42
43 private class Rygel.AudioItem : MediaItem {
44     public int64 duration = 2048;
45 }
46
47 public class Rygel.ClientHacks : GLib.Object {
48     public static ClientHacks create (Soup.Message msg) throws Error {
49         return new ClientHacks ();
50     }
51
52     public bool force_seek () {
53         return false;
54     }
55 }
56
57 private class Rygel.Thumbnail : GLib.Object {}
58 private class Rygel.Subtitle : GLib.Object {}
59
60 private class Rygel.HTTPGet : GLib.Object {
61     public const string ITEM_URI = "http://DoesntMatterWhatThisIs";
62
63     public Soup.Message msg;
64     public MediaObject object;
65     public Thumbnail thumbnail;
66     public Subtitle subtitle;
67
68     public HTTPTranscodeHandler handler;
69
70     public HTTPGet (Thumbnail? thumbnail, Subtitle? subtitle) {
71         this.msg = new Soup.Message ("HTTP", ITEM_URI);
72         this.object = new AudioItem ();
73         this.handler = new HTTPTranscodeHandler ();
74         this.thumbnail = thumbnail;
75         this.subtitle = subtitle;
76     }
77
78     public HTTPGet.seek_start (int64      start,
79                                Thumbnail? thumbnail,
80                                Subtitle?  subtitle) {
81         this (thumbnail, subtitle);
82
83         this.add_headers (start, -1);
84     }
85
86     public HTTPGet.seek_stop (int64      stop,
87                               Thumbnail? thumbnail,
88                               Subtitle?  subtitle) {
89         this (thumbnail, subtitle);
90
91         this.add_headers (0, stop);
92     }
93
94     public HTTPGet.seek_start_stop (int64      start,
95                                     int64      stop,
96                                     Thumbnail? thumbnail,
97                                     Subtitle?  subtitle) {
98         this (thumbnail, subtitle);
99
100         this.add_headers (start, stop);
101     }
102
103     public HTTPGet.seek_strings (string     start,
104                                  string     stop,
105                                  Thumbnail? thumbnail,
106                                  Subtitle?  subtitle) {
107         this (thumbnail, subtitle);
108
109         this.add_string_headers (start, stop);
110     }
111
112     private void add_headers (int64 start, int64 stop) requires (start >= 0) {
113         var stop_str = (stop > 0)? stop.to_string (): "";
114         var range = "npt=" + start.to_string () + "-" + stop_str;
115         this.msg.request_headers.append ("TimeSeekRange.dlna.org", range);
116     }
117
118     private void add_string_headers (string start, string stop) {
119         var range = "npt=" + start + "-" + stop;
120         this.msg.request_headers.append ("TimeSeekRange.dlna.org", range);
121     }
122 }
123
124 private class Rygel.HTTPTimeSeekTest : GLib.Object {
125     private Regex range_regex;
126
127     enum TestType {
128         TEST_SECONDS_PARSING,
129         TEST_HHMMSS_PARSING,
130         TEST_MIXED_PARSING
131     }
132     private TestType test_type;
133
134     public static int main (string[] args) {
135         try {
136             var test = new HTTPTimeSeekTest ();
137
138             test.run ();
139         /* TODO: Nothing throws this exception. Should it?
140         } catch (TestError.SKIP error) {
141             return 77;
142         */
143         } catch (Error error) {
144             critical ("%s", error.message);
145
146             return -1;
147         }
148
149         return 0;
150     }
151
152     public void run () throws HTTPSeekError {
153         var thumbnails = new Thumbnail[] { null, new Thumbnail () };
154         var subtitles = new Subtitle[] { null, new Subtitle () };
155
156         foreach (var thumbnail in thumbnails) {
157             foreach (var subtitle in subtitles) {
158                 this.test_type = TestType.TEST_SECONDS_PARSING;
159                 this.test_no_seek (thumbnail, subtitle);
160                 this.test_start_only_seek (thumbnail, subtitle);
161                 this.test_stop_only_seek (thumbnail, subtitle);
162                 this.test_start_stop_seek (thumbnail, subtitle);
163                 this.test_type = TestType.TEST_HHMMSS_PARSING;
164                 this.test_start_only_seek (thumbnail, subtitle);
165                 this.test_stop_only_seek (thumbnail, subtitle);
166                 this.test_start_stop_seek (thumbnail, subtitle);
167                 this.test_type = TestType.TEST_MIXED_PARSING;
168                 this.test_start_stop_seek (thumbnail, subtitle);
169             }
170         }
171     }
172
173     private HTTPTimeSeekTest () {
174         var expression = "npt=[0-9]+\\.[0-9][0-9][0-9]-" +
175                          "[0-9]+\\.[0-9][0-9][0-9]/" +
176                          "[0-9]+\\.[0-9][0-9][0-9]";
177
178         try {
179             this.range_regex = new Regex (expression, RegexCompileFlags.CASELESS);
180         } catch (RegexError error) {
181             // This means that it is not a regular expression
182             assert_not_reached ();
183         }
184     }
185
186     private void test_no_seek (Thumbnail? thumbnail,
187                                Subtitle?  subtitle) throws HTTPSeekError {
188         var request = new HTTPGet (thumbnail, subtitle);
189         var audio_item = request.object as AudioItem;
190         this.test_seek (request,
191                         0,
192                         audio_item.duration * TimeSpan.SECOND - TimeSpan.MILLISECOND);
193     }
194
195     private void test_start_only_seek (Thumbnail? thumbnail,
196                                        Subtitle?  subtitle)
197                                        throws HTTPSeekError {
198         HTTPGet request = null;
199
200         switch (this.test_type) {
201         case TestType.TEST_SECONDS_PARSING:
202             request = new HTTPGet.seek_start (128, thumbnail, subtitle);
203
204             break;
205
206         case TestType.TEST_HHMMSS_PARSING:
207             request = new HTTPGet.seek_strings ("00:02:08.000", "", thumbnail, subtitle);
208
209             break;
210         }
211
212         var audio_item = request.object as AudioItem;
213         this.test_seek (request,
214                         128 * TimeSpan.SECOND,
215                         audio_item.duration * TimeSpan.SECOND - TimeSpan.MILLISECOND);
216     }
217
218     private void test_stop_only_seek (Thumbnail? thumbnail,
219                                       Subtitle?  subtitle)
220                                       throws HTTPSeekError {
221         HTTPGet request = null;
222
223         switch (this.test_type) {
224         case TestType.TEST_SECONDS_PARSING:
225             request = new HTTPGet.seek_stop (128, thumbnail, subtitle);
226
227             break;
228
229         case TestType.TEST_HHMMSS_PARSING:
230             request = new HTTPGet.seek_strings ("00:00:00.000",
231                                                 "00:02:08.000",
232                                                 thumbnail,
233                                                 subtitle);
234
235             break;
236         }
237
238         this.test_seek (request, 0, 128 * TimeSpan.SECOND);
239     }
240
241     private void test_start_stop_seek (Thumbnail? thumbnail,
242                                        Subtitle?  subtitle)
243                                        throws HTTPSeekError {
244         HTTPGet request = null;
245
246         switch (this.test_type) {
247         case TestType.TEST_SECONDS_PARSING:
248             request = new HTTPGet.seek_start_stop (128,
249                                                    256,
250                                                    thumbnail,
251                                                    subtitle);
252
253             break;
254
255         case TestType.TEST_HHMMSS_PARSING:
256             request = new HTTPGet.seek_strings ("00:02:08.000",
257                                                 "00:04:16.000",
258                                                 thumbnail,
259                                                 subtitle);
260
261             break;
262
263         case TestType.TEST_MIXED_PARSING:
264             request = new HTTPGet.seek_strings ("00:02:08.000",
265                                                 "256.000",
266                                                 thumbnail,
267                                                 subtitle);
268
269             break;
270         }
271
272
273         this.test_seek (request, 128 * TimeSpan.SECOND, 256 * TimeSpan.SECOND);
274     }
275
276     private void test_seek (HTTPGet request,
277                             int64   start,
278                             int64   stop) throws HTTPSeekError {
279         assert (HTTPTimeSeek.needed (request));
280
281         var seek = new HTTPTimeSeek (request);
282         seek.add_response_headers ();
283
284         assert (seek != null);
285         assert (seek.start == start);
286         assert (seek.stop == stop - 1);
287         assert (seek.length == seek.stop + TimeSpan.MILLISECOND - seek.start);
288
289         var audio_item = request.object as AudioItem;
290         assert (seek.total_length == audio_item.duration * TimeSpan.SECOND);
291
292         var header = request.msg.response_headers.get_one
293                                         ("TimeSeekRange.dlna.org");
294         assert (header != null);
295         assert (this.range_regex.match (header));
296
297         /* TODO: This is just here to avoid a warning about
298          * requested() not being used.
299          * How should this really be tested?
300          * Sometimes the result here is true, and sometimes it is false.
301          */
302         /* bool result = */ HTTPTimeSeek.requested(request);
303     }
304 }