9

プログラムのさまざまなランスルーのテストをシミュレートしようとしています。@BeforeメソッドでJettyサーバーをセットアップし、で閉じ@Afterます。

最初のテストは正常に実行されますが、次のテストでデータをPOSTしようとするとcom.sun.jersey.api.client.ClientHandlerException: java.net.SocketException: Software caused connection abort: recv failed発生します。テストの合間にサーバー(およびクライアント)を正常にシャットダウンする方法はありますか?

私のBeforeと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();
    }
}
4

6 に答える 6

8

シナリオをテストする際のベストプラクティスは、ポートをハードコーディングしないことです。これは、他の場所で実行する場合、特に中程度の負荷やさまざまなプロジェクトがあるCIシステムでのみ競合を引き起こします。

Jetty 9で(6、7、8でも同じ考え)

_server = new Server();
_connector = new ServerConnector(_server);  
_server.setConnectors(new Connector[] { _connector });
_server.start();
int port = _connector.getLocalPort();
于 2013-04-19T20:00:51.147 に答える
2

私が持っていたものは実際には機能していたことがわかりましたが、の非同期性のためserver.stop()に、前のサーバーのシャットダウンスレッドが完全に実行される前に、新しいサーバーがインスタンス化を試みていました。

Thread.sleep(n)後の単純なものserver.stop()は、サーバーがテスト間でシャットダウンするのに必要な時間を与えます。残念ながら、サーバーはサーバーの状態をチェックすることで正確な解決策を妨げているため、サーバーが停止したと時期尚早に主張しているようですが、サーバーでポーリングするものがある可能性があります。スレッドプールを調べると、一貫した結果が得られる可能性がありますか?

いずれにせよ、これはテスト目的のみであるため、でサーバーを起動して@BeforeClassシャットダウンするだけで、サーバー@AfterClass全体がkerfuffleをシャットダウンするのを防ぐことができますが、テストスイートの同じポートで別のサーバーを起動することに注意してください。

于 2012-08-03T14:08:08.773 に答える
0

私はこれをいくつかの方法で処理します。まず、各テストの後で、サーバーがシャットダウンjoin()されていることを確認します。これを実行するか、実行し@After@AfterClassいる内容に応じて実行します。

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

次に、各テストの前に、ポートが使用可能であることを確認します。Socketsで入手可能なスニペットを使用します:Javaを使用してポートの可用性を検出します

すると、セットアップコードは

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);
}

最後に少し余分sleepに追加すると、ポートが使用可能になります。利用可能かどうかを確認するだけで、システムが再利用できなくなる可能性があるためです。もう1つのオプションはSO_REUSEADDR、ポートをチェックした後、ポートを開いているときに設定することです。

于 2013-03-06T06:54:42.703 に答える
0

私の推測では、ポートの競合が発生していました。私たちは実際にテストのためにこれを行いますが、驚くべきことに、パフォーマンスへの影響はそれほど悪くありません。答えが示すように、すべてのテストの前に単一のサーバーを起動することから始めましたが、ミューテーションテストをサポートするように切り替える必要がありました。Mavenに依存することの1つの欠点は、IDEで単一のテストを実行するためにMavenをサイドで起動する必要があることです。

興味のある人のために、私たちの実装はここにあります:embedded-test-jetty。異なるポートで一度に複数のサーバーを実行し(並列テスト用)、ポートの可用性をチェックし、SSLをサポートします。

于 2012-09-28T23:01:01.633 に答える
-1

試す:

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();

それからどこかであなたは言う:

    server.stop()

役立つ記事: http:
//www.codeproject.com/Articles/128145/Run-Jetty-Web-Server-Within-Your-Application

于 2012-08-03T11:31:17.397 に答える
-1

これはあなたの質問に直接答えるものではないことを理解しています...しかし、サーバーを実行する必要がある統合テストが複数ある場合、サーバーはテストごとに再起動されるため、サーバーの起動と停止、@Beforeおよびメソッドは非効率的です。 @After

テストスイート全体でサーバーの起動と停止を検討することをお勧めします。ビルドにMavenを使用している場合は、フェイルセーフプラグインとJettyプラグインを組み合わせてこれを行うことができます。

于 2012-08-04T09:50:22.587 に答える