-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adding unit tests for utilities.py
#415
Changes from 25 commits
132952f
a11a81d
f10468f
eaeba19
e053e3f
3b1985b
739c879
7c427d3
5b695a9
b0afda6
08f5cde
dddf555
99dccac
8eb4020
1253cde
7fc6697
bbf3d92
dd60f3a
f09c813
791c207
aadff83
95a5d6c
9b65f8c
8cc1637
446569c
92ffbd1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -223,7 +223,13 @@ def install_plugins(): # pylint: disable=too-many-locals,too-many-statements,to | |
logger.error(f"File does not exist: [{plugin_install_script_path}]") | ||
sys.exit(1) | ||
|
||
result = run_cmd([plugin_install_language, plugin_install_script_path]) | ||
try: | ||
result = run_cmd([plugin_install_language, plugin_install_script_path]) | ||
except Exception as e: | ||
logger.error( | ||
f"Failed to run plugin install script: [{plugin_install_script_path}]. Error: [{e}]" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Error message for deploy and install should be similar. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This one comes from the Exception, eg. when something wrong happens on the Popen system side like a timeout, permissions issue, etc. What would be the more expected error message to you? |
||
) | ||
sys.exit(101) | ||
if result.returncode == 0: | ||
logger.info(f"~#~#~#~INSTALLING PLUGIN [{plugin_config}] SUCCESSFULLY COMPLETED~#~#~#~") | ||
logger.debug( | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
import os | ||
|
||
# Disable logging to file when running tests | ||
os.environ["BITOPS_LOGGING_FILENAME"] = "false" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
#!/bin/bash | ||
|
||
echo "In before_test.sh" | ||
|
||
ls ../../ | ||
|
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
import os | ||
import subprocess | ||
from io import StringIO | ||
from unittest import mock, TestCase | ||
from plugins.utilities import add_value_to_env, load_yaml, run_cmd, handle_hooks | ||
|
||
|
||
class TestAddValueToEnv(TestCase): | ||
"""Testing add_value_to_env utilties function""" | ||
|
||
def setUp(self): | ||
self.export_env = "" | ||
self.value = "" | ||
os.environ.clear() | ||
|
||
def test_add_value_to_env_with_value(self): | ||
"""Test the add_value_to_env() function with valid value""" | ||
self.export_env = "ANSIBLE_VERBOSITY" | ||
self.value = "1" | ||
|
||
add_value_to_env(self.export_env, self.value) | ||
self.assertEqual(os.environ[self.export_env], self.value) | ||
self.assertEqual(os.environ["BITOPS_" + self.export_env], self.value) | ||
|
||
def test_add_value_to_env_with_none(self): | ||
"""Test the add_value_to_env() function with None""" | ||
self.export_env = "ANSIBLE_VERBOSITY" | ||
self.value = None | ||
|
||
add_value_to_env(self.export_env, self.value) | ||
self.assertNotIn(self.export_env, os.environ) | ||
self.assertNotIn("BITOPS_" + self.export_env, os.environ) | ||
|
||
def test_add_value_to_env_with_list(self): | ||
"""Test the add_value_to_env() function with a list""" | ||
self.export_env = "ANSIBLE_VERBOSITY" | ||
self.value = ["1", "2", "3"] | ||
|
||
add_value_to_env(self.export_env, self.value) | ||
self.assertEqual(os.environ[self.export_env], " ".join(self.value)) | ||
self.assertEqual(os.environ["BITOPS_" + self.export_env], " ".join(self.value)) | ||
|
||
|
||
class TestLoadYAML(TestCase): | ||
"""Testing load_yaml utilties function""" | ||
|
||
def setUp(self): | ||
root_dir = os.getcwd() | ||
self.inc_yaml = f"{root_dir}/prebuilt-config/omnibus/bitops.config.yaml" | ||
|
||
def test_load_yaml(self): | ||
""" | ||
Test the load_yaml function. | ||
""" | ||
out_yaml = load_yaml(self.inc_yaml) | ||
self.assertIsNotNone(out_yaml) | ||
self.assertIsInstance(out_yaml, dict) | ||
|
||
def test_load_yaml_with_invalid_filename(self): | ||
""" | ||
Test the load_yaml function with a non-existent file. | ||
""" | ||
with self.assertRaises(FileNotFoundError): | ||
load_yaml("invalid_file.yaml") | ||
|
||
|
||
class TestRunCmd(TestCase): | ||
"""Testing run_cmd utilties function""" | ||
|
||
@mock.patch("sys.stdout", new_callable=StringIO) | ||
def test_valid_run_cmd(self, stdout): | ||
""" | ||
Test the run_cmd function with a valid command | ||
""" | ||
process = run_cmd("ls") | ||
self.assertIsInstance(process, subprocess.Popen) | ||
self.assertEqual(process.returncode, 0) | ||
self.assertEqual(process.args, "ls") | ||
self.assertIn("README.md", stdout.getvalue()) | ||
self.assertIn("LICENSE.md", stdout.getvalue()) | ||
|
||
def test_invalid_run_cmd(self): | ||
""" | ||
Test the run_cmd function with an invalid command should throw an exception | ||
""" | ||
with self.assertRaises(Exception) as context: | ||
run_cmd("not_a_real_command") | ||
self.assertIsInstance(context.exception, FileNotFoundError) | ||
|
||
|
||
class TestHandleHooks(TestCase): | ||
"""Testing handle_hooks utilties function""" | ||
|
||
def setUp(self): | ||
self.original_cwd = os.getcwd() | ||
self.hooks_folder = f"{self.original_cwd}/scripts/tests/unit/assets/bitops.before-deploy.d" | ||
self.source_folder = f"{self.original_cwd}/scripts/tests/unit/assets" | ||
|
||
def tearDown(self): | ||
os.chdir(self.original_cwd) | ||
|
||
def test_handle_hooks_called_with_invalid_folder(self): | ||
""" | ||
Test handle_hooks with invalid folder path | ||
""" | ||
result = handle_hooks("before", "./invalid_folder", self.source_folder) | ||
self.assertFalse(result) | ||
|
||
def test_handle_hooks_called_with_invalid_mode(self): | ||
""" | ||
Test handle_hooks with invalid mode | ||
""" | ||
result = handle_hooks("random_mode.exe", self.hooks_folder, self.source_folder) | ||
self.assertFalse(result) | ||
|
||
@mock.patch("sys.stdout", new_callable=StringIO) | ||
def test_handle_hooks_called_with_valid_folder(self, stdout): | ||
""" | ||
Test handle_hooks with valid folder path | ||
""" | ||
result = handle_hooks("before", self.hooks_folder, self.source_folder) | ||
self.assertTrue(result) | ||
self.assertIn("In before_test.sh", stdout.getvalue()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
run_cmd try catch blocks exit with 1xx, should we consider making this a 1xx exit as well? What denotes a 2 vs 101
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's how you added it here initially: eaeba19#diff-ec9057b7cfb0579064835fe003bf275eb479b2910d976987366051d5d7593c9dR24, so that's more a question to you.
There is no difference to me, unless we're returning the non-zero error code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated in 92ffbd1