Skip to content

Commit 3de4159

Browse files
authored
Merge pull request #337 from manu-chroma/node_fix
sandboxjs.py: check for valid version of node/nodejs engine
2 parents 1354b49 + 342194b commit 3de4159

File tree

3 files changed

+74
-8
lines changed

3 files changed

+74
-8
lines changed

cwltool/sandboxjs.py

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
from io import BytesIO
99

1010
from pkg_resources import resource_stream
11-
from typing import Any, Dict, List, Mapping, Text, Union
11+
from typing import Any, Dict, List, Mapping, Text, Union, Tuple
12+
1213

1314
class JavascriptException(Exception):
1415
pass
@@ -21,6 +22,27 @@ class JavascriptException(Exception):
2122
localdata = threading.local()
2223

2324
have_node_slim = False
25+
# minimum acceptable version of nodejs engine
26+
minimum_node_version_str = '0.10.26'
27+
28+
def check_js_threshold_version(working_alias):
29+
# type: (str) -> bool
30+
31+
"""Checks if the nodeJS engine version on the system
32+
with the allowed minimum version.
33+
https://github.com/nodejs/node/blob/master/CHANGELOG.md#nodejs-changelog
34+
"""
35+
# parse nodejs version into int Tuple: 'v4.2.6\n' -> [4, 2, 6]
36+
current_version_str = subprocess.check_output(
37+
[working_alias, "-v"]).decode('ascii')
38+
39+
current_version = [int(v) for v in current_version_str.strip().strip('v').split('.')]
40+
minimum_node_version = [int(v) for v in minimum_node_version_str.split('.')]
41+
42+
if current_version >= minimum_node_version:
43+
return True
44+
else:
45+
return False
2446

2547

2648
def new_js_proc():
@@ -29,17 +51,21 @@ def new_js_proc():
2951
res = resource_stream(__name__, 'cwlNodeEngine.js')
3052
nodecode = res.read()
3153

54+
required_node_version, docker = (False,)*2
3255
nodejs = None
3356
trynodes = ("nodejs", "node")
3457
for n in trynodes:
3558
try:
3659
if subprocess.check_output([n, "--eval", "process.stdout.write('t')"]) != "t":
3760
continue
38-
nodejs = subprocess.Popen([n, "--eval", nodecode],
39-
stdin=subprocess.PIPE,
40-
stdout=subprocess.PIPE,
41-
stderr=subprocess.PIPE)
42-
break
61+
else:
62+
nodejs = subprocess.Popen([n, "--eval", nodecode],
63+
stdin=subprocess.PIPE,
64+
stdout=subprocess.PIPE,
65+
stderr=subprocess.PIPE)
66+
67+
required_node_version = check_js_threshold_version(n)
68+
break
4369
except subprocess.CalledProcessError:
4470
pass
4571
except OSError as e:
@@ -48,7 +74,7 @@ def new_js_proc():
4874
else:
4975
raise
5076

51-
if nodejs is None:
77+
if nodejs is None or nodejs is not None and required_node_version is False:
5278
try:
5379
nodeimg = "node:slim"
5480
global have_node_slim
@@ -63,6 +89,7 @@ def new_js_proc():
6389
"--sig-proxy=true", "--interactive",
6490
"--rm", nodeimg, "node", "--eval", nodecode],
6591
stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
92+
docker = True
6693
except OSError as e:
6794
if e.errno == errno.ENOENT:
6895
pass
@@ -71,12 +98,19 @@ def new_js_proc():
7198
except subprocess.CalledProcessError:
7299
pass
73100

101+
# docker failed and nodejs not on system
74102
if nodejs is None:
75103
raise JavascriptException(
76104
u"cwltool requires Node.js engine to evaluate Javascript "
77105
"expressions, but couldn't find it. Tried %s, docker run "
78106
"node:slim" % u", ".join(trynodes))
79107

108+
# docker failed, but nodejs is installed on system but the version is below the required version
109+
if docker is False and required_node_version is False:
110+
raise JavascriptException(
111+
u'cwltool requires minimum v{} version of Node.js engine.'.format(minimum_node_version_str),
112+
u'Try updating: https://docs.npmjs.com/getting-started/installing-node')
113+
80114
return nodejs
81115

82116

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
'extensions.yml']},
5353
include_package_data=True,
5454
install_requires=[
55+
'mock >= 2.0.0',
5556
'setuptools',
5657
'requests >= 1.0',
5758
'ruamel.yaml >= 0.12.4',
@@ -60,7 +61,6 @@
6061
'schema-salad >= 2.4.20170308171942, < 3',
6162
'typing >= 3.5.2, < 3.6',
6263
'six >= 1.8.0',
63-
6464
],
6565
setup_requires=[] + pytest_runner,
6666
test_suite='tests',

tests/test_js_sandbox.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import unittest
2+
from mock import Mock, patch
3+
4+
# we should modify the subprocess imported from cwltool.sandboxjs
5+
from cwltool.sandboxjs import check_js_threshold_version, subprocess, minimum_node_version_str
6+
7+
class Javascript_Sanity_Checks(unittest.TestCase):
8+
9+
def setUp(self):
10+
self.check_output = subprocess.check_output
11+
12+
def tearDown(self):
13+
subprocess.check_output = self.check_output
14+
15+
def test_node_version(self):
16+
subprocess.check_output = Mock(return_value=b'v0.8.26\n')
17+
self.assertEquals(check_js_threshold_version('node'), False)
18+
19+
subprocess.check_output = Mock(return_value=b'v0.10.25\n')
20+
self.assertEquals(check_js_threshold_version('node'), False)
21+
22+
subprocess.check_output = Mock(return_value=b'v0.10.26\n')
23+
self.assertEquals(check_js_threshold_version('node'), True)
24+
25+
subprocess.check_output = Mock(return_value=b'v4.4.2\n')
26+
self.assertEquals(check_js_threshold_version('node'), True)
27+
28+
subprocess.check_output = Mock(return_value=b'v7.7.3\n')
29+
self.assertEquals(check_js_threshold_version('node'), True)
30+
31+
def test_is_javascript_installed(self):
32+
pass

0 commit comments

Comments
 (0)