pytest-testinfra icon indicating copy to clipboard operation
pytest-testinfra copied to clipboard

File module fails in MacOS with coreutils installed

Open relaxdiego opened this issue 4 years ago • 3 comments

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.

relaxdiego avatar Dec 17 '21 03:12 relaxdiego

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 avatar Jan 07 '22 13:01 relaxdiego

@relaxdiego hi, no because this need to work on remote system as well, and python might not be installed here.

philpep avatar Jan 07 '22 14:01 philpep

D’oh! How could I forget that 🤦‍♂️. What about specifying the full path (/bin/stat) in DarwinFile?

relaxdiego avatar Jan 07 '22 22:01 relaxdiego