Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
S2-group
GitHub Repository: S2-group/android-runner
Path: blob/master/tests/unit/test_utils.py
908 views
1
import os
2
import os.path as op
3
import subprocess
4
import pytest
5
from mock import Mock, patch, call
6
from AndroidRunner.USBHandler import USBHandler, USBHandlerException
7
import AndroidRunner.Tests as Tests
8
import AndroidRunner.util as util
9
import paths
10
import csv
11
12
13
class TestUtilClass(object):
14
@pytest.fixture()
15
def tmp_file(self, tmpdir):
16
tmp_file = tmpdir.join('tmp.txt')
17
tmp_file.write("test content")
18
return str(tmp_file)
19
@pytest.fixture()
20
def fixture_dir(self):
21
return op.join(op.dirname(op.abspath(__file__)), 'fixtures')
22
23
def test_load_json_succes(self, tmp_file):
24
fixtures = op.join(op.dirname(op.realpath(__file__)), "fixtures")
25
config = util.load_json(op.join(fixtures, 'test_config.json'))
26
assert config['type'] == 'web'
27
assert config['devices'] == ['nexus6p']
28
assert config['randomization'] == False
29
assert config['repetitions'] == 3
30
31
def test_load_json_file_format_error(self, tmp_file):
32
fixtures = op.join(op.dirname(op.realpath(__file__)), "fixtures")
33
with pytest.raises(util.FileFormatError) as except_result:
34
util.load_json(op.join(fixtures, 'test_progress.xml'))
35
assert op.join(fixtures, 'test_progress.xml') in str(except_result.value)
36
37
def test_load_json_file_file_not_found(self, tmp_file):
38
fixtures = op.join(op.dirname(op.realpath(__file__)), "fixtures")
39
40
with pytest.raises(util.FileNotFoundError) as except_result:
41
util.load_json(op.join(fixtures, 'fake_file.json'))
42
assert "FileNotFoundError" in str(except_result.typename)
43
44
def test_load_json_file_permission_denied(self, tmp_file):
45
os.chmod(tmp_file, 0o222)
46
with pytest.raises(IOError) as except_result:
47
util.load_json(tmp_file)
48
assert "Permission denied" in str(except_result.value)
49
50
@patch("time.sleep")
51
def test_wait_until_call_succeeded(self, time_sleep_mock):
52
func_ = Mock()
53
func_.side_effect = [False, False, True]
54
55
util.wait_until(func_, 5)
56
57
assert func_.call_count == 3
58
59
@patch("time.sleep")
60
def test_wait_until_call_timeout_error(self, time_sleep_mock):
61
func_ = Mock()
62
func_.return_value = False
63
64
with pytest.raises(TimeoutError):
65
util.wait_until(func_, 5)
66
67
@patch("psutil.Process")
68
def test_keyboardinterrupt_handler(self, psutil_mock):
69
def test_function():
70
raise KeyboardInterrupt
71
72
new_function = util.keyboardinterrupt_handler(test_function)
73
new_function()
74
75
psutil_mock.return_value.terminate.assert_called_once()
76
77
def test_makedirs_succes(self, tmpdir):
78
dir_path = op.join(str(tmpdir), 'test1')
79
assert op.isdir(dir_path) is False
80
util.makedirs(dir_path)
81
assert op.isdir(dir_path) is True
82
83
def test_makedirs_fail_already_exist(self, tmpdir):
84
dir_path = op.join(str(tmpdir), 'test1')
85
assert op.isdir(dir_path) is False
86
util.makedirs(dir_path)
87
util.makedirs(dir_path)
88
assert op.isdir(dir_path) is True
89
files_in_path = [f for f in os.listdir(str(tmpdir)) if os.path.isdir(os.path.join(str(tmpdir), f))]
90
91
assert len(files_in_path) == 1
92
93
def test_makedirs_fail(self, tmpdir):
94
os.chmod(str(tmpdir), 0o444)
95
dir_path = op.join(str(tmpdir), 'test2')
96
assert op.isdir(dir_path) is False
97
with pytest.raises(OSError) as except_result:
98
util.makedirs(dir_path)
99
assert "Permission denied" in str(except_result.value)
100
assert op.isdir(dir_path) is False
101
102
def test_slugify(self):
103
string1 = "asdfghjkl.test"
104
assert util.slugify_dir(string1) == string1.replace(".", "-")
105
106
string2 = "ASDFGHJKL"
107
assert util.slugify_dir(string2) == string2.lower()
108
109
string3 = "@#$%^&*"
110
assert util.slugify_dir(string3) == ""
111
112
string4 = "a b c d e f"
113
assert util.slugify_dir(string4) == string4.replace(" ", "-")
114
115
def test_write_to_file(self, tmpdir):
116
tmp_file = op.join(str(tmpdir), 'test_output.csv')
117
test_rows = [{'key1': 'value1', 'key2': 'value2'}, {'key1': 'value3', 'key2': 'value4'}]
118
util.write_to_file(tmp_file, test_rows)
119
120
assert op.isfile(tmp_file)
121
assert self.csv_reader_to_table(tmp_file) == list(
122
[['key1', 'key2'], ['value1', 'value2'], ['value3', 'value4']])
123
124
def test_list_subdir(self, fixture_dir):
125
test_dir = op.join(fixture_dir, 'test_dir_struct')
126
127
result_subdirs = util.list_subdir(test_dir)
128
129
assert len(result_subdirs) == 2
130
assert 'data_native' in result_subdirs
131
assert 'data_web' in result_subdirs
132
133
@staticmethod
134
def csv_reader_to_table(filename):
135
result = []
136
with open(filename, mode='r') as csv_file:
137
csv_reader = csv.reader(csv_file)
138
for row in csv_reader:
139
result.append(row)
140
return result
141
142
class TestPathsClass(object):
143
def test_paths_dict(self):
144
string_config = 'test/dir/1'
145
string_output = 'test/dir/2'
146
string_base = 'test/dir/3'
147
string_original = 'test/dir/4'
148
paths.CONFIG_DIR = string_config
149
paths.OUTPUT_DIR = string_output
150
paths.BASE_OUTPUT_DIR = string_base
151
paths.ORIGINAL_CONFIG_DIR = string_original
152
153
paths_dict = paths.paths_dict()
154
assert paths_dict['ROOT_DIR'] == op.dirname(op.abspath(paths.__file__))
155
assert paths_dict['CONFIG_DIR'] == string_config
156
assert paths_dict['OUTPUT_DIR'] == string_output
157
assert paths_dict['BASE_OUTPUT_DIR'] == string_base
158
assert paths_dict['ORIGINAL_CONFIG_DIR'] == string_original
159
160
161
162
163
class TestTestsClass(object):
164
def test_is_integer_not_int(self):
165
with pytest.raises(util.ConfigError) as except_result:
166
Tests.is_integer("error")
167
assert 'error is not an integer' in str(except_result.value)
168
169
def test_is_integer_too_small(self):
170
with pytest.raises(util.ConfigError) as except_result:
171
Tests.is_integer(-1)
172
assert '-1 should be equal or larger than 0' in str(except_result.value)
173
174
def test_is_integer_succes(self):
175
assert Tests.is_integer(10) == 10
176
177
def test_cmd_not_valid(self):
178
with pytest.raises(util.ConfigError) as except_result:
179
Tests.is_valid_option("r", ["restart", "abc"])
180
assert "'r' not recognized. Use one of: ['restart', 'abc']" in str(except_result.value)
181
182
def test_cmd_truthy(self):
183
with pytest.raises(util.ConfigError) as except_result:
184
Tests.is_valid_option("True", [False, True])
185
assert "'True' not recognized. Use one of: [False, True]" in str(except_result.value)
186
187
def test_more_than_one_cmd(self):
188
with pytest.raises(util.ConfigError) as except_result:
189
Tests.is_valid_option("restart abc", ["restart", "abc"])
190
assert "'restart abc' not recognized. Use one of: ['restart', 'abc']" in str(except_result.value)
191
192
def test_cmd_is_valid(self):
193
test_command = "foo"
194
assert Tests.is_valid_option(test_command, ["bar","foo"]) == test_command
195
196
def test_is_string_fail(self):
197
with pytest.raises(util.ConfigError) as except_result:
198
Tests.is_string(list())
199
assert "String expected, got <class 'list'>" in str(except_result.value)
200
201
def test_is_string_succes(self):
202
test_string = 'This is a string'
203
assert Tests.is_string(test_string) == test_string
204
205
@patch('logging.Logger.error')
206
def test_check_dependencies_fail(self, mock_log):
207
mock_device = Mock()
208
mock_device.id = 'Fake_device'
209
mock_device.is_installed.return_value = {'NotInstalled': False, 'installed': True}
210
mocked_devices = [mock_device, mock_device]
211
212
with pytest.raises(util.ConfigError) as except_result:
213
Tests.check_dependencies(mocked_devices, "")
214
assert "Required packages ['NotInstalled'] are not installed on device Fake_device" in str(except_result.value)
215
mock_log.assert_called_once_with('Fake_device: Required package NotInstalled is not installed')
216
217
@patch('logging.Logger.error')
218
def test_check_dependencies_succes(self, mock_log):
219
mock_dependencies = Mock()
220
mock_device = Mock()
221
mock_device.id = 'Fake_device'
222
mock_device.is_installed.return_value = {'Installed2': True, 'installed': True}
223
mocked_devices = [mock_device, mock_device]
224
Tests.check_dependencies(mocked_devices, mock_dependencies)
225
assert mock_device.is_installed.call_count == 2
226
assert mock_log.call_count == 0
227
228
class TestUSBHandler(object):
229
@pytest.fixture()
230
def usb_handler(self):
231
usb_handler_config = {"enable_command" : "enable", "disable_command" : "disable"}
232
usb_handler = USBHandler(usb_handler_config)
233
return usb_handler
234
235
def test_init_error_no_enable_command(self):
236
usb_handler_config = {"disable_command" : "command"}
237
238
with pytest.raises(util.ConfigError) as exception_result:
239
usb_handler = USBHandler(usb_handler_config)
240
assert "Please provide an enable_command for the usb_handler." in str(exception_result.value)
241
242
def test_init_error_no_disable_command(self):
243
usb_handler_config = {"enable_command" : "command"}
244
245
with pytest.raises(util.ConfigError) as exception_result:
246
usb_handler = USBHandler(usb_handler_config)
247
assert "Please provide an disable_command for the usb_handler." in str(exception_result.value)
248
249
def test_init_no_config(self):
250
usb_handler_config = None
251
usb_handler = USBHandler(usb_handler_config)
252
253
assert usb_handler.usb_enable_command == None
254
assert usb_handler.usb_disable_command == None
255
assert usb_handler._usb_enabled == None
256
257
def test_init_with_valid_config(self):
258
usb_handler_config = {"enable_command" : "enable", "disable_command" : "disable"}
259
usb_handler = USBHandler(usb_handler_config)
260
261
assert usb_handler.usb_enable_command == "enable"
262
assert usb_handler.usb_disable_command == "disable"
263
assert usb_handler._usb_enabled == True
264
265
@patch("AndroidRunner.USBHandler.USBHandler._run_command")
266
def test_enable_usb_do_enable_run_command(self, run_command_mock, usb_handler):
267
usb_handler._usb_enabled = False
268
usb_handler.enable_usb()
269
270
run_command_mock.assert_called_once_with("enable")
271
assert run_command_mock.call_count == 1
272
273
@patch("AndroidRunner.USBHandler.USBHandler._run_command")
274
def test_enable_usb_do_not_run_command(self, run_command_mock, usb_handler):
275
usb_handler._usb_enabled = True
276
usb_handler.enable_usb()
277
278
assert run_command_mock.call_count == 0
279
280
@patch("AndroidRunner.USBHandler.USBHandler._run_command")
281
def test_disable_do_disable_run_command(self, run_command_mock, usb_handler):
282
usb_handler._usb_enabled = True
283
usb_handler.disable_usb()
284
285
run_command_mock.assert_called_once_with("disable")
286
assert run_command_mock.call_count == 1
287
288
@patch("AndroidRunner.USBHandler.USBHandler._run_command")
289
def test_disable_usb_do_not_disable_run_command(self, run_command_mock, usb_handler):
290
usb_handler._usb_enabled = False
291
usb_handler.disable_usb()
292
293
assert run_command_mock.call_count == 0
294
295
@patch("subprocess.Popen")
296
def test_run_command_no_command(self, popen_mock):
297
usb_handler_config = None
298
usb_handler = USBHandler(usb_handler_config)
299
300
usb_handler._run_command(None)
301
assert popen_mock.call_count == 0
302
303
@patch("subprocess.Popen")
304
def test_run_command_throw_timeout_expired_exception(self, popen_mock, usb_handler):
305
def throw_timeout_expired_exception(timeout):
306
raise subprocess.TimeoutExpired("cmd", 5)
307
308
proc_object = Mock()
309
proc_object.communicate = throw_timeout_expired_exception
310
popen_mock.return_value = proc_object
311
312
with pytest.raises(USBHandlerException) as exception_result:
313
usb_handler._run_command("enable")
314
assert "TimeOutError while executing USB command" in str(exception_result.value)
315
316
popen_mock.assert_called_once_with(["enable"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
317
318
@patch("subprocess.Popen")
319
def test_run_command_throw_timeout_throw_stderr(self, popen_mock, usb_handler):
320
proc_object = Mock()
321
proc_object.communicate.return_value = (None, b"error")
322
popen_mock.return_value = proc_object
323
324
with pytest.raises(USBHandlerException) as exception_result:
325
usb_handler._run_command("enable")
326
assert "Could not execute USB command: error" in str(exception_result.value)
327
328
popen_mock.assert_called_once_with(["enable"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
329
330