From b0ed7ecfac6e9ea422f237a44cb605b8f700fe10 Mon Sep 17 00:00:00 2001 From: CamDavidsonPilon Date: Wed, 22 May 2024 11:55:39 -0400 Subject: [PATCH] fix some tests, preventative updates --- .github/workflows/build.yaml | 10 +++++++++- CHANGELOG.md | 8 ++++++-- pioreactor/tests/test_cli.py | 9 +++------ pioreactor/tests/test_stirring.py | 33 +++++++++++++++++++++---------- pioreactor/tests/test_watchdog.py | 8 ++++---- pioreactor/utils/__init__.py | 21 +++++++++++--------- update_scripts/upcoming/update.sh | 4 ++-- 7 files changed, 59 insertions(+), 34 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index d97ac2e3..40242c52 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -117,10 +117,11 @@ jobs: [ -f update.sh ] || touch update.sh [ -f post_update.sh ] || touch post_update.sh [ -f update.sql ] || touch update.sql - - name: Zip the assets + - name: Zip the assets and produce hash run: | cd release_assets zip -r ../release_${{ github.event.release.tag_name }}.zip . + sha256sum ../release_${{ github.event.release.tag_name }}.zip > ../release_${{ github.event.release.tag_name }}.zip.sha256 - name: Upload zipped assets uses: svenstaro/upload-release-action@v2 with: @@ -128,6 +129,13 @@ jobs: file: release_${{ github.event.release.tag_name }}.zip tag: ${{ github.event.release.tag_name }} overwrite: true + - name: Upload hash + uses: svenstaro/upload-release-action@v2 + with: + repo_token: ${{ secrets.GITHUB_TOKEN }} + file: release_${{ github.event.release.tag_name }}.zip.sha256 + tag: ${{ github.event.release.tag_name }} + overwrite: true publish-on-pypi: name: 📦 Publish tagged releases to PyPI diff --git a/CHANGELOG.md b/CHANGELOG.md index 56287ea0..4315e98f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,9 +16,13 @@ - fix leader not correctly being identified in `pio workers status` - For RPi Zero W (first gen), sometimes the load_rp2040 script was failing. A new script will retry a few times. This only applies to new images. - fix `pio workers update-active` using the wrong HTTP verb. - - When the local access point would start on a fresh boot, the SSID would start as `pioreactor`, and then change to `pioreactor-` after the next reboot. Now, this will now always be `pioreactor-`. - Fix using ethernet cable to connect Pioreactor to a router: a new simple ethernet nmconnection has been added, and has higher connection priority than the PioreactorLocalLink nmconnection. - - Fix race conditions between stirring and growth-rate. + - Fix race conditions occurring between stirring and growth-rate when they were started too quickly. + +#### Known issues + + - When the local access point would start on a fresh boot, the SSID would start as `pioreactor`, and then change to `pioreactor-` after the next reboot. + ### 24.5.13 diff --git a/pioreactor/tests/test_cli.py b/pioreactor/tests/test_cli.py index b992d438..fb086c8a 100644 --- a/pioreactor/tests/test_cli.py +++ b/pioreactor/tests/test_cli.py @@ -93,6 +93,7 @@ def put_into_bucket(msg): assert len(bucket) >= 1 +@pytest.mark.xfail(reason="the `pio kill` will kill the pid, which is this pytest process!") def test_pio_kill_cleans_up_automations_correctly() -> None: exp = "test_pio_kill_cleans_up_automations_correctly" unit = "testing_unit" @@ -102,14 +103,10 @@ def test_pio_kill_cleans_up_automations_correctly() -> None: assert is_pio_job_running("dosing_automation") assert is_pio_job_running("dosing_control") - pause() - pause() - pause() - pause() - runner = CliRunner() - result = runner.invoke(pio, ["kill", "--all-jobs"]) + result = runner.invoke(pio, ["kill", "--name", "dosing_control"]) + pause() assert result.exit_code == 0 pause() pause() diff --git a/pioreactor/tests/test_stirring.py b/pioreactor/tests/test_stirring.py index a832a91b..3968199f 100644 --- a/pioreactor/tests/test_stirring.py +++ b/pioreactor/tests/test_stirring.py @@ -32,7 +32,11 @@ def test_stirring_runs() -> None: def test_change_target_rpm_mid_cycle() -> None: original_rpm = 500 exp = "test_change_target_rpm_mid_cycle" - with Stirrer(original_rpm, unit, exp, rpm_calculator=RpmCalculator()) as st: + + rpm_calculator = RpmCalculator() + rpm_calculator.setup() + + with Stirrer(original_rpm, unit, exp, rpm_calculator=rpm_calculator) as st: assert st.target_rpm == original_rpm pause() @@ -74,8 +78,9 @@ def test_publish_target_rpm() -> None: publish(f"pioreactor/{unit}/{exp}/stirring/target_rpm", None, retain=True) pause() target_rpm = 500 - - with Stirrer(target_rpm, unit, exp, rpm_calculator=RpmCalculator()) as st: + rpm_calculator = RpmCalculator() + rpm_calculator.setup() + with Stirrer(target_rpm, unit, exp, rpm_calculator=rpm_calculator) as st: assert st.target_rpm == target_rpm pause() @@ -91,8 +96,9 @@ def test_publish_measured_rpm() -> None: pause() target_rpm = 500 - - with Stirrer(target_rpm, unit, exp, rpm_calculator=RpmFromFrequency()) as st: + rpm_calculator = RpmFromFrequency() + rpm_calculator.setup() + with Stirrer(target_rpm, unit, exp, rpm_calculator=rpm_calculator) as st: st.start_stirring() assert st.target_rpm == target_rpm @@ -138,7 +144,9 @@ def clean_up(self): cache["linear_v1"] = json.dumps({"rpm_coef": 0.1, "intercept": 20}) target_rpm = 500 - with Stirrer(target_rpm, unit, exp, rpm_calculator=FakeRpmCalculator()) as st: # type: ignore + rpm_calculator = FakeRpmCalculator() + rpm_calculator.setup() + with Stirrer(target_rpm, unit, exp, rpm_calculator=rpm_calculator) as st: # type: ignore st.start_stirring() current_dc = st.duty_cycle @@ -153,11 +161,12 @@ def clean_up(self): def test_stirring_will_try_to_restart_and_dodge_od_reading() -> None: # TODO make this an actual test exp = "test_stirring_will_try_to_restart_and_dodge_od_reading" - + rpm_calculator = RpmCalculator() + rpm_calculator.setup() with start_od_reading( "90", interval=5.0, unit=unit, experiment=exp, fake_data=True, use_calibration=False ): - with Stirrer(500, unit, exp, rpm_calculator=RpmCalculator()) as st: # type: ignore + with Stirrer(500, unit, exp, rpm_calculator=rpm_calculator) as st: # type: ignore st.start_stirring() pause(20) @@ -165,8 +174,10 @@ def test_stirring_will_try_to_restart_and_dodge_od_reading() -> None: def test_block_until_rpm_is_close_to_target_will_timeout() -> None: exp = "test_block_until_rpm_is_close_to_target_will_timeout" + rpm_calculator = MockRpmCalculator() + rpm_calculator.setup() with Stirrer( - 2 * MockRpmCalculator.ALWAYS_RETURN_RPM, unit, exp, rpm_calculator=MockRpmCalculator() # type: ignore + 2 * MockRpmCalculator.ALWAYS_RETURN_RPM, unit, exp, rpm_calculator=rpm_calculator # type: ignore ) as st: with catchtime() as delta: st.block_until_rpm_is_close_to_target(timeout=10) @@ -175,8 +186,10 @@ def test_block_until_rpm_is_close_to_target_will_timeout() -> None: def test_block_until_rpm_is_close_will_exit() -> None: exp = "test_block_until_rpm_is_close_to_target_will_timeout" + rpm_calculator = MockRpmCalculator() + rpm_calculator.setup() with Stirrer( - MockRpmCalculator.ALWAYS_RETURN_RPM, unit, exp, rpm_calculator=MockRpmCalculator() # type: ignore + MockRpmCalculator.ALWAYS_RETURN_RPM, unit, exp, rpm_calculator=rpm_calculator # type: ignore ) as st: with catchtime() as delta: st.block_until_rpm_is_close_to_target(timeout=50) diff --git a/pioreactor/tests/test_watchdog.py b/pioreactor/tests/test_watchdog.py index 36125323..55d308bc 100644 --- a/pioreactor/tests/test_watchdog.py +++ b/pioreactor/tests/test_watchdog.py @@ -18,9 +18,9 @@ def test_watchdog_alerts_on_found_worker() -> None: info = zeroconf.ServiceInfo( "_pio-worker._tcp.local.", - "pioreactor-worker-on-worker1._pio-worker._tcp.local.", + "pioreactor-worker-on-workerX._pio-worker._tcp.local.", addresses=["192.168.1.0"], - server="worker1.local.", + server="workerX.local.", port=1234, ) @@ -28,7 +28,7 @@ def test_watchdog_alerts_on_found_worker() -> None: with collect_all_logs_of_level("NOTICE", get_unit_name(), experiment) as logs: with WatchDog(unit=get_unit_name(), experiment=experiment): - time.sleep(8) + time.sleep(20) assert len(logs) > 0 @@ -52,7 +52,7 @@ def test_watchdog_doesnt_alert_if_already_in_cluster() -> None: with collect_all_logs_of_level("NOTICE", get_unit_name(), experiment) as logs: with WatchDog(unit=get_unit_name(), experiment=experiment): - time.sleep(8) + time.sleep(20) assert len(logs) == 0 diff --git a/pioreactor/utils/__init__.py b/pioreactor/utils/__init__.py index c88e1b74..fbb15e54 100644 --- a/pioreactor/utils/__init__.py +++ b/pioreactor/utils/__init__.py @@ -491,12 +491,14 @@ def __init__(self) -> None: def append(self, pid: int) -> None: self.list_of_pids.append(pid) - def kill(self) -> None: + def kill_jobs(self) -> int: if len(self.list_of_pids) == 0: - return + return 0 safe_kill(*self.list_of_pids) + return len(self.list_of_pids) + class MQTTKill: def __init__(self) -> None: @@ -505,14 +507,16 @@ def __init__(self) -> None: def append(self, name: str) -> None: self.list_of_job_names.append(name) - def kill(self) -> None: + def kill_jobs(self) -> int: + count = 0 if len(self.list_of_job_names) == 0: - return + return count from pioreactor.pubsub import create_client with create_client() as client: for i, name in enumerate(self.list_of_job_names): + count += 1 msg = client.publish( f"pioreactor/{whoami.get_unit_name()}/{whoami.UNIVERSAL_EXPERIMENT}/{name}/$state/set", "disconnected", @@ -523,6 +527,8 @@ def kill(self) -> None: # last one msg.wait_for_publish(2) + return count + class JobManager: AUTOMATION_JOBS = ("temperature_automation", "dosing_automation", "led_automation") @@ -625,7 +631,6 @@ def kill_jobs(self, all_jobs: bool = False, **query) -> int: for job, pid in self._get_jobs(all_jobs, **query): if job in self.PUMPING_JOBS: mqtt_kill.append(job) - count += 1 elif job == "led_intensity": # led_intensity doesn't register with the JobManager, probably should somehow. #502 pass @@ -634,10 +639,8 @@ def kill_jobs(self, all_jobs: bool = False, **query) -> int: pass else: shell_kill.append(pid) - count += 1 - - mqtt_kill.kill() - shell_kill.kill() + count += mqtt_kill.kill_jobs() + count += shell_kill.kill_jobs() return count diff --git a/update_scripts/upcoming/update.sh b/update_scripts/upcoming/update.sh index 0d3ae2ff..94d693db 100644 --- a/update_scripts/upcoming/update.sh +++ b/update_scripts/upcoming/update.sh @@ -8,7 +8,7 @@ export LC_ALL=C echo "force_turbo=1" | sudo tee -a /boot/config.txt -nmcli con add type ethernet con-name eth0 ifname eth0 autoconnect yes ipv4.method auto ipv6.method auto ipv6.addr-gen-mode default connection.id eth0 connection.uuid 5e55231f-ea1a-484b-88f9-88e3598c66ae connection.autoconnect-priority 1 -nmcli con modify PioreactorLocalLink connection.autoconnect-priority 0 connection.autoconnect no +nmcli con add type ethernet con-name eth0 ifname eth0 autoconnect yes ipv4.method auto ipv6.method auto ipv6.addr-gen-mode default connection.id eth0 connection.autoconnect-priority 1 || : +nmcli con modify PioreactorLocalLink connection.autoconnect-priority 0 connection.autoconnect no || : echo "max_inflight_messages 1000" | sudo tee /etc/mosquitto/mosquitto.conf -a