Repository: borgbackup/borg

Issue:
openindiana borg create --content-from-command return code
These tests are failing on openindiana:

```
self = <borg.testsuite.archiver.ArchiverTestCase testMethod=test_create_content_from_command_with_failed_command>

    def test_create_content_from_command_with_failed_command(self):
        self.cmd('init', '--encryption=repokey', self.repository_location)
        output = self.cmd('create', '--content-from-command', self.repository_location + '::test',
                          '--', 'false', '--arg-passed-to-false', exit_code=2)
>       assert output.endswith("Command 'false' exited with status 1\n")
E       AssertionError: assert False
E        +  where False = <built-in method endswith of str object at 0xfffffd7feb435ea0>("Command 'false' exited with status 1\n")
E        +    where <built-in method endswith of str object at 0xfffffd7feb435ea0> = "Command 'false' exited with status 255\n".endswith

src/borg/testsuite/archiver.py:1064: AssertionError
_________________________________________________ RemoteArchiverTestCase.test_create_content_from_command_with_failed_command _________________________________________________

self = <borg.testsuite.archiver.RemoteArchiverTestCase testMethod=test_create_content_from_command_with_failed_command>

    def test_create_content_from_command_with_failed_command(self):
        self.cmd('init', '--encryption=repokey', self.repository_location)
        output = self.cmd('create', '--content-from-command', self.repository_location + '::test',
                          '--', 'false', '--arg-passed-to-false', exit_code=2)
>       assert output.endswith("Command 'false' exited with status 1\n")
E       AssertionError: assert False
E        +  where False = <built-in method endswith of str object at 0xfffffd7feac83d40>("Command 'false' exited with status 1\n")
E        +    where <built-in method endswith of str object at 0xfffffd7feac83d40> = "Command 'false' exited with status 255\n".endswith

src/borg/testsuite/archiver.py:1064: AssertionError
```


Discussion:
```
(borg-env) vagrant@openindiana:~/borg/borg$ false
(borg-env) vagrant@openindiana:~/borg/borg$ echo $?
1
```
Strange that we see 255 in the test!?
Related code in archiver.py:
```
                    try:
                        try:
                            proc = subprocess.Popen(args.paths, stdout=subprocess.PIPE)
                        except (FileNotFoundError, PermissionError) as e:
                            self.print_error('Failed to execute command: %s', e)
                            return self.exit_code
                        status = fso.process_pipe(path=path, cache=cache, fd=proc.stdout)
                        rc = proc.wait()
                        if rc != 0:
                            self.print_error('Command %r exited with status %d', args.paths[0], rc)
                            return self.exit_code
                    except BackupOSError as e:
                        self.print_error('%s: %s', path, e)
                        return self.exit_code
```

I've had a look at the manpage of `false` and it just states that it'll "[e]xit with a status code indicating failure". Guess we should not rely on it returning one.

As for using `false` in a shell, it's often implemented as a built-in. Example from bash:

```
$ type false
false is a shell builtin
```

It's very possible that the built-in exits with a different code. Guess you could bypass the built-in and see what that returns: `command false; echo $?`.

I'll open a pull request to make the test no longer rely on `false` returning 1.

Resolving patch:
diff --git a/src/borg/testsuite/archiver.py b/src/borg/testsuite/archiver.py
--- a/src/borg/testsuite/archiver.py
+++ b/src/borg/testsuite/archiver.py
@@ -1060,8 +1060,8 @@ def test_create_content_from_command(self):
     def test_create_content_from_command_with_failed_command(self):
         self.cmd('init', '--encryption=repokey', self.repository_location)
         output = self.cmd('create', '--content-from-command', self.repository_location + '::test',
-                          '--', 'false', '--arg-passed-to-false', exit_code=2)
-        assert output.endswith("Command 'false' exited with status 1\n")
+                          '--', 'sh', '-c', 'exit 73;', exit_code=2)
+        assert output.endswith("Command 'sh' exited with status 73\n")
         archive_list = json.loads(self.cmd('list', '--json', self.repository_location))
         assert archive_list['archives'] == []
 


Test patch: