From a7f71b3a9f972bf2088d6cc02e4052a5450996a0 Mon Sep 17 00:00:00 2001 From: Andrew Kiellor Date: Wed, 26 Nov 2014 16:15:12 -0800 Subject: [PATCH 1/7] Extracted script to run just unit tests --- run-tests.sh | 2 +- scripts/unit | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100755 scripts/unit diff --git a/run-tests.sh b/run-tests.sh index 8a517d6..de34e48 100755 --- a/run-tests.sh +++ b/run-tests.sh @@ -20,7 +20,7 @@ if ! make assert_templates_js_up_to_date ; then exit 1 fi -/usr/bin/env python2.7 -m unittest discover -s test/ -p '*_test.py' +scripts/unit if which nodejs ; then NODEJS=nodejs else diff --git a/scripts/unit b/scripts/unit new file mode 100755 index 0000000..4ac60bd --- /dev/null +++ b/scripts/unit @@ -0,0 +1,5 @@ +#!/bin/sh + +set -e + +/usr/bin/env python2.7 -m unittest discover -s test/ -p '*_test.py' From 97524cfa03f47c9b5e328828b85d7e13883e6f9e Mon Sep 17 00:00:00 2001 From: Andrew Kiellor Date: Fri, 28 Nov 2014 23:26:06 -0800 Subject: [PATCH 2/7] Removed global params dictionary, introduced a main method, errors return a 500. --- routerapi/update_setting | 108 ++++++++++++++++++++------------------- 1 file changed, 55 insertions(+), 53 deletions(-) diff --git a/routerapi/update_setting b/routerapi/update_setting index 5ce1c1c..b5d8d34 100755 --- a/routerapi/update_setting +++ b/routerapi/update_setting @@ -7,7 +7,6 @@ import common import uci environ = os.environ -params = {} band_5_channel_options = ['auto', '36 (5.180 GHz)', '40 (5.200 GHz)', '44 (5.220 GHz)', '48 (5.240 GHz)', '149 (5.745 GHz)', '153 (5.765 GHz)', '159 (5.785 GHz)', '161 (5.805 GHz)', @@ -37,30 +36,30 @@ def set_param(device, param, value): uci.commit("wireless") def set_error(param): - params['error'] = 'Invalid ' + param + raise Exception('Invalid ' + param) def check_band(band_name, interface_name): - if params.get(band_name): - if params.get(band_name) in ["2.4", "5"]: - current_band = check_device(interface_name) + if band_name: + if band_name in ["2.4", "5"]: + current_band = check_device(interface_name) - if current_band == "radio0": - new_band = "radio1" + if current_band == "radio0": + new_band = "radio1" - else: - new_band = "radio0" + else: + new_band = "radio0" - if new_band != check_param(interface_name, "device"): - set_param(interface_name, "device", new_band) - common.reset_wifi() + if new_band != check_param(interface_name, "device"): + set_param(interface_name, "device", new_band) + common.reset_wifi() - else: - set_error('band') + else: + set_error('band') def check_channel(channel_name, interface_name): - if params.get(channel_name): + if channel_name: current_device = check_device(interface_name) - new_channel = params.get(channel_name) + new_channel = channel_name if validate_channel(current_device, new_channel): if new_channel.split(' ')[0] != check_param(current_device, 'channel'): set_param(current_device, 'channel', new_channel.split(' ')[0]) @@ -70,9 +69,9 @@ def check_channel(channel_name, interface_name): set_error('channel') def check_channel_bandwidth(channel_name, interface_name): - if params.get(channel_name): + if channel_name: current_device = check_device(interface_name) - new_bandwidth = params.get(channel_name) + new_bandwidth = channel_name if validate_bandwidth(new_bandwidth): if check_param(current_device, 'htmode') != "HT" + new_bandwidth: set_param(current_device, 'htmode', "HT" + new_bandwidth) @@ -88,57 +87,60 @@ def set_openwireless_use_limit(option): uci.set(openwireless_interface, str(int(openwireless_bandwidth))) uci.commit("sqm") -def check_openwireless_bandwidth_percentage(): - if (params.get("openwirelessBandwidth")): - new_percentage = params.get("openwirelessBandwidth") - - uci.set("openwireless.maxbandwidthpercentage", new_percentage) +def check_openwireless_bandwidth_percentage(percentage): + if percentage: + uci.set("openwireless.maxbandwidthpercentage", percentage) uci.commit("openwireless") set_openwireless_use_limit("download") set_openwireless_use_limit("upload") -def check_isp_upload_speed(): - if (params.get("ispUploadSpeed")): - new_speed = float(params.get("ispUploadSpeed")) - new_speed_kbs = str(int(new_speed * 1000)) - uci.set("sqm.ge00.upload", new_speed_kbs) +def check_isp_upload_speed(speed): + if speed: + speed_kbs = str(int(float(speed) * 1000)) + uci.set("sqm.ge00.upload", speed_kbs) uci.commit("sqm") set_openwireless_use_limit("upload") -def check_isp_download_speed(): - if (params.get("ispDownloadSpeed")): - new_speed = float(params.get("ispDownloadSpeed")) - new_speed_kbs = str(int(new_speed * 1000)) - uci.set("sqm.ge00.download", new_speed_kbs) +def check_isp_download_speed(speed): + if speed: + speed_kbs = str(int(float(speed) * 1000)) + uci.set("sqm.ge00.download", speed_kbs) uci.commit("sqm") set_openwireless_use_limit("download") -def check_openwireless_monthly_data(): - if (params.get("openwirelessData")): - new_bandwidth = params.get("openwirelessData") - uci.set("openwireless.maxmonthlybandwidth", new_bandwidth) - uci.commit("openwireless") +def check_openwireless_monthly_data(bandwidth): + if bandwidth: + uci.set("openwireless.maxmonthlybandwidth", bandwidth) + uci.commit("openwireless") +def do_post(params): + check_band(params.get('routerBand'), "@wifi-iface[2]") + check_channel(params.get('routerChannel'), "@wifi-iface[2]") + check_channel_bandwidth(params.get('routerChannelBandwidth'), "@wifi-iface[2]") + check_band(params.get('openwirelessBand'), "@wifi-iface[1]") + check_channel(params.get('openwirelessChannel'), "@wifi-iface[1]") + check_channel_bandwidth(params.get('openwirelessChannelBandwidth'), "@wifi-iface[1]") -if environ.get('REQUEST_METHOD').lower() == 'post': - params = json.loads(sys.stdin.read()) + check_isp_upload_speed(params.get("ispUploadSpeed")) + check_isp_download_speed(params.get("ispDownloadSpeed")) - check_band('routerBand', "@wifi-iface[2]") - check_channel('routerChannel', "@wifi-iface[2]") - check_channel_bandwidth('routerChannelBandwidth', "@wifi-iface[0]") + check_openwireless_bandwidth_percentage(params.get("openwirelessBandwidth")) - check_band('openwirelessBand', "@wifi-iface[1]") - check_channel('openwirelessChannel', "@wifi-iface[1]") - check_channel_bandwidth('openwirelessChannelBandwidth', "@wifi-iface[1]") + check_openwireless_monthly_data(params.get("openwirelessData")) - check_isp_upload_speed() - check_isp_download_speed() - check_openwireless_bandwidth_percentage() - check_openwireless_monthly_data() -else: - set_error('GET request') +def main(): + try: + if environ.get('REQUEST_METHOD').lower() == 'post': + params = json.loads(sys.stdin.read()) + do_post(params) + else: + raise Exception('GET request') + common.render_success(params) + except Exception as e: + common.render_error(str.join(' ', e.args), status = 500) -common.render_success(params) +if __name__ == '__main__': + main() From 4327aa29c8dc2cbc6c2bc77566eb199426bb2c71 Mon Sep 17 00:00:00 2001 From: Andrew Kiellor Date: Sat, 29 Nov 2014 18:08:42 -0800 Subject: [PATCH 3/7] Extracted FakeUci to separate class. --- test/fake_uci.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 test/fake_uci.py diff --git a/test/fake_uci.py b/test/fake_uci.py new file mode 100644 index 0000000..a78155d --- /dev/null +++ b/test/fake_uci.py @@ -0,0 +1,14 @@ +class FakeUci: + def __init__(self): + self.data = {} + self.tmp = {} + + def get(self, name): + return self.data[name] + + def set(self, name, value): + self.tmp[name] = value + + def commit(self, section): + self.data = dict(self.data.items() + self.tmp.items()) + self.tmp = {} From 2621ec6040dc2651291508b38f7331d4e618bbf8 Mon Sep 17 00:00:00 2001 From: Andrew Kiellor Date: Sat, 29 Nov 2014 23:22:26 -0800 Subject: [PATCH 4/7] Update network availablility upon bandwidth change. --- routerapi/accumulate_bytes | 12 ++++++++---- routerapi/accumulate_bytes.py | 1 + routerapi/update_setting | 2 ++ test/update_setting_test.py | 21 +++++++++++++++++++++ 4 files changed, 32 insertions(+), 4 deletions(-) create mode 120000 routerapi/accumulate_bytes.py create mode 100644 test/update_setting_test.py diff --git a/routerapi/accumulate_bytes b/routerapi/accumulate_bytes index 01a3686..d12bd95 100644 --- a/routerapi/accumulate_bytes +++ b/routerapi/accumulate_bytes @@ -8,7 +8,7 @@ from subprocess import check_output from get_bytecounts import get_device_and_byte_counts -def disable_overutilized_network(): +def update_network_availability(): use_before_last_reset = float(uci.get("openwireless.use_before_last_reset")) use_since_last_reset = float(uci.get("openwireless.use_since_last_reset")) use_at_last_ui_reset = float(uci.get("openwireless.use_at_last_ui_reset")) @@ -62,6 +62,10 @@ def update_openwireless_usage(): else: increment_use_since_last_reset() -update_openwireless_usage() -disable_overutilized_network() -uci.commit("openwireless") +def main(): + update_openwireless_usage() + update_network_availability() + uci.commit("openwireless") + +if __name__ == '__main__': + main() diff --git a/routerapi/accumulate_bytes.py b/routerapi/accumulate_bytes.py new file mode 120000 index 0000000..d0897fd --- /dev/null +++ b/routerapi/accumulate_bytes.py @@ -0,0 +1 @@ +accumulate_bytes \ No newline at end of file diff --git a/routerapi/update_setting b/routerapi/update_setting index b5d8d34..ac5a663 100755 --- a/routerapi/update_setting +++ b/routerapi/update_setting @@ -5,6 +5,7 @@ import sys import common import uci +import accumulate_bytes environ = os.environ band_5_channel_options = ['auto', @@ -113,6 +114,7 @@ def check_openwireless_monthly_data(bandwidth): if bandwidth: uci.set("openwireless.maxmonthlybandwidth", bandwidth) uci.commit("openwireless") + accumulate_bytes.update_network_availability() def do_post(params): check_band(params.get('routerBand'), "@wifi-iface[2]") diff --git a/test/update_setting_test.py b/test/update_setting_test.py new file mode 100644 index 0000000..8f7b6f9 --- /dev/null +++ b/test/update_setting_test.py @@ -0,0 +1,21 @@ +import unittest +import mock +from fake_uci import FakeUci + +import update_setting + +class TestUpdateSetting(unittest.TestCase): + @mock.patch('accumulate_bytes.update_network_availability') + @mock.patch('update_setting.uci', new_callable = FakeUci) + def test_update_network_availability_after_monthly_data_limit_change(self, _, update_network_availability): + update_setting.check_openwireless_monthly_data('500') + update_network_availability.assert_called_with() + + @mock.patch('accumulate_bytes.update_network_availability') + @mock.patch('update_setting.uci', new_callable = FakeUci) + def test_update_openwireless_monthly_data(self, uci, _): + update_setting.check_openwireless_monthly_data('500') + + bandwidth = uci.get("openwireless.maxmonthlybandwidth") + self.assertEquals(bandwidth, '500') + From 77decea784e8fe5d12af3ee8a0bfee0e8d2dfe9c Mon Sep 17 00:00:00 2001 From: Andrew Kiellor Date: Sun, 30 Nov 2014 19:37:07 -0800 Subject: [PATCH 5/7] Enable wireless router when current_use is below limit. --- routerapi/accumulate_bytes | 5 +++- test/accumulate_bytes_test.py | 45 +++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 test/accumulate_bytes_test.py diff --git a/routerapi/accumulate_bytes b/routerapi/accumulate_bytes index d12bd95..ed8e2f6 100644 --- a/routerapi/accumulate_bytes +++ b/routerapi/accumulate_bytes @@ -18,7 +18,10 @@ def update_network_availability(): uci.set("wireless.@wifi-iface[1].disabled", "1") uci.commit("wireless") common.reset_wifi() - + if current_use < max_use: + uci.set("wireless.@wifi-iface[1].disabled", "0") + uci.commit("wireless") + common.reset_wifi() def update_openwireless_usage(): diff --git a/test/accumulate_bytes_test.py b/test/accumulate_bytes_test.py new file mode 100644 index 0000000..2088058 --- /dev/null +++ b/test/accumulate_bytes_test.py @@ -0,0 +1,45 @@ +import unittest +import mock +import sys +import os + +sys.path.insert(0, os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "..", "routerapi")) + +import accumulate_bytes +from fake_uci import FakeUci + +class AccumulateBytesTest(unittest.TestCase): + def with_usage_in_mb(self, uci, usage): + uci.set("openwireless.use_before_last_reset", "0") + uci.set("openwireless.use_since_last_reset", float(usage) * 1024 * 1024) + uci.set("openwireless.use_at_last_ui_reset", "0") + uci.commit("openwireless") + + @mock.patch('accumulate_bytes.common.reset_wifi') + @mock.patch('accumulate_bytes.uci', new_callable = FakeUci) + def test_turn_on_adapter_if_off_and_sufficient_bandwidth(self, uci, reset): + uci.set("openwireless.maxmonthlybandwidth", "20") + uci.set("wireless.@wifi-iface[1].disabled", "1") + self.with_usage_in_mb(uci, "0") + uci.commit("all") + + accumulate_bytes.update_network_availability() + + self.assertEquals(uci.get("wireless.@wifi-iface[1].disabled"), "0") + reset.assert_called_with() + + @mock.patch('accumulate_bytes.common.reset_wifi') + @mock.patch('accumulate_bytes.uci', new_callable = FakeUci) + def test_turn_off_adapter_if_on_and_insufficient_bandwidth(self, uci, reset): + self.with_usage_in_mb(uci, "20") + uci.set("openwireless.maxmonthlybandwidth", "20") + uci.set("wireless.@wifi-iface[1].disabled", "0") + uci.commit("all") + + accumulate_bytes.update_network_availability() + + self.assertEquals(uci.get("wireless.@wifi-iface[1].disabled"), "1") + reset.assert_called_with() + From 65ea99a1d8c77af4bf14ea46768fbaf756435196 Mon Sep 17 00:00:00 2001 From: Andrew Kiellor Date: Sun, 30 Nov 2014 23:18:18 -0800 Subject: [PATCH 6/7] Should not restart wifi if disabled state does not change. --- routerapi/accumulate_bytes | 10 ++++------ test/accumulate_bytes_test.py | 25 +++++++++++++++++++++---- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/routerapi/accumulate_bytes b/routerapi/accumulate_bytes index ed8e2f6..315dcb9 100644 --- a/routerapi/accumulate_bytes +++ b/routerapi/accumulate_bytes @@ -14,12 +14,10 @@ def update_network_availability(): use_at_last_ui_reset = float(uci.get("openwireless.use_at_last_ui_reset")) current_use = use_before_last_reset + use_since_last_reset - use_at_last_ui_reset max_use = float(uci.get("openwireless.maxmonthlybandwidth"))*1000000 - if current_use > max_use: - uci.set("wireless.@wifi-iface[1].disabled", "1") - uci.commit("wireless") - common.reset_wifi() - if current_use < max_use: - uci.set("wireless.@wifi-iface[1].disabled", "0") + current_state = uci.get("wireless.@wifi-iface[1].disabled") + new_state = "1" if current_use > max_use else "0" + if current_state != new_state: + uci.set("wireless.@wifi-iface[1].disabled", new_state) uci.commit("wireless") common.reset_wifi() diff --git a/test/accumulate_bytes_test.py b/test/accumulate_bytes_test.py index 2088058..4ae8b9d 100644 --- a/test/accumulate_bytes_test.py +++ b/test/accumulate_bytes_test.py @@ -10,6 +10,8 @@ import accumulate_bytes from fake_uci import FakeUci +@mock.patch('accumulate_bytes.common.reset_wifi') +@mock.patch('accumulate_bytes.uci', new_callable = FakeUci) class AccumulateBytesTest(unittest.TestCase): def with_usage_in_mb(self, uci, usage): uci.set("openwireless.use_before_last_reset", "0") @@ -17,8 +19,6 @@ def with_usage_in_mb(self, uci, usage): uci.set("openwireless.use_at_last_ui_reset", "0") uci.commit("openwireless") - @mock.patch('accumulate_bytes.common.reset_wifi') - @mock.patch('accumulate_bytes.uci', new_callable = FakeUci) def test_turn_on_adapter_if_off_and_sufficient_bandwidth(self, uci, reset): uci.set("openwireless.maxmonthlybandwidth", "20") uci.set("wireless.@wifi-iface[1].disabled", "1") @@ -30,8 +30,6 @@ def test_turn_on_adapter_if_off_and_sufficient_bandwidth(self, uci, reset): self.assertEquals(uci.get("wireless.@wifi-iface[1].disabled"), "0") reset.assert_called_with() - @mock.patch('accumulate_bytes.common.reset_wifi') - @mock.patch('accumulate_bytes.uci', new_callable = FakeUci) def test_turn_off_adapter_if_on_and_insufficient_bandwidth(self, uci, reset): self.with_usage_in_mb(uci, "20") uci.set("openwireless.maxmonthlybandwidth", "20") @@ -43,3 +41,22 @@ def test_turn_off_adapter_if_on_and_insufficient_bandwidth(self, uci, reset): self.assertEquals(uci.get("wireless.@wifi-iface[1].disabled"), "1") reset.assert_called_with() + def test_do_not_reset_when_not_changing_on_state(self, uci, reset): + self.with_usage_in_mb(uci, "20") + uci.set("openwireless.maxmonthlybandwidth", "40") + uci.set("wireless.@wifi-iface[1].disabled", "0") + uci.commit("all") + + accumulate_bytes.update_network_availability() + + self.assertFalse(reset.called) + + def test_do_not_reset_when_not_changing_off_state(self, uci, reset): + self.with_usage_in_mb(uci, "20") + uci.set("openwireless.maxmonthlybandwidth", "10") + uci.set("wireless.@wifi-iface[1].disabled", "1") + uci.commit("all") + + accumulate_bytes.update_network_availability() + + self.assertFalse(reset.called) From d983251b188d6fae985bb1a1770bb92efe286cad Mon Sep 17 00:00:00 2001 From: Andrew Kiellor Date: Mon, 1 Dec 2014 00:21:30 -0800 Subject: [PATCH 7/7] Fix fake_uci for multiple sections. --- test/accumulate_bytes_test.py | 12 ++++++--- test/fake_uci.py | 12 ++++++--- test/fake_uci_test.py | 46 +++++++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 8 deletions(-) create mode 100644 test/fake_uci_test.py diff --git a/test/accumulate_bytes_test.py b/test/accumulate_bytes_test.py index 4ae8b9d..066efac 100644 --- a/test/accumulate_bytes_test.py +++ b/test/accumulate_bytes_test.py @@ -23,7 +23,8 @@ def test_turn_on_adapter_if_off_and_sufficient_bandwidth(self, uci, reset): uci.set("openwireless.maxmonthlybandwidth", "20") uci.set("wireless.@wifi-iface[1].disabled", "1") self.with_usage_in_mb(uci, "0") - uci.commit("all") + uci.commit("openwireless") + uci.commit("wireless") accumulate_bytes.update_network_availability() @@ -34,7 +35,8 @@ def test_turn_off_adapter_if_on_and_insufficient_bandwidth(self, uci, reset): self.with_usage_in_mb(uci, "20") uci.set("openwireless.maxmonthlybandwidth", "20") uci.set("wireless.@wifi-iface[1].disabled", "0") - uci.commit("all") + uci.commit("openwireless") + uci.commit("wireless") accumulate_bytes.update_network_availability() @@ -45,7 +47,8 @@ def test_do_not_reset_when_not_changing_on_state(self, uci, reset): self.with_usage_in_mb(uci, "20") uci.set("openwireless.maxmonthlybandwidth", "40") uci.set("wireless.@wifi-iface[1].disabled", "0") - uci.commit("all") + uci.commit("openwireless") + uci.commit("wireless") accumulate_bytes.update_network_availability() @@ -55,7 +58,8 @@ def test_do_not_reset_when_not_changing_off_state(self, uci, reset): self.with_usage_in_mb(uci, "20") uci.set("openwireless.maxmonthlybandwidth", "10") uci.set("wireless.@wifi-iface[1].disabled", "1") - uci.commit("all") + uci.commit("openwireless") + uci.commit("wireless") accumulate_bytes.update_network_availability() diff --git a/test/fake_uci.py b/test/fake_uci.py index a78155d..b860e5b 100644 --- a/test/fake_uci.py +++ b/test/fake_uci.py @@ -1,6 +1,6 @@ class FakeUci: - def __init__(self): - self.data = {} + def __init__(self, data={}): + self.data = data self.tmp = {} def get(self, name): @@ -10,5 +10,9 @@ def set(self, name, value): self.tmp[name] = value def commit(self, section): - self.data = dict(self.data.items() + self.tmp.items()) - self.tmp = {} + match = lambda x: x[0].startswith(section + ".") + tmp_section_items = [i for i in self.tmp.items() if match(i)] + non_tmp_section_items = [i for i in self.tmp.items() if not match(i)] + + self.data = dict(self.data.items() + tmp_section_items) + self.tmp = dict(non_tmp_section_items) diff --git a/test/fake_uci_test.py b/test/fake_uci_test.py new file mode 100644 index 0000000..f98a787 --- /dev/null +++ b/test/fake_uci_test.py @@ -0,0 +1,46 @@ +import unittest + +from fake_uci import FakeUci + +class FakeUciTest(unittest.TestCase): + def test_get_when_key_exists(self): + uci = FakeUci(data = {'section.key': 1}) + + self.assertEquals(1, uci.get('section.key')) + + def test_get_when_key_missing(self): + uci = FakeUci(data = {}) + + self.assertRaises(KeyError, uci.get, ('section.key')) + + def test_set_without_commit(self): + uci = FakeUci() + + uci.set('section.key', 1) + + self.assertRaises(KeyError, uci.get, ('section.key')) + + def test_set_with_commit(self): + uci = FakeUci() + + uci.set('section.key', 1) + uci.commit('section') + + self.assertEquals(1, uci.get('section.key')) + + def test_set_with_commit_on_different_section(self): + uci = FakeUci() + + uci.set('section.key', 1) + uci.commit('section1') + + self.assertRaises(KeyError, uci.get, ('section.key')) + + def test_set_with_commit_on_section_after_commit_on_different_section(self): + uci = FakeUci() + + uci.set('section.key', 1) + uci.commit('section1') + uci.commit('section') + + self.assertEquals(1, uci.get('section.key'))