Skip to content

Commit

Permalink
tests: Add a pre-allocation test
Browse files Browse the repository at this point in the history
I used this test when diagnosing openzfs#281 and think it would be a good
addition.

This tests file sizes when pre-allocating a file.

Expected values have been confirmed on NTFS, ReFS and FAT32.
This test currently does not work on a SMB share with the Samba server
because it reports a fixed cluster size based on a configuration option
instead of getting the correct value from the underlying file system.
ksmbd does not have the same issue, it correctly gets the values from
the file system. So far this is untested with Windows SMB shares.

Signed-off-by: Axel Gembe <[email protected]>
  • Loading branch information
EchterAgo committed Oct 11, 2023
1 parent 30f59ca commit 4b7824b
Show file tree
Hide file tree
Showing 4 changed files with 752 additions and 222 deletions.
33 changes: 33 additions & 0 deletions .github/workflows/windows-build-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2735,3 +2735,36 @@ jobs:



test9_regression_test:
needs: [build_windows]
timeout-minutes: 30
runs-on: windows-latest
steps:
- uses: actions/checkout@v3

- uses: actions/download-artifact@v3
with:
name: dev_build_inno

- name: get zfsexename
id: zfsinstaller
run: |
$p = Get-ChildItem | Where-Object {$_.Name -like 'OpenZFSOnWindows-*.exe'} | Select-Object -first 1
echo $p
$f = (Get-Item $p ).Name
echo $f
echo "filename=$f" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append
# https://github.com/MicrosoftDocs/windows-powershell-docs/issues/266
- name: Import root certificate
run: |
$plaintextpwd = 'password1234'
$pwd = ConvertTo-SecureString -String $plaintextpwd -Force -AsPlainText
Import-PfxCertificate -FilePath ${{github.workspace}}/contrib/windows/TestCert/test_sign_cert_pass.pfx -CertStoreLocation Cert:\LocalMachine\Root -Password $pwd
Import-PfxCertificate -FilePath ${{github.workspace}}/contrib/windows/TestCert/test_sign_cert_pass.pfx -CertStoreLocation Cert:\LocalMachine\TrustedPublisher -Password $pwd
- name: install zfs
run: 'Start-Process -FilePath "${{github.workspace}}\${{ steps.zfsinstaller.outputs.filename }}" -Wait -ArgumentList "/NORESTART /ALLUSERS /VERYSILENT /LOG=`"${{github.workspace}}\InnoSetup-Install.log`""'

- name: test
run: 'python.exe -u "${{github.workspace}}\contrib\windows\tests\regression.py" --path ${{github.workspace}}\'
141 changes: 141 additions & 0 deletions contrib/windows/tests/regression.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
import argparse
import logging
import os
import pathlib
import unittest

from utils import (
ZfsContext,
Size,
setup_logging,
argparse_as_abspath,
argparse_as_zfs_abspath,
created_zpool,
preallocate_file_object,
get_sizes_from_path,
get_sizes_from_file,
get_cluster_size_from_file,
)


args: argparse.Namespace
ctx: ZfsContext


logger = setup_logging("regression", logging.INFO)
tc = unittest.TestCase()


def parse_arguments() -> argparse.Namespace:
parser = argparse.ArgumentParser(description="Process command line arguments.")

parser.add_argument("--path", type=argparse_as_abspath, required=True)

# TODO: We need to verify that the zfs path is actually usable because the default path is not
# passed to `argparse_as_zfs_abspath`.
program_files = pathlib.PureWindowsPath(os.getenv("ProgramFiles"))
default_zfs_path = program_files / "OpenZFS On Windows"
parser.add_argument(
"--zfspath",
type=argparse_as_zfs_abspath,
default=default_zfs_path,
help="Directory path of either an OpenZFS installation or build directory",
)

parser.add_argument(
"-np",
"--no_pool",
action="store_true",
default=False,
help="Don't create a zpool, run tests in path",
)

return parser.parse_args()


def test_preallocation(test_path: pathlib.Path):
"""Tests file sizes when pre-allocating a file.
Expected values have been confirmed on NTFS, ReFS and FAT32.
This test currently does not work on a SMB share with the Samba server
because it reports a fixed cluster size based on a configuration option
instead of getting the correct value from the underlying file system. ksmbd
does not have the same issue, it correctly gets the values from the file
system. So far this is untested with Windows SMB shares.
Args:
test_path (pathlib.Path): The path where we want to run the test
"""

fpath = test_path / "testfile.bin"

try:
with open(fpath, "wb") as test_file:
csize = get_cluster_size_from_file(test_file)
tc.assertNotEqual(csize, 0, f"Reported cluster size for {fpath} is 0")

fsize = get_sizes_from_file(test_file)
tc.assertEqual(
fsize,
{"AllocationSize": 0, "EndOfFile": 0},
f"Wrong file size after creation of {fpath}",
)

preallocate_file_object(test_file, 512)

fsize = get_sizes_from_file(test_file)
tc.assertEqual(
fsize,
{"AllocationSize": csize, "EndOfFile": 0},
f"Wrong file size after preallocation of {fpath}",
)

test_file.write(b"\x55" * 117)

fsize = get_sizes_from_file(test_file)
tc.assertEqual(
fsize,
{"AllocationSize": csize, "EndOfFile": 0},
f"Wrong file size after write to preallocated file {fpath}",
)

fsize = get_sizes_from_path(fpath)
tc.assertEqual(
fsize,
{"AllocationSize": csize, "EndOfFile": 117},
f"Wrong file size after close of preallocated file {fpath}",
)
finally:
if os.path.isfile(fpath):
os.unlink(fpath)


def run_tests(test_path: pathlib.Path):
test_preallocation(test_path)


def main():
global args
global ctx

args = parse_arguments()
ctx = ZfsContext(args.zfspath)

if args.no_pool:
run_tests(args.path)
else:
test_backing_file = args.path / "test.dat"

with created_zpool(
ctx, "test", test_backing_file, 1 * Size.GIB
) as test_pool_path:
logger.info(
f'Created zpool named "test", backed by {test_backing_file}, mounted in {test_pool_path}'
)

run_tests(test_pool_path)

logger.info("PASSED")


if __name__ == "__main__":
main()
Loading

0 comments on commit 4b7824b

Please sign in to comment.