11import os
2+ from subprocess import Popen
23from unittest import TestCase
34
45from mock import patch , call , Mock
6+ from psutil import Process
57
68from .. import Consumer , Provider , pact
79from ..constants import MOCK_SERVICE_PATH
@@ -208,17 +210,24 @@ def setUp(self):
208210 self .addCleanup (patch .stopall )
209211 self .mock_Popen = patch .object (pact , 'Popen' , autospec = True ).start ()
210212 self .mock_Popen .return_value .returncode = 0
213+ self .mock_Process = patch .object (
214+ pact .psutil , 'Process' , autospec = True ).start ()
215+ self .mock_platform = patch .object (
216+ pact .platform , 'platform' , autospec = True ).start ()
217+ self .mock_wait_for_server_start = patch .object (
218+ pact .Pact , '_wait_for_server_start' , autospec = True ).start ()
211219
212220 def test_start_fails (self ):
213221 self .mock_Popen .return_value .returncode = 1
222+ self .mock_wait_for_server_start .side_effect = RuntimeError
214223 pact = Pact (Consumer ('consumer' ), Provider ('provider' ),
215224 log_dir = '/logs' , pact_dir = '/pacts' )
216225
217226 with self .assertRaises (RuntimeError ):
218227 pact .start_service ()
219228
220229 self .mock_Popen .assert_called_once_with ([
221- MOCK_SERVICE_PATH , 'start ' ,
230+ MOCK_SERVICE_PATH , 'service ' ,
222231 '--host=localhost' ,
223232 '--port=1234' ,
224233 '--log' , '/logs/pact-mock-service.log' ,
@@ -227,15 +236,13 @@ def test_start_fails(self):
227236 '--consumer' , 'consumer' ,
228237 '--provider' , 'provider' ])
229238
230- self .mock_Popen .return_value .communicate .assert_called_once_with ()
231-
232239 def test_start_no_ssl (self ):
233240 pact = Pact (Consumer ('consumer' ), Provider ('provider' ),
234241 log_dir = '/logs' , pact_dir = '/pacts' )
235242 pact .start_service ()
236243
237244 self .mock_Popen .assert_called_once_with ([
238- MOCK_SERVICE_PATH , 'start ' ,
245+ MOCK_SERVICE_PATH , 'service ' ,
239246 '--host=localhost' ,
240247 '--port=1234' ,
241248 '--log' , '/logs/pact-mock-service.log' ,
@@ -244,16 +251,14 @@ def test_start_no_ssl(self):
244251 '--consumer' , 'consumer' ,
245252 '--provider' , 'provider' ])
246253
247- self .mock_Popen .return_value .communicate .assert_called_once_with ()
248-
249254 def test_start_with_ssl (self ):
250255 pact = Pact (Consumer ('consumer' ), Provider ('provider' ),
251256 log_dir = '/logs' , pact_dir = '/pacts' ,
252257 ssl = True , sslcert = '/ssl.cert' , sslkey = '/ssl.key' )
253258 pact .start_service ()
254259
255260 self .mock_Popen .assert_called_once_with ([
256- MOCK_SERVICE_PATH , 'start ' ,
261+ MOCK_SERVICE_PATH , 'service ' ,
257262 '--host=localhost' ,
258263 '--port=1234' ,
259264 '--log' , '/logs/pact-mock-service.log' ,
@@ -265,25 +270,86 @@ def test_start_with_ssl(self):
265270 '--sslcert' , '/ssl.cert' ,
266271 '--sslkey' , '/ssl.key' ])
267272
268- self .mock_Popen .return_value .communicate .assert_called_once_with ()
273+ def test_stop_posix (self ):
274+ self .mock_platform .return_value = 'Linux'
275+ pact = Pact (Consumer ('consumer' ), Provider ('provider' ))
276+ pact ._process = Mock (spec = Popen , pid = 999 , returncode = 0 )
277+ pact .stop_service ()
278+
279+ pact ._process .terminate .assert_called_once_with ()
280+ pact ._process .communicate .assert_called_once_with ()
281+ self .assertFalse (self .mock_Process .called )
269282
270- def test_stop (self ):
283+ def test_stop_windows (self ):
284+ self .mock_platform .return_value = 'Windows'
285+ ruby_exe = Mock (spec = Process )
286+ self .mock_Process .return_value .children .return_value = [ruby_exe ]
271287 pact = Pact (Consumer ('consumer' ), Provider ('provider' ))
288+ pact ._process = Mock (spec = Popen , pid = 999 , returncode = 0 )
272289 pact .stop_service ()
273290
274- self .mock_Popen .assert_called_once_with (
275- [MOCK_SERVICE_PATH , 'stop' , '--port=1234' ])
276- self .mock_Popen .return_value .communicate .assert_called_once_with ()
291+ self .assertFalse (pact ._process .terminate .called )
292+ pact ._process .communicate .assert_called_once_with ()
293+ self .mock_Process .assert_called_once_with (999 )
294+ self .mock_Process .return_value .children .assert_called_once_with (
295+ recursive = True )
296+ ruby_exe .terminate .assert_called_once_with ()
277297
278298 def test_stop_fails (self ):
279299 self .mock_Popen .return_value .returncode = 1
280300 pact = Pact (Consumer ('consumer' ), Provider ('provider' ))
301+ pact ._process = Mock (spec = Popen , pid = 999 , returncode = 1 )
281302 with self .assertRaises (RuntimeError ):
282303 pact .stop_service ()
283304
284- self .mock_Popen .assert_called_once_with (
285- [MOCK_SERVICE_PATH , 'stop' , '--port=1234' ])
286- self .mock_Popen .return_value .communicate .assert_called_once_with ()
305+ pact ._process .terminate .assert_called_once_with ()
306+ pact ._process .communicate .assert_called_once_with ()
307+
308+
309+ class PactWaitForServerStartTestCase (TestCase ):
310+ def setUp (self ):
311+ super (PactWaitForServerStartTestCase , self ).setUp ()
312+ self .addCleanup (patch .stopall )
313+ self .mock_HTTPAdapter = patch .object (
314+ pact , 'HTTPAdapter' , autospec = True ).start ()
315+ self .mock_Retry = patch .object (pact , 'Retry' , autospec = True ).start ()
316+ self .mock_Session = patch .object (
317+ pact .requests , 'Session' , autospec = True ).start ()
318+
319+ def test_wait_for_server_start_success (self ):
320+ self .mock_Session .return_value .get .return_value .status_code = 200
321+ pact = Pact (Consumer ('consumer' ), Provider ('provider' ))
322+ pact ._process = Mock (spec = Popen )
323+ pact ._wait_for_server_start ()
324+
325+ session = self .mock_Session .return_value
326+ session .mount .assert_called_once_with (
327+ 'http://' , self .mock_HTTPAdapter .return_value )
328+ session .get .assert_called_once_with (
329+ 'http://localhost:1234' , headers = {'X-Pact-Mock-Service' : 'true' })
330+ self .mock_HTTPAdapter .assert_called_once_with (
331+ max_retries = self .mock_Retry .return_value )
332+ self .mock_Retry .assert_called_once_with (total = 15 , backoff_factor = 0.1 )
333+ self .assertFalse (pact ._process .communicate .called )
334+ self .assertFalse (pact ._process .terminate .called )
335+
336+ def test_wait_for_server_start_failure (self ):
337+ self .mock_Session .return_value .get .return_value .status_code = 500
338+ pact = Pact (Consumer ('consumer' ), Provider ('provider' ))
339+ pact ._process = Mock (spec = Popen )
340+ with self .assertRaises (RuntimeError ):
341+ pact ._wait_for_server_start ()
342+
343+ session = self .mock_Session .return_value
344+ session .mount .assert_called_once_with (
345+ 'http://' , self .mock_HTTPAdapter .return_value )
346+ session .get .assert_called_once_with (
347+ 'http://localhost:1234' , headers = {'X-Pact-Mock-Service' : 'true' })
348+ self .mock_HTTPAdapter .assert_called_once_with (
349+ max_retries = self .mock_Retry .return_value )
350+ self .mock_Retry .assert_called_once_with (total = 15 , backoff_factor = 0.1 )
351+ pact ._process .communicate .assert_called_once_with ()
352+ pact ._process .terminate .assert_called_once_with ()
287353
288354
289355class PactVerifyTestCase (PactTestCase ):
0 commit comments