[U-Boot] [PATCH] test/py: gpt: make use of infra-structure

From: Stephen Warren swarren@nvidia.com
Make various changes to the GPT test:
1) Reference the disk image using an absolute path in all cases. This allows test/py to operate correctly if it's run from a directory other than the root of the U-Boot source tree.
2) Store the disk image in the teswt/py persistent data directory. This removes the need to re-generate it every time the tests are run.
3) Execute sgdisk using u_boot_utils.run_and_log() so that its output is captured in the test log. This allows debugging any problems running it.
4) Make the disk image a test fixture. This removes the requirement to always run all GPT tests, and run them in order. The current code doesn't create the disk image if e.g. just test_gpt_uuid() is executed via the test.py -k command-line option.
5) Use @pytest.mark.buildconfigspec for all feature dependencies, rather than manually implementing some of them.
Fixes: a2f422555fc8 ("add pytests for 'gpt guid' command in sandbox") Fixes: c5772188ede9 ("add pytests for 'gpt rename' and 'gpt swap'") Signed-off-by: Stephen Warren swarren@nvidia.com --- test/py/make_test_disk.py | 19 ----------- test/py/tests/test_gpt.py | 83 +++++++++++++++++++++++++++++++++++------------ 2 files changed, 62 insertions(+), 40 deletions(-) delete mode 100755 test/py/make_test_disk.py
diff --git a/test/py/make_test_disk.py b/test/py/make_test_disk.py deleted file mode 100755 index 5288295588a7..000000000000 --- a/test/py/make_test_disk.py +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright (c) 2017 Alison Chaiken -# -# SPDX-License-Identifier: GPL-2.0 -# -# Create a block device for testing of 'gpt' and 'part' commands. - -import os - -def makeDisk(): - if (os.path.exists("testdisk.raw")): - os.remove("testdisk.raw") - fd = os.open("testdisk.raw", os.O_RDWR|os.O_CREAT ) - os.ftruncate(fd, 4194304) - os.close(fd) - os.spawnl(os.P_WAIT, "/sbin/sgdisk", "sgdisk", "-U", - "375a56f7-d6c9-4e81-b5f0-09d41ca89efe", "testdisk.raw") - os.spawnl(os.P_WAIT, "/sbin/sgdisk", "sgdisk", "--new=1:2048:2560", "testdisk.raw") - os.spawnl(os.P_WAIT, "/sbin/sgdisk", "sgdisk", "--new=2:4096:4608", "testdisk.raw") - os.spawnl(os.P_WAIT, "/sbin/gdisk", "sgdisk", "-l", "testdisk.raw") diff --git a/test/py/tests/test_gpt.py b/test/py/tests/test_gpt.py index 06f24b66cef8..378d82a66e3b 100644 --- a/test/py/tests/test_gpt.py +++ b/test/py/tests/test_gpt.py @@ -1,4 +1,5 @@ # Copyright (c) 2017 Alison Chaiken +# Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. # # SPDX-License-Identifier: GPL-2.0
@@ -7,42 +8,85 @@ import os import pytest import u_boot_utils -import make_test_disk
""" -These tests rely on a 4 MB block device called testdisk.raw -which is automatically removed at the end of the tests. +These tests rely on a 4 MB disk image, which is automatically created by +the test. """
+class GptTestDiskImage(object): + """Disk Image used by the GPT tests.""" + + def __init__(self, u_boot_console): + """Initialize a new GptTestDiskImage object. + + Args: + u_boot_console: A U-Boot console. + + Returns: + Nothing. + """ + + filename = 'test_gpt_disk_image.bin' + self.path = u_boot_console.config.persistent_data_dir + '/' + filename + + if os.path.exists(self.path): + u_boot_console.log.action('Disk image file ' + self.path + + ' already exists') + else: + u_boot_console.log.action('Generating ' + self.path) + fd = os.open(self.path, os.O_RDWR | os.O_CREAT) + os.ftruncate(fd, 4194304) + os.close(fd) + sgdisk = '/sbin/sgdisk' + cmd = (sgdisk, '-U', '375a56f7-d6c9-4e81-b5f0-09d41ca89efe', + self.path) + u_boot_utils.run_and_log(u_boot_console, cmd) + cmd = (sgdisk, '--new=1:2048:2560', self.path) + u_boot_utils.run_and_log(u_boot_console, cmd) + cmd = (sgdisk, '--new=2:4096:4608', self.path) + u_boot_utils.run_and_log(u_boot_console, cmd) + cmd = (sgdisk, '-l', self.path) + u_boot_utils.run_and_log(u_boot_console, cmd) + +gtdi = None +@pytest.fixture(scope='function') +def state_disk_image(u_boot_console): + """pytest fixture to provide a GptTestDiskImage object to tests. + This is function-scoped because it uses u_boot_console, which is also + function-scoped. However, we don't need to actually do any function-scope + work, so this simply returns the same object over and over each time.""" + + global gtdi + if not gtdi: + gtdi = GptTestDiskImage(u_boot_console) + return gtdi + @pytest.mark.buildconfigspec('cmd_gpt') -def test_gpt_guid(u_boot_console): +def test_gpt_guid(state_disk_image, u_boot_console): """Test the gpt guid command."""
- if u_boot_console.config.buildconfig.get('config_cmd_gpt', 'n') != 'y': - pytest.skip('gpt command not supported') - make_test_disk.makeDisk() - u_boot_console.run_command('host bind 0 testdisk.raw') + u_boot_console.run_command('host bind 0 ' + state_disk_image.path) output = u_boot_console.run_command('gpt guid host 0') assert '375a56f7-d6c9-4e81-b5f0-09d41ca89efe' in output
@pytest.mark.buildconfigspec('cmd_gpt') -def test_gpt_save_guid(u_boot_console): +def test_gpt_save_guid(state_disk_image, u_boot_console): """Test the gpt guid command to save GUID into a string."""
if u_boot_console.config.buildconfig.get('config_cmd_gpt', 'n') != 'y': pytest.skip('gpt command not supported') - u_boot_console.run_command('host bind 0 testdisk.raw') + u_boot_console.run_command('host bind 0 ' + state_disk_image.path) output = u_boot_console.run_command('gpt guid host 0 newguid') output = u_boot_console.run_command('printenv newguid') assert '375a56f7-d6c9-4e81-b5f0-09d41ca89efe' in output
@pytest.mark.buildconfigspec('cmd_gpt') -def test_gpt_rename_partition(u_boot_console): +@pytest.mark.buildconfigspec('cmd_gpt_rename') +def test_gpt_rename_partition(state_disk_image, u_boot_console): """Test the gpt rename command to write partition names."""
- if u_boot_console.config.buildconfig.get('config_cmd_gpt_rename', 'n') != 'y': - pytest.skip('gpt rename command not supported') - u_boot_console.run_command('host bind 0 testdisk.raw') + u_boot_console.run_command('host bind 0 ' + state_disk_image.path) u_boot_console.run_command('gpt rename host 0 1 first') output = u_boot_console.run_command('gpt read host 0') assert 'name first' in output @@ -51,14 +95,12 @@ def test_gpt_rename_partition(u_boot_console): assert 'name second' in output
@pytest.mark.buildconfigspec('cmd_gpt') -def test_gpt_swap_partitions(u_boot_console): +@pytest.mark.buildconfigspec('cmd_gpt_rename') +@pytest.mark.buildconfigspec('cmd_part') +def test_gpt_swap_partitions(state_disk_image, u_boot_console): """Test the gpt swap command to exchange two partition names."""
- if u_boot_console.config.buildconfig.get('config_cmd_gpt_rename', 'n') != 'y': - pytest.skip('gpt rename command not supported') - if u_boot_console.config.buildconfig.get('config_cmd_part', 'n') != 'y': - pytest.skip('gpt swap test needs CMD_PART') - u_boot_console.run_command('host bind 0 testdisk.raw') + u_boot_console.run_command('host bind 0 ' + state_disk_image.path) output = u_boot_console.run_command('part list host 0') assert '0x000007ff "first"' in output assert '0x000017ff "second"' in output @@ -66,4 +108,3 @@ def test_gpt_swap_partitions(u_boot_console): output = u_boot_console.run_command('part list host 0') assert '0x000007ff "second"' in output assert '0x000017ff "first"' in output - os.remove('testdisk.raw')

On Fri, Sep 15, 2017 at 11:25:51AM -0600, Stephen Warren wrote:
From: Stephen Warren swarren@nvidia.com
Make various changes to the GPT test:
- Reference the disk image using an absolute path in all cases. This
allows test/py to operate correctly if it's run from a directory other than the root of the U-Boot source tree.
- Store the disk image in the teswt/py persistent data directory. This
removes the need to re-generate it every time the tests are run.
- Execute sgdisk using u_boot_utils.run_and_log() so that its output is
captured in the test log. This allows debugging any problems running it.
- Make the disk image a test fixture. This removes the requirement to
always run all GPT tests, and run them in order. The current code doesn't create the disk image if e.g. just test_gpt_uuid() is executed via the test.py -k command-line option.
- Use @pytest.mark.buildconfigspec for all feature dependencies, rather
than manually implementing some of them.
Fixes: a2f422555fc8 ("add pytests for 'gpt guid' command in sandbox") Fixes: c5772188ede9 ("add pytests for 'gpt rename' and 'gpt swap'") Signed-off-by: Stephen Warren swarren@nvidia.com
Having kicked my jenkins (sigh), and then really tried to run these tests on hardware, I think we're not quite done:
@pytest.mark.buildconfigspec('cmd_gpt') -def test_gpt_guid(u_boot_console): +def test_gpt_guid(state_disk_image, u_boot_console): """Test the gpt guid command."""
- if u_boot_console.config.buildconfig.get('config_cmd_gpt', 'n') != 'y':
pytest.skip('gpt command not supported')
- make_test_disk.makeDisk()
- u_boot_console.run_command('host bind 0 testdisk.raw')
- u_boot_console.run_command('host bind 0 ' + state_disk_image.path)
Here and elsewhere we also need to say it depends on sandbox as that's what gives the host command. Thanks!

I suggest that while we're cleaning this test up, that we add something like this to each of the tests:
diff --git a/test/py/tests/test_gpt.py b/test/py/tests/test_gpt.py index e2bbd08e6d..485d092371 100644 --- a/test/py/tests/test_gpt.py +++ b/test/py/tests/test_gpt.py @@ -67,6 +67,8 @@ def state_disk_image(u_boot_console): def test_gpt_guid(state_disk_image, u_boot_console): """Test the gpt guid command."""
+ if not os.path.exists('/sbin/sgdisk'): + pytest.skip('install gdisk package to test gpt commands')
Otherwise, the tests will all fail if the gdisk package is not installed. Assuredly anyone who does not have gdisk installed does not care about these tests anyway. If people agree, I can submit a patch, or perhaps Stephen could just add it to his.
Best wishes, Alison Chaiken Peloton Technology
On Fri, Sep 15, 2017 at 10:54 AM, Tom Rini trini@konsulko.com wrote:
On Fri, Sep 15, 2017 at 11:25:51AM -0600, Stephen Warren wrote:
From: Stephen Warren swarren@nvidia.com
Make various changes to the GPT test:
- Reference the disk image using an absolute path in all cases. This
allows test/py to operate correctly if it's run from a directory other than the root of the U-Boot source tree.
- Store the disk image in the teswt/py persistent data directory. This
removes the need to re-generate it every time the tests are run.
- Execute sgdisk using u_boot_utils.run_and_log() so that its output is
captured in the test log. This allows debugging any problems running it.
- Make the disk image a test fixture. This removes the requirement to
always run all GPT tests, and run them in order. The current code doesn't create the disk image if e.g. just test_gpt_uuid() is executed via the test.py -k command-line option.
- Use @pytest.mark.buildconfigspec for all feature dependencies, rather
than manually implementing some of them.
Fixes: a2f422555fc8 ("add pytests for 'gpt guid' command in sandbox") Fixes: c5772188ede9 ("add pytests for 'gpt rename' and 'gpt swap'") Signed-off-by: Stephen Warren swarren@nvidia.com
Having kicked my jenkins (sigh), and then really tried to run these tests on hardware, I think we're not quite done:
@pytest.mark.buildconfigspec('cmd_gpt') -def test_gpt_guid(u_boot_console): +def test_gpt_guid(state_disk_image, u_boot_console): """Test the gpt guid command."""
- if u_boot_console.config.buildconfig.get('config_cmd_gpt', 'n') != 'y':
pytest.skip('gpt command not supported')
- make_test_disk.makeDisk()
- u_boot_console.run_command('host bind 0 testdisk.raw')
- u_boot_console.run_command('host bind 0 ' + state_disk_image.path)
Here and elsewhere we also need to say it depends on sandbox as that's what gives the host command. Thanks!
-- Tom

On 09/16/2017 08:47 PM, Alison Chaiken wrote:
I suggest that while we're cleaning this test up, that we add something like this to each of the tests:
diff --git a/test/py/tests/test_gpt.py b/test/py/tests/test_gpt.py
- if not os.path.exists('/sbin/sgdisk'):
pytest.skip('install gdisk package to test gpt commands')
I'd suggest doing that in a separate commit; my patch below already does enough things that it should probably be a series of smaller patches, and the change above probably applies to other tests as well.
Otherwise, the tests will all fail if the gdisk package is not installed. Assuredly anyone who does not have gdisk installed does not care about these tests anyway. If people agree, I can submit a patch, or perhaps Stephen could just add it to his.
Best wishes, Alison Chaiken Peloton Technology
On Fri, Sep 15, 2017 at 10:54 AM, Tom Rini trini@konsulko.com wrote:
On Fri, Sep 15, 2017 at 11:25:51AM -0600, Stephen Warren wrote:
From: Stephen Warren swarren@nvidia.com
Make various changes to the GPT test:
- Reference the disk image using an absolute path in all cases. This
allows test/py to operate correctly if it's run from a directory other than the root of the U-Boot source tree.
- Store the disk image in the teswt/py persistent data directory. This
removes the need to re-generate it every time the tests are run.
- Execute sgdisk using u_boot_utils.run_and_log() so that its output is
captured in the test log. This allows debugging any problems running it.
- Make the disk image a test fixture. This removes the requirement to
always run all GPT tests, and run them in order. The current code doesn't create the disk image if e.g. just test_gpt_uuid() is executed via the test.py -k command-line option.
- Use @pytest.mark.buildconfigspec for all feature dependencies, rather
than manually implementing some of them.
Fixes: a2f422555fc8 ("add pytests for 'gpt guid' command in sandbox") Fixes: c5772188ede9 ("add pytests for 'gpt rename' and 'gpt swap'") Signed-off-by: Stephen Warren swarren@nvidia.com
Having kicked my jenkins (sigh), and then really tried to run these tests on hardware, I think we're not quite done:
@pytest.mark.buildconfigspec('cmd_gpt') -def test_gpt_guid(u_boot_console): +def test_gpt_guid(state_disk_image, u_boot_console): """Test the gpt guid command."""
- if u_boot_console.config.buildconfig.get('config_cmd_gpt', 'n') != 'y':
pytest.skip('gpt command not supported')
- make_test_disk.makeDisk()
- u_boot_console.run_command('host bind 0 testdisk.raw')
- u_boot_console.run_command('host bind 0 ' + state_disk_image.path)
Here and elsewhere we also need to say it depends on sandbox as that's what gives the host command. Thanks!
-- Tom
participants (3)
-
Alison Chaiken
-
Stephen Warren
-
Tom Rini