// Copyright 2010 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 org.npr.android.news; import java.io.IOException; import java.lang.Thread.UncaughtExceptionHandler; import java.net.InetAddress; import java.net.Socket; import java.net.UnknownHostException; import android.test.AndroidTestCase; import android.util.Log; /** * A collection of test for the StreamProxy class. * * @author jeremywadsack */ public class StreamProxyTest extends AndroidTestCase { private static final String TAG = StreamProxyTest.class.getName(); /* * This may only occur in testing (see below) but the proxy server throws a * NullPointerException when opened and closed and no data is sent to it. */ public void testShouldNotThrowNPEWhenStreamClosedWithoutContent() { StreamProxy proxy = new StreamProxy(); proxy.init(); proxy.start(); Socket socket = null; UncaughtExceptionHandler oldHandler = Thread .getDefaultUncaughtExceptionHandler(); ThreadExceptionHandler newHandler = new ThreadExceptionHandler(); Thread.setDefaultUncaughtExceptionHandler(newHandler); try { socket = new Socket( InetAddress.getByAddress(new byte[] { 127, 0, 0, 1 }), proxy.getPort()); } catch (Exception e) { fail(e.getClass().getSimpleName() + ":" + e.getMessage()); } finally { if (socket != null) { try { socket.close(); } catch (IOException e) { Log.w(TAG, e.getClass().getSimpleName() + ":" + e.getMessage()); } } proxy.stop(); Thread.setDefaultUncaughtExceptionHandler(oldHandler); assertFalse( "Proxy isn't checking for null content when reading from buffer.", newHandler.caughtNPE); } } /* * Most android devices are not on a named host. So the default implementation * of InetAddres.getLocalHost() returns 127.0.0.1. However, it is possible * that some devices may, in the future, be on a named host. In that case the * call would return inet interface address, 10.0.2.15. */ public void testShouldRunOnLocalhost() { // Connect the proxy and test the address StreamProxy proxy = new StreamProxy(); proxy.init(); proxy.start(); Socket socket = null; try { socket = new Socket( InetAddress.getByAddress(new byte[] { 127, 0, 0, 1 }), proxy .getPort()); assertTrue("Socket connected.", socket.isConnected()); } catch (UnknownHostException e) { fail("Proxy is not running on localhost. " + e.getClass().getSimpleName() + ":" + e.getMessage()); } catch (Exception e) { fail(e.getClass().getSimpleName() + ":" + e.getMessage()); } finally { if (socket != null) { try { socket.close(); } catch (IOException e) { Log.w(TAG, e.getClass().getSimpleName() + ":" + e.getMessage()); } } proxy.stop(); } } public void testShouldNotBeAbleToStopProxyIfNotStarted() { StreamProxy proxy = new StreamProxy(); try { proxy.stop(); } catch (NullPointerException ex) { fail("Proxy threw NPE, when attempting to stop without starting."); } catch (IllegalStateException ex) { // This is the ideal behavior } } public void testShouldNotBeAbleToStartProxyIfNotInitialized() { StreamProxy proxy = new StreamProxy(); boolean started = false; try { proxy.start(); assertTrue("Proxy should not report port 0", proxy.getPort() != 0); } catch (IllegalStateException ex) { // This is the ideal behavior } finally { if (started) { proxy.stop(); } } } // ------------------ // Test helpers private class ThreadExceptionHandler implements UncaughtExceptionHandler { public boolean caughtNPE = false; @Override public void uncaughtException(Thread thread, Throwable ex) { if (ex instanceof NullPointerException) { caughtNPE = true; } } } }