summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrett Holman <brett.holman@canonical.com>2021-11-17 11:35:00 -0700
committerGitHub <noreply@github.com>2021-11-17 12:35:00 -0600
commit7f03da357e4e72f7fe09e9b35b23ba1d83477f6c (patch)
tree1fe38ed74d9396cfc96cfb97f28ff4e769c7d59d
parent8c52bb3fc530742fce50f7f1061a24f3c453ef94 (diff)
downloadvyos-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.
-rw-r--r--tests/integration_tests/modules/test_combined.py2
-rw-r--r--tests/integration_tests/modules/test_growpart.py62
-rw-r--r--tests/unittests/test_handler/test_handler_growpart.py69
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',