diff options
author | Brett Holman <brett.holman@canonical.com> | 2021-11-17 11:35:00 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-11-17 12:35:00 -0600 |
commit | 7f03da357e4e72f7fe09e9b35b23ba1d83477f6c (patch) | |
tree | 1fe38ed74d9396cfc96cfb97f28ff4e769c7d59d /tests | |
parent | 8c52bb3fc530742fce50f7f1061a24f3c453ef94 (diff) | |
download | vyos-cloud-init-7f03da357e4e72f7fe09e9b35b23ba1d83477f6c.tar.gz vyos-cloud-init-7f03da357e4e72f7fe09e9b35b23ba1d83477f6c.zip |
testing: add growpart integration test (#1104)
Add growpart integration test and associated unit tests
Additionally, a small runcmd check for a commented line.
Diffstat (limited to 'tests')
-rw-r--r-- | tests/integration_tests/modules/test_combined.py | 2 | ||||
-rw-r--r-- | tests/integration_tests/modules/test_growpart.py | 62 | ||||
-rw-r--r-- | tests/unittests/test_handler/test_handler_growpart.py | 69 |
3 files changed, 132 insertions, 1 deletions
diff --git a/tests/integration_tests/modules/test_combined.py b/tests/integration_tests/modules/test_combined.py index 2635d41a..bc19c2a2 100644 --- a/tests/integration_tests/modules/test_combined.py +++ b/tests/integration_tests/modules/test_combined.py @@ -53,6 +53,8 @@ rsyslog: me: "127.0.0.1" runcmd: - echo 'hello world' > /var/tmp/runcmd_output + + - # - logger "My test log" snap: squashfuse_in_container: true diff --git a/tests/integration_tests/modules/test_growpart.py b/tests/integration_tests/modules/test_growpart.py new file mode 100644 index 00000000..af1e3a15 --- /dev/null +++ b/tests/integration_tests/modules/test_growpart.py @@ -0,0 +1,62 @@ +import os +import pytest +import pathlib +import json +from uuid import uuid4 +from pycloudlib.lxd.instance import LXDInstance + +from cloudinit.subp import subp +from tests.integration_tests.instances import IntegrationInstance + +DISK_PATH = '/tmp/test_disk_setup_{}'.format(uuid4()) + + +def setup_and_mount_lxd_disk(instance: LXDInstance): + subp('lxc config device add {} test-disk-setup-disk disk source={}'.format( + instance.name, DISK_PATH).split()) + + +@pytest.fixture(scope='class', autouse=True) +def create_disk(): + """Create 16M sparse file""" + pathlib.Path(DISK_PATH).touch() + os.truncate(DISK_PATH, 1 << 24) + yield + os.remove(DISK_PATH) + + +# Create undersized partition in bootcmd +ALIAS_USERDATA = """\ +#cloud-config +bootcmd: + - parted /dev/sdb --script \ + mklabel gpt \ + mkpart primary 0 1MiB + - parted /dev/sdb --script print +growpart: + devices: + - "/" + - "/dev/sdb1" +runcmd: + - parted /dev/sdb --script print +""" + + +@pytest.mark.user_data(ALIAS_USERDATA) +@pytest.mark.lxd_setup.with_args(setup_and_mount_lxd_disk) +@pytest.mark.ubuntu +@pytest.mark.lxd_vm +class TestGrowPart: + """Test growpart""" + + def test_grow_part(self, client: IntegrationInstance): + """Verify """ + log = client.read_from_file('/var/log/cloud-init.log') + assert ("cc_growpart.py[INFO]: '/dev/sdb1' resized:" + " changed (/dev/sdb, 1) from") in log + + lsblk = json.loads(client.execute('lsblk --json')) + sdb = [x for x in lsblk['blockdevices'] if x['name'] == 'sdb'][0] + assert len(sdb['children']) == 1 + assert sdb['children'][0]['name'] == 'sdb1' + assert sdb['size'] == '16M' diff --git a/tests/unittests/test_handler/test_handler_growpart.py b/tests/unittests/test_handler/test_handler_growpart.py index 7f039b79..b7d5d7ba 100644 --- a/tests/unittests/test_handler/test_handler_growpart.py +++ b/tests/unittests/test_handler/test_handler_growpart.py @@ -3,16 +3,19 @@ from cloudinit import cloud from cloudinit.config import cc_growpart from cloudinit import subp +from cloudinit import temp_utils from cloudinit.tests.helpers import TestCase import errno import logging import os +import shutil import re import unittest from contextlib import ExitStack from unittest import mock +import stat # growpart: # mode: auto # off, on, auto, 'growpart' @@ -58,6 +61,28 @@ usage: gpart add -t type [-a alignment] [-b start] <SNIP> geom """ +class Dir: + '''Stub object''' + def __init__(self, name): + self.name = name + self.st_mode = name + + def is_dir(self, *args, **kwargs): + return True + + def stat(self, *args, **kwargs): + return self + + +class Scanner: + '''Stub object''' + def __enter__(self): + return (Dir(''), Dir(''),) + + def __exit__(self, *args): + pass + + class TestDisabled(unittest.TestCase): def setUp(self): super(TestDisabled, self).setUp() @@ -91,6 +116,13 @@ class TestConfig(TestCase): self.cloud_init = None self.handle = cc_growpart.handle + self.tmppath = '/tmp/cloudinit-test-file' + self.tmpdir = os.scandir('/tmp') + self.tmpfile = open(self.tmppath, 'w') + + def tearDown(self): + self.tmpfile.close() + os.remove(self.tmppath) @mock.patch.dict("os.environ", clear=True) def test_no_resizers_auto_is_fine(self): @@ -130,7 +162,42 @@ class TestConfig(TestCase): mockobj.assert_called_once_with( ['growpart', '--help'], env={'LANG': 'C'}) - @mock.patch.dict("os.environ", clear=True) + @mock.patch.dict("os.environ", {'LANG': 'cs_CZ.UTF-8'}, clear=True) + @mock.patch.object(temp_utils, 'mkdtemp', return_value='/tmp/much-random') + @mock.patch.object(stat, 'S_ISDIR', return_value=False) + @mock.patch.object(os.path, 'samestat', return_value=True) + @mock.patch.object(os.path, "join", return_value='/tmp') + @mock.patch.object(os, 'scandir', return_value=Scanner()) + @mock.patch.object(os, 'mkdir') + @mock.patch.object(os, 'unlink') + @mock.patch.object(os, 'rmdir') + @mock.patch.object(os, 'open', return_value=1) + @mock.patch.object(os, 'close') + @mock.patch.object(shutil, 'rmtree') + @mock.patch.object(os, 'lseek', return_value=1024) + @mock.patch.object(os, 'lstat', return_value='interesting metadata') + def test_force_lang_check_tempfile(self, *args, **kwargs): + with mock.patch.object( + subp, + 'subp', + return_value=(HELP_GROWPART_RESIZE, "")) as mockobj: + + ret = cc_growpart.resizer_factory(mode="auto") + self.assertIsInstance(ret, cc_growpart.ResizeGrowPart) + diskdev = '/dev/sdb' + partnum = 1 + partdev = '/dev/sdb' + ret.resize(diskdev, partnum, partdev) + mockobj.assert_has_calls([ + mock.call( + ["growpart", '--dry-run', diskdev, partnum], + env={'LANG': 'C', 'TMPDIR': '/tmp'}), + mock.call( + ["growpart", diskdev, partnum], + env={'LANG': 'C', 'TMPDIR': '/tmp'}), + ]) + + @mock.patch.dict("os.environ", {'LANG': 'cs_CZ.UTF-8'}, clear=True) def test_mode_auto_falls_back_to_gpart(self): with mock.patch.object( subp, 'subp', |