File module fails in MacOS with coreutils installed
Given:
- Mac OS 10.15
- coreutils 9.0 (installed via HomeBrew)
- testinfra 6.0.0
When using File module methods/properties such as host.file("/path/to/file").user, testinfra fails with the following error:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/path/to/venv/lib/python3.9/site-packages/testinfra/modules/file.py", line 247, in user
return self.check_output("stat -f %%Su %s", self.path)
File "/path/to/.venv/lib/python3.9/site-packages/testinfra/modules/base.py", line 49, in check_output
return cls._host.check_output(*args, **kwargs)
File "/path/to/.venv/lib/python3.9/site-packages/testinfra/host.py", line 111, in check_output
assert out.rc == 0, "Unexpected exit code {} for {}".format(out.rc, out)
AssertionError: Unexpected exit code 1 for CommandResult(command=b'stat -f %Su /path/to/file, exit_status=1, stdout=b' File: "/path/to/file"\n ID: 100000500000019 Namelen: ? Type: apfs\nBlock size: 4096 Fundamental block size: 4096\nBlocks: Total: 122061322 Free: 33632631 Available: 30415781\nInodes: Total: 4882452880 Free: 4878422198\n', stderr=b"stat: cannot read file system information for '%Su': No such file or directory\n")
This appears to be caused by the File.get_module_class method choosing a concrete File module that makes assumptions about the stat command that don't always hold true.
In this case, the chosen concrete File module--DarwinFile--assumes that /usr/bin/stat would be used. However, if coreutils is installed, /usr/local/opt/coreutils/libexec/gnubin/stat will be found earlier in $PATH. This results in the File module using arguments that GNU stat doesn't understand.
In thinking about a solution to this, would it make sense to use Python's os.stat() method instead so that it's more portable? This approach could potentially reduce the amount of code since all of the methods that call the system's stat could be consolidated into the File class.
@relaxdiego hi, no because this need to work on remote system as well, and python might not be installed here.
D’oh! How could I forget that 🤦♂️. What about specifying the full path (/bin/stat) in DarwinFile?