diff --git a/openwisp-config/files/lib/openwisp/utils.lua b/openwisp-config/files/lib/openwisp/utils.lua index 82db0ea..ac98754 100644 --- a/openwisp-config/files/lib/openwisp/utils.lua +++ b/openwisp-config/files/lib/openwisp/utils.lua @@ -7,6 +7,13 @@ function starts_with_dot(str) return false end +function add_values_to_set(set, values) + for i, el in pairs(values) do + set[el] = true + end + return set +end + -- writes uci section, eg: -- -- write_uci_section(cursor, 'network', { @@ -49,9 +56,12 @@ function write_uci_option(cursor, config, name, key, value) if type(value) == 'table' then -- create set with unique values local set = {} - for i, el in pairs(value) do - set[el] = true + -- read existing value + current = cursor:get(config, name, key) + if type(current) == 'table' then + set = add_values_to_set(set, current) end + set = add_values_to_set(set, value) -- reset value var with set contents value = {} for item_value, present in pairs(set) do diff --git a/openwisp-config/tests/test_utils.lua b/openwisp-config/tests/test_utils.lua index 269fde0..266ba95 100644 --- a/openwisp-config/tests/test_utils.lua +++ b/openwisp-config/tests/test_utils.lua @@ -138,4 +138,95 @@ function TestUtils.test_is_table_empty_false() el = "value" }), false) end + +function TestUtils.test_merge_uci_option() + u = uci.cursor(write_dir) + -- prepare config + write_uci_section(u, 'network', { + [".name"] = "wlan1", + [".type"] = "interface", + [".anonymous"] = false, + [".index"] = 5, + ipaddr = "172.27.254.252/16", + proto = "static", + ifname = "wlan1" + }) + u:commit('network') + -- add one option + write_uci_section(u, 'network', { + [".name"] = "wlan1", + [".type"] = "interface", + [".anonymous"] = false, + [".index"] = 5, + added = "merged" + }) + u:commit('network') + local file = io.open(write_dir..'/network') + luaunit.assertNotNil(file) + local contents = file:read('*all') + luaunit.assertNotNil(string.find(contents, "config interface 'wlan1'")) + luaunit.assertNotNil(string.find(contents, "option ifname 'wlan1'")) + luaunit.assertNotNil(string.find(contents, "option proto 'static'")) + luaunit.assertNotNil(string.find(contents, "option ipaddr '172.27.254.252/16'")) + luaunit.assertNotNil(string.find(contents, "option added 'merged'")) +end + +function TestUtils.test_merge_uci_list() + u = uci.cursor(write_dir) + -- prepare config + write_uci_section(u, 'network', { + [".name"] = "wlan1", + [".type"] = "interface", + [".anonymous"] = false, + [".index"] = 5, + ipaddr = {"172.27.254.252/16"}, + proto = "static", + ifname = "wlan1" + }) + u:commit('network') + -- add one option + write_uci_section(u, 'network', { + [".name"] = "wlan1", + [".type"] = "interface", + [".anonymous"] = false, + [".index"] = 5, + ipaddr = {"172.27.254.253/16"}, + }) + u:commit('network') + local file = io.open(write_dir..'/network') + luaunit.assertNotNil(file) + local contents = file:read('*all') + luaunit.assertNotNil(string.find(contents, "list ipaddr '172.27.254.252/16'")) + luaunit.assertNotNil(string.find(contents, "list ipaddr '172.27.254.253/16'")) +end + +function TestUtils.test_merge_uci_list_duplicate() + u = uci.cursor(write_dir) + -- prepare config + write_uci_section(u, 'network', { + [".name"] = "wlan1", + [".type"] = "interface", + [".anonymous"] = false, + [".index"] = 5, + ipaddr = {"172.27.254.252/16"}, + proto = "static", + ifname = "wlan1" + }) + u:commit('network') + -- add one option + write_uci_section(u, 'network', { + [".name"] = "wlan1", + [".type"] = "interface", + [".anonymous"] = false, + [".index"] = 5, + ipaddr = {"172.27.254.252/16"}, + }) + u:commit('network') + local file = io.open(write_dir..'/network') + luaunit.assertNotNil(file) + local contents = file:read('*all') + local _, count = string.gsub(contents, "list ipaddr '172.27.254.252/16'", "") + luaunit.assertEquals(count, 1) +end + os.exit(luaunit.LuaUnit.run())