2012-08-03 18 views
6

मैं अपने प्रोग्राम के विभिन्न रन-थ्रू के परीक्षणों को अनुकरण करने की कोशिश कर रहा हूं, @Before विधि में जेटी सर्वर स्थापित करना और @After में इसे बंद करना।जुनीट परीक्षणों के बीच जेटी सर्वर को शुरू करना और रोकना

मेरा पहला परीक्षण सफलतापूर्वक चलाया जाएगा, लेकिन निम्नलिखित परीक्षणों में POST डेटा का प्रयास करने पर com.sun.jersey.api.client.ClientHandlerException: java.net.SocketException: Software caused connection abort: recv failed होता है। परीक्षण के बीच साफ-सफाई बंद करने के लिए क्या कोई तरीका है कि मैं अपना सर्वर (और क्लाइंट?) प्राप्त कर सकता हूं?

मेरे पहले और कोड के बाद इस प्रकार है:

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

उत्तर

8

परीक्षण परिदृश्यों में सर्वोत्तम अभ्यास पोर्ट को हार्ड कोड नहीं करना है। इससे कहीं और चलने पर संघर्ष होता है, खासकर सीआई सिस्टम पर जिनके पास मध्यम भार या परियोजनाओं की विविधता भी होती है।

जेट्टी 9 में

(6 में एक ही विचार, 7, 8)

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

बहुत बढ़िया, यह मेरे लिए काम करता है! – hsestupin

+0

जेटी 6 के लिए मुझे SelectChannelConnector का उपयोग करना पड़ा (सर्वर कनेक्टर मौजूद नहीं है)। – Dennie

-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

2

यह पता चला है कि वास्तव में जो काम कर रहा था, हालांकि server.stop() की असीमित प्रकृति के कारण, मेरा नया सर्वर पिछले सर्वर के बंद डाउन थ्रेड को पूरी तरह से निष्पादित करने से पहले तुरंत चालू करने का प्रयास कर रहा था।

server.stop() के बाद एक साधारण Thread.sleep(n) सर्वर को परीक्षण के बीच बंद करने की आवश्यकता देता है। दुर्भाग्यवश, सर्वर समय-समय पर दावा करता है कि इसने सर्वर स्थिति की जांच के माध्यम से एक सटीक समाधान को रोक दिया है - लेकिन शायद सर्वर पर मतदान करने के लिए कुछ है; संभवतः थ्रेड पूल की जांच करना एक निरंतर परिणाम प्रदान कर सकता है?

किसी भी मामले में, यह केवल परीक्षण के लिए है, केवल @BeforeClass में सर्वर शुरू करने और @AfterClass में यह नीचे बंद के रूप में होने से बचाता है पूरे सर्वर kerfuffle शट डाउन है, लेकिन फिर में एक ही बंदरगाह पर किसी अन्य सर्वर शुरू करने से सावधान अपने परीक्षण सूट।

+0

आप शायद सिर्फ 'server.join उपयोग करना चाहते हैं()' इसे रोकने के लिए के लिए इंतजार करना। –

-1

मुझे एहसास है कि यह सीधे आपके प्रश्न का उत्तर नहीं देता है ... लेकिन @Before और @After में सर्वर को शुरू करना और रोकना अक्षम है जब आपके पास एक से अधिक एकीकरण परीक्षण है जिसके लिए सर्वर को चलने की आवश्यकता होती है, सर्वर के रूप में प्रत्येक परीक्षण के लिए पुनरारंभ किया जाएगा।

आप अपने सर्वर को अपने पूरे परीक्षण के आस-पास शुरू करने और रोकने पर विचार करना चाहेंगे। यदि आप मेवेन का निर्माण करने के लिए उपयोग कर रहे हैं, तो आप इसे असफलता और जेटी प्लगइन के संयोजन से कर सकते हैं।

+0

Failsafe के साथ जेटी का उपयोग करने के उदाहरण के लिए http://maven.apache.org/plugins/maven-failsafe-plugin/usage.html देखें। – Kkkev

0

मेरा अनुमान है कि यह एक बंदरगाह संघर्ष प्राप्त कर रहा था। हम वास्तव में हमारे परीक्षणों के लिए ऐसा करते हैं, और आश्चर्यजनक रूप से प्रदर्शन हिट वह बुरा नहीं है। उत्तर के सुझाव के अनुसार हमने सभी परीक्षणों से पहले एक सर्वर शुरू करके शुरू किया, लेकिन हमें उत्परिवर्तन परीक्षण का समर्थन करने के लिए स्विच करना पड़ा। मेवेन पर भरोसा करने के लिए एक नकारात्मक पक्ष यह है कि आपको आईडीई में एक भी परीक्षण चलाने के लिए इसे शुरू करना होगा।

रुचि रखने वाले किसी भी व्यक्ति के लिए, हमारा कार्यान्वयन यहां है: embedded-test-jetty। यह अलग-अलग बंदरगाहों (समानांतर परीक्षण के लिए) पर कई सर्वर चलाता है, पोर्ट उपलब्धता की जांच करता है, एसएसएल का समर्थन करता है, आदि

+1

इमो, यह पूछने में कोई बात नहीं है कि क्या कोई कोड समाधान में रूचि रखता है, अगर आपको लगता है कि यह प्रासंगिक है, तो बस इसे ऊपर रखो, पूछो मत :)। यदि यह बहुत लंबा है, तो आप लिंक को अपने रेपो में डाल सकते हैं। –

+0

यह सुनिश्चित नहीं था कि जब हम इसे अपने आंतरिक रेपो से बाहर ले जाने के लिए चारों ओर घूमते हैं - लेकिन यह अब वहां है :) –

0

मैं इसे कुछ चीजों का उपयोग करके संभालता हूं। सबसे पहले, प्रत्येक परीक्षण के बाद, सुनिश्चित करें कि आपका सर्वर बंद हो गया है, और join() उस पर है। आप जो भी कर रहे हैं उसके आधार पर या तो @After या @AfterClass में ऐसा करें।

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

अगला, प्रत्येक परीक्षण से पहले, सुनिश्चित करें कि बंदरगाह उपलब्ध है। मैं तो Sockets: Discover port availability using 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 अंत में सुनिश्चित करता है कि बंदरगाह उपलब्ध है बन जाता है; क्योंकि सिर्फ यह जांचना कि यह उपलब्ध है, सिस्टम को इसका पुन: उपयोग नहीं कर सकता है। एक और विकल्प यह है कि जब आप इसे चेक करने के बाद बंदरगाह खोल रहे हों तो बस SO_REUSEADDR सेट करें।