// Copyright 2009 Google Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package com.google.enterprise.connector.util; import com.google.enterprise.connector.util.Clock; import com.google.enterprise.connector.util.SystemClock; import junit.framework.TestCase; /** * Unit Test for iHarder Base64. */ public class Base64Test extends TestCase { static final String input = " Google's indices consist of information that has been" + " identified, indexed and compiled through an automated" + " process with no advance review by human beings. Given" + " the enormous volume of web site information added," + " deleted, and changed on a frequent basis, Google cannot" + " and does not screen anything made available through its" + " indices. For each web site reflected in Google's" + " indices, if either (i) a site owner restricts access to" + " his or her web site or (ii) a site is taken down from" + " the web, then, upon receipt of a request by the site" + " owner or a third party in the second instance, Google" + " would consider on a case-by-case basis requests to" + " remove the link to that site from its indices. However," + " if the operator of the site does not take steps to" + " prevent it, the automatic facilities used to create" + " the indices are likely to find that site and index it" + " again in a relatively short amount of time."; static final String expect = "IEdvb2dsZSdzIGluZGljZXMgY29uc2lzdCBvZiBpbmZvcm1hdGlvbi" + "B0aGF0IGhhcyBiZWVuIGlkZW50aWZpZWQsIGluZGV4ZWQgYW5kIGNv" + "bXBpbGVkIHRocm91Z2ggYW4gYXV0b21hdGVkIHByb2Nlc3Mgd2l0aC" + "BubyBhZHZhbmNlIHJldmlldyBieSBodW1hbiBiZWluZ3MuIEdpdmVu" + "IHRoZSBlbm9ybW91cyB2b2x1bWUgb2Ygd2ViIHNpdGUgaW5mb3JtYX" + "Rpb24gYWRkZWQsIGRlbGV0ZWQsIGFuZCBjaGFuZ2VkIG9uIGEgZnJl" + "cXVlbnQgYmFzaXMsIEdvb2dsZSBjYW5ub3QgYW5kIGRvZXMgbm90IH" + "NjcmVlbiBhbnl0aGluZyBtYWRlIGF2YWlsYWJsZSB0aHJvdWdoIGl0" + "cyBpbmRpY2VzLiBGb3IgZWFjaCB3ZWIgc2l0ZSByZWZsZWN0ZWQgaW" + "4gR29vZ2xlJ3MgaW5kaWNlcywgaWYgZWl0aGVyIChpKSBhIHNpdGUg" + "b3duZXIgcmVzdHJpY3RzIGFjY2VzcyB0byBoaXMgb3IgaGVyIHdlYi" + "BzaXRlIG9yIChpaSkgYSBzaXRlIGlzIHRha2VuIGRvd24gZnJvbSB0" + "aGUgd2ViLCB0aGVuLCB1cG9uIHJlY2VpcHQgb2YgYSByZXF1ZXN0IG" + "J5IHRoZSBzaXRlIG93bmVyIG9yIGEgdGhpcmQgcGFydHkgaW4gdGhl" + "IHNlY29uZCBpbnN0YW5jZSwgR29vZ2xlIHdvdWxkIGNvbnNpZGVyIG" + "9uIGEgY2FzZS1ieS1jYXNlIGJhc2lzIHJlcXVlc3RzIHRvIHJlbW92" + "ZSB0aGUgbGluayB0byB0aGF0IHNpdGUgZnJvbSBpdHMgaW5kaWNlcy" + "4gSG93ZXZlciwgaWYgdGhlIG9wZXJhdG9yIG9mIHRoZSBzaXRlIGRv" + "ZXMgbm90IHRha2Ugc3RlcHMgdG8gcHJldmVudCBpdCwgdGhlIGF1dG" + "9tYXRpYyBmYWNpbGl0aWVzIHVzZWQgdG8gY3JlYXRlIHRoZSBpbmRp" + "Y2VzIGFyZSBsaWtlbHkgdG8gZmluZCB0aGF0IHNpdGUgYW5kIGluZG" + "V4IGl0IGFnYWluIGluIGEgcmVsYXRpdmVseSBzaG9ydCBhbW91bnQg" + "b2YgdGltZS4="; static final String expectNL = "IEdvb2dsZSdzIGluZGljZXMgY29uc2lzdCBvZiBpbmZvcm1hdGlvbiB0aGF0IGhhcyBiZWVuIGlk\n" + "ZW50aWZpZWQsIGluZGV4ZWQgYW5kIGNvbXBpbGVkIHRocm91Z2ggYW4gYXV0b21hdGVkIHByb2Nl\n" + "c3Mgd2l0aCBubyBhZHZhbmNlIHJldmlldyBieSBodW1hbiBiZWluZ3MuIEdpdmVuIHRoZSBlbm9y\n" + "bW91cyB2b2x1bWUgb2Ygd2ViIHNpdGUgaW5mb3JtYXRpb24gYWRkZWQsIGRlbGV0ZWQsIGFuZCBj\n" + "aGFuZ2VkIG9uIGEgZnJlcXVlbnQgYmFzaXMsIEdvb2dsZSBjYW5ub3QgYW5kIGRvZXMgbm90IHNj\n" + "cmVlbiBhbnl0aGluZyBtYWRlIGF2YWlsYWJsZSB0aHJvdWdoIGl0cyBpbmRpY2VzLiBGb3IgZWFj\n" + "aCB3ZWIgc2l0ZSByZWZsZWN0ZWQgaW4gR29vZ2xlJ3MgaW5kaWNlcywgaWYgZWl0aGVyIChpKSBh\n" + "IHNpdGUgb3duZXIgcmVzdHJpY3RzIGFjY2VzcyB0byBoaXMgb3IgaGVyIHdlYiBzaXRlIG9yIChp\n" + "aSkgYSBzaXRlIGlzIHRha2VuIGRvd24gZnJvbSB0aGUgd2ViLCB0aGVuLCB1cG9uIHJlY2VpcHQg\n" + "b2YgYSByZXF1ZXN0IGJ5IHRoZSBzaXRlIG93bmVyIG9yIGEgdGhpcmQgcGFydHkgaW4gdGhlIHNl\n" + "Y29uZCBpbnN0YW5jZSwgR29vZ2xlIHdvdWxkIGNvbnNpZGVyIG9uIGEgY2FzZS1ieS1jYXNlIGJh\n" + "c2lzIHJlcXVlc3RzIHRvIHJlbW92ZSB0aGUgbGluayB0byB0aGF0IHNpdGUgZnJvbSBpdHMgaW5k\n" + "aWNlcy4gSG93ZXZlciwgaWYgdGhlIG9wZXJhdG9yIG9mIHRoZSBzaXRlIGRvZXMgbm90IHRha2Ug\n" + "c3RlcHMgdG8gcHJldmVudCBpdCwgdGhlIGF1dG9tYXRpYyBmYWNpbGl0aWVzIHVzZWQgdG8gY3Jl\n" + "YXRlIHRoZSBpbmRpY2VzIGFyZSBsaWtlbHkgdG8gZmluZCB0aGF0IHNpdGUgYW5kIGluZGV4IGl0\n" + "IGFnYWluIGluIGEgcmVsYXRpdmVseSBzaG9ydCBhbW91bnQgb2YgdGltZS4="; /* Test the basic encode and decode functions. */ public void testFixed() throws Exception { String result = Base64.encode(input.getBytes()); assertEquals(expect, result); String decode = new String(Base64.decode(result), "UTF-8"); assertEquals(input, decode); } /* Test my special write-to-preallocated array enhancement. */ public void testWriteToByteArray() throws Exception { byte[] resultBytes = new byte[expect.length()]; int length = Base64.encode(input.getBytes(), 0, input.length(), resultBytes, 0, Base64.ALPHABET, Integer.MAX_VALUE); assertTrue(length == expect.length()); String result = new String(resultBytes, "UTF-8"); assertEquals(expect, result); String decode = new String(Base64.decode(result), "UTF-8"); assertEquals(input, decode); } /* Test my special write-to-preallocated array enhancement, * specifying a destination offset. */ public void testWriteToByteArray2() throws Exception { byte[] resultBytes = new byte[expect.length() + 9]; int length = Base64.encode(input.getBytes(), 0, input.length(), resultBytes, 4, Base64.ALPHABET, Integer.MAX_VALUE); assertTrue(length == expect.length()); String result = new String(resultBytes, 4, length, "UTF-8"); assertEquals(expect, result); String decode = new String(Base64.decode(result), "UTF-8"); assertEquals(input, decode); } /* Test my special write-to-preallocated array enhancement, * specifying a source offset. */ public void testWriteToByteArray3() throws Exception { byte[] sourceBytes = new byte[input.length() + 9]; System.arraycopy(input.getBytes(), 0, sourceBytes, 5, input.length()); byte[] resultBytes = new byte[expect.length()]; int length = Base64.encode(sourceBytes, 5, input.length(), resultBytes, 0, Base64.ALPHABET, Integer.MAX_VALUE); assertTrue(length == expect.length()); String result = new String(resultBytes, "UTF-8"); assertEquals(expect, result); String decode = new String(Base64.decode(result), "UTF-8"); assertEquals(input, decode); } /* Test my special write-to-preallocated array enhancement w/newlines. */ public void testWriteToByteArray4() throws Exception { byte[] resultBytes = new byte[expectNL.length()]; int length = Base64.encode(input.getBytes(), 0, input.length(), resultBytes, 0, Base64.ALPHABET, 76); assertTrue(length == expectNL.length()); String result = new String(resultBytes, "UTF-8"); assertEquals(expectNL, result); String decode = new String(Base64.decode(result), "UTF-8"); assertEquals(input, decode); } /* Test my special write-to-preallocated array enhancement, * specifying a destination offset and line length. */ public void testWriteToByteArray5() throws Exception { byte[] resultBytes = new byte[expectNL.length() + 9]; int length = Base64.encode(input.getBytes(), 0, input.length(), resultBytes, 4, Base64.ALPHABET, 76); assertTrue(length == expectNL.length()); String result = new String(resultBytes, 4, length, "UTF-8"); assertEquals(expectNL, result); String decode = new String(Base64.decode(result), "UTF-8"); assertEquals(input, decode); } /* Test performance of encoder. This might still fail on slow machines. */ public void testSpeed() throws Exception { byte[] input = new byte[5*1024*1024]; byte[] output = new byte[4 + ((input.length * 4) / 3)]; // Force these arrays to be paged in before starting the clock. System.arraycopy(input, 0, output, 0, input.length); System.arraycopy(input, 0, output, input.length, output.length - input.length); Clock clock = new SystemClock(); long start = clock.getTimeMillis(); Base64.encode(input, 0, input.length, output, 0, Base64.ALPHABET, Integer.MAX_VALUE); long duration = clock.getTimeMillis() - start; System.out.println("testSpeed: " + duration + " millisecs"); // OriginalBase64Encoder used to run 20x longer than this one. // TODO: This threshold is already 10x longer than this test // takes on my machine, so I don't think this is a valid // regression test. Fails on code coverage and Pulse. // assertTrue(duration < 300); } }