1 /* 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.tradefed.util.net; 17 18 import com.android.tradefed.util.RunUtil; 19 20 import junit.framework.TestCase; 21 22 import java.io.OutputStream; 23 import java.net.ServerSocket; 24 import java.net.Socket; 25 import java.net.SocketTimeoutException; 26 import java.util.concurrent.CyclicBarrier; 27 import java.util.concurrent.TimeUnit; 28 29 /** 30 * Functional tests for {@link HttpHelper} 31 */ 32 public class HttpHelperFuncTest extends TestCase { 33 /** 34 * Make sure that we get a timeout if the backend doesn't respond 35 */ testTimeout()36 public void testTimeout() throws Exception { 37 final int backendDelay = 500; // msecs 38 final int backendTimeout = 200; 39 final int clientTimeout = 250; // 250ms < 500ms, hence timeout 40 final int threadStartTimeout = 100; 41 final CyclicBarrier barrier = new CyclicBarrier(2); 42 43 Backend backend = new Backend(backendDelay, backendTimeout, barrier); 44 IHttpHelper http = new HttpHelper(); 45 http.setOpTimeout(clientTimeout); 46 47 // Kick off the backend and wait for it to get up and running 48 backend.start(); 49 barrier.await(threadStartTimeout, TimeUnit.MILLISECONDS); 50 // backendTimeout is now ticking down 51 52 final int port = backend.getPort(); // FIXME race condition 53 if (port <= 0) { 54 backend.join(2 * backendTimeout); 55 Throwable e = backend.getException(); 56 String msg = "Backend was not initialized properly"; 57 if (e != null) { 58 msg = String.format("%s:\n%s", msg, e.toString()); 59 } 60 fail(msg); 61 return; 62 } 63 64 final String url = String.format("http://localhost:%d/", port); 65 try { 66 http.doGet(url); 67 fail("SocketTimeoutException not thrown"); 68 } catch (SocketTimeoutException e) { 69 // expected 70 } 71 72 backend.join(2 * backendTimeout); 73 } 74 75 /** 76 * Make sure that we _do not_ time out if the backend responds expediently 77 */ testNoTimeout()78 public void testNoTimeout() throws Exception { 79 final int backendDelay = 0; // msecs 80 final int backendTimeout = 1000; 81 final int clientTimeout = 250; // 250ms > 0ms, hence no timeout 82 final int threadStartTimeout = 100; 83 final CyclicBarrier barrier = new CyclicBarrier(2); 84 85 Backend backend = new Backend(backendDelay, backendTimeout, barrier); 86 IHttpHelper http = new HttpHelper(); 87 http.setOpTimeout(clientTimeout); 88 89 // Kick off the backend and wait for it to get up and running 90 backend.start(); 91 barrier.await(threadStartTimeout, TimeUnit.MILLISECONDS); 92 // backendTimeout is now ticking down 93 94 final int port = backend.getPort(); // FIXME race condition 95 if (port <= 0) { 96 backend.join(2 * backendTimeout); 97 Throwable e = backend.getException(); 98 String msg = "Backend was not initialized properly"; 99 if (e != null) { 100 msg = String.format("%s:\n%s", msg, e.toString()); 101 } 102 fail(msg); 103 return; 104 } 105 106 final String url = String.format("http://localhost:%d/", port); 107 http.doGet(url); 108 109 backend.join(2 * backendTimeout); 110 } 111 112 private class Backend extends Thread { 113 public ServerSocket mSS = null; 114 public Throwable mException = null; 115 public static final String RESPONSE = "HTTP/1.1 200 OK\r\n" + 116 "Content-Length: 30\r\n" + 117 "Content-Type: text/html\r\n\r\n" + 118 "<h1>Hello, this is dog.</h1>\r\n"; 119 120 private final int mDelay; 121 private final int mTimeout; 122 private final CyclicBarrier mBarrier; 123 Backend(int delay, int timeout, CyclicBarrier barrier)124 public Backend(int delay, int timeout, CyclicBarrier barrier) { 125 super("HttpHelperFuncTest.Backend"); 126 mDelay = delay; 127 mTimeout = timeout; 128 mBarrier = barrier; 129 } 130 getPort()131 public int getPort() { 132 if (mSS == null) { 133 return -1; 134 } else { 135 return mSS.getLocalPort(); 136 } 137 } 138 getException()139 public Throwable getException() { 140 return mException; 141 } 142 143 @Override run()144 public void run() { 145 try { 146 mSS = new ServerSocket(0); 147 mSS.setSoTimeout(mTimeout); 148 mBarrier.await(2 * (mDelay + mTimeout), TimeUnit.MILLISECONDS); 149 150 Socket sock = mSS.accept(); 151 RunUtil.getDefault().sleep(mDelay); 152 OutputStream oStream = sock.getOutputStream(); 153 oStream.write(RESPONSE.getBytes()); 154 oStream.flush(); 155 oStream.close(); 156 sock.close(); 157 } catch (Exception e) { 158 mException = e; 159 mSS = null; 160 return; 161 } 162 } 163 } 164 } 165