Files
mars-nwe/tests/afp
..

AFP integration smoke tests

Status: finished for the current AFP compatibility slice.

This directory contains the AFP endpoint smoke tests and the single remaining AFP documentation file for this test group. Earlier endpoint-inventory, WebSDK-audit, deleted-file-info, and TODO notes have been folded into this README so the AFP test directory has one Markdown entry point.

Scope

The AFP endpoints are backed by mars_nwe itself rather than Netatalk/libatalk. AFP handlers must keep NetWare semantics on mars_nwe core paths:

  • path, namespace, create, delete, rename, and directory operations use the existing mars_nwe path/namespace and object-lifecycle helpers;
  • file I/O uses normal mars_nwe NetWare file handles;
  • rights checks use mars_nwe trustee/effective-rights logic;
  • Hidden, System, Archive, timestamps, creator/modifier, backup/archive, and related metadata use mars_nwe attribute/archive/fileinfo paths;
  • AFP-only xattrs are limited to user.org.mars-nwe.afp.entry-id, user.org.mars-nwe.afp.finder-info, user.org.mars-nwe.afp.prodos-info, and future AFP-only bits in user.org.mars-nwe.afp.attributes.

Resource forks remain unsupported. AFP resource-fork requests should return the documented completion code instead of inventing a parallel storage backend.

Endpoint inventory

The generated helper remains the source of truth for fresh checks:

tests/afp/afp_endpoint_inventory.py
tests/afp/afp_endpoint_inventory.py --json

Current coverage:

Subfn Name Status Backend discipline
0x01 AFP Create Directory implemented mars_nwe namespace/object lifecycle
0x02 AFP Create File implemented mars_nwe namespace/object lifecycle; AFP xattr only for file entry-id metadata
0x03 AFP Delete implemented mars_nwe namespace/object lifecycle
0x04 AFP Get Entry ID From Name implemented mars_nwe namespace/basehandle; directory bases only
0x05 AFP Get File Information implemented mars_nwe attributes/rights plus AFP metadata xattrs
0x06 AFP Get Entry ID From NetWare Handle implemented mars_nwe file-handle lookup, then AFP entry-id metadata
0x07 AFP Rename implemented mars_nwe namespace/object lifecycle; AFP entry-id metadata follows renamed files
0x08 AFP Open File Fork implemented for data fork mars_nwe file handles; resource fork unsupported
0x09 AFP Set File Information implemented mars_nwe attributes/archive/fileinfo/trustee; AFP xattrs only for AFP metadata
0x0a AFP Scan File Information implemented mars_nwe directory scan; entry-id-only bases must resolve to directories
0x0b AFP Alloc Temporary Dir Handle implemented mars_nwe namespace and directory handles
0x0c AFP Get Entry ID From Path Name implemented mars_nwe namespace plus AFP entry-id metadata
0x0d AFP 2.0 Create Directory implemented same discipline as 0x01
0x0e AFP 2.0 Create File implemented same discipline as 0x02
0x0f AFP 2.0 Get File Information implemented same discipline as 0x05
0x10 AFP 2.0 Set File Information implemented same discipline as 0x09
0x11 AFP 2.0 Scan File Information implemented same discipline as 0x0a
0x12 AFP Get DOS Name From Entry ID implemented mars_nwe namespace and AFP entry-id reverse lookup
0x13 AFP Get Macintosh Info On Deleted Files implemented adapter over the shared salvage backend

WebSDK / Novell audit result

The AFP WebSDK pass confirmed the NCP 0x2222 / function 35 map above. The uploaded reference tree contained AFP HTML reference pages rather than a single nwafp.h; the checked pages were under:

/mnt/data/websdk_full/websdk/htmldoc/nwhtm/redleg14/a_apiref/0002R001.htm
...
/mnt/data/websdk_full/websdk/htmldoc/nwhtm/redleg14/a_apiref/0002R018.htm

The deleted-file dependency check also used the normal salvage reference pages for Scan, Recover, Purge, and old Scan Salvageable File. No AFP subfunction beyond 0x13 appeared in the WebSDK AFP reference TOC.

Important audit decisions now considered closed for this slice:

  • entry-id-only 0x0a / 0x11 scans are supported only when the AFP entry ID resolves to a directory through mars_nwe namespace/basehandle logic;
  • file AFP xattr entry IDs are not valid scan bases;
  • 0x13 is salvage-backed and must not scan live paths, .recycle, or .salvage directly from AFP code.

AFP 0x13 deleted-file metadata

AFP Get Macintosh Info On Deleted Files is NCP 0x2222 / 35 / 19 and WebSDK subfunction byte 0x13. Its request is VolumeNumber plus DOSDirectoryNumber; the reply contains FinderInfo[32], ProDOSInfo[6], resource fork size, and the deleted file name.

The implementation is finished for the current slice and remains a thin adapter over the shared mars_nwe salvage/deleted-entry backend:

  1. resolve the deleted DOS directory entry through the salvage backend;
  2. return FinderInfo from the salvage JSON snapshot;
  3. return ProDOS information from the nwatalk xattr-backed salvage JSON snapshot field prodos_info_hex;
  4. return resource fork size from the salvage JSON snapshot;
  5. return the deleted original filename from the salvage record.

The AFP code must not create a second deleted-file store and must not expose the backend .recycle / .salvage repositories as AFP-visible paths.

Build

The helpers require ncpfs/libncp headers and library, so they are optional and not built by default. Enable the test build and build individual helpers or the suite target:

cmake -DMARS_NWE_BUILD_TESTS=ON ...
cmake --build . --target afp_entry_id_smoke
cmake --build . --target afp_file_info_smoke
cmake --build . --target afp_scan_info_smoke
cmake --build . --target afp_set_file_info_smoke
cmake --build . --target afp_deleted_info_smoke
cmake --build . --target afp_smoke_suite

Smoke suite

afp_smoke_suite.sh is the single AFP integration entry point. CMake copies it into the build-tree tests/afp directory through the afp_smoke_suite target so the runtime helper stays in sync with source changes.

Example from the build tests/afp directory:

./afp_smoke_suite.sh \
  -S MARS -U SUPERVISOR -P secret \
  --path SYS:PUBLIC/pmdflts.ini \
  --unix-path /var/mars_nwe/SYS/public/pmdflts.ini \
  --log /var/log/mars_nwe/nw.log \
  --out /tmp/mars-afp-smoke.txt

The suite covers Entry ID lookup, Entry ID from NetWare handle, Get File Information, Scan File Information, Alloc Temporary Directory Handle, Create Directory, Create File, Delete, Rename, Open File Fork, Set File Information, DOS name lookup, and AFP 0x13 deleted-file metadata. It also checks the AFP xattrs on the tested Unix file:

user.org.mars-nwe.afp.finder-info
user.org.mars-nwe.afp.prodos-info
user.org.mars-nwe.afp.attributes
user.org.mars-nwe.afp.entry-id

Use --no-log when the server log is unavailable or collected separately. Use --stop-on-failure for strict bisect-style runs; by default the script keeps going so one failing endpoint does not hide later AFP output.

Rights-negative coverage

The suite can optionally exercise Modify-rights failures with a second user:

./afp_smoke_suite.sh \
  -S MARS -U SUPERVISOR -P secret \
  --path SYS:PUBLIC/pmdflts.ini \
  --unix-path /var/mars_nwe/SYS/public/pmdflts.ini \
  --readonly-user NOPASSUSER --readonly-no-password \
  --prepare-readonly-rights \
  --out /tmp/mars-afp-smoke.txt

--prepare-readonly-rights uses nwrevoke and nwgrant -r '[RF]' to grant read and file-scan rights without Modify. The negative probes verify that FinderInfo, Hidden, and System metadata writes are rejected while the SUPERVISOR positive path still succeeds. Use this only on smoke files or paths where removing an explicit trustee assignment for the readonly test user is acceptable.

Completion status

The AFP test group is complete for the current compatibility slice. Verified runs have completed with failures=0, including FinderInfo/ProDOSInfo xattr checks, AFP 35/19 deleted-file metadata, legacy and AFP 2.0 Set File Information, Hidden/System/Archive mapping through the NetWare attribute path, and Modify-rights negative coverage.

Future AFP work should keep using this README as the single documentation entry point for the test directory and should add new runtime checks to afp_smoke_suite.sh rather than creating unrelated top-level smoke scripts.