/* test rig for MPLE functions */ /* caution: will delete the contents of whatever you tell it is the test device */ #include #include #include #include #include #include #include #define TEST_DEVICE "/var/tmp/NW-S23" #define TEST_FILE "test.mp3" /* * The original MP3 code pads out short reads with zeros, which is * fine and sensible for streaming but makes no sense, really, for * file reads. This switches it on and off and adjusts the expected * test results accordingly. */ #ifdef PAD_SHORT_READ #define TEST_FILE_SIZE 703040 #define TEST_FILE_MS 43521 #define TEST_FILE_FRAMES 1682 #else #define TEST_FILE_SIZE 702622 #define TEST_FILE_MS 43495 #define TEST_FILE_FRAMES 1681 #endif void progress( double percent, void *context ) { fprintf( stderr, "\r done %.2f%%", percent * 100 ); } pblist_folder *new_folder( char * name ) { pblist_folder *folder = g_malloc0( sizeof( pblist_folder )); int i; for ( i = 0; i < strlen( name ); i++ ) { folder->foldername[i] = GUINT16_TO_BE( name[i] ); if ( i > 126 ) { break; } } return folder; } /* * optional args: /path/to/device and testfile */ int main( int argc, char *argv[] ) { int retval = 1; mple_device *dev; guint16 test, test2; pblist_folder *folder = NULL, *folder2 = NULL; pblist_track *track = NULL; gchar *testdev = NULL; gchar *testfile = NULL; MPLEFILE *mfp = NULL; long offset = 0; struct stat statbuf; mple_track *tptr = NULL; gchar *buffer = NULL; int nbytes = 0; int total = nbytes; FILE *fp = NULL; GList *players = NULL; if ( argc > 1 ) { testdev = g_strdup( argv[1] ); } else { testdev = g_strdup( TEST_DEVICE ); } if ( argc > 2 ) { testfile = g_strdup( argv[2] ); } else { testfile = g_strdup( TEST_FILE ); } /* test for available devices */ fprintf( stderr, "scanning for devices..." ); players = mple_get_nw_devs( NULL ); fprintf( stderr, "done\n" ); if ( g_list_length( players ) == 0 ) { fprintf( stderr, "no NW players found\n" ); } else { GList *p; for ( p = players; p != NULL; p = g_list_next( p )) { fprintf( stderr, " %s (%s)\n", ((mple_device *)( p->data ))->device, ((mple_device *)( p->data ))->path == NULL ? "unmounted" : ((mple_device *)( p->data ))->path ); mple_dev_free( p->data ); } g_list_free( players ); } dev = mple_dev_init( testdev ); if ( dev == NULL ) { perror( "mple_dev_init" ); goto out; } /* this is a hack to stop the progress bar from trying to display when I compile from within emacs */ if ( getenv( "EMACS" ) == NULL ) { dev->progress = progress; } if ( mple_parse_pblist( dev ) == NULL ) { if ( errno && errno != ENOENT ) { perror( "parsing pblist" ); goto out; } else { /* empty device */ } } /* make sure the device is empty */ fprintf( stderr, "Making sure device is clean..." ); while( g_list_length( dev->folderlist )) { fprintf( stderr, "." ); mple_del_folder( dev, 1 ); } fprintf( stderr, "done\n" ); if ( mple_parse_pblist( dev ) == NULL ) { if ( errno && errno != ENOENT ) { perror( "parsing pblist" ); goto out; } } else { fprintf( stderr, "unexpected non-NULL from parse_pblist\n" ); goto out; } fprintf( stderr, "FOLDER TESTS\n" ); folder = new_folder( "TEST" ); folder2 = new_folder( "TEST2" ); test = mple_add_folder( dev, folder, 1 ); if ( test == 1 ) { fprintf( stderr, " added folder at position %d\n", test ); } else { perror( " first folder not added at position 1" ); goto out; } if ( mple_get_folder( dev, folder ) != test ) { perror( " mple_get_folder failed\n" ); } test2 = mple_add_folder( dev, folder2, 0 ); if ( test2 == 2 ) { fprintf( stderr, " added folder 2 at position %d\n", test2 ); } else { perror( " second folder not added at position 2" ); goto out; } test = mple_del_folder( dev, test ); if ( !test ) { perror( " deleting first folder" ); goto out; } else { fprintf( stderr, " deleted first folder\n" ); } test = mple_add_folder( dev, folder, 0 ); if ( test != 2 ) { perror( " first folder not re-added at position 2" ); goto out; } else { fprintf( stderr, " first folder re-added at position %d\n", test ); } test = mple_mv_folder( dev, test, 1 ); if ( test != 1 ) { perror( " moving first folder" ); goto out; } else { fprintf( stderr, " moved first folder to position %d\n", test ); } if ( mple_get_folder( dev, folder ) != 1 ) { perror( " folder not where I expected" ); goto out; } free( folder ); folder = new_folder( "TEST3" ); test = mple_ren_folder( dev, test, folder ); if ( test != 1 ) { perror( " renaming folder" ); goto out; } else { fprintf( stderr, " renamed first folder\n" ); } /* end of folder tests; now let's test some files */ fprintf( stderr, "\nTRACK TESTS\n" ); test2 = mple_add_track( dev, TEST_FILE, NULL, 0, 0 ); if ( test2 == 0 ) { perror( " adding track" ); goto out; } else { fprintf( stderr, " added %s to device as track %d\n", TEST_FILE, test2 ); } /* pull the metadata */ if ( mple_get_track_header( dev, test2 ) == FALSE ) { perror( " getting metadata" ); goto out; } else { mple_track *tptr = mple_get_track_ptr( dev, test2 ); /* obviously these depend on a very specific test track! */ /* check header data */ if ( GUINT32_FROM_BE( tptr->header.size ) != TEST_FILE_SIZE ) { fprintf( stderr, " size mismatch (%u != %u)\n", GUINT32_FROM_BE( tptr->header.size ), TEST_FILE_SIZE ); goto out; } if ( GUINT32_FROM_BE( tptr->header.time ) != TEST_FILE_MS ) { fprintf( stderr, " time mismatch (%u != %u)\n", GUINT32_FROM_BE( tptr->header.time ), TEST_FILE_MS ); goto out; } if ( GUINT32_FROM_BE( tptr->header.frames ) != TEST_FILE_FRAMES ) { fprintf( stderr, " frames mismatch (%u != %u)\n", GUINT32_FROM_BE( tptr->header.frames ), TEST_FILE_FRAMES ); goto out; } /* fixme check metadata */ } test2 = mple_del_track( dev, test2 ); if ( test2 == 0 ) { perror( " deleting track" ); goto out; } else { fprintf( stderr, " deleted track\n" ); } test2 = mple_add_track( dev, TEST_FILE, NULL, 0, 0 ); if ( test2 == 0 ) { perror( " re-adding track" ); goto out; } else { fprintf( stderr, " added %s to device as track %d\n", TEST_FILE, test2 ); } /* give the second track some slightly different metadata to differentiate it */ track = mple_get_metadata_NAME( TEST_FILE ); track->filename[1] = 0x6100; /* 'a' */ test2 = mple_add_track( dev, TEST_FILE, track, 0, 0 ); if ( test2 == 0 ) { perror( " re-adding track" ); goto out; } else { fprintf( stderr, " added %s to device as track %d\n", TEST_FILE, test2 ); } /* swap the tracks around */ fprintf( stderr, " swapping tracks\n" ); test2 = mple_mv_track( dev, test2, 0, 1 ); if ( test2 == 0 ) { perror( " moving track" ); goto out; } else { fprintf( stderr, " moved track 2 to position %d in its own folder\n", test2 ); } fprintf( stderr, " moving track to other folder\n" ); test2 = mple_mv_track( dev, 1, 2, 0 ); if ( test2 == 0 ) { perror( " moving track" ); goto out; } else { fprintf( stderr, " moved track to other folder\n" ); } /* now overwrite the metadata on track 1 so that it matches track 1 */ test2 = mple_ren_track( dev, 1, track ); if ( test2 == 0 ) { perror( " renaming track" ); goto out; } else { fprintf( stderr, " renamed track\n" ); } fprintf( stderr, "completed all tests\n" ); retval = 0; /* filesystem interface */ fprintf( stderr, "\nFILESYSTEM TESTS\n" ); if ( mple_stat( dev, 1, &statbuf ) == -1 ) { perror( " stat" ); goto out; } else { fprintf( stderr, " file stat ok, file size is %ld\n", statbuf.st_size ); } mfp = mple_open( dev, 0, 1, NULL, "rb" ); if ( mfp != NULL ) { fprintf( stderr, " file open ok\n" ); } else { perror( " file open" ); goto out; } /* fixme: verify _CUR and _END as well */ offset = mple_seek( mfp, 10, SEEK_SET ); if ( offset == -1 ) { perror( " file seek" ); goto out; } else { fprintf( stderr, " file seek ok\n" ); } if ( mple_tell( mfp ) != 10 ) { if ( errno ) { perror( " file tell" ); } else { fprintf( stderr, " file pointer not at %ld\n", offset ); } goto out; } else { fprintf( stderr, " file tell ok\n" ); } /* push the pointer back to 0 */ offset = mple_seek( mfp, 0, SEEK_SET ); if ( offset == -1 ) { perror( " file seek" ); goto out; } else { fprintf( stderr, " file seek ok\n" ); } if (( tptr = mple_get_track_ptr( dev, 1 )) == NULL ) { perror( " failed to get tptr" ); goto out; } if (( fp = fopen( "retrieved.mp3", "wb" )) != NULL ) { } else { perror( " copying" ); goto out; } buffer = g_malloc0( tptr->id3datalen ); errno = 0; nbytes = mple_read( buffer, tptr->id3datalen, 1, mfp ); if ( nbytes != tptr->id3datalen ) { if ( errno ) { perror( " file read" ); } else { fprintf( stderr, " file read got %d, expected %ld\n", nbytes, tptr->id3datalen ); } goto out; } else { fprintf( stderr, " file read (id3 data) ok\n" ); total = nbytes; } if ( memcmp( buffer, tptr->id3data, tptr->id3datalen )) { fprintf( stderr, " id3 data mismatch\n" ); goto out; } else { fprintf( stderr, " id3 data matches\n" ); } fwrite( buffer, tptr->id3datalen, 1, fp ); while( total < statbuf.st_size ) { size_t wanted = MIN( tptr->id3datalen, statbuf.st_size - total ); errno = 0; nbytes = mple_read( buffer, 1, wanted, mfp ); total += nbytes; if ( nbytes != wanted ) { if ( errno ) { perror( " file read" ); } else { fprintf( stderr, " file read got %d, expected %d\n", nbytes, wanted ); fprintf( stderr, " short read: got %d of %ld\n", total, statbuf.st_size ); } goto out; } else { progress( (double)total / (double)statbuf.st_size, NULL ); } fwrite( buffer, tptr->id3datalen, 1, fp ); } fclose( fp ); fp = NULL; fprintf( stderr, "\n" ); mple_close( mfp ); /* file write tests */ mfp = mple_open( dev, 2, 0, "testwrite.mp3", "wb" ); if ( mfp != NULL ) { fprintf( stderr, " file open (write) ok\n" ); } else { perror( " file open (write)" ); goto out; } if (( fp = fopen( "noid3.mp3", "rb" )) == NULL ) { perror( " fopen" ); goto out; } buffer = g_realloc( buffer, 1024 ); while(( nbytes = fread( buffer, 1, 1024, fp )) > 0 ) { int written = mple_write( buffer, 1, nbytes, mfp ); if ( written != nbytes ) { fprintf( stderr, "write mismatch: got %d, expected %d\n", written, nbytes ); } } mple_close( mfp ); mfp = NULL; out: if ( buffer != NULL ) { g_free( buffer ); } if ( fp != NULL ) { fclose( fp ); } if ( mfp != NULL ) { mple_close( mfp ); } if ( testdev != NULL ) { g_free( testdev ); } if ( testfile != NULL ) { g_free( testfile ); } if ( track != NULL ) { g_free( track ); } if ( folder2 != NULL ) { g_free( folder2 ); } if ( folder != NULL ) { g_free( folder ); } if ( dev != NULL ) { mple_dev_free( dev ); } exit( retval ); }