Files
edx-platform/pavelib/paver_tests/test_prereqs.py
Tim McCormack 437418d367 feat: Switch Dockerfile from npm install to npm ci; some cleanup (#32590)
Otherwise we're not really respecting the package-lock file and won't get
repeatable results.

Also:

- Clean up old error handling for npm<3. Were on npm 8 now. Probably
  can get rid of this.
- Use the shorthand `npm ci` rather than `npm clean-install` just for
  consistency with code elsewhere.
- Update comments in tests to be explicit about use of ci rather than
  install
2023-06-29 21:55:23 +00:00

121 lines
3.6 KiB
Python

"""
Tests covering the Open edX Paver prequisites installation workflow
"""
import os
import unittest
from unittest import mock
from unittest.mock import patch
import pytest
from paver.easy import BuildFailure
import pavelib.prereqs
from pavelib.paver_tests.utils import PaverTestCase, fail_on_npm_install, unexpected_fail_on_npm_install
class TestPaverPrereqInstall(unittest.TestCase):
"""
Test the status of the NO_PREREQ_INSTALL variable, its presence and how
paver handles it.
"""
def check_val(self, set_val, expected_val):
"""
Verify that setting the variable to a certain value returns
the expected boolean for it.
As environment variables are only stored as strings, we have to cast
whatever it's set at to a boolean that does not violate expectations.
"""
_orig_environ = dict(os.environ)
os.environ['NO_PREREQ_INSTALL'] = set_val
assert pavelib.prereqs.no_prereq_install() == expected_val,\
f'NO_PREREQ_INSTALL is set to {set_val}, but we read it as {expected_val}'
# Reset Environment back to original state
os.environ.clear()
os.environ.update(_orig_environ)
def test_no_prereq_install_true_lowercase(self):
"""
Ensure that 'true' will be True.
"""
self.check_val('true', True)
def test_no_prereq_install_false_lowercase(self):
"""
Ensure that 'false' will be False.
"""
self.check_val('false', False)
def test_no_prereq_install_true(self):
"""
Ensure that 'True' will be True.
"""
self.check_val('True', True)
def test_no_prereq_install_false(self):
"""
Ensure that 'False' will be False.
"""
self.check_val('False', False)
def test_no_prereq_install_0(self):
"""
Ensure that '0' will be False.
"""
self.check_val('0', False)
def test_no_prereq_install_1(self):
"""
Ensure that '1' will be True.
"""
self.check_val('1', True)
class TestPaverNodeInstall(PaverTestCase):
"""
Test node install logic
"""
def setUp(self):
super().setUp()
# Ensure prereqs will be run
os.environ['NO_PREREQ_INSTALL'] = 'false'
def test_npm_install_with_subprocess_error(self):
"""
Test an error in 'npm ci' execution
"""
with patch('subprocess.Popen') as _mock_popen:
_mock_subprocess = mock.Mock()
attrs = {'wait': fail_on_npm_install}
_mock_subprocess.configure_mock(**attrs)
_mock_popen.return_value = _mock_subprocess
with pytest.raises(Exception):
pavelib.prereqs.node_prereqs_installation()
# npm ci will be called twice
assert _mock_popen.call_count == 2
def test_npm_install_called_once_when_successful(self):
"""
Vanilla npm ci should only be calling npm ci one time
"""
with patch('subprocess.Popen') as _mock_popen:
pavelib.prereqs.node_prereqs_installation()
# when there's no failure, npm ci is only called once
assert _mock_popen.call_count == 1
def test_npm_install_with_unexpected_subprocess_error(self):
"""
If there's some other error, only call npm ci once, and raise a failure
"""
with patch('subprocess.Popen') as _mock_popen:
_mock_popen.side_effect = unexpected_fail_on_npm_install
with pytest.raises(BuildFailure):
pavelib.prereqs.node_prereqs_installation()
assert _mock_popen.call_count == 1