Use io.open to set file encoding (#465)
diff --git a/mobly/config_parser.py b/mobly/config_parser.py
index a61bfe1..4eed6a1 100644
--- a/mobly/config_parser.py
+++ b/mobly/config_parser.py
@@ -15,6 +15,7 @@
from builtins import str
import copy
+import io
import os
import yaml
@@ -149,7 +150,7 @@
Returns:
A dict that represents info in the config file.
"""
- with open(utils.abs_path(path), 'r') as f:
+ with io.open(utils.abs_path(path), 'r', encoding='utf-8') as f:
conf = yaml.load(f)
return conf
diff --git a/mobly/controllers/android_device.py b/mobly/controllers/android_device.py
index 2ff854e..504f671 100644
--- a/mobly/controllers/android_device.py
+++ b/mobly/controllers/android_device.py
@@ -13,10 +13,10 @@
# limitations under the License.
from builtins import str as new_str
-from builtins import open
from past.builtins import basestring
import contextlib
+import io
import logging
import os
import shutil
@@ -436,9 +436,8 @@
self._log_path = os.path.join(self._log_path_base,
'AndroidDevice%s' % self._serial)
self._debug_tag = self._serial
- self.log = AndroidDeviceLoggerAdapter(logging.getLogger(), {
- 'tag': self.debug_tag
- })
+ self.log = AndroidDeviceLoggerAdapter(logging.getLogger(),
+ {'tag': self.debug_tag})
self.sl4a = None
self.ed = None
self._adb_logcat_process = None
@@ -964,9 +963,10 @@
tag = tag[:tag_len]
out_name = tag + out_name
full_adblog_path = os.path.join(adb_excerpt_path, out_name)
- with open(full_adblog_path, 'w', encoding='utf-8') as out:
+ with io.open(full_adblog_path, 'w', encoding='utf-8') as out:
in_file = self.adb_logcat_file_path
- with open(in_file, 'r', encoding='utf-8', errors='replace') as f:
+ with io.open(
+ in_file, 'r', encoding='utf-8', errors='replace') as f:
in_range = False
while True:
line = None
diff --git a/mobly/controllers/iperf_server.py b/mobly/controllers/iperf_server.py
index c72d70e..4d01e17 100644
--- a/mobly/controllers/iperf_server.py
+++ b/mobly/controllers/iperf_server.py
@@ -1,17 +1,18 @@
# Copyright 2016 Google Inc.
-#
+#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
+import io
import json
import logging
import os
@@ -43,10 +44,10 @@
class IPerfResult(object):
def __init__(self, result_path):
try:
- with open(result_path, 'r') as f:
+ with io.open(result_path, 'r', encoding='utf-8') as f:
self.result = json.load(f)
except ValueError:
- with open(result_path, 'r') as f:
+ with io.open(result_path, 'r', encoding='utf-8') as f:
# Possibly a result from interrupted iperf run, skip first line
# and try again.
lines = f.readlines()[1:]
@@ -135,8 +136,8 @@
utils.create_dir(self.log_path)
if tag:
tag = tag + ','
- out_file_name = "IPerfServer,{},{}{}.log".format(self.port, tag,
- len(self.log_files))
+ out_file_name = "IPerfServer,{},{}{}.log".format(
+ self.port, tag, len(self.log_files))
full_out_path = os.path.join(self.log_path, out_file_name)
cmd = '%s %s > %s' % (self.iperf_str, extra_args, full_out_path)
self.iperf_process = utils.start_standing_subprocess(cmd, shell=True)
diff --git a/mobly/controllers/monsoon.py b/mobly/controllers/monsoon.py
index 60fc69f..314bfbd 100644
--- a/mobly/controllers/monsoon.py
+++ b/mobly/controllers/monsoon.py
@@ -11,7 +11,6 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
-
"""Interface for a USB-connected Monsoon power meter
(http://msoon.com/LabEquipment/PowerMonitor/).
"""
@@ -19,6 +18,7 @@
from past.builtins import basestring
import fcntl
+import io
import logging
import os
import select
@@ -143,7 +143,7 @@
if not dev.startswith(prefix):
continue
tmpname = "/tmp/monsoon.%s.%s" % (os.uname()[0], dev)
- self._tempfile = open(tmpname, "w")
+ self._tempfile = open(tmpname, "w", encoding='utf-8')
try:
os.chmod(tmpname, 0o666)
except OSError as e:
@@ -240,8 +240,8 @@
logging.warning("Wanted status, dropped type=0x%02x, len=%d",
read_bytes[0], len(read_bytes))
continue
- status = dict(zip(STATUS_FIELDS, struct.unpack(STATUS_FORMAT,
- read_bytes)))
+ status = dict(
+ zip(STATUS_FIELDS, struct.unpack(STATUS_FORMAT, read_bytes)))
p_type = status["packetType"]
if p_type != 0x10:
raise MonsoonError("Package type %s is not 0x10." % p_type)
@@ -344,8 +344,11 @@
continue
seq, _type, x, y = struct.unpack("BBBB", _bytes[:4])
- data = [struct.unpack(">hhhh", _bytes[x:x + 8])
- for x in range(4, len(_bytes) - 8, 8)]
+ data = [
+ struct.unpack(">hhhh", _bytes[x:x + 8])
+ for x in range(4,
+ len(_bytes) - 8, 8)
+ ]
if self._last_seq and seq & 0xF != (self._last_seq + 1) & 0xF:
logging.warning("Data sequence skipped, lost packet?")
@@ -421,8 +424,8 @@
self.ser.flush()
flushed = 0
while True:
- ready_r, ready_w, ready_x = select.select(
- [self.ser], [], [self.ser], 0)
+ ready_r, ready_w, ready_x = select.select([self.ser], [],
+ [self.ser], 0)
if len(ready_x) > 0:
logging.error("Exception from serial port.")
return None
@@ -464,9 +467,9 @@
self.offset = offset
num_of_data_pt = len(self._data_points)
if self.offset >= num_of_data_pt:
- raise MonsoonError(("Offset number (%d) must be smaller than the "
- "number of data points (%d).") %
- (offset, num_of_data_pt))
+ raise MonsoonError(
+ ("Offset number (%d) must be smaller than the "
+ "number of data points (%d).") % (offset, num_of_data_pt))
self.data_points = self._data_points[self.offset:]
self.timestamps = self._timestamps[self.offset:]
self.hz = hz
@@ -512,11 +515,12 @@
lines = data_str.strip().split('\n')
err_msg = ("Invalid input string format. Is this string generated by "
"MonsoonData class?")
- conditions = [len(lines) <= 4, "Average Current:" not in lines[1],
- "Voltage: " not in lines[2],
- "Total Power: " not in lines[3],
- "samples taken at " not in lines[4],
- lines[5] != "Time" + ' ' * 7 + "Amp"]
+ conditions = [
+ len(lines) <= 4, "Average Current:" not in lines[1],
+ "Voltage: " not in lines[2], "Total Power: " not in lines[3],
+ "samples taken at " not in lines[4],
+ lines[5] != "Time" + ' ' * 7 + "Amp"
+ ]
if any(conditions):
raise MonsoonError(err_msg)
hz_str = lines[4].split()[2]
@@ -549,7 +553,7 @@
raise MonsoonError("Attempting to write empty Monsoon data to "
"file, abort")
utils.create_dir(os.path.dirname(file_path))
- with open(file_path, 'w') as f:
+ with io.open(file_path, 'w', encoding='utf-8') as f:
for md in monsoon_data:
f.write(str(md))
f.write(MonsoonData.delimiter)
@@ -567,7 +571,7 @@
A list of MonsoonData objects.
"""
results = []
- with open(file_path, 'r') as f:
+ with io.open(file_path, 'r', encoding='utf-8') as f:
data_strs = f.read().split(MonsoonData.delimiter)
for data_str in data_strs:
results.append(MonsoonData.from_string(data_str))
@@ -634,9 +638,9 @@
strs.append("Average Current: {}mA.".format(self.average_current))
strs.append("Voltage: {}V.".format(self.voltage))
strs.append("Total Power: {}mW.".format(self.total_power))
- strs.append(("{} samples taken at {}Hz, with an offset of {} samples."
- ).format(
- len(self._data_points), self.hz, self.offset))
+ strs.append(
+ ("{} samples taken at {}Hz, with an offset of {} samples.").format(
+ len(self._data_points), self.hz, self.offset))
return "\n".join(strs)
def __len__(self):
@@ -794,11 +798,12 @@
pass
self.mon.StopDataCollection()
try:
- return MonsoonData(current_values,
- timestamps,
- sample_hz,
- voltage,
- offset=sample_offset)
+ return MonsoonData(
+ current_values,
+ timestamps,
+ sample_hz,
+ voltage,
+ offset=sample_offset)
except:
return None
@@ -864,8 +869,8 @@
try:
data = self.take_samples(hz, num, sample_offset=oset)
if not data:
- raise MonsoonError("No data was collected in measurement %s." %
- tag)
+ raise MonsoonError(
+ "No data was collected in measurement %s." % tag)
data.tag = tag
self.dut.log.info("Measurement summary: %s", repr(data))
return data
diff --git a/mobly/records.py b/mobly/records.py
index 74dd8f9..ad37cad 100644
--- a/mobly/records.py
+++ b/mobly/records.py
@@ -14,11 +14,10 @@
"""This module has classes for test result collection, and test result output.
"""
-from io import open
-
import collections
import copy
import enum
+import io
import logging
import sys
import threading
@@ -121,7 +120,7 @@
# because Python3 file descriptors set an encoding by default, which
# PyYAML uses instead of the encoding on yaml.safe_dump. So, the
# encoding has to be set on the open call instead.
- with open(self._path, 'a', encoding='utf-8') as f:
+ with io.open(self._path, 'a', encoding='utf-8') as f:
# Use safe_dump here to avoid language-specific tags in final
# output.
yaml.safe_dump(
diff --git a/mobly/utils.py b/mobly/utils.py
index 275d990..b4f8536 100644
--- a/mobly/utils.py
+++ b/mobly/utils.py
@@ -15,6 +15,7 @@
import base64
import concurrent.futures
import datetime
+import io
import logging
import os
import platform
@@ -209,7 +210,7 @@
A base64 string representing the content of the file in utf-8 encoding.
"""
path = abs_path(f_path)
- with open(path, 'rb') as f:
+ with io.open(path, 'rb') as f:
f_bytes = f.read()
base64_str = base64.b64encode(f_bytes).decode("utf-8")
return base64_str
diff --git a/tests/mobly/base_test_test.py b/tests/mobly/base_test_test.py
index a20e1fb..593ff0b 100755
--- a/tests/mobly/base_test_test.py
+++ b/tests/mobly/base_test_test.py
@@ -12,6 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+import io
import os
import mock
import shutil
@@ -1734,7 +1735,7 @@
actual_record = bt_cls.results.passed[0]
self.assertEqual(actual_record.test_name, "test_something")
hit = False
- with open(self.summary_file, 'r') as f:
+ with io.open(self.summary_file, 'r', encoding='utf-8') as f:
for c in yaml.load_all(f):
if c['Type'] != records.TestSummaryEntryType.USER_DATA.value:
continue
diff --git a/tests/mobly/config_parser_test.py b/tests/mobly/config_parser_test.py
new file mode 100644
index 0000000..ea16668
--- /dev/null
+++ b/tests/mobly/config_parser_test.py
@@ -0,0 +1,61 @@
+# Copyright 2018 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import io
+import os
+import shutil
+import tempfile
+import unittest
+
+from mobly import config_parser
+
+
+class OutputTest(unittest.TestCase):
+ """This test class has unit tests for the implementation of Mobly's output
+ files.
+ """
+
+ def setUp(self):
+ self.tmp_dir = tempfile.mkdtemp()
+
+ def tearDown(self):
+ shutil.rmtree(self.tmp_dir)
+
+ def test__load_config_file(self):
+ tmp_file_path = os.path.join(self.tmp_dir, 'config.yml')
+ with io.open(tmp_file_path, 'w', encoding='utf-8') as f:
+ f.write(u'TestBeds:\n')
+ f.write(u' # A test bed where adb will find Android devices.\n')
+ f.write(u' - Name: SampleTestBed\n')
+ f.write(u' Controllers:\n')
+ f.write(u' AndroidDevice: \'*\'\n')
+
+ config = config_parser._load_config_file(tmp_file_path)
+ self.assertEqual(config['TestBeds'][0]['Name'], u'SampleTestBed')
+
+ def test__load_config_file_with_unicode(self):
+ tmp_file_path = os.path.join(self.tmp_dir, 'config.yml')
+ with io.open(tmp_file_path, 'w', encoding='utf-8') as f:
+ f.write(u'TestBeds:\n')
+ f.write(u' # A test bed where adb will find Android devices.\n')
+ f.write(u' - Name: \u901a\n')
+ f.write(u' Controllers:\n')
+ f.write(u' AndroidDevice: \'*\'\n')
+
+ config = config_parser._load_config_file(tmp_file_path)
+ self.assertEqual(config['TestBeds'][0]['Name'], u'\u901a')
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/tests/mobly/controllers/android_device_test.py b/tests/mobly/controllers/android_device_test.py
index 6949903..e12e511 100755
--- a/tests/mobly/controllers/android_device_test.py
+++ b/tests/mobly/controllers/android_device_test.py
@@ -14,6 +14,7 @@
from builtins import str as new_str
+import io
import logging
import mock
import os
@@ -38,11 +39,23 @@
'02-29 14:02:21.456 4454 Something\n',
'02-29 14:02:21.789 4454 Something again\n'
]
-# A mockd piece of adb logcat output.
-MOCK_ADB_LOGCAT = ('02-29 14:02:19.123 4454 Nothing\n'
- '%s'
- '02-29 14:02:22.123 4454 Something again and again\n'
- ) % ''.join(MOCK_ADB_LOGCAT_CAT_RESULT)
+# A mocked piece of adb logcat output.
+MOCK_ADB_LOGCAT = (u'02-29 14:02:19.123 4454 Nothing\n'
+ u'%s'
+ u'02-29 14:02:22.123 4454 Something again and again\n'
+ ) % u''.join(MOCK_ADB_LOGCAT_CAT_RESULT)
+# The expected result of the cat adb operation.
+MOCK_ADB_UNICODE_LOGCAT_CAT_RESULT = [
+ '02-29 14:02:21.456 4454 Something \u901a\n',
+ '02-29 14:02:21.789 4454 Something again\n'
+]
+# A mocked piece of adb logcat output.
+MOCK_ADB_UNICODE_LOGCAT = (
+ u'02-29 14:02:19.123 4454 Nothing\n'
+ u'%s'
+ u'02-29 14:02:22.123 4454 Something again and again\n'
+) % u''.join(MOCK_ADB_UNICODE_LOGCAT_CAT_RESULT)
+
# Mock start and end time of the adb cat.
MOCK_ADB_LOGCAT_BEGIN_TIME = '02-29 14:02:20.123'
MOCK_ADB_LOGCAT_END_TIME = '02-29 14:02:22.000'
@@ -548,8 +561,9 @@
FastbootProxy, MockAdbProxy):
ad = android_device.AndroidDevice(serial='1')
new_log_path = tempfile.mkdtemp()
- with open(os.path.join(new_log_path, 'file.txt'), 'w') as f:
- f.write('hahah.')
+ new_file_path = os.path.join(new_log_path, 'file.txt')
+ with io.open(new_file_path, 'w', encoding='utf-8') as f:
+ f.write(u'hahah.')
expected_msg = '.* Logs already exist .*'
with self.assertRaisesRegex(android_device.Error, expected_msg):
ad.log_path = new_log_path
@@ -625,13 +639,13 @@
utils.create_dir(ad.log_path)
mock_adb_log_path = os.path.join(ad.log_path, 'adblog,%s,%s.txt' %
(ad.model, ad.serial))
- with open(mock_adb_log_path, 'w') as f:
+ with io.open(mock_adb_log_path, 'w', encoding='utf-8') as f:
f.write(MOCK_ADB_LOGCAT)
ad.cat_adb_log('some_test', MOCK_ADB_LOGCAT_BEGIN_TIME)
cat_file_path = os.path.join(
ad.log_path, 'AdbLogExcerpts',
('some_test,02-29 14-02-20.123,%s,%s.txt') % (ad.model, ad.serial))
- with open(cat_file_path, 'r') as f:
+ with io.open(cat_file_path, 'r', encoding='utf-8') as f:
actual_cat = f.read()
self.assertEqual(actual_cat, ''.join(MOCK_ADB_LOGCAT_CAT_RESULT))
# Stops adb logcat.
@@ -639,6 +653,51 @@
@mock.patch(
'mobly.controllers.android_device_lib.adb.AdbProxy',
+ return_value=mock_android_device.MockAdbProxy('1'))
+ @mock.patch(
+ 'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
+ return_value=mock_android_device.MockFastbootProxy('1'))
+ @mock.patch(
+ 'mobly.utils.start_standing_subprocess', return_value='process')
+ @mock.patch('mobly.utils.stop_standing_subprocess')
+ @mock.patch(
+ 'mobly.logger.get_log_line_timestamp',
+ return_value=MOCK_ADB_LOGCAT_END_TIME)
+ def test_AndroidDevice_cat_adb_log_with_unicode(
+ self, mock_timestamp_getter, stop_proc_mock, start_proc_mock,
+ FastbootProxy, MockAdbProxy):
+ """Verifies that AndroidDevice.cat_adb_log loads the correct adb log
+ file, locates the correct adb log lines within the given time range,
+ and writes the lines to the correct output file.
+ """
+ mock_serial = '1'
+ ad = android_device.AndroidDevice(serial=mock_serial)
+ # Direct the log path of the ad to a temp dir to avoid racing.
+ ad._log_path_base = self.tmp_dir
+ # Expect error if attempted to cat adb log before starting adb logcat.
+ expected_msg = ('.* Attempting to cat adb log when none'
+ ' has been collected.')
+ with self.assertRaisesRegex(android_device.Error, expected_msg):
+ ad.cat_adb_log('some_test', MOCK_ADB_LOGCAT_BEGIN_TIME)
+ ad.start_adb_logcat()
+ utils.create_dir(ad.log_path)
+ mock_adb_log_path = os.path.join(ad.log_path, 'adblog,%s,%s.txt' %
+ (ad.model, ad.serial))
+ with io.open(mock_adb_log_path, 'w', encoding='utf-8') as f:
+ f.write(MOCK_ADB_UNICODE_LOGCAT)
+ ad.cat_adb_log('some_test', MOCK_ADB_LOGCAT_BEGIN_TIME)
+ cat_file_path = os.path.join(
+ ad.log_path, 'AdbLogExcerpts',
+ ('some_test,02-29 14-02-20.123,%s,%s.txt') % (ad.model, ad.serial))
+ with io.open(cat_file_path, 'r', encoding='utf-8') as f:
+ actual_cat = f.read()
+ self.assertEqual(actual_cat,
+ ''.join(MOCK_ADB_UNICODE_LOGCAT_CAT_RESULT))
+ # Stops adb logcat.
+ ad.stop_adb_logcat()
+
+ @mock.patch(
+ 'mobly.controllers.android_device_lib.adb.AdbProxy',
return_value=mock.MagicMock())
@mock.patch(
'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
diff --git a/tests/mobly/output_test.py b/tests/mobly/output_test.py
index ff5cae8..d700272 100755
--- a/tests/mobly/output_test.py
+++ b/tests/mobly/output_test.py
@@ -12,6 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+import io
import logging
import mock
import os
@@ -85,7 +86,7 @@
return (summary_file_path, debug_log_path, info_log_path)
def assert_log_contents(self, log_path, whitelist=[], blacklist=[]):
- with open(log_path, 'r') as f:
+ with io.open(log_path, 'r', encoding='utf-8') as f:
content = f.read()
for item in whitelist:
self.assertIn(item, content)
@@ -232,7 +233,7 @@
(summary_file_path, debug_log_path,
info_log_path) = self.assert_output_logs_exist(output_dir)
summary_entries = []
- with open(summary_file_path) as f:
+ with io.open(summary_file_path, 'r', encoding='utf-8') as f:
for entry in yaml.load_all(f):
self.assertTrue(entry['Type'])
summary_entries.append(entry)
@@ -253,7 +254,7 @@
summary_file_path = os.path.join(output_dir,
records.OUTPUT_FILE_SUMMARY)
found = False
- with open(summary_file_path, 'r') as f:
+ with io.open(summary_file_path, 'r', encoding='utf-8') as f:
raw_content = f.read()
f.seek(0)
for entry in yaml.load_all(f):
diff --git a/tests/mobly/records_test.py b/tests/mobly/records_test.py
index fbbc4f4..f818e62 100755
--- a/tests/mobly/records_test.py
+++ b/tests/mobly/records_test.py
@@ -13,9 +13,9 @@
# limitations under the License.
from builtins import str
-from io import open
import copy
+import io
import mock
import os
import shutil
@@ -356,7 +356,7 @@
dump_path = os.path.join(self.tmp_path, 'ha.yaml')
writer = records.TestSummaryWriter(dump_path)
writer.dump(record1.to_dict(), records.TestSummaryEntryType.RECORD)
- with open(dump_path, 'r', encoding='utf-8') as f:
+ with io.open(dump_path, 'r', encoding='utf-8') as f:
content = yaml.load(f)
self.assertEqual(content['Type'],
records.TestSummaryEntryType.RECORD.value)
@@ -375,7 +375,7 @@
dump_path = os.path.join(self.tmp_path, 'ha.yaml')
writer = records.TestSummaryWriter(dump_path)
writer.dump(record1.to_dict(), records.TestSummaryEntryType.RECORD)
- with open(dump_path, 'r', encoding='utf-8') as f:
+ with io.open(dump_path, 'r', encoding='utf-8') as f:
content = yaml.load(f)
self.assertEqual(content['Type'],
records.TestSummaryEntryType.RECORD.value)
@@ -392,7 +392,7 @@
writer = records.TestSummaryWriter(dump_path)
for data in user_data:
writer.dump(data, records.TestSummaryEntryType.USER_DATA)
- with open(dump_path, 'r', encoding='utf-8') as f:
+ with io.open(dump_path, 'r', encoding='utf-8') as f:
contents = []
for c in yaml.load_all(f):
contents.append(c)
diff --git a/tests/mobly/test_runner_test.py b/tests/mobly/test_runner_test.py
index ab26971..c0ff4b5 100755
--- a/tests/mobly/test_runner_test.py
+++ b/tests/mobly/test_runner_test.py
@@ -12,6 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+import io
import logging
import mock
import os
@@ -206,7 +207,7 @@
tr.run()
summary_path = os.path.join(logging.log_path,
records.OUTPUT_FILE_SUMMARY)
- with open(summary_path, 'r') as f:
+ with io.open(summary_path, 'r', encoding='utf-8') as f:
summary_entries = list(yaml.load_all(f))
self.assertEqual(len(summary_entries), 4)
# Verify the first entry is the list of test names.
diff --git a/tests/mobly/utils_test.py b/tests/mobly/utils_test.py
index 7ce4f50..605dc8c 100755
--- a/tests/mobly/utils_test.py
+++ b/tests/mobly/utils_test.py
@@ -12,9 +12,11 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+import io
import mock
import os
import platform
+import shutil
import socket
import subprocess
import tempfile
@@ -36,6 +38,10 @@
def setUp(self):
system = platform.system()
self.sleep_cmd = 'timeout' if system == 'Windows' else 'sleep'
+ self.tmp_dir = tempfile.mkdtemp()
+
+ def tearDown(self):
+ shutil.rmtree(self.tmp_dir)
def test_start_standing_subproc(self):
try:
@@ -61,17 +67,15 @@
self.assertFalse(p1.is_running())
def test_create_dir(self):
- tmp_dir = tempfile.mkdtemp()
- new_path = os.path.join(tmp_dir, 'haha')
+ new_path = os.path.join(self.tmp_dir, 'haha')
self.assertFalse(os.path.exists(new_path))
utils.create_dir(new_path)
self.assertTrue(os.path.exists(new_path))
def test_create_dir_already_exists(self):
- tmp_dir = tempfile.mkdtemp()
- self.assertTrue(os.path.exists(tmp_dir))
- utils.create_dir(tmp_dir)
- self.assertTrue(os.path.exists(tmp_dir))
+ self.assertTrue(os.path.exists(self.tmp_dir))
+ utils.create_dir(self.tmp_dir)
+ self.assertTrue(os.path.exists(self.tmp_dir))
@mock.patch(
'mobly.controllers.android_device_lib.adb.list_occupied_adb_ports')
@@ -114,6 +118,33 @@
finally:
s.close()
+ def test_load_file_to_base64_str_reads_bytes_file_as_base64_string(self):
+ tmp_file_path = os.path.join(self.tmp_dir, 'b64.bin')
+ expected_base64_encoding = u'SGVsbG93IHdvcmxkIQ=='
+ with io.open(tmp_file_path, 'wb') as f:
+ f.write(b'Hellow world!')
+ self.assertEqual(
+ utils.load_file_to_base64_str(tmp_file_path),
+ expected_base64_encoding)
+
+ def test_load_file_to_base64_str_reads_text_file_as_base64_string(self):
+ tmp_file_path = os.path.join(self.tmp_dir, 'b64.bin')
+ expected_base64_encoding = u'SGVsbG93IHdvcmxkIQ=='
+ with io.open(tmp_file_path, 'w', encoding='utf-8') as f:
+ f.write(u'Hellow world!')
+ self.assertEqual(
+ utils.load_file_to_base64_str(tmp_file_path),
+ expected_base64_encoding)
+
+ def test_load_file_to_base64_str_reads_unicode_file_as_base64_string(self):
+ tmp_file_path = os.path.join(self.tmp_dir, 'b64.bin')
+ expected_base64_encoding = u'6YCa'
+ with io.open(tmp_file_path, 'w', encoding='utf-8') as f:
+ f.write(u'\u901a')
+ self.assertEqual(
+ utils.load_file_to_base64_str(tmp_file_path),
+ expected_base64_encoding)
+
if __name__ == '__main__':
unittest.main()