/* * Copyright 2008 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.jstestdriver; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Sets; import com.google.gson.JsonArray; import com.google.gson.JsonObject; import com.google.jstestdriver.browser.BrowserIdStrategy; import com.google.jstestdriver.config.ExecutionType; import com.google.jstestdriver.hooks.FileInfoScheme; import com.google.jstestdriver.hooks.ServerListener; import com.google.jstestdriver.model.NullPathPrefix; import com.google.jstestdriver.runner.RunnerMode; import com.google.jstestdriver.server.JstdTestCaseStore; import com.google.jstestdriver.util.NullStopWatch; import junit.framework.TestCase; import org.mortbay.jetty.bio.SocketConnector; import org.mortbay.jetty.servlet.Context; import org.mortbay.jetty.servlet.ServletHolder; import java.io.IOException; import java.io.InputStream; import java.io.PrintStream; import java.net.HttpURLConnection; import java.net.URL; import java.util.Collection; import java.util.Collections; import java.util.concurrent.atomic.AtomicInteger; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * @author jeremiele@google.com (Jeremie Lenfant-Engelmann) */ public class JsTestDriverServerTest extends TestCase { private CapturedBrowsers browsers = new CapturedBrowsers(new BrowserIdStrategy(new MockTime(1))); private JsTestDriverServerImpl server; private JsTestDriverServerImpl createServer(ServerListener listener) { server = new JsTestDriverServerImpl(4224, 4225, new JstdTestCaseStore(), browsers, SlaveBrowser.TIMEOUT, new NullPathPrefix(), Sets.newHashSet(listener), Collections.<FileInfoScheme>emptySet(), ExecutionType.INTERACTIVE, false); return server; } @Override protected void tearDown() throws Exception { if (server != null) { server.stop(); server = null; } } public void testServerLifecycle() throws Exception { TestListener listener = new TestListener(); createServer(listener); server.start(); URL url = new URL("http://localhost:4224/hello"); assertEquals("hello", read(url.openStream())); } private String read(InputStream inputStream) throws IOException { StringBuilder builder = new StringBuilder(); int ch; while ((ch = inputStream.read()) != -1) { builder.append((char) ch); } return builder.toString(); } public void testStaticFiles() throws Exception { TestListener listener = new TestListener(); createServer(listener); server.start(); URL url = new URL("http://localhost:4224/static/Namespace.js"); assertTrue(read(url.openStream()).length() > 0); } public void testCapture() throws Exception { TestListener listener = new TestListener(); createServer(listener); server.start(); URL captureUrl = new URL("http://localhost:4224/capture"); assertTrue(read(captureUrl.openStream()).length() > 0); assertEquals(1, browsers.getBrowsers().size()); assertEquals(1, browsers.getBrowsers().get(0).getId().intValue()); assertEquals(new Long(1), listener.captured.getId()); } public void testCaptureWithId() throws Exception { TestListener listener = new TestListener(); createServer(listener); server.start(); URL captureUrl = new URL("http://localhost:4224/capture?id=5"); assertTrue(read(captureUrl.openStream()).length() > 0); assertEquals(1, browsers.getBrowsers().size()); assertEquals(5, browsers.getBrowsers().get(0).getId().intValue()); assertEquals(new Long(5), listener.captured.getId()); } public void testListBrowsers() throws Exception { final NullStopWatch stopWatch = new NullStopWatch(); JsTestDriverClient client = new JsTestDriverClientImpl( new CommandTaskFactory( new DefaultFileFilter(), null, null, stopWatch, ImmutableSet.<FileInfoScheme>of(new HttpFileInfoScheme()), new NullPathPrefix()), "http://localhost:4224", new HttpServer(new NullStopWatch()), false, null, new NullStopWatch()); TestListener listener = new TestListener(); createServer(listener); server.start(); Collection<BrowserInfo> browsers = client.listBrowsers(); assertEquals(0, browsers.size()); } public void testShouldNotifyObserversOnServerStart() throws Exception { TestListener listener = new TestListener(); createServer(listener); server.start(); assertTrue(listener.started); } public void testShouldNotifyObserversOnServerStop() throws Exception { TestListener listener = new TestListener(); createServer(listener); server.start(); assertTrue(listener.started); server.stop(); assertTrue(listener.stopped); } public void testGetShouldNotBeSentAsPost() throws Exception { createServer(new TestListener()); server.start(); JsonObject entry = new JsonObject(); entry.addProperty("matcher", "/*"); entry.addProperty("server", "http://localhost:8888/"); JsonArray gatewayConfig = new JsonArray(); gatewayConfig.add(entry); final HttpServer client = new HttpServer(new NullStopWatch()); client.postJson("http://localhost:4224/jstd/gateway", gatewayConfig); SocketConnector connector = new SocketConnector(); connector.setPort(8888); org.mortbay.jetty.Server dummy = new org.mortbay.jetty.Server(); dummy.addConnector(connector); Context context = new Context(dummy, "/", Context.SESSIONS); DummyServlet servlet = new DummyServlet(); context.addServlet(new ServletHolder(servlet), "/"); dummy.start(); final PrintStream out = System.out; final int N = 100; Thread[] threads = new Thread[2*N]; final AtomicInteger a = new AtomicInteger(0); for (int i = 0; i < 2*N; ++i) { final int j = i; threads[i] = new Thread() { @Override public void run() { try { if (j % 2 == 0) { client.postJson("http://localhost:4224/asdf", new JsonArray()); } else { HttpURLConnection connection = (HttpURLConnection) new URL("http://localhost:4224/asdf").openConnection(); // TODO(rdionne): Add Content-Type to prevent failure case after // gateway is rewritten. //connection.addRequestProperty("Content-Type", "application/x-www-form-urlencoded"); connection.setRequestMethod("GET"); read(connection.getInputStream()); } a.incrementAndGet(); } catch (Exception e) { e.printStackTrace(out); throw new RuntimeException(e); } } }; threads[i].start(); } for (int i = 0; i < 2*N; ++i) { threads[i].join(); } assertEquals(2*N + " " + N + " " + N, a.intValue() + " " + servlet.gets.intValue() + " " + servlet.posts.intValue()); server.stop(); } private final class TestListener implements ServerListener { public boolean stopped; public boolean started; private BrowserInfo panicked; private BrowserInfo captured; public void serverStopped() { stopped = true; } public void serverStarted() { started = true; } public void browserPanicked(BrowserInfo info) { panicked = info; } public void browserCaptured(BrowserInfo info) { captured = info; } } private static final class DummyServlet extends HttpServlet { public final AtomicInteger gets = new AtomicInteger(0); public final AtomicInteger posts = new AtomicInteger(0); @Override public void doGet(HttpServletRequest request, HttpServletResponse response) { gets.incrementAndGet(); } @Override public void doPost(HttpServletRequest request, HttpServletResponse response) { posts.incrementAndGet(); } } }