summaryrefslogtreecommitdiff
path: root/smoketest/scripts/cli
diff options
context:
space:
mode:
authorJohn Estabrook <jestabro@vyos.io>2025-09-24 18:57:13 -0500
committerJohn Estabrook <jestabro@vyos.io>2025-09-24 23:27:13 -0500
commit95a7aec65de1ce64dbca3d52648d458b7a172981 (patch)
treed79089b5f2bb6ead12ca09ec63fa04ee90ef29c6 /smoketest/scripts/cli
parentc8dde333d96c08e4d61ed373dedc2f12da8e4fe1 (diff)
downloadvyos-1x-95a7aec65de1ce64dbca3d52648d458b7a172981.tar.gz
vyos-1x-95a7aec65de1ce64dbca3d52648d458b7a172981.zip
T7709: add smoketest for config save
Check that write_file_sync reaches disk, by using util vmtouch to evict cache.
Diffstat (limited to 'smoketest/scripts/cli')
-rw-r--r--smoketest/scripts/cli/base_vyostest_shim.py5
-rwxr-xr-xsmoketest/scripts/cli/test_config_save.py101
2 files changed, 106 insertions, 0 deletions
diff --git a/smoketest/scripts/cli/base_vyostest_shim.py b/smoketest/scripts/cli/base_vyostest_shim.py
index 526b24c46..56905c92a 100644
--- a/smoketest/scripts/cli/base_vyostest_shim.py
+++ b/smoketest/scripts/cli/base_vyostest_shim.py
@@ -106,6 +106,11 @@ class VyOSUnitTestSHIM:
return out
+ def cli_save(self, file):
+ if self.debug:
+ print('save')
+ self._session.save_config(file)
+
def op_mode(self, path : list) -> None:
"""
Execute OP-mode command and return stdout
diff --git a/smoketest/scripts/cli/test_config_save.py b/smoketest/scripts/cli/test_config_save.py
new file mode 100755
index 000000000..f9f403a6e
--- /dev/null
+++ b/smoketest/scripts/cli/test_config_save.py
@@ -0,0 +1,101 @@
+#!/usr/bin/env python3
+#
+# Copyright VyOS maintainers and contributors <maintainers@vyos.io>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+import os
+import unittest
+
+from vyos.utils.process import cmd
+from vyos.utils.config import read_saved_value
+from vyos.defaults import directories
+
+from base_vyostest_shim import VyOSUnitTestSHIM
+
+
+class TestConfigDep(VyOSUnitTestSHIM.TestCase):
+ def test_disk_resident(self):
+ config_file = os.path.join(directories['config'], 'config.boot')
+
+ evict_cmd = f'vmtouch -e {config_file}'
+ page_count_cmd = f'fincore -o PAGES -n {config_file}'
+
+ test_value = 'test_disk_resident'
+ test_path = ['interfaces', 'ethernet', 'eth3', 'description']
+
+ self.cli_set(test_path, value=test_value)
+ self.cli_commit()
+ self.cli_save(config_file)
+
+ cmd(evict_cmd)
+ # pages may be paged back into memory by the time the above
+ # completes (man vmtouch); either way, we read what is resident on
+ # disk. The following is just for curiosity:
+ pages = cmd(page_count_cmd)
+
+ saved_value = read_saved_value(test_path)
+
+ if self.debug:
+ print(f'vm pages on read config: {int(pages)}')
+
+ self.assertEqual(test_value, saved_value)
+
+ # clean up remaining
+ self.cli_delete(test_path)
+ self.cli_commit()
+ self.cli_save(config_file)
+
+ def test_disk_resident_atomic(self):
+ config_file = os.path.join(directories['config'], 'config.boot')
+
+ # save config will only call write_file_atomic if euid == 0:
+ # below is the command as invoked by CLI 'save'
+ save_cmd = (
+ 'sudo sg vyattacfg "umask 0002; /usr/libexec/vyos/vyos-save-config.py"'
+ )
+
+ evict_cmd = f'vmtouch -e {config_file}'
+ page_count_cmd = f'fincore -o PAGES -n {config_file}'
+
+ test_value = 'test_disk_resident'
+ test_path = ['interfaces', 'ethernet', 'eth3', 'description']
+
+ self.cli_set(test_path, value=test_value)
+ self.cli_commit()
+ cmd(save_cmd)
+
+ cmd(evict_cmd)
+ # pages may be paged back into memory by the time the above
+ # completes (man vmtouch); either way, we read what is resident on
+ # disk. The following is just for curiosity:
+ pages = cmd(page_count_cmd)
+
+ saved_value = read_saved_value(test_path)
+
+ if self.debug:
+ print(f'vm pages on read config: {int(pages)}')
+
+ # check that we have at the least sync'd config;
+ # checking actual atomicity is a different matter ...
+ self.assertEqual(test_value, saved_value)
+
+ # clean up remaining
+ self.cli_delete(test_path)
+ self.cli_commit()
+ cmd(save_cmd)
+
+
+if __name__ == '__main__':
+ unittest.main(verbosity=2)