diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..16dc11f --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,23 @@ +name: Run tests + +on: + pull_request: + +jobs: + run-tests: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: [3.8, 3.11] + + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip . + - name: Run tests + run: | + python -m unittest diff --git a/VERSION.txt b/VERSION.txt index 78a37ec..f33f5ed 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -0.2.4.2 \ No newline at end of file +0.2.4.3 \ No newline at end of file diff --git a/test.py b/test.py new file mode 100644 index 0000000..9453875 --- /dev/null +++ b/test.py @@ -0,0 +1,86 @@ +import json +import subprocess +import unittest + + +# ufbt invokation & json status output +def ufbt_status() -> dict: + # Call "ufbt status --json" and return the parsed json + try: + status = subprocess.check_output(["ufbt", "status", "--json"]) + except subprocess.CalledProcessError as e: + status = e.output + return json.loads(status) + + +def ufbt_exec(args): + # Call "ufbt" with the given args and return the parsed json + return subprocess.check_output(["ufbt"] + args) + + +# Test initial deployment +class TestInitialDeployment(unittest.TestCase): + def test_default_deployment(self): + ufbt_exec(["clean"]) + status = ufbt_status() + self.assertEqual(status.get("error"), "SDK is not deployed") + + ufbt_exec(["update"]) + status = ufbt_status() + self.assertIsNone(status.get("error")) + self.assertEqual(status.get("target"), "f7") + self.assertEqual(status.get("mode"), "channel") + self.assertEqual(status.get("details", {}).get("channel"), "release") + + def test_customized_deployment(self): + ufbt_exec(["clean"]) + status = ufbt_status() + self.assertEqual(status.get("error"), "SDK is not deployed") + + ufbt_exec(["update", "-t", "f18", "-c", "rc"]) + status = ufbt_status() + self.assertIsNone(status.get("error")) + self.assertEqual(status.get("target"), "f18") + self.assertEqual(status.get("mode"), "channel") + self.assertEqual(status.get("details", {}).get("channel"), "rc") + self.assertIn("rc", status.get("version", "")) + + def test_target_switch(self): + ufbt_exec(["clean"]) + status = ufbt_status() + self.assertEqual(status.get("error"), "SDK is not deployed") + + ufbt_exec(["update"]) + status = ufbt_status() + self.assertEqual(status.get("target"), "f7") + + ufbt_exec(["update", "-t", "f18"]) + status = ufbt_status() + self.assertEqual(status.get("target"), "f18") + self.assertEqual(status.get("mode"), "channel") + self.assertEqual(status.get("details", {}).get("channel"), "release") + + def test_target_mode_switches(self): + ufbt_exec(["clean"]) + status = ufbt_status() + self.assertEqual(status.get("error"), "SDK is not deployed") + + ufbt_exec(["update"]) + status = ufbt_status() + self.assertEqual(status.get("target"), "f7") + + ufbt_exec(["update", "-t", "f18"]) + status = ufbt_status() + self.assertEqual(status.get("target"), "f18") + self.assertEqual(status.get("mode"), "channel") + + ufbt_exec(["update", "-b", "dev"]) + status = ufbt_status() + self.assertEqual(status.get("target"), "f18") + self.assertEqual(status.get("mode"), "branch") + self.assertEqual(status.get("details", {}).get("branch"), "dev") + + previous_status = status + ufbt_exec(["update"]) + status = ufbt_status() + self.assertEqual(previous_status, status) diff --git a/ufbt/bootstrap.py b/ufbt/bootstrap.py index 8a6ba3e..4cefb18 100644 --- a/ufbt/bootstrap.py +++ b/ufbt/bootstrap.py @@ -597,25 +597,11 @@ def _add_arguments(self, parser: argparse.ArgumentParser) -> None: def _func(self, args) -> int: sdk_deployer = UfbtSdkDeployer(args.ufbt_home) - current_task = SdkDeployTask.from_args(args) - task_to_deploy = None - if previous_task := sdk_deployer.get_previous_task(): - previous_task.update_from(current_task) - task_to_deploy = previous_task - else: - if current_task.mode: - task_to_deploy = current_task - # No previous state, use default hw target - if task_to_deploy and not task_to_deploy.hw_target: - task_to_deploy.hw_target = SdkDeployTask.DEFAULT_HW_TARGET - else: - log.warn("No previous SDK state was found, fetching latest release") - task_to_deploy = SdkDeployTask.default() + task_to_deploy = sdk_deployer.get_previous_task() or SdkDeployTask.default() + task_to_deploy.update_from(SdkDeployTask.from_args(args)) - if not sdk_deployer.deploy(task_to_deploy): - return 1 - return 0 + return 0 if sdk_deployer.deploy(task_to_deploy) else 1 class CleanSubcommand(CliSubcommand):