package freenet.client.filter; import junit.framework.TestCase; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Arrays; import freenet.support.api.Bucket; import freenet.support.io.ArrayBucket; import freenet.support.io.BucketTools; public class MP3FilterTest extends TestCase { private static final String RESOURCE_PATH = "mp3/"; /** Known good files, should pass filter unaltered. */ private static final String[] GOOD = { // MPEG ADTS, layer III, v2.5, 8 kbps, 8 kHz, Stereo "8khz-8kbps-cbr-stereo.mp3", // MPEG ADTS, layer III, v2.5, 48 kbps, 11.025 kHz, Stereo "11khz-48kbps-cbr-stereo.mp3", // MPEG ADTS, layer III, v2, 56 kbps, 16 kHz, Stereo "16khz-56kbps-cbr-stereo.mp3", // MPEG ADTS, layer III, v2, 96 kbps, 22.05 kHz, Stereo "22khz-96kbps-cbr-stereo.mp3", // MPEG ADTS, layer III, v1, 96 kbps, 32 kHz, Stereo "32khz-96kbps-cbr-stereo.mp3", // MPEG ADTS, layer III, v1, 96 kbps, 44.1 kHz, Stereo "44khz-96kbps-cbr-stereo.mp3", // MPEG ADTS, layer III, v1, 128 kbps, 48 kHz, Stereo "48khz-64kbps-vbr-stereo.mp3", // MPEG ADTS, layer III, v1, 128 kbps, 48 kHz, JntStereo "48khz-96kbps-vbr-joint.mp3", // MPEG ADTS, layer III, v1, 128 kbps, 48 kHz, Stereo "48khz-128kbps-cbr-stereo.mp3", // MPEG ADTS, layer III, v1, 320 kbps, 48 kHz, JntStereo "48khz-320kbps-cbr-joint.mp3" }; /** Pairs of unfiltered file and their expected output file. */ private static final String[][] FILTER_PAIRS = { // random + 48khz-96kbps-vbr-joint + random + 48khz-96kbps-vbr-joint + random // Random data is to be removed, leaving file with duplicate 48khz-96kbps-vbr-joint new String[] { "48khz-96kbps-vbr-joint-randompadding-unfiltered.mp3", "48khz-96kbps-vbr-joint-randompadding-expected.mp3" }, // 48khz-128kbps-cbr-stereo with ID3v2 tags to be stripped new String[] { "48khz-128kbps-cbr-stereo-id3v2.mp3", "48khz-128kbps-cbr-stereo.mp3" } }; public void testKnownGood() { for (String good : GOOD) { assertEqualAfterFilter(good, good); } } public void testFilterPairs() { for (String[] pair : FILTER_PAIRS) { assertEqualAfterFilter(pair[0], pair[1]); } } /** * Asserts that the test file in the first argument, after passing through the content filter, * is equal to the reference file in the second argument. * * @param fileUnfiltered the test file * @param fileExpected the reference file */ private static void assertEqualAfterFilter(String fileUnfiltered, String fileExpected) { Bucket input = resourceToBucket(fileUnfiltered); Bucket expected = resourceToBucket(fileExpected); Bucket filtered = filterMP3(input); assertTrue("Filtered and expected output are not identical. " + "Input = " + fileUnfiltered + ", expected = " + fileExpected, equalBuckets(filtered, expected) ); } /** * Checks for equality of Bucket contents. */ private static boolean equalBuckets(Bucket a, Bucket b) { try { return Arrays.equals(BucketTools.toByteArray(a), BucketTools.toByteArray(b)); } catch (IOException e) { throw new AssertionError(e); } } /** * Runs a Bucket through the content filter. * * @throws AssertionError on failure */ private static Bucket filterMP3(Bucket input) { ContentDataFilter filter = new MP3Filter(); Bucket output = new ArrayBucket(); InputStream inStream; OutputStream outStream; try { inStream = input.getInputStream(); outStream = output.getOutputStream(); } catch (IOException e) { throw new AssertionError(e); } try { filter.readFilter(inStream, outStream, "", null, null); } catch (Exception e) { throw new AssertionError("Unexpected exception in the content filter.", e); } try { inStream.close(); outStream.close(); } catch (IOException e) { throw new AssertionError(e); } return output; } /** * Loads a resource relative to the resource path into a Bucket. * * @throws AssertionError on failure */ private static Bucket resourceToBucket(String filename) { InputStream is = MP3FilterTest.class.getResourceAsStream(RESOURCE_PATH + filename); if (is == null) { throw new AssertionError("Test resource could not be opened: " + filename); } Bucket ab = new ArrayBucket(); try { BucketTools.copyFrom(ab, is, Long.MAX_VALUE); } catch (Exception e) { throw new AssertionError(e); } return ab; } }