]> source.dussan.org Git - sonarqube.git/commitdiff
Replace jetty-servlet-tester with SimpleHttp
authorDavid Gageot <david@gageot.net>
Tue, 17 Jul 2012 20:47:55 +0000 (22:47 +0200)
committerDavid Gageot <david@gageot.net>
Tue, 17 Jul 2012 20:48:02 +0000 (22:48 +0200)
sonar-plugin-api/pom.xml
sonar-plugin-api/src/test/java/org/sonar/api/utils/FakeServlet.java [deleted file]
sonar-plugin-api/src/test/java/org/sonar/api/utils/HttpDownloaderTest.java
sonar-plugin-api/src/test/java/org/sonar/api/utils/RedirectServlet.java [deleted file]

index 2cc98c4714cd8503100835aa12b1d9a7ba062e1a..ae182ec583a66e5ee55a45cfcb3953d1d928cda9 100644 (file)
       <scope>test</scope>
     </dependency>
     <dependency>
-      <groupId>org.mortbay.jetty</groupId>
-      <artifactId>jetty-servlet-tester</artifactId>
+      <groupId>org.simpleframework</groupId>
+      <artifactId>simple</artifactId>
+      <version>4.1.21</version>
       <scope>test</scope>
     </dependency>
   </dependencies>
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/utils/FakeServlet.java b/sonar-plugin-api/src/test/java/org/sonar/api/utils/FakeServlet.java
deleted file mode 100644 (file)
index 2e365e7..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * Sonar is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * Sonar is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Sonar; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
- */
-package org.sonar.api.utils;
-
-import java.io.IOException;
-import java.util.Properties;
-import javax.servlet.GenericServlet;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletRequest;
-
-public class FakeServlet extends GenericServlet {
-
-  int count = 0;
-
-  @Override
-  public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
-    count++;
-    Properties props = new Properties();
-    props.setProperty("count", String.valueOf(count));
-    props.setProperty("agent", ((HttpServletRequest)request).getHeader("User-Agent"));
-    props.store(response.getOutputStream(), null);
-  }
-}
-
index c45d8076d21851b02274138a3063d5a26c92ad7c..83101c20fdb3e921e244fa39c55946909bb0a259 100644 (file)
 package org.sonar.api.utils;
 
 import com.google.common.base.Charsets;
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang.SystemUtils;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
+import org.junit.Rule;
 import org.junit.Test;
-import org.mortbay.jetty.testing.ServletTester;
+import org.junit.rules.TemporaryFolder;
+import org.simpleframework.http.Request;
+import org.simpleframework.http.Response;
+import org.simpleframework.http.core.Container;
+import org.simpleframework.transport.connect.SocketConnection;
 import org.sonar.api.config.Settings;
 import org.sonar.api.platform.Server;
 
 import java.io.File;
 import java.io.IOException;
-import java.net.*;
+import java.io.InputStream;
+import java.net.InetSocketAddress;
+import java.net.Proxy;
+import java.net.ProxySelector;
+import java.net.SocketAddress;
+import java.net.URI;
+import java.net.URISyntaxException;
 import java.util.Arrays;
 import java.util.Properties;
 
 import static org.fest.assertions.Assertions.assertThat;
-import static org.hamcrest.core.Is.is;
-import static org.junit.Assume.assumeThat;
-import static org.mockito.Matchers.anyObject;
+import static org.mockito.Matchers.any;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
 public class HttpDownloaderTest {
 
-  private static ServletTester tester;
+  @Rule
+  public TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+  private static SocketConnection socketConnection;
   private static String baseUrl;
 
   @BeforeClass
-  public static void startServer() throws Exception {
-    assumeThat(SystemUtils.IS_OS_WINDOWS, is(false)); // Temporarily deactivated on Windows because of frequent freezes
-
-    tester = new ServletTester();
-    tester.setContextPath("/");
-    tester.addServlet(RedirectServlet.class, "/redirect/");
-    tester.addServlet(FakeServlet.class, "/");
-    baseUrl = tester.createSocketConnector(true);
-    tester.start();
+  public static void startServer() throws IOException {
+    socketConnection = new SocketConnection(new Container() {
+      public void handle(Request req, Response resp) {
+        try {
+          if (req.getPath().getPath().contains("/redirect/")) {
+            resp.setCode(303);
+            resp.add("Location", "/");
+          } else {
+            resp.getPrintStream().append("agent=" + req.getValues("User-Agent").get(0));
+          }
+        } catch (IOException e) {
+        } finally {
+          try {
+            resp.close();
+          } catch (IOException e) {
+          }
+        }
+      }
+    });
+    SocketAddress address = socketConnection.connect(new InetSocketAddress(0));
+
+    baseUrl = "http://localhost:" + ((InetSocketAddress) address).getPort();
   }
 
   @AfterClass
-  public static void stopServer() throws Exception {
-    /* workaround for a jetty deadlock :
-      1. stopping server logs a SLF4J/Logback message, but the message calls AbstractConnector.toString, which is synchronized on getLocalPort()
-      2. a jetty thread tries also to stop and is locked on the same synchronized block.
-
-      "3862294@qtp-17303670-1":
-       at ch.qos.logback.core.AppenderBase.doAppend(AppenderBase.java:66)
-       - waiting to lock <0x8be33f88> (a ch.qos.logback.core.ConsoleAppender)
-       at ch.qos.logback.core.spi.AppenderAttachableImpl.appendLoopOnAppenders(AppenderAttachableImpl.java:60)
-       at ch.qos.logback.classic.Logger.appendLoopOnAppenders(Logger.java:270)
-       at ch.qos.logback.classic.Logger.callAppenders(Logger.java:257)
-       at ch.qos.logback.classic.Logger.buildLoggingEventAndAppend(Logger.java:439)
-       at ch.qos.logback.classic.Logger.filterAndLog_2(Logger.java:430)
-       at ch.qos.logback.classic.Logger.debug(Logger.java:508)
-       at org.mortbay.log.Slf4jLog.debug(Slf4jLog.java:40)
-       at org.mortbay.log.Log.debug(Log.java:112)
-       at org.mortbay.component.AbstractLifeCycle.stop(AbstractLifeCycle.java:77)
-       - locked <0x8b8cf980> (a java.lang.Object)
-       at org.mortbay.jetty.nio.SelectChannelConnector.close(SelectChannelConnector.java:136)
-       - locked <0x8b8c0150> (a org.mortbay.jetty.nio.SelectChannelConnector)
-       at org.mortbay.jetty.AbstractConnector$Acceptor.run(AbstractConnector.java:735)
-       at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)
-"main":
-       at org.mortbay.jetty.nio.SelectChannelConnector.getLocalPort(SelectChannelConnector.java:188)
-       - waiting to lock <0x8b8c0150> (a org.mortbay.jetty.nio.SelectChannelConnector)
-       at org.mortbay.jetty.AbstractConnector.toString(AbstractConnector.java:669)
-       at java.lang.String.valueOf(String.java:2826)
-       at java.lang.StringBuffer.append(StringBuffer.java:219)
-       - locked <0x8b7e8618> (a java.lang.StringBuffer)
-       at org.slf4j.helpers.MessageFormatter.deeplyAppendParameter(MessageFormatter.java:237)
-       at org.slf4j.helpers.MessageFormatter.arrayFormat(MessageFormatter.java:196)
-       at ch.qos.logback.classic.spi.LoggingEvent.getFormattedMessage(LoggingEvent.java:282)
-       at ch.qos.logback.classic.pattern.MessageConverter.convert(MessageConverter.java:22)
-       at ch.qos.logback.classic.pattern.MessageConverter.convert(MessageConverter.java:19)
-       at ch.qos.logback.core.pattern.FormattingConverter.write(FormattingConverter.java:32)
-       at ch.qos.logback.core.pattern.PatternLayoutBase.writeLoopOnConverters(PatternLayoutBase.java:110)
-       at ch.qos.logback.classic.PatternLayout.doLayout(PatternLayout.java:132)
-       at ch.qos.logback.classic.PatternLayout.doLayout(PatternLayout.java:51)
-       at ch.qos.logback.core.WriterAppender.subAppend(WriterAppender.java:261)
-       at ch.qos.logback.core.WriterAppender.append(WriterAppender.java:114)
-       at ch.qos.logback.core.AppenderBase.doAppend(AppenderBase.java:87)
-       - locked <0x8be33f88> (a ch.qos.logback.core.ConsoleAppender)
-       at ch.qos.logback.core.spi.AppenderAttachableImpl.appendLoopOnAppenders(AppenderAttachableImpl.java:60)
-       at ch.qos.logback.classic.Logger.appendLoopOnAppenders(Logger.java:270)
-       at ch.qos.logback.classic.Logger.callAppenders(Logger.java:257)
-       at ch.qos.logback.classic.Logger.buildLoggingEventAndAppend(Logger.java:439)
-       at ch.qos.logback.classic.Logger.filterAndLog_2(Logger.java:430)
-       at ch.qos.logback.classic.Logger.info(Logger.java:605)
-       at org.mortbay.log.Slf4jLog.info(Slf4jLog.java:67)
-       at org.mortbay.log.Log.info(Log.java:154)
-       at org.mortbay.jetty.AbstractConnector.doStop(AbstractConnector.java:313)
-       at org.mortbay.jetty.nio.SelectChannelConnector.doStop(SelectChannelConnector.java:326)
-       at org.mortbay.component.AbstractLifeCycle.stop(AbstractLifeCycle.java:76)
-       - locked <0x8b8ce798> (a java.lang.Object)
-       at org.mortbay.jetty.Server.doStop(Server.java:280)
-       at org.mortbay.component.AbstractLifeCycle.stop(AbstractLifeCycle.java:76)
-       - locked <0x8b8cf7b8> (a java.lang.Object)
-       at org.mortbay.jetty.testing.ServletTester.stop(ServletTester.java:92)
-       at org.sonar.api.utils.HttpDownloaderTest.stopServer(HttpDownloaderTest.java:62)
-       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
-       at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
-       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
-       at java.lang.reflect.Method.invoke(Method.java:597)
-       at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
-       at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
-       at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
-       at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:37)
-       at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76)
-       at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
-       at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
-       at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
-       at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
-       at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
-       at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
-       at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
-       at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:59)
-       at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.executeTestSet(AbstractDirectoryTestSuite.java:120)
-       at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.execute(AbstractDirectoryTestSuite.java:103)
-       at org.apache.maven.surefire.Surefire.run(Surefire.java:169)
-       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
-       at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
-       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
-       at java.lang.reflect.Method.invoke(Method.java:597)
-       at org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:350)
-       at org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:1021)
-
-
-
-       For this reason the ugly workaround is to wait the end of the thread before stopping...
-
-       We'll have to check if Jetty 7 resolves this toString() issue.
-    */
-    if (tester != null) {
-      Thread.sleep(1000);
-      tester.stop();
+  public static void stopServer() throws IOException {
+    if (null != socketConnection) {
+      socketConnection.close();
     }
   }
 
   @Test
-  public void downloadBytes() throws Exception {
+  public void downloadBytes() throws URISyntaxException {
     byte[] bytes = new HttpDownloader(new Settings()).readBytes(new URI(baseUrl));
     assertThat(bytes.length).isGreaterThan(10);
   }
 
   @Test
-  public void readString() throws Exception {
+  public void readString() throws URISyntaxException {
     String text = new HttpDownloader(new Settings()).readString(new URI(baseUrl), Charsets.UTF_8);
     assertThat(text.length()).isGreaterThan(10);
   }
 
   @Test(expected = SonarException.class)
-  public void failIfServerDown() throws Exception {
+  public void failIfServerDown() throws URISyntaxException {
     // I hope that the port 1 is not used !
     new HttpDownloader(new Settings()).readBytes(new URI("http://localhost:1/unknown"));
   }
 
   @Test
   public void downloadToFile() throws URISyntaxException, IOException {
-    File toDir = new File("target/test-tmp/org/sonar/api/utils/DownloaderTest/");
-    FileUtils.forceMkdir(toDir);
-    FileUtils.cleanDirectory(toDir);
+    File toDir = temporaryFolder.newFolder();
     File toFile = new File(toDir, "downloadToFile.txt");
 
     new HttpDownloader(new Settings()).download(new URI(baseUrl), toFile);
@@ -191,9 +119,7 @@ public class HttpDownloaderTest {
 
   @Test
   public void shouldNotCreateFileIfFailToDownload() throws Exception {
-    File toDir = new File("target/test-tmp/org/sonar/api/utils/DownloaderTest/");
-    FileUtils.forceMkdir(toDir);
-    FileUtils.cleanDirectory(toDir);
+    File toDir = temporaryFolder.newFolder();
     File toFile = new File(toDir, "downloadToFile.txt");
 
     try {
@@ -209,29 +135,31 @@ public class HttpDownloaderTest {
     Server server = mock(Server.class);
     when(server.getVersion()).thenReturn("2.2");
 
-    byte[] bytes = new HttpDownloader(server, new Settings()).readBytes(new URI(baseUrl));
+    InputStream stream = new HttpDownloader(server, new Settings()).openStream(new URI(baseUrl));
     Properties props = new Properties();
-    props.load(IOUtils.toInputStream(new String(bytes)));
+    props.load(stream);
+    stream.close();
+
     assertThat(props.getProperty("agent")).isEqualTo("Sonar 2.2");
   }
 
   @Test
   public void followRedirect() throws URISyntaxException {
-    byte[] bytes = new HttpDownloader(new Settings()).readBytes(new URI(baseUrl + "/redirect/"));
-    assertThat(new String(bytes)).contains("count");
+    String content = new HttpDownloader(new Settings()).readString(new URI(baseUrl + "/redirect/"), Charsets.UTF_8);
+    assertThat(content).contains("agent");
   }
 
   @Test
   public void shouldGetDirectProxySynthesis() throws URISyntaxException {
     ProxySelector proxySelector = mock(ProxySelector.class);
-    when(proxySelector.select((URI) anyObject())).thenReturn(Arrays.asList(Proxy.NO_PROXY));
+    when(proxySelector.select(any(URI.class))).thenReturn(Arrays.asList(Proxy.NO_PROXY));
     assertThat(HttpDownloader.getProxySynthesis(new URI("http://an_url"), proxySelector)).isEqualTo("no proxy");
   }
 
   @Test
   public void shouldGetProxySynthesis() throws URISyntaxException {
     ProxySelector proxySelector = mock(ProxySelector.class);
-    when(proxySelector.select((URI) anyObject())).thenReturn(Arrays.asList((Proxy) new FakeProxy()));
+    when(proxySelector.select(any(URI.class))).thenReturn(Arrays.<Proxy> asList(new FakeProxy()));
     assertThat(HttpDownloader.getProxySynthesis(new URI("http://an_url"), proxySelector)).isEqualTo("proxy: http://proxy_url:4040");
   }
 
@@ -241,9 +169,8 @@ public class HttpDownloaderTest {
   }
 
   @Test
-  public void uri_description() throws Exception {
-    HttpDownloader downloader = new HttpDownloader(new Settings());
-    String description = downloader.description(new URI("http://sonarsource.org"));
+  public void uri_description() throws URISyntaxException {
+    String description = new HttpDownloader(new Settings()).description(new URI("http://sonarsource.org"));
     assertThat(description).matches("http://sonarsource.org \\(.*\\)");
   }
 }
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/utils/RedirectServlet.java b/sonar-plugin-api/src/test/java/org/sonar/api/utils/RedirectServlet.java
deleted file mode 100644 (file)
index ff7a0de..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * Sonar is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * Sonar is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Sonar; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
- */
-package org.sonar.api.utils;
-
-import javax.servlet.GenericServlet;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-
-public class RedirectServlet extends GenericServlet {
-
-  @Override
-  public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
-    ((HttpServletResponse)response).sendRedirect("/");
-  }
-}
-