# Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance # with the License. A copy of the License is located at http://aws.amazon.com/apache2.0/ # or in the "LICENSE.txt" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES # OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions and # limitations under the License. import logging import subprocess import pytest from assertpy import assert_that from pcluster.api import util class TestParallelClusterApiUtil: @pytest.mark.parametrize( "version, error, expected_message", [ ("13.7.0", None, None), ("10.13.0", None, None), ("v18.12.0", None, None), ("10.1.0", Exception(), "requires Node.js version >="), ("13.0.0", Exception(), "Node.js version 13.0.0 is within this range"), ("13.6.0", Exception(), "Node.js version 13.6.0 is within this range"), (Exception(), Exception(), "Unable to check Node.js version"), ], ) def test_assert_node_version(self, mocker, version, error, expected_message): if isinstance(version, Exception): check_output_mock = mocker.patch("pcluster.api.util.subprocess.check_output", side_effect=Exception) with pytest.raises(Exception) as exc: util._assert_node_version() check_output_mock.assert_has_calls( [ mocker.call((["node", "--version"]), stderr=subprocess.STDOUT, encoding="utf-8", shell=False), mocker.call((["nvm", "current"]), stderr=subprocess.STDOUT, encoding="utf-8", shell=False), ] ) assert_that(str(exc.value)).matches(expected_message) else: check_output_mock = mocker.patch("pcluster.api.util.subprocess.check_output", return_value=version) if isinstance(error, Exception): with pytest.raises(Exception) as exc: util._assert_node_version() assert_that(str(exc.value)).matches(expected_message) else: util._assert_node_version() check_output_mock.assert_called_once_with( (["node", "--version"]), stderr=subprocess.STDOUT, encoding="utf-8", shell=False ) @pytest.mark.parametrize( "version, expected_message", [ ("v18.12.0", "Unable to invoke Node.js for the installed version v18.12.0."), ("v16.16.0", "Unable to invoke Node.js for the installed version v16.16.0."), ("none", "Node.js does not appear to be installed."), ], ) def test_assert_node_version_fallback_to_nvm(self, mocker, caplog, version, expected_message): check_output_mock = mocker.patch("pcluster.api.util.subprocess.check_output") check_output_mock.side_effect = [Exception, version] with pytest.raises(Exception) as exc: util._assert_node_version() assert_that(str(exc.value)).starts_with(expected_message) check_output_mock.assert_has_calls( [ mocker.call((["node", "--version"]), stderr=subprocess.STDOUT, encoding="utf-8", shell=False), mocker.call((["nvm", "current"]), stderr=subprocess.STDOUT, encoding="utf-8", shell=False), ] ) warnings = [record for record in caplog.records if record.levelno == logging.CRITICAL] assert_that(warnings).is_length(1) assert_that(warnings[0].message).starts_with(expected_message)