File: command_test.py

package info (click to toggle)
kiwi 10.2.33-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 7,528 kB
  • sloc: python: 67,299; sh: 3,980; xml: 3,379; ansic: 391; makefile: 354
file content (140 lines) | stat: -rw-r--r-- 5,119 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
from unittest.mock import patch
from collections import namedtuple
from pytest import raises
import unittest.mock as mock
import os

import pytest

from kiwi.command import Command

from kiwi.exceptions import (
    KiwiCommandError,
    KiwiCommandNotFound
)


class TestCommand:
    @patch('kiwi.path.Path.which')
    @patch('subprocess.Popen')
    def test_run_raises_error(self, mock_popen, mock_which):
        mock_which.return_value = 'command'
        mock_process = mock.Mock()
        mock_process.communicate = mock.Mock(
            return_value=[str.encode(''), str.encode('')]
        )
        mock_process.returncode = 1
        mock_popen.return_value = mock_process
        with raises(KiwiCommandError):
            Command.run(['command', 'args'])

    @patch('kiwi.path.Path.which')
    @patch('subprocess.Popen')
    def test_run_failure(self, mock_popen, mock_which):
        mock_which.return_value = 'command'
        mock_popen.side_effect = OSError('Run failure')
        with raises(KiwiCommandError):
            Command.run(['command', 'args'])

    def test_run_invalid_environment(self):
        with raises(KiwiCommandNotFound):
            Command.run(['command', 'args'], custom_env={'PATH': '/root'})

    @patch('kiwi.path.Path.which')
    @patch('subprocess.Popen')
    def test_run_does_not_raise_error(self, mock_popen, mock_which):
        mock_which.return_value = 'command'
        mock_process = mock.Mock()
        mock_process.communicate = mock.Mock(
            return_value=[str.encode('stdout'), str.encode('')]
        )
        mock_process.returncode = 1
        mock_popen.return_value = mock_process
        result = Command.run(['command', 'args'], os.environ, False)
        assert result.error == ''
        assert result.output == 'stdout'

    @patch('kiwi.path.Path.which')
    def test_run_does_not_raise_error_if_command_not_found(self, mock_which):
        mock_which.return_value = None
        result = Command.run(['command', 'args'], os.environ, raise_on_command_not_found=False)
        assert result is None

    @patch('kiwi.path.Path.which')
    @patch('os.path.exists')
    @patch('subprocess.Popen')
    def test_run_does_not_call_which_for_abspaths(self, mock_popen, mock_exists, mock_which):
        mock_exists.return_value = True
        proc = mock.MagicMock()
        proc.communicate.return_value = (str.encode("stdout"), str.encode("stderr"))
        proc.returncode = 0
        mock_popen.return_value = proc

        result = Command.run(['/bin/command', 'args'])
        mock_which.assert_not_called()
        assert result is not None

    @patch('kiwi.path.Path.which')
    @patch('os.path.exists')
    def test_run_fails_for_non_existent_abspath(self, mock_exists, mock_which):
        mock_exists.return_value = False

        with pytest.raises(KiwiCommandNotFound) as cmd_not_found_err:
            Command.run(['/bin/command', 'args'])

        mock_which.assert_not_called()
        assert '"/bin/command" not found' in str(cmd_not_found_err.value)

    @patch('os.access')
    @patch('os.path.exists')
    @patch('subprocess.Popen')
    def test_run(self, mock_popen, mock_exists, mock_access):
        mock_exists.return_value = True
        command_run = namedtuple(
            'command', ['output', 'error', 'returncode']
        )
        run_result = command_run(
            output='stdout',
            error='stderr',
            returncode=0
        )
        mock_process = mock.Mock()
        mock_process.communicate = mock.Mock(
            return_value=[str.encode('stdout'), str.encode('stderr')]
        )
        mock_process.returncode = 0
        mock_popen.return_value = mock_process
        mock_access.return_value = True
        assert Command.run(['command', 'args']) == run_result

    def test_run_command_does_not_exist(self):
        with raises(KiwiCommandNotFound):
            Command.run(['does-not-exist'])

    def test_call_command_does_not_exist(self):
        with raises(KiwiCommandNotFound):
            Command.call(['does-not-exist'], os.environ)

    @pytest.mark.parametrize("available", (True, False))
    @patch('kiwi.path.Path.which')
    @patch('subprocess.Popen')
    @patch('select.select')
    def test_call(self, mock_select, mock_popen, mock_which, available: bool):
        mock_which.return_value = 'command'
        mock_select.return_value = [True, False, not available]
        mock_process = mock.Mock()
        mock_popen.return_value = mock_process
        call = Command.call(['command', 'args'])
        assert call.output_available() == available
        assert call.error_available() == available
        assert call.output == mock_process.stdout
        assert call.error == mock_process.stderr
        assert call.process == mock_process

    @patch('kiwi.path.Path.which')
    @patch('subprocess.Popen')
    def test_call_failure(self, mock_popen, mock_which):
        mock_which.return_value = 'command'
        mock_popen.side_effect = KiwiCommandError('Call failure')
        with raises(KiwiCommandError):
            Command.call(['command', 'args'])