diff --git a/.gitignore b/.gitignore index 1626ced..b4ddcb5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ +dist/* + .env coverage.xml junit.xml diff --git a/README.md b/README.md index 80042ce..e2c7aa8 100644 --- a/README.md +++ b/README.md @@ -88,6 +88,10 @@ You can setup env through `.env` file or environment variables with defined as d ## Changelog +### Version 0.2.0 + +Setup automatic release from gitlab while pushing new tag + ### Version 0.1.0 Initial version diff --git a/opnsense_exporter/server.py b/opnsense_exporter/server.py index 2dd635c..2949b43 100644 --- a/opnsense_exporter/server.py +++ b/opnsense_exporter/server.py @@ -51,10 +51,10 @@ def process_requests(main, backup, exporter_instance: str = ""): """A dummy function that takes some time.""" main_state = main.get_interface_vip_status() backup_sate = backup.get_interface_vip_status() - main_ha_state.labels(instance=exporter_instance, host=main.host) - main_ha_state.state(main_state) - backup_ha_state.labels(instance=exporter_instance, host=backup.host) - backup_ha_state.state(backup_sate) + main_ha_state.labels(instance=exporter_instance, host=main.host).state(main_state) + backup_ha_state.labels(instance=exporter_instance, host=backup.host).state( + backup_sate + ) active_opnsense = None if main_state == "active": active_opnsense = main @@ -65,13 +65,11 @@ def process_requests(main, backup, exporter_instance: str = ""): if bytes_received or bytes_received == 0: active_server_bytes_received.labels( instance=exporter_instance, host=active_opnsense.host - ) - active_server_bytes_received.set(bytes_received) + ).set(bytes_received) if bytes_transmitted or bytes_transmitted == 0: active_server_bytes_transmitted.labels( instance=exporter_instance, host=active_opnsense.host - ) - active_server_bytes_transmitted.set(bytes_transmitted) + ).set(bytes_transmitted) def start_server( diff --git a/tests/test_server.py b/tests/test_server.py index 9c438ad..16526cb 100644 --- a/tests/test_server.py +++ b/tests/test_server.py @@ -15,6 +15,32 @@ from .common import ( ) +class FakePromMetric: + _labels = {} + + def labels(self, *args, **kwargs): + self._labels = kwargs + return self + + +class FakePromEnum(FakePromMetric): + _state = None + count_state_calls = 0 + + def state(self, state): + self.count_state_calls += 1 + self._state = state + + +class FakePromGauge(FakePromMetric): + value = None + count_set_calls = 0 + + def set(self, value): + self.count_set_calls += 1 + self.value = value + + @mock.patch("opnsense_exporter.server.start_server") def test_parser(server_mock): with mock.patch( @@ -64,30 +90,54 @@ def test_process_requests(): f"https://{MAIN_HOST}/api/diagnostics/traffic/interface", body=generate_diagnostics_traffic_interface_paylaod(), ) - with mock.patch( - "opnsense_exporter.server.main_ha_state.state" - ) as main_ha_state_mock: + + main_ha_state_mock = FakePromEnum() + backup_ha_state_mock = FakePromEnum() + active_server_bytes_received_mock = FakePromGauge() + active_server_bytes_transmitted_mock = FakePromGauge() + + with mock.patch("opnsense_exporter.server.main_ha_state", new=main_ha_state_mock): with mock.patch( - "opnsense_exporter.server.backup_ha_state.state" - ) as backup_ha_state_mock: + "opnsense_exporter.server.backup_ha_state", new=backup_ha_state_mock + ): with mock.patch( - "opnsense_exporter.server.active_server_bytes_received.set" - ) as active_server_bytes_received_mock: + "opnsense_exporter.server.active_server_bytes_received", + new=active_server_bytes_received_mock, + ): with mock.patch( - "opnsense_exporter.server.active_server_bytes_transmitted.set" - ) as active_server_bytes_transmitted_mock: + "opnsense_exporter.server.active_server_bytes_transmitted", + new=active_server_bytes_transmitted_mock, + ): process_requests( OPNSenseAPI(MAIN_HOST, LOGIN, PASSWORD), OPNSenseAPI(BACKUP_HOST, LOGIN, PASSWORD), ) - main_ha_state_mock.assert_called_once_with("active") - backup_ha_state_mock.assert_called_once_with("hot_standby") - active_server_bytes_received_mock.assert_called_once_with(11725192686820) - active_server_bytes_transmitted_mock.assert_called_once_with(2489262014203) + + assert main_ha_state_mock._state == "active" + assert main_ha_state_mock.count_state_calls == 1 + assert main_ha_state_mock._labels == {"instance": "", "host": MAIN_HOST} + + assert backup_ha_state_mock._state == "hot_standby" + assert backup_ha_state_mock.count_state_calls == 1 + assert backup_ha_state_mock._labels == {"instance": "", "host": BACKUP_HOST} + + assert active_server_bytes_received_mock.value == 11725192686820 + assert active_server_bytes_received_mock.count_set_calls == 1 + assert active_server_bytes_received_mock._labels == { + "instance": "", + "host": MAIN_HOST, + } + + assert active_server_bytes_transmitted_mock.value == 2489262014203 + assert active_server_bytes_transmitted_mock.count_set_calls == 1 + assert active_server_bytes_transmitted_mock._labels == { + "instance": "", + "host": MAIN_HOST, + } @responses.activate -def test_process_requests_backend_active(): +def test_process_requests_backup_active(): responses.add( responses.GET, f"https://{MAIN_HOST}/api/diagnostics/interface/get_vip_status/", @@ -103,26 +153,49 @@ def test_process_requests_backend_active(): f"https://{BACKUP_HOST}/api/diagnostics/traffic/interface", body=generate_diagnostics_traffic_interface_paylaod(), ) - with mock.patch( - "opnsense_exporter.server.main_ha_state.state" - ) as main_ha_state_mock: + + main_ha_state_mock = FakePromEnum() + backup_ha_state_mock = FakePromEnum() + active_server_bytes_received_mock = FakePromGauge() + active_server_bytes_transmitted_mock = FakePromGauge() + + with mock.patch("opnsense_exporter.server.main_ha_state", new=main_ha_state_mock): with mock.patch( - "opnsense_exporter.server.backup_ha_state.state" - ) as backup_ha_state_mock: + "opnsense_exporter.server.backup_ha_state", new=backup_ha_state_mock + ): with mock.patch( - "opnsense_exporter.server.active_server_bytes_received.set" - ) as active_server_bytes_received_mock: + "opnsense_exporter.server.active_server_bytes_received", + new=active_server_bytes_received_mock, + ): with mock.patch( - "opnsense_exporter.server.active_server_bytes_transmitted.set" - ) as active_server_bytes_transmitted_mock: + "opnsense_exporter.server.active_server_bytes_transmitted", + new=active_server_bytes_transmitted_mock, + ): process_requests( OPNSenseAPI(MAIN_HOST, LOGIN, PASSWORD), OPNSenseAPI(BACKUP_HOST, LOGIN, PASSWORD), ) - main_ha_state_mock.assert_called_once_with("maintenancemode") - backup_ha_state_mock.assert_called_once_with("active") - active_server_bytes_received_mock.assert_called_once_with(11725192686820) - active_server_bytes_transmitted_mock.assert_called_once_with(2489262014203) + assert main_ha_state_mock._state == "maintenancemode" + assert main_ha_state_mock.count_state_calls == 1 + assert main_ha_state_mock._labels == {"instance": "", "host": MAIN_HOST} + + assert backup_ha_state_mock._state == "active" + assert backup_ha_state_mock.count_state_calls == 1 + assert backup_ha_state_mock._labels == {"instance": "", "host": BACKUP_HOST} + + assert active_server_bytes_received_mock.value == 11725192686820 + assert active_server_bytes_received_mock.count_set_calls == 1 + assert active_server_bytes_received_mock._labels == { + "instance": "", + "host": BACKUP_HOST, + } + + assert active_server_bytes_transmitted_mock.value == 2489262014203 + assert active_server_bytes_transmitted_mock.count_set_calls == 1 + assert active_server_bytes_transmitted_mock._labels == { + "instance": "", + "host": BACKUP_HOST, + } @responses.activate @@ -143,26 +216,39 @@ def test_process_no_active(): f"https://{BACKUP_HOST}/api/diagnostics/traffic/interface", body=generate_diagnostics_traffic_interface_paylaod(), ) - with mock.patch( - "opnsense_exporter.server.main_ha_state.state" - ) as main_ha_state_mock: + + main_ha_state_mock = FakePromEnum() + backup_ha_state_mock = FakePromEnum() + active_server_bytes_received_mock = FakePromGauge() + active_server_bytes_transmitted_mock = FakePromGauge() + + with mock.patch("opnsense_exporter.server.main_ha_state", new=main_ha_state_mock): with mock.patch( - "opnsense_exporter.server.backup_ha_state.state" - ) as backup_ha_state_mock: + "opnsense_exporter.server.backup_ha_state", new=backup_ha_state_mock + ): with mock.patch( - "opnsense_exporter.server.active_server_bytes_received.set" - ) as active_server_bytes_received_mock: + "opnsense_exporter.server.active_server_bytes_received", + new=active_server_bytes_received_mock, + ): with mock.patch( - "opnsense_exporter.server.active_server_bytes_transmitted.set" - ) as active_server_bytes_transmitted_mock: + "opnsense_exporter.server.active_server_bytes_transmitted", + new=active_server_bytes_transmitted_mock, + ): process_requests( OPNSenseAPI(MAIN_HOST, LOGIN, PASSWORD), OPNSenseAPI(BACKUP_HOST, LOGIN, PASSWORD), ) - main_ha_state_mock.assert_called_once_with("maintenancemode") - backup_ha_state_mock.assert_called_once_with("unavailable") - active_server_bytes_received_mock.assert_not_called() - active_server_bytes_transmitted_mock.assert_not_called() + + assert main_ha_state_mock._state == "maintenancemode" + assert main_ha_state_mock.count_state_calls == 1 + assert main_ha_state_mock._labels == {"instance": "", "host": MAIN_HOST} + + assert backup_ha_state_mock._state == "unavailable" + assert backup_ha_state_mock.count_state_calls == 1 + assert backup_ha_state_mock._labels == {"instance": "", "host": BACKUP_HOST} + + assert active_server_bytes_received_mock.count_set_calls == 0 + assert active_server_bytes_transmitted_mock.count_set_calls == 0 @responses.activate @@ -183,23 +269,35 @@ def test_process_with_falsy_value(): body=generate_diagnostics_traffic_interface_paylaod(), status=404, ) - with mock.patch( - "opnsense_exporter.server.main_ha_state.state" - ) as main_ha_state_mock: + + main_ha_state_mock = FakePromEnum() + backup_ha_state_mock = FakePromEnum() + active_server_bytes_received_mock = FakePromGauge() + active_server_bytes_transmitted_mock = FakePromGauge() + + with mock.patch("opnsense_exporter.server.main_ha_state", new=main_ha_state_mock): with mock.patch( - "opnsense_exporter.server.backup_ha_state.state" - ) as backup_ha_state_mock: + "opnsense_exporter.server.backup_ha_state", new=backup_ha_state_mock + ): with mock.patch( - "opnsense_exporter.server.active_server_bytes_received.set" - ) as active_server_bytes_received_mock: + "opnsense_exporter.server.active_server_bytes_received", + new=active_server_bytes_received_mock, + ): with mock.patch( - "opnsense_exporter.server.active_server_bytes_transmitted.set" - ) as active_server_bytes_transmitted_mock: + "opnsense_exporter.server.active_server_bytes_transmitted", + new=active_server_bytes_transmitted_mock, + ): process_requests( OPNSenseAPI(MAIN_HOST, LOGIN, PASSWORD), OPNSenseAPI(BACKUP_HOST, LOGIN, PASSWORD), ) - main_ha_state_mock.assert_called_once_with("active") - backup_ha_state_mock.assert_called_once_with("hot_standby") - active_server_bytes_received_mock.assert_not_called() - active_server_bytes_transmitted_mock.assert_not_called() + assert main_ha_state_mock._state == "active" + assert main_ha_state_mock.count_state_calls == 1 + assert main_ha_state_mock._labels == {"instance": "", "host": MAIN_HOST} + + assert backup_ha_state_mock.count_state_calls == 1 + assert backup_ha_state_mock._state == "hot_standby" + assert backup_ha_state_mock._labels == {"instance": "", "host": BACKUP_HOST} + + assert active_server_bytes_received_mock.count_set_calls == 0 + assert active_server_bytes_transmitted_mock.count_set_calls == 0