Projet

Général

Profil

0001-kill-phantomjs-if-stalled-14606.patch

Josué Kouka, 27 janvier 2017 07:23

Télécharger (4,11 ko)

Voir les différences:

Subject: [PATCH] kill phantomjs if stalled (#14606)

 mandayejs/mandaye/utils.py | 60 +++++++++++++++++++++++++++++-----------------
 tests/test_mandayejs.py    | 17 +++++++++++++
 2 files changed, 55 insertions(+), 22 deletions(-)
mandayejs/mandaye/utils.py
17 17
import json
18 18
import subprocess
19 19
import logging
20
import multiprocessing
20 21

  
21 22
from django.conf import settings
22 23

  
......
28 29

  
29 30

  
30 31
def exec_phantom(data, script='do_login.js'):
31
    phantom = subprocess.Popen([
32
        settings.PHANTOM_JS_BINARY,
33
        '--ignore-ssl-errors=yes', '--ssl-protocol=any',
34
        os.path.join(settings.BASE_DIR, 'mandayejs', script)],
35
        close_fds=True,
36
        stdin=subprocess.PIPE,
37
        stdout=subprocess.PIPE
38
    )
32
    result = None
33
    waiting_time = getattr(settings, 'PHANTOM_JS_WAITING_TIME', 10)
34

  
35
    def run(send_end):
36
        phantom = subprocess.Popen([
37
            settings.PHANTOM_JS_BINARY,
38
            '--ignore-ssl-errors=yes', '--ssl-protocol=any',
39
            os.path.join(settings.BASE_DIR, 'mandayejs', script)],
40
            close_fds=True,
41
            stdin=subprocess.PIPE,
42
            stdout=subprocess.PIPE
43
        )
44
        stdout, stderr = phantom.communicate(json.dumps(data))
45

  
46
        try:
47
            result = json.loads(stdout)
48
        except (ValueError,):
49
            result = {"result": "failure, couldn't decode JSON"}
50
            logger.error(stdout)
51

  
52
        if result.get('stderr', None):
53
            logger.warning(result['stderr'])
54

  
55
        send_end.send(result)
56

  
57
    recv_end, send_end = multiprocessing.Pipe(False)
58
    process = multiprocessing.Process(target=run, args=(send_end,))
59
    process.start()
60
    process.join(waiting_time)
61

  
62
    if process.is_alive():
63
        process.terminate()
64
        data.pop('locators')
65
        logger.error("Phantomjs process stalled with conetext : %s" % data)
66
        result = {'result': 'failure'}
67
    else:
68
        result = recv_end.recv()
39 69

  
40
    stdout, stderr = phantom.communicate(json.dumps(data))
41

  
42
    try:
43
        result = json.loads(stdout)
44
    except (ValueError,):
45
        result = {"result": "failure, couldn't decode JSON"}
46
        logger.error(stdout)
47

  
48
        # only kill process if it's still running
49
        if phantom.poll() is None:
50
            phantom.terminate()
51

  
52
    if result.get('stderr'):
53
        logger.warning(result['stderr'])
54 70
    return result
55 71

  
56 72

  
tests/test_mandayejs.py
1 1
# -*- coding: utf-8 -*-
2 2

  
3 3
import json
4
import time
4 5
import mock
5 6
import pytest
6 7

  
......
47 48

  
48 49

  
49 50
class MockedPopen(mock.Mock):
51
    stall_for = False
50 52

  
51 53
    def communicate(self, data):
54
        if self.stall_for:
55
            print(self.stall_for)
56
            time.sleep(13)
52 57
        return self.expected_output
53 58

  
54 59

  
......
272 277
    assert result['url'] == 'https://whatever.com/someurl'
273 278

  
274 279

  
280
@mock.patch('mandayejs.mandaye.utils.subprocess.Popen')
281
def test_phantom_js_stalled_process(mocked_popen, caplog):
282
    mocked_popen.return_value = MockedPopen(expected_output=json.dumps({'whatever': 'whatever'}), stall_for=True)
283
    result = exec_phantom(LOGIN_INFO)
284

  
285
    for record in caplog.records():
286
        assert record.levelname == 'ERROR'
287
        assert record.message == "Phantomjs process stalled with conetext : {'cookies': [], 'form_submit_element': 'input[type=submit], button', 'auth_checker': 'tenants/static/js/auth.checker.js', 'address': 'https://whatever.com'}"
288

  
289
    assert result['result'] == 'failure'
290

  
291

  
275 292
@mock.patch('mandayejs.applications.Test.SITE_LOCATORS', MOCKED_SITE_LOCATORS)
276 293
def test_credentials_json_encoding(user_john):
277 294

  
278
-