diff --git a/tests/functional2/store/test_evil_nars.py b/tests/functional2/store/test_evil_nars.py index 937eed0ce..e1df94d84 100644 --- a/tests/functional2/store/test_evil_nars.py +++ b/tests/functional2/store/test_evil_nars.py @@ -1,5 +1,7 @@ import pytest import os +import unicodedata +from pathlib import Path from ..testlib.nar import * from ..testlib.fixtures import Nix from io import BytesIO @@ -12,59 +14,59 @@ meow_nfd = meow_nfd_.encode('utf-8') assert meow_nfc != meow_nfd EVIL_NARS: list[tuple[str, NarItem]] = [ - ('valid-dir-1', Directory([ - (b'a-nested', Directory([ + ('valid-dir-1', DirectoryUnordered([ + (b'a-nested', DirectoryUnordered([ (b'loopy', Symlink(b'../abc-nested')) ])), (b'b-file', Regular(False, b'meow kbity')), (b'c-exe', Regular(True, b'#!/usr/bin/env cat\nmeow kbity')), ])), - ('invalid-slashes-1', Directory([ + ('invalid-slashes-1', DirectoryUnordered([ (b'meow', Symlink(b'meowmeow')), (b'meow/nya', Regular(False, b'eepy')), ])), - ('invalid-dot-1', Directory([ + ('invalid-dot-1', DirectoryUnordered([ (b'.', Symlink(b'meowmeow')), ])), - ('invalid-dot-2', Directory([ + ('invalid-dot-2', DirectoryUnordered([ (b'..', Symlink(b'meowmeow')), ])), - ('invalid-nul-1', Directory([ + ('invalid-nul-1', DirectoryUnordered([ (b'meow\0nya', Symlink(b'meowmeow')), ])), - ('invalid-misorder-1', Directory([ + ('invalid-misorder-1', DirectoryUnordered([ (b'zzz', Regular(False, b'eepy')), (b'kbity', Regular(False, b'meow')), ])), - ('invalid-dupe-1', Directory([ + ('invalid-dupe-1', DirectoryUnordered([ (b'zzz', Regular(False, b'eepy')), (b'zzz', Regular(False, b'meow')), ])), - ('invalid-dupe-2', Directory([ - (b'zzz', Directory([ + ('invalid-dupe-2', DirectoryUnordered([ + (b'zzz', DirectoryUnordered([ (b'meow', Regular(False, b'kbity')) ])), (b'zzz', Regular(False, b'meow')), ])), - ('invalid-dupe-3', Directory([ - (b'zzz', Directory([ + ('invalid-dupe-3', DirectoryUnordered([ + (b'zzz', DirectoryUnordered([ (b'meow', Regular(False, b'kbity')) ])), - (b'zzz', Directory([ + (b'zzz', DirectoryUnordered([ (b'meow', Regular(False, b'kbityy')) ])), ])), - ('invalid-dupe-4', Directory([ + ('invalid-dupe-4', DirectoryUnordered([ (b'zzz', Symlink(b'../kbity')), - (b'zzz', Directory([ + (b'zzz', DirectoryUnordered([ (b'meow', Regular(False, b'kbityy')) ])), ])), - ('invalid-casehack-1', Directory([ + ('invalid-casehack-1', DirectoryUnordered([ (b'ZZZ~nix~case~hack~2', Regular(False, b'meow')), (b'zzz~nix~case~hack~1', Regular(False, b'eepy')), ])), - ('invalid-casehack-2', Directory([ + ('invalid-casehack-2', DirectoryUnordered([ (b'ZZZ~nix~case~hack~1', Regular(False, b'meow')), (b'zzz~nix~case~hack~1', Regular(False, b'eepy')), ])), @@ -106,12 +108,12 @@ def test_unicode_evil_nar(nix: Nix, tmp_path: Path): # normalization is not applied to this system pytest.skip('filesystem does not use unicode normalization') - test_evil_nar(nix, 'invalid-unicode-normalization-1', Directory([ + test_evil_nar(nix, 'invalid-unicode-normalization-1', DirectoryUnordered([ # méow (meow_nfd, Regular(False, b'eepy')), (meow_nfc, Symlink(b'meowmeow')), ])) - test_evil_nar(nix, 'invalid-unicode-normalization-2', Directory([ + test_evil_nar(nix, 'invalid-unicode-normalization-2', DirectoryUnordered([ # méow (meow_nfd, Symlink(b'meowmeow')), (meow_nfc, Regular(False, b'eepy')), diff --git a/tests/functional2/testlib/fixtures/__init__.py b/tests/functional2/testlib/fixtures/__init__.py index 259132c14..49d686772 100644 --- a/tests/functional2/testlib/fixtures/__init__.py +++ b/tests/functional2/testlib/fixtures/__init__.py @@ -20,6 +20,8 @@ class CommandResult: def ok(self): if self.rc != 0: + print('stdout:', self.stdout_s) + print('stderr:', self.stderr_s) raise subprocess.CalledProcessError(returncode=self.rc, cmd=self.cmd, stderr=self.stderr, @@ -28,6 +30,8 @@ class CommandResult: def expect(self, rc: int): if self.rc != rc: + print('stdout:', self.stdout_s) + print('stderr:', self.stderr_s) raise subprocess.CalledProcessError(returncode=self.rc, cmd=self.cmd, stderr=self.stderr, diff --git a/tests/functional2/testlib/nar.py b/tests/functional2/testlib/nar.py index ffeb5a809..927e3feab 100644 --- a/tests/functional2/testlib/nar.py +++ b/tests/functional2/testlib/nar.py @@ -7,14 +7,14 @@ See "The Purely Functional Software Deployment Model", fig. 5.2 [1]. from abc import ABCMeta, abstractmethod import dataclasses import struct -from pathlib import Path from typing import Protocol -import unicodedata class Writable(Protocol): """Realistically could just be IOBase but this is more constrained""" - def write(self, data: bytes, /) -> int: ... + + def write(self, data: bytes, /) -> int: + ... @dataclasses.dataclass @@ -68,7 +68,7 @@ class Regular(NarItem): @dataclasses.dataclass -class Directory(NarItem): +class DirectoryUnordered(NarItem): entries: list[tuple[bytes, NarItem]] """Entries in the directory, not required to be in order because this nar is evil""" type_ = b'directory' @@ -91,6 +91,15 @@ class Directory(NarItem): self.entry(out, name, entry) +@dataclasses.dataclass +class Directory(NarItem): + entries: dict[bytes, NarItem] + + def serialize_type(self, out: NarListener): + for name, item in sorted(self.entries.items(), key=lambda v: v[0]): + DirectoryUnordered.entry(out, name, item) + + @dataclasses.dataclass class Symlink(NarItem): target: bytes