/* * Copyright (C) 2010 The Android Open Source Project * * 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.android.tradefed.util.net; import com.android.tradefed.util.MultiMap; import com.android.tradefed.util.StreamUtil; import com.android.tradefed.util.net.IHttpHelper.DataSizeException; import junit.framework.TestCase; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.URL; /** * Unit tests for {@link HttpHelper}. */ public class HttpHelperTest extends TestCase { private static final String TEST_URL_STRING = "http://foo"; private static final String TEST_POST_DATA = "this is post data"; private static final String TEST_DATA = "this is test data"; private TestHttpHelper mHelper; /** * {@inheritDoc} */ @Override protected void setUp() throws Exception { super.setUp(); mHelper = new TestHttpHelper(); } /** * {@inheritDoc} */ @Override protected void tearDown() throws Exception { super.tearDown(); mHelper.close(); } /** * Test {@link HttpHelper#buildParameters(MultiMap)}. */ public void testBuildParams() { MultiMap<String, String> paramMap = new MultiMap<String, String>(); paramMap.put("key", "value"); assertEquals("key=value", mHelper.buildParameters(paramMap)); paramMap.clear(); paramMap.put("key1", "value1"); paramMap.put("key2", "value2"); String params = mHelper.buildParameters(paramMap); assertTrue(params.contains("key1=value1")); assertTrue(params.contains("key2=value2")); assertTrue(params.contains("&")); paramMap.clear(); paramMap.put("key", "value1"); paramMap.put("key", "value2"); assertEquals("key=value1&key=value2", mHelper.buildParameters(paramMap)); paramMap.clear(); paramMap.put("key+f?o=o;", "value"); assertEquals("key%2Bf%3Fo%3Do%3B=value", mHelper.buildParameters(paramMap)); } /** * Test {@link HttpHelper#buildUrl(String, MultiMap)} with simple parameters. */ public void testBuildUrl() { assertEquals("http://foo", mHelper.buildUrl(TEST_URL_STRING, null)); MultiMap<String, String> paramMap = new MultiMap<String, String>(); assertEquals("http://foo", mHelper.buildUrl(TEST_URL_STRING, paramMap)); paramMap.put("key", "value"); assertEquals("http://foo?key=value", mHelper.buildUrl(TEST_URL_STRING, paramMap)); } /** * Normal case test for {@link HttpHelper#doGet(String)} */ public void testDoGet() throws IOException, DataSizeException { assertEquals(TEST_DATA, mHelper.doGet(TEST_URL_STRING)); } /** * Test that {@link HttpHelper#doGet(String)} throws {@link DataSizeException} when the * remote stream returns too much data. */ public void testDoGet_datasize() throws IOException { mHelper.close(); mHelper = new TestHttpHelper() { @Override InputStream getRemoteUrlStream(URL url) { // test with 64K + 1 return new ByteArrayInputStream(new byte[IHttpHelper.MAX_DATA_SIZE + 1]); } }; try { mHelper.doGet(TEST_URL_STRING); fail("DataSizeException not thrown"); } catch (DataSizeException e) { // expected } } /** * Normal case test for {@link HttpHelper#doGetWithRetry(String)}. */ public void testDoGetWithRetry() throws IOException, DataSizeException { assertEquals(TEST_DATA, mHelper.doGetWithRetry(TEST_URL_STRING)); } /** * Test that {@link HttpHelper#doGetWithRetry(String)} throws a {@link DataSizeException} when * the remote stream returns too much data. */ public void testDoGetWithRetry_datasize() throws IOException { mHelper.close(); mHelper = new TestHttpHelper() { @Override InputStream getRemoteUrlStream(URL url) { // test with 64K + 1 return new ByteArrayInputStream(new byte[IHttpHelper.MAX_DATA_SIZE + 1]); } }; try { mHelper.doGetWithRetry(TEST_URL_STRING); fail("DataSizeException not thrown"); } catch (DataSizeException e) { // expected } } /** * Test that {@link HttpHelper#doGetWithRetry(String)} throws a {@link IOException} if an * {@link IOException} is thrown on each attempt. */ public void testDoGetWithRetry_ioexception() throws DataSizeException { mHelper.close(); mHelper = new TestHttpHelper() { @Override public String doGet(String url) throws IOException { throw new IOException(); } }; try { mHelper.doGetWithRetry(TEST_URL_STRING); fail("IOException not thrown"); } catch (IOException e) { // expected } } /** * Test that {@link HttpHelper#doGetWithRetry(String)} returns data if an {@link IOException} is * thrown on the first attempt, but is fine on the second attempt. */ public void testDoGetWithRetry_retry() throws IOException, DataSizeException { mHelper.close(); mHelper = new TestHttpHelper() { boolean mExceptionThrown = false; @Override public String doGet(String url) throws IOException, DataSizeException { if (!mExceptionThrown) { mExceptionThrown = true; throw new IOException(); } return super.doGet(url); } }; assertEquals(TEST_DATA, mHelper.doGetWithRetry(TEST_URL_STRING)); } /** * Normal case test for {@link HttpHelper#doPostWithRetry(String, String)}. */ public void testDoPostWithRetry() throws IOException, DataSizeException { assertEquals(TEST_DATA, mHelper.doPostWithRetry(TEST_URL_STRING, TEST_POST_DATA)); assertEquals(TEST_POST_DATA, mHelper.getOutputStream().toString()); } /** * Test that {@link HttpHelper#doPostWithRetry(String, String)} throws a * {@link DataSizeException} when the remote stream returns too much data. */ public void testDoPostWithRetry_datasize() throws IOException { mHelper.close(); mHelper = new TestHttpHelper() { @Override InputStream getConnectionInputStream(HttpURLConnection conn) { // test with 64K + 1 return new ByteArrayInputStream(new byte[IHttpHelper.MAX_DATA_SIZE + 1]); } }; try { mHelper.doPostWithRetry(TEST_URL_STRING, TEST_POST_DATA); fail("DataSizeException not thrown"); } catch (DataSizeException e) { // expected } } /** * Test that {@link HttpHelper#doPostWithRetry(String, String)} throws a {@link IOException} if * an {@link IOException} is thrown on each attempt. */ public void testDoPostWithRetry_ioexception() throws DataSizeException { mHelper.close(); mHelper = new TestHttpHelper() { @Override public HttpURLConnection createConnection(URL url, String method, String contentType) throws IOException { throw new IOException(); } }; try { mHelper.doPostWithRetry(TEST_URL_STRING, TEST_POST_DATA); fail("IOException not thrown"); } catch (IOException e) { // expected } } /** * Test that {@link HttpHelper#doPostWithRetry(String, String)} returns data if an * {@link IOException} is thrown on the first attempt, but is fine on the second attempt. */ public void testDoPostWithRetry_retry() throws IOException, DataSizeException { mHelper.close(); mHelper = new TestHttpHelper() { boolean mExceptionThrown = false; @Override public HttpURLConnection createConnection(URL url, String method, String contentType) throws IOException { if (!mExceptionThrown) { mExceptionThrown = true; throw new IOException(); } return super.createConnection(url, method, contentType); } }; assertEquals(TEST_DATA, mHelper.doPostWithRetry(TEST_URL_STRING, TEST_POST_DATA)); assertEquals(TEST_POST_DATA, mHelper.getOutputStream().toString()); } /** * A class which extends {@link HttpHelper} for testing without using the network. */ private class TestHttpHelper extends HttpHelper { InputStream mInputStream = new ByteArrayInputStream(TEST_DATA.getBytes()); OutputStream mOutputStream = new ByteArrayOutputStream(); /** * Create a {@link TestHttpHelper} */ public TestHttpHelper() { // Override all the polling related values to make this unit test run as fast as // possible while still delivering consistent results. setOpTimeout(300); setInitialPollInterval(10); setMaxPollInterval(50); setMaxTime(50); } /** * Close any open streams. */ public void close() { StreamUtil.close(mInputStream); StreamUtil.close(mOutputStream); } /** * Get the output stream used in {@link #doPostWithRetry(String, String)}. */ public OutputStream getOutputStream() { return mOutputStream; } /** * {@inheritDoc} */ @Override InputStream getRemoteUrlStream(URL url) { return mInputStream; } /** * {@inheritDoc} */ @Override public HttpURLConnection createConnection(URL url, String method, String contentType) throws IOException { return null; } /** * {@inheritDoc} */ @Override InputStream getConnectionInputStream(HttpURLConnection conn) throws IOException { return mInputStream; } /** * {@inheritDoc} */ @Override OutputStream getConnectionOutputStream(HttpURLConnection conn) throws IOException { return mOutputStream; } } }