ba0856e1ea
* fix(errors): one condition vocabulary, one classifier per language A condition is named once (FsCondition) and every boundary keeps only a table from that name to its own number: posix, wasi preview1, and the monty guest view. CycleError gets its ELOOP seat (was EIO at every kernel and guest boundary), the wasi wire's EXDEV is 75 per wasi-libc (18 is EDOM there), and the cross-mount-rename-is-ENOENT decision moves from an adapter arm into the wasi table row. * fix(stat): one stat view per language, offset-less stamps read as UTC mtime, dir-ness, content size and the mode bits live once per language (utils/stat_view), delegating to the existing naive-stamp-is-UTC parsers. Three of the four translators (node FUSE, the runtime bridge, py wasm) read an offset-less backend stamp as local time, so python FUSE and node FUSE disagreed by the host's UTC offset for the same stamp; all four now answer the same epoch, pinned by tests. * refactor(errors): move the wasi and cpython tables into their runtimes * refactor(errors): classifier arm tables into constants modules * fix(errors): address review on the ValueError arm and epoch-zero mtime
76 lines
2.8 KiB
Python
76 lines
2.8 KiB
Python
# ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
# ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========
|
|
|
|
import errno
|
|
|
|
import pytest
|
|
|
|
from mirage.errors.posix import POSIX, gnu_phrase, posix_errno
|
|
from mirage.errors.types import FsCondition
|
|
|
|
|
|
@pytest.mark.parametrize("cond,number", [
|
|
(FsCondition.ENOENT, errno.ENOENT),
|
|
(FsCondition.ENOTDIR, errno.ENOTDIR),
|
|
(FsCondition.EISDIR, errno.EISDIR),
|
|
(FsCondition.EEXIST, errno.EEXIST),
|
|
(FsCondition.EACCES, errno.EACCES),
|
|
(FsCondition.EPERM, errno.EPERM),
|
|
(FsCondition.ENOTEMPTY, errno.ENOTEMPTY),
|
|
(FsCondition.EXDEV, errno.EXDEV),
|
|
(FsCondition.CROSS_MOUNT, errno.EXDEV),
|
|
(FsCondition.ENOTSUP, errno.ENOTSUP),
|
|
(FsCondition.ELOOP, errno.ELOOP),
|
|
(FsCondition.EINVAL, errno.EINVAL),
|
|
(FsCondition.EIO, errno.EIO),
|
|
(FsCondition.EBUSY, errno.EBUSY),
|
|
(FsCondition.EROFS, errno.EROFS),
|
|
])
|
|
def test_numbers_come_from_the_host_errno_module(cond, number):
|
|
assert posix_errno(cond) == number
|
|
|
|
|
|
def test_xattr_miss_resolves_per_platform():
|
|
# ENOATTR on macOS, ENODATA on Linux; one condition, one row.
|
|
expected = getattr(errno, "ENOATTR", None) or errno.ENODATA
|
|
assert posix_errno(FsCondition.NO_XATTR) == expected
|
|
|
|
|
|
@pytest.mark.parametrize("cond,phrase", [
|
|
(FsCondition.ENOENT, "No such file or directory"),
|
|
(FsCondition.ENOTDIR, "Not a directory"),
|
|
(FsCondition.EISDIR, "Is a directory"),
|
|
(FsCondition.EEXIST, "File exists"),
|
|
(FsCondition.EACCES, "Permission denied"),
|
|
(FsCondition.EPERM, "Operation not permitted"),
|
|
(FsCondition.ENOTEMPTY, "Directory not empty"),
|
|
(FsCondition.EXDEV, "Invalid cross-device link"),
|
|
(FsCondition.CROSS_MOUNT, "Invalid cross-device link"),
|
|
(FsCondition.ENOTSUP, "Operation not supported"),
|
|
(FsCondition.ELOOP, "Too many levels of symbolic links"),
|
|
(FsCondition.EINVAL, "Invalid argument"),
|
|
(FsCondition.EIO, "Input/output error"),
|
|
(FsCondition.EBUSY, "Device or resource busy"),
|
|
(FsCondition.EROFS, "Read-only file system"),
|
|
])
|
|
def test_phrases_are_gnu_strerror(cond, phrase):
|
|
assert gnu_phrase(cond) == phrase
|
|
|
|
|
|
def test_every_row_has_a_positive_number_and_a_phrase():
|
|
for cond in FsCondition:
|
|
row = POSIX[cond]
|
|
assert row.errno > 0
|
|
assert row.phrase
|