diff --git a/code/iottb/logger.py b/code/iottb/logger.py index 2d60e6d..ea6add2 100644 --- a/code/iottb/logger.py +++ b/code/iottb/logger.py @@ -2,6 +2,7 @@ import logging import sys from logging.handlers import RotatingFileHandler + def setup_logging(): logger_obj = logging.getLogger('iottbLogger') logger_obj.setLevel(logging.DEBUG) diff --git a/code/iottb/subcommands/add_device.py b/code/iottb/subcommands/add_device.py index 3cf1b4a..62c74bf 100644 --- a/code/iottb/subcommands/add_device.py +++ b/code/iottb/subcommands/add_device.py @@ -19,26 +19,36 @@ def setup_init_device_root_parser(subparsers): def handle_add(args): logger.info(f"Add device handler called with args {args}") + args.root_dir.mkdir(parents=True, exist_ok=True) # else metadata.save_to_file will fail TODO: unclear what to assume + if args.guided: - logger.debug("Guided setup") + logger.debug("begin guided setup") metadata = guided_setup(args.root_dir) + logger.debug("guided setup complete") else: logger.debug("Setup through passed args: setup") - device_name = args.name - args.root_dir.mkdir(parents=True, exist_ok=True) - metadata = DeviceMetadata(device_name, args.root_dir) + if not args.name: + logger.error("No device name specified with unguided setup.") + return ReturnCodes.ERROR + metadata = DeviceMetadata(args.name, args.root_dir) file_path = args.root_dir / DEVICE_METADATA_FILE - - response = input(f"Confirm device metadata: {metadata.to_json()} [y/N]") - if response.lower() not in definitions.AFFIRMATIVE_USER_RESPONSE.add(""): - configure_metadata() - assert False, "TODO implement dynamic setup" - args.root_dir.mkdir(parents=True, exist_ok=True) # else metadata.save_to_file will fail TODO: unclear - if metadata.save_to_json(file_path) == ReturnCodes.FILE_ALREADY_EXISTS: - print("Directory already contains a device metadata file. Aborting operation.") + if file_path.exists(): + print("Directory already contains a metadata file. Aborting.") return ReturnCodes.ABORTED - assert Path(file_path).exists(), f"{file_path} does not exist" + serialized_metadata = metadata.to_json() + response = input(f"Confirm device metadata: {serialized_metadata} [y/N]") + logger.debug(f"response: {response}") + if response not in definitions.AFFIRMATIVE_USER_RESPONSE: + print("Adding device aborted by user.") + return ReturnCodes.ABORTED + + logger.debug(f"Device metadata file {file_path}") + if metadata.save_to_json(file_path) == ReturnCodes.FILE_ALREADY_EXISTS: + logger.error("File exists after checking, which should not happen.") + return ReturnCodes.ABORTED + + print("Device metadata successfully created.") return ReturnCodes.SUCCESS diff --git a/code/tests/subcommands/test_add_device.py b/code/tests/subcommands/test_add_device.py new file mode 100644 index 0000000..a7fedcf --- /dev/null +++ b/code/tests/subcommands/test_add_device.py @@ -0,0 +1,37 @@ +import sys +import unittest +from io import StringIO +from unittest.mock import patch, MagicMock +from pathlib import Path +from iottb.definitions import DEVICE_METADATA_FILE +import shutil +from iottb.__main__ import main + + +class TestDeviceSetup(unittest.TestCase): + def setUp(self): + self.test_dir = Path("/tmp/iottbtest/test_add_device") + self.test_dir.mkdir(parents=True, exist_ok=True) + # self.captured_output = StringIO() + # sys.stdout = self.captured_output + + def tearDown(self): + # shutil.rmtree(str(self.test_dir)) + for item in self.test_dir.iterdir(): + if item.is_dir(): + item.rmdir() + else: + item.unlink() + self.test_dir.rmdir() + # sys.stdout = sys.__stdout__ + + @patch("builtins.input", side_effect=["iPhone 14", "y", "y"]) + def test_guided_device_setup(self, mock_input): + sys.argv = ['__main__.py', 'add', '--root_dir', str(self.test_dir), '--guided'] + main() + expected_file = self.test_dir / DEVICE_METADATA_FILE + self.assertTrue(expected_file.exists()), f"Expected file not created: {expected_file}" + + +if __name__ == '__main__': + unittest.main()