1 /*****************************************************************************
2 * playlist.c : Playlist testsuite
3 *****************************************************************************
4 * Copyright (C) 2004 the VideoLAN team
7 * Authors : Clément Stenac <zorglub@videolan.org>
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.
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.
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 *****************************************************************************/
24 /* To run these tests, run vlc with
25 * --playlist-test --quiet --no-plugins-cache -I dummy */
27 /* greek tree used for tests, borrowed from the SubVersion project
31 _______________________//|\
32 / ______________/ | \_____________
36 _____/|\_____ _____________/|\
47 ________/|\_______ chi psi omega
55 /*****************************************************************************
57 *****************************************************************************/
60 #include <vlc_input.h>
61 #include <vlc_playlist.h>
65 /*****************************************************************************
67 *****************************************************************************/
68 int PlaylistTest ( vlc_object_t *, char const *,
69 vlc_value_t, vlc_value_t, void * );
71 static int Callback( vlc_object_t *, char *, vlc_value_t, vlc_value_t,void*);
73 static void Assert( intf_sys_t *p_sys,const char* psz_text, int condition );
75 static void StressTest (vlc_object_t *);
79 #define CREATE_GT 1000
83 char *ppsz_names[MAX_ITEMS];
84 playlist_t *p_playlist;
90 /*****************************************************************************
92 *****************************************************************************/
94 set_description( _("Playlist stress tests") );
95 add_bool( "playlist-test" , VLC_FALSE , PlaylistTest , "" , "" ,
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 )
105 if( newval.b_bool == VLC_FALSE ) return VLC_SUCCESS;
107 if( vlc_thread_create( p_this, "playlist tester", StressTest,
108 VLC_THREAD_PRIORITY_LOW, VLC_FALSE ) )
110 msg_Err( p_this, "unable to spawn playlist test thread" );
116 /*****************************************************************************
118 *****************************************************************************/
119 static void StressTest( vlc_object_t *p_this )
121 playlist_t *p_playlist = NULL;
122 playlist_view_t *p_view;
125 playlist_item_t *p_item,*p_a,*p_b,*p_c,*p_d,*p_e,*p_f,*p_g,*p_h, *p_gamma;
127 intf_sys_t *p_sys = (intf_sys_t *)malloc( sizeof( intf_sys_t ) );
128 p_sys->b_error = VLC_FALSE;
130 fprintf( stderr, "beginning playlist test\n" );
131 while( p_playlist == NULL )
133 msleep( INTF_IDLE_SLEEP );
134 p_playlist = vlc_object_find( p_this, VLC_OBJECT_PLAYLIST,
137 fprintf( stderr, "Attached to playlist\n");
139 p_sys->p_playlist = p_playlist;
141 /* let time for vlc initialization */
144 var_AddCallback( p_playlist, "playlist-current", Callback, p_sys );
147 /* Test 1 : Create a greek tree */
148 fprintf(stderr,"1/ Creating greek tree pattern (except H)\n");
150 p_view = playlist_ViewFind( p_playlist, VIEW_CATEGORY );
153 playlist_Stop( p_playlist );
154 Assert( p_sys, "Checking playlist status STOPPED ...",
155 p_playlist->status.i_status == PLAYLIST_STOPPED );
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 );
193 fprintf( stderr, "Created in "I64Fi " us\n", mdate() - i_start );
195 fprintf(stderr,"Dumping category view\n" );
196 playlist_ViewDump( p_playlist, p_view );
198 Assert( p_sys, "Checking playlist status STOPPED ...",
199 p_playlist->status.i_status == PLAYLIST_STOPPED );
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 );
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");
217 p_sys->i_current = 0;
219 fprintf( stderr, "Starting playlist\n");
221 playlist_Play( p_playlist );
225 Assert( p_sys, "Checking nothing was played ...",
226 (p_sys->i_current == 0) );
227 fprintf(stderr,"played : %i\n",p_sys->i_current );
229 playlist_Control( p_playlist, PLAYLIST_VIEWPLAY, VIEW_CATEGORY,
230 p_view->p_root, NULL );
232 Assert( p_sys, "Checking playlist RUNNING ...",
233 p_playlist->status.i_status == 1 );
235 /* Wait for everything to have played */
237 while( p_sys->i_current != 8 );// && p_sys->b_error == VLC_FALSE )
239 msleep( INTF_IDLE_SLEEP );
241 fprintf(stderr,"finished\n" );
244 /* Let some more time */
246 Assert( p_sys, "Checking playlist status STOPPED ...",
247 (p_playlist->status.i_status == PLAYLIST_STOPPED) );
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 );
256 Assert( p_sys, "Checking playing of gamma ...",
257 p_playlist->status.p_item == p_gamma );
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 );
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 );
273 Assert( p_sys, "Checking playlist stopped ...",
274 p_playlist->status.i_status == PLAYLIST_STOPPED );
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 );
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 );
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" );
292 /* Test 6 : Add many items */
293 fprintf( stderr, "6/ Adding %i items", 12*CREATE_GT );
297 for( i = CREATE_GT ; i >= 0 ; i-- )
299 GreekTree( p_playlist, p_view->p_root );
302 fprintf( stderr, "Created in "I64Fi " us\n", mdate() - i_start );
304 vlc_object_release( p_playlist );
306 if( p_sys->b_error == VLC_FALSE )
308 p_this->p_libvlc->b_die = VLC_TRUE;
317 static inline void GreekTree( playlist_t *p_playlist, playlist_item_t *p_node )
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 );
354 static void Assert( intf_sys_t *p_sys,const char* psz_text, int condition )
356 fprintf( stderr, "%s", psz_text );
359 fprintf( stderr, "Fail\n" );
360 p_sys->b_error = VLC_TRUE;
364 fprintf(stderr,"Pass\n" );
370 static int Callback( vlc_object_t *p_this, char *psz_cmd,
371 vlc_value_t ov, vlc_value_t nv,void *param)
373 intf_sys_t *p_sys = (intf_sys_t*) param;
374 playlist_t *p_playlist = (playlist_t*)p_this;
376 playlist_item_t *p_item;
378 if( p_sys->i_names == -1 ) return;
380 p_item= playlist_ItemGetById( p_sys->p_playlist,nv.i_int );
381 psz_name = strdup (p_item->input.psz_name );
383 if( p_sys->i_current >= p_sys->i_names )
385 fprintf( stderr,"Error, we read too many items\n" );
386 p_sys->b_error = VLC_TRUE;
390 if( !strcmp( p_sys->ppsz_names[p_sys->i_current], psz_name ) )
393 fprintf(stderr,"playing %s\n",p_sys->ppsz_names[p_sys->i_current-1]);
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;