]> git.sesse.net Git - vlc/blob - modules/misc/testsuite/playlist.c
For consistency, remove references to vlc from libvlc
[vlc] / modules / misc / testsuite / playlist.c
1 /*****************************************************************************
2  * playlist.c : Playlist testsuite
3  *****************************************************************************
4  * Copyright (C) 2004 the VideoLAN team
5  * $Id$
6  *
7  * Authors : ClĂ©ment Stenac <zorglub@videolan.org>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU 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  * This program 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 General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22  *****************************************************************************/
23
24 /* To run these tests, run vlc with
25  *  --playlist-test --quiet --no-plugins-cache -I dummy */
26
27 /* greek tree used for tests, borrowed from the SubVersion project 
28  *
29
30                                    A                       iota
31           _______________________//|\
32          /         ______________/ | \_____________
33         mu        /                |               \
34                  /                 |                \
35                 B                  C                 D
36           _____/|\_____                _____________/|\
37          /      |      \              /              | \
38         /       |       \            /              /   \___
39      lambda     |        F          /              /        \
40                 E                gamma            /          \
41                / \                               /            |
42               /   \                     ________/             |
43           alpha   beta                 /                      H
44                                       /               _______/|\______
45                                      /               /        |       \
46                                     G               /         |        \
47                            ________/|\_______     chi        psi      omega
48                           /         |        \
49                          /          |         \
50                         /           |          \
51                        pi          rho         tau
52
53  */
54  
55 /*****************************************************************************
56  * Preamble
57  *****************************************************************************/
58 #include <vlc/vlc.h>
59
60 #include <vlc_input.h>
61 #include <vlc_playlist.h>
62
63 #include <stdlib.h>
64
65 /*****************************************************************************
66  * Local prototypes.
67  *****************************************************************************/
68 int    PlaylistTest    ( vlc_object_t *, char const *,
69                           vlc_value_t, vlc_value_t, void * );
70
71 static int Callback( vlc_object_t *, char *, vlc_value_t, vlc_value_t,void*);
72
73 static void Assert( intf_sys_t *p_sys,const char* psz_text, int condition );
74
75 static void StressTest (vlc_object_t *);
76
77 #define MAX_ITEMS 100
78
79 #define CREATE_GT 1000
80
81 struct intf_sys_t
82 {
83     char *ppsz_names[MAX_ITEMS];
84     playlist_t *p_playlist;
85     int i_names;
86     int i_current;
87     vlc_bool_t b_error;
88 };
89
90 /*****************************************************************************
91  * Module descriptor.
92  *****************************************************************************/
93 vlc_module_begin();
94     set_description( _("Playlist stress tests") );
95     add_bool( "playlist-test" , VLC_FALSE , PlaylistTest , "" , "" ,
96               VLC_TRUE );
97 vlc_module_end();
98
99 /*****************************************************************************
100  * PlaylistTest: callback function, spawns the tester thread
101  *****************************************************************************/
102 int PlaylistTest( vlc_object_t *p_this, char const *psz_cmd,
103                    vlc_value_t oldval, vlc_value_t newval, void *p_data )
104 {
105     if( newval.b_bool == VLC_FALSE ) return VLC_SUCCESS;
106
107     if( vlc_thread_create( p_this, "playlist tester", StressTest,
108                     VLC_THREAD_PRIORITY_LOW, VLC_FALSE ) )
109     {
110         msg_Err( p_this, "unable to spawn playlist test thread" );
111         return VLC_EGENERIC;
112     }
113     return VLC_SUCCESS;
114 }
115
116 /*****************************************************************************
117  * Tester thread 
118  *****************************************************************************/
119 static void StressTest( vlc_object_t *p_this )
120 {
121     playlist_t *p_playlist = NULL;
122     playlist_view_t *p_view;
123     int i;
124     mtime_t i_start;
125     playlist_item_t *p_item,*p_a,*p_b,*p_c,*p_d,*p_e,*p_f,*p_g,*p_h, *p_gamma;
126
127     intf_sys_t *p_sys = (intf_sys_t *)malloc( sizeof( intf_sys_t ) );
128     p_sys->b_error = VLC_FALSE;
129
130     fprintf( stderr, "beginning playlist test\n" );
131     while( p_playlist == NULL )
132     {
133         msleep( INTF_IDLE_SLEEP );
134         p_playlist = vlc_object_find( p_this, VLC_OBJECT_PLAYLIST,
135                                         FIND_ANYWHERE );
136     }
137     fprintf( stderr, "Attached to playlist\n");
138
139     p_sys->p_playlist = p_playlist;
140
141     /* let time for vlc initialization */
142     sleep( 3 );
143
144     var_AddCallback( p_playlist, "playlist-current", Callback, p_sys );
145
146
147     /* Test 1 : Create a greek tree */
148     fprintf(stderr,"1/ Creating greek tree pattern (except H)\n");
149
150     p_view = playlist_ViewFind( p_playlist, VIEW_CATEGORY );
151     i_start = mdate();
152
153     playlist_Stop( p_playlist );
154     Assert( p_sys, "Checking playlist status STOPPED ...",
155             p_playlist->status.i_status == PLAYLIST_STOPPED );
156
157     p_a = playlist_NodeCreate( p_playlist, VIEW_CATEGORY, "A", p_view->p_root );
158     p_item = playlist_ItemNew(p_playlist, "mu","mu" );
159     playlist_NodeAddItem( p_playlist, p_item, VIEW_CATEGORY,
160                           p_a, PLAYLIST_APPEND, PLAYLIST_END );
161     p_b = playlist_NodeCreate( p_playlist, VIEW_CATEGORY, "B", p_a );
162     p_c = playlist_NodeCreate( p_playlist, VIEW_CATEGORY, "C", p_a );
163     p_d = playlist_NodeCreate( p_playlist, VIEW_CATEGORY, "D", p_a );
164     p_item = playlist_ItemNew(p_playlist, "lambda","lambda" );
165     playlist_NodeAddItem( p_playlist, p_item, VIEW_CATEGORY,
166                           p_b, PLAYLIST_APPEND, PLAYLIST_END );
167     p_e = playlist_NodeCreate( p_playlist, VIEW_CATEGORY, "E", p_b );
168     p_f = playlist_NodeCreate( p_playlist, VIEW_CATEGORY, "F", p_b );
169     p_gamma = p_item = playlist_ItemNew(p_playlist, "gamma","gamma" );
170     playlist_NodeAddItem( p_playlist, p_item, VIEW_CATEGORY,
171                           p_d, PLAYLIST_APPEND, PLAYLIST_END );
172     p_g = playlist_NodeCreate( p_playlist, VIEW_CATEGORY, "G", p_d );
173     p_item = playlist_ItemNew(p_playlist, "beta","beta" );
174     playlist_NodeAddItem( p_playlist, p_item, VIEW_CATEGORY,
175                           p_e, PLAYLIST_INSERT, 0 );
176     p_item = playlist_ItemNew(p_playlist, "alpha","alpha" );
177     playlist_NodeAddItem( p_playlist, p_item, VIEW_CATEGORY,
178                           p_e, PLAYLIST_INSERT, 0 );
179     p_item = playlist_ItemNew(p_playlist, "pi","pi" );
180     playlist_NodeAddItem( p_playlist, p_item, VIEW_CATEGORY,
181                           p_g, PLAYLIST_APPEND, PLAYLIST_END );
182     p_item = playlist_ItemNew(p_playlist, "tau","tau" );
183     playlist_NodeAddItem( p_playlist, p_item, VIEW_CATEGORY,
184                           p_g, PLAYLIST_APPEND, PLAYLIST_END );
185     p_item = playlist_ItemNew(p_playlist, "rho","rho" );
186     playlist_NodeAddItem( p_playlist, p_item, VIEW_CATEGORY,
187                           p_g, PLAYLIST_INSERT, 1 );
188     /* Create H as an item, we'll expand it later */
189     p_item = playlist_ItemNew(p_playlist, "H","H" );
190     playlist_NodeAddItem( p_playlist, p_item, VIEW_CATEGORY,
191                           p_d, PLAYLIST_INSERT, 1 );
192
193     fprintf( stderr, "Created in "I64Fi " us\n", mdate() - i_start );
194
195     fprintf(stderr,"Dumping category view\n" );
196     playlist_ViewDump( p_playlist, p_view );
197
198     Assert( p_sys, "Checking playlist status STOPPED ...",
199             p_playlist->status.i_status == PLAYLIST_STOPPED );
200
201 //    Assert( p_sys, "Checking 0 items in VIEW_SIMPLE ...",
202   //          playlist_ViewItemsCount( p_playlist, VIEW_SIMPLE ) == 0 );
203  //   Assert( p_sys, "Checking 9 items in VIEW_ALL ...",
204    //         playlist_ViewItemsCount( p_playlist, VIEW_ALL ) == 9 );
205
206
207     p_sys->ppsz_names[0] = strdup("mu");
208     p_sys->ppsz_names[1]= strdup("lambda");
209     p_sys->ppsz_names[2] = strdup("beta");
210     p_sys->ppsz_names[3] = strdup("alpha");
211     p_sys->ppsz_names[4] = strdup("gamma");
212     p_sys->ppsz_names[5] = strdup("pi");
213     p_sys->ppsz_names[6] = strdup("tau");
214     p_sys->ppsz_names[7] = strdup("rho");
215     p_sys->ppsz_names[8] = strdup("H");
216     p_sys->i_names = 9;
217     p_sys->i_current = 0;
218
219     fprintf( stderr, "Starting playlist\n");
220
221     playlist_Play( p_playlist );
222
223     sleep( 1 );
224
225     Assert( p_sys, "Checking nothing was played ...",
226                     (p_sys->i_current == 0) );
227     fprintf(stderr,"played : %i\n",p_sys->i_current );
228
229     playlist_Control( p_playlist, PLAYLIST_VIEWPLAY, VIEW_CATEGORY,
230                       p_view->p_root, NULL );
231
232     Assert( p_sys, "Checking playlist RUNNING ...",
233                      p_playlist->status.i_status == 1 );
234
235     /* Wait for everything to have played */
236 #if 0
237      while( p_sys->i_current != 8 );// && p_sys->b_error == VLC_FALSE )
238      {
239          msleep( INTF_IDLE_SLEEP );
240      }
241      fprintf(stderr,"finished\n" );
242 #endif
243
244     /* Let some more time */
245     sleep( 5 );
246     Assert( p_sys, "Checking playlist status STOPPED ...",
247             (p_playlist->status.i_status == PLAYLIST_STOPPED) );
248
249     p_sys->i_names = -1;
250
251     /* Test 2 : Repeat */
252     fprintf( stderr, "2/ Checking repeat\n" );
253     var_SetBool( p_playlist, "repeat", VLC_TRUE );
254     playlist_Goto( p_playlist, 4 );
255     msleep( 100 );
256     Assert( p_sys, "Checking playing of gamma ...",
257             p_playlist->status.p_item == p_gamma );
258     sleep( 2 );
259     Assert( p_sys, "Checking still playing gamma ...", 
260             p_playlist->status.p_item == p_gamma );
261     Assert( p_sys, "Checking playlist still running ...",
262             p_playlist->status.i_status == PLAYLIST_RUNNING );
263
264     /* Test 3: Play and stop */
265     fprintf( stderr, "3/ Checking play and stop\n" );
266     playlist_Stop( p_playlist );
267     var_SetBool( p_playlist, "repeat", VLC_FALSE );
268     var_SetBool( p_playlist, "play-and-stop", VLC_TRUE );
269     playlist_Skip( p_playlist, 1 );
270     Assert( p_sys, "Checking playlist status RUNNING ...",
271             p_playlist->status.i_status == PLAYLIST_RUNNING );
272     sleep( 2 );
273     Assert( p_sys, "Checking playlist stopped  ...",
274             p_playlist->status.i_status == PLAYLIST_STOPPED );
275
276     /* Test 4 : Simple adding of iota */
277     fprintf( stderr, "4/ Checking simple add\n" );
278     p_item = playlist_ItemNew( p_playlist, "iota","iota" );
279     playlist_AddItem( p_playlist, p_item, PLAYLIST_APPEND, PLAYLIST_END ); 
280
281     /* Check items counts */
282 //    Assert( p_sys, "Checking 1 item in VIEW_SIMPLE ...",
283   //          playlist_ViewItemsCount( p_playlist, VIEW_SIMPLE ) == 1 );
284 //    Assert( p_sys, "Checking 10 items in VIEW_CATEGORY ...",
285   //          playlist_ViewItemsCount( p_playlist, VIEW_CATEGORY ) == 10 );
286
287     /* Test 5:Expand H : it was added only to view_category so the children 
288      * should not appear in VIEW_SIMPLE */
289     fprintf( stderr, "5/ ItemToNode - Parent inheritance\n" );
290
291     
292     /* Test 6 : Add many items */
293     fprintf( stderr, "6/ Adding %i items", 12*CREATE_GT );
294
295     i_start = mdate();
296
297     for( i = CREATE_GT ; i >= 0 ; i-- )
298     {
299         GreekTree( p_playlist, p_view->p_root );
300     }
301     
302     fprintf( stderr, "Created in "I64Fi " us\n", mdate() - i_start );
303
304     vlc_object_release( p_playlist );
305
306     if( p_sys->b_error == VLC_FALSE )
307     {
308         p_this->p_libvlc->b_die = VLC_TRUE;
309     }
310     else
311     {
312         exit( 1 );
313     }
314     return;
315 }
316
317 static inline void GreekTree( playlist_t *p_playlist, playlist_item_t *p_node )
318 {
319     playlist_item_t *p_item,*p_a,*p_b,*p_c,*p_d,*p_e,*p_f,*p_g,*p_h;    
320     p_a = playlist_NodeCreate( p_playlist, VIEW_CATEGORY, "A", p_node );
321     p_item = playlist_ItemNew(p_playlist, "mu","mu" );
322     playlist_NodeAddItem( p_playlist, p_item, VIEW_CATEGORY,
323                           p_a, PLAYLIST_APPEND, PLAYLIST_END );
324     p_b = playlist_NodeCreate( p_playlist, VIEW_CATEGORY, "B", p_a );
325     p_c = playlist_NodeCreate( p_playlist, VIEW_CATEGORY, "C", p_a );
326     p_d = playlist_NodeCreate( p_playlist, VIEW_CATEGORY, "D", p_a );
327     p_item = playlist_ItemNew(p_playlist, "lambda","lambda" );
328     playlist_NodeAddItem( p_playlist, p_item, VIEW_CATEGORY,
329                           p_b, PLAYLIST_APPEND, PLAYLIST_END );
330     p_e = playlist_NodeCreate( p_playlist, VIEW_CATEGORY, "E", p_b );
331     p_f = playlist_NodeCreate( p_playlist, VIEW_CATEGORY, "F", p_b );
332     p_item = playlist_ItemNew(p_playlist, "gamma","gamma" );
333     playlist_NodeAddItem( p_playlist, p_item, VIEW_CATEGORY,
334                           p_d, PLAYLIST_APPEND, PLAYLIST_END );
335     p_g = playlist_NodeCreate( p_playlist, VIEW_CATEGORY, "G", p_d );
336     p_item = playlist_ItemNew(p_playlist, "beta","beta" );
337     playlist_NodeAddItem( p_playlist, p_item, VIEW_CATEGORY,
338                           p_e, PLAYLIST_INSERT, 0 );
339     p_item = playlist_ItemNew(p_playlist, "alpha","alpha" );
340     playlist_NodeAddItem( p_playlist, p_item, VIEW_CATEGORY,
341                           p_e, PLAYLIST_INSERT, 0 );
342     p_item = playlist_ItemNew(p_playlist, "pi","pi" );
343     playlist_NodeAddItem( p_playlist, p_item, VIEW_CATEGORY,
344                           p_g, PLAYLIST_APPEND, PLAYLIST_END );
345     p_item = playlist_ItemNew(p_playlist, "tau","tau" );
346     playlist_NodeAddItem( p_playlist, p_item, VIEW_CATEGORY,
347                           p_g, PLAYLIST_APPEND, PLAYLIST_END );
348     p_item = playlist_ItemNew(p_playlist, "rho","rho" );
349     playlist_NodeAddItem( p_playlist, p_item, VIEW_CATEGORY,
350                           p_g, PLAYLIST_INSERT, 1 );
351     p_g = playlist_NodeCreate( p_playlist, VIEW_CATEGORY, "H", p_d );
352 }
353
354 static void Assert( intf_sys_t *p_sys,const char* psz_text, int condition )
355 {
356     fprintf( stderr, "%s", psz_text );
357     if( condition == 0 )
358     {
359         fprintf( stderr, "Fail\n" );
360         p_sys->b_error = VLC_TRUE;
361     }
362     else
363     {
364         fprintf(stderr,"Pass\n" );
365     }
366     return;
367 }
368
369
370 static int Callback( vlc_object_t *p_this, char *psz_cmd,
371                 vlc_value_t ov, vlc_value_t nv,void *param)
372 {
373     intf_sys_t *p_sys = (intf_sys_t*) param;
374     playlist_t *p_playlist = (playlist_t*)p_this;
375     char *psz_name;
376     playlist_item_t *p_item;
377     
378     if( p_sys->i_names == -1 ) return;
379     
380     p_item= playlist_ItemGetById( p_sys->p_playlist,nv.i_int );
381     psz_name = strdup (p_item->input.psz_name );
382
383     if( p_sys->i_current >= p_sys->i_names )
384     {
385         fprintf( stderr,"Error, we read too many items\n" );
386         p_sys->b_error = VLC_TRUE;
387         return;
388     }
389
390     if( !strcmp( p_sys->ppsz_names[p_sys->i_current], psz_name ) )
391     {
392         p_sys->i_current++;
393         fprintf(stderr,"playing %s\n",p_sys->ppsz_names[p_sys->i_current-1]);
394     }
395     else
396     {
397         fprintf( stderr, "Error, we read %s, %s expected",
398                  psz_name ,  p_sys->ppsz_names[p_sys->i_current] );
399         p_sys->b_error = VLC_TRUE;
400     }
401
402     return VLC_SUCCESS;
403 }