Starting and stopping the Jetty server between JUnit tests

I am trying to simulate tests of various runs of my program by setting up the Jetty server in the @Before method and closing it in @After .

My first test will work successfully, but when trying to get POST data in the following tests com.sun.jersey.api.client.ClientHandlerException: java.net.SocketException: Software caused connection abort: recv failed will happen. Is there any way to force my server (and client?) To completely shut down between tests?

My code before and after:

 @Before public void startServer() { try { server = new Server(8080); ServletContextHandler root = new ServletContextHandler(server, "/ingest", ServletContextHandler.SESSIONS); root.addServlet(new Servlet(), "/*"); server.start(); client = new Client(); client.setChunkedEncodingSize(16 * 1024); FileInputStream stream = new FileInputStream(testFile); try { client.resource(uri).type(MediaType.APPLICATION_OCTET_STREAM).post(stream); } catch (Exception e) { e.printStackTrace(); } finally { Closeables.closeQuietly(stream); client.destroy(); } } catch (Exception e) { e.printStackTrace(); fail("Unexpected Exception when starting up server."); } } @After public void shutDown() { if (output.exists()) { output.delete(); } try { server.stop(); } catch (Exception e) { e.printStackTrace(); } } 
+6
source share
6 answers

Best practice in test scenarios is not hard port code. This only leads to conflicts when working in other places, especially in CI systems that have even moderate workloads or various projects.

in Jetty 9 (same idea in 6, 7, 8)

 _server = new Server(); _connector = new ServerConnector(_server); _server.setConnectors(new Connector[] { _connector }); _server.start(); int port = _connector.getLocalPort(); 
+8
source

It turned out that what I actually worked for, however, due to the asynchronous nature of server.stop() , my new server was trying to create an instance before the previous thread of the completed server ended.

The simple Thread.sleep(n) after server.stop() gives the server the time it takes to close between tests. Unfortunately, the server, apparently, prematurely claims that it stopped, thereby preventing an exact solution by checking the status of the server - but perhaps there is something to interrogate on the server; perhaps studying a thread pool can provide a consistent result?

In any case, since this is only for testing purposes, just starting the server in @BeforeClass and closing it in @AfterClass prevents the cedar from shutting down completely, but beware then starting another server on the same port in your test package.

+2
source

I assume this caused a port conflict. We really do this for our tests, and surprisingly, the performance hit is not so bad. We started by starting one server before all tests, as the answer suggests, but we had to switch to support mutation testing. One drawback to relying on Maven is that you need to run it on the side to run a single test in the IDE.

For anyone interested, our implementation is here: embedded-test-jetty . It starts several servers on different ports at once (for parallel testing), checks for ports, supports SSL, etc.

0
source

I handle this using a couple of things. First, after each test, make sure your server is turned off and join() on it. Either do it in @After or @AfterClass depending on what you are doing.

 server.stop(); server.join(); 

Then, before each test, make sure the port is accessible. I am using a snippet available on Sockets: find out port availability using Java

Then the installation code becomes

 public static void waitForPort(int port) { while( !available(port) ) { try { Thread.sleep(PORT_SLEEP_MILLIS); } catch (InterruptedException e) {} } } @Before public void setUp() throws Exception { waitForPort(9876); waitForPort(9877); // Make sure the ports are clear Thread.sleep(500); } 

A little extra sleep at the end ensures that the port is accessible; because just checking that it is available can cause the system not to reuse it. Another option is to simply set SO_REUSEADDR when you open the port after checking it.

0
source

Try:

 server = new Server(); SocketConnector connector = new SocketConnector(); connector.setPort(8080); server.setConnectors(new Connector[] { connector }); WebAppContext context = new WebAppContext(); context.setServer(server); context.setContextPath("/your-context"); context.setWar("path to war"); server.addHandler(context); Thread monitor = new MonitorThread(); monitor.start(); server.start(); server.join(); 

then somewhere you say:

  server.stop() 

Useful article:
http://www.codeproject.com/Articles/128145/Run-Jetty-Web-Server-Within-Your-Application

-1
source

I understand that this does not directly answer your question ... but starting and stopping the server in the @Before and @After ineffective if you have more than one integration test that requires the server to start, since the server will be restarted for each test.

You might want to consider starting and stopping the server throughout the test suite. If you use Maven to build, you can do this with a combination of failover and Jetty plugins.

-1
source

Source: https://habr.com/ru/post/922037/


All Articles