Kevin Cheng | 5272ca7 | 2016-01-11 11:55:31 -0800 | [diff] [blame] | 1 | # Copyright 2016 The Chromium OS Authors. All rights reserved. |
| 2 | # Use of this source code is governed by a BSD-style license that can be |
| 3 | # found in the LICENSE file. |
| 4 | |
| 5 | import cStringIO |
| 6 | import json |
| 7 | import mock |
| 8 | import os |
| 9 | import shutil |
| 10 | import tempfile |
| 11 | import unittest |
| 12 | import urllib2 |
| 13 | |
| 14 | import common |
| 15 | |
| 16 | from autotest_lib.site_utils import hwid_lib |
| 17 | |
| 18 | |
| 19 | class HwIdUnittests(unittest.TestCase): |
| 20 | """Unittest for testing get_hwid_info.""" |
| 21 | |
| 22 | def setUp(self): |
| 23 | # Create tmp dir and dummy key files. |
| 24 | self.tmp_dir = tempfile.mkdtemp(prefix='hwid_test') |
| 25 | self.dummy_key = 'dummy_key' |
| 26 | self.dummy_key_file = os.path.join(self.tmp_dir, 'dummy_key') |
| 27 | with open(self.dummy_key_file, 'w') as f: |
| 28 | f.write(self.dummy_key) |
| 29 | self.dummy_key_file_spaces = os.path.join(self.tmp_dir, |
| 30 | 'dummy_key_spaces') |
| 31 | with open(self.dummy_key_file_spaces, 'w') as f: |
| 32 | f.write(' %s ' % self.dummy_key) |
| 33 | self.dummy_key_file_newline = os.path.join(self.tmp_dir, |
| 34 | 'dummy_key_newline') |
| 35 | with open(self.dummy_key_file_newline, 'w') as f: |
| 36 | f.write('%s\n' % self.dummy_key) |
| 37 | self.invalid_dummy_key_file = os.path.join(self.tmp_dir, |
| 38 | 'invalid_dummy_key_file') |
| 39 | |
| 40 | |
| 41 | def tearDown(self): |
| 42 | mock.patch.stopall() |
| 43 | if os.path.exists(self.tmp_dir): |
| 44 | shutil.rmtree(self.tmp_dir) |
| 45 | |
| 46 | |
| 47 | def validate_exception(self, exception, *args): |
| 48 | """Helper method to validate proper exception is raised. |
| 49 | |
| 50 | @param exception: The exception class to check against. |
| 51 | @param args: The unamed args to pass to func. |
| 52 | """ |
| 53 | with self.assertRaises(exception): |
| 54 | hwid_lib.get_hwid_info(*args) |
| 55 | |
| 56 | |
| 57 | def test_none_hwid(self): |
| 58 | """Test that an empty hwid raises a ValueError.""" |
| 59 | self.validate_exception(ValueError, None, None, None) |
| 60 | |
| 61 | |
| 62 | def test_invalid_info_type(self): |
| 63 | """Test that an invalid info type raises a ValueError.""" |
| 64 | self.validate_exception(ValueError, 'hwid', 'invalid_info_type', None) |
| 65 | |
| 66 | |
| 67 | def test_fail_open_with_nonexistent_file(self): |
| 68 | """Test that trying to open non-existent file will raise an IOError.""" |
| 69 | self.validate_exception(IOError, 'hwid', hwid_lib.HWID_INFO_BOM, |
| 70 | self.invalid_dummy_key_file) |
| 71 | |
| 72 | |
| 73 | @mock.patch('urllib2.urlopen', side_effect=urllib2.URLError('url error')) |
| 74 | def test_fail_to_open_url_urlerror(self, *args, **dargs): |
| 75 | """Test that failing to open a url will raise a HwIdException.""" |
| 76 | self.validate_exception(hwid_lib.HwIdException, 'hwid', |
| 77 | hwid_lib.HWID_INFO_BOM, self.dummy_key_file) |
| 78 | |
| 79 | |
| 80 | # pylint: disable=missing-docstring |
| 81 | @mock.patch('urllib2.urlopen') |
| 82 | def test_fail_decode_hwid(self, mock_urlopen, *args, **dargs): |
| 83 | """Test that supplying bad json raises a HwIdException.""" |
| 84 | mock_page_contents = mock.Mock(wraps=cStringIO.StringIO('bad json')) |
| 85 | mock_urlopen.return_value = mock_page_contents |
| 86 | self.validate_exception(hwid_lib.HwIdException, 'hwid', |
| 87 | hwid_lib.HWID_INFO_BOM, self.dummy_key_file) |
| 88 | mock_page_contents.close.assert_called_once_with() |
| 89 | |
| 90 | |
| 91 | # pylint: disable=missing-docstring |
| 92 | @mock.patch('urllib2.urlopen') |
| 93 | def test_success(self, mock_urlopen, *args, **dargs): |
| 94 | """Test that get_hwid_info successfully returns a hwid dict. |
| 95 | |
| 96 | We want to check that it works on all valid info types. |
| 97 | """ |
| 98 | returned_json = '{"key1": "data1"}' |
| 99 | expected_dict = json.loads(returned_json) |
| 100 | for valid_info_type in hwid_lib.HWID_INFO_TYPES: |
| 101 | mock_page_contents = mock.Mock( |
| 102 | wraps=cStringIO.StringIO(returned_json)) |
| 103 | mock_urlopen.return_value = mock_page_contents |
| 104 | self.assertEqual(hwid_lib.get_hwid_info('hwid', valid_info_type, |
| 105 | self.dummy_key_file), |
| 106 | expected_dict) |
| 107 | mock_page_contents.close.assert_called_once_with() |
| 108 | |
| 109 | |
| 110 | # pylint: disable=missing-docstring |
| 111 | @mock.patch('urllib2.urlopen') |
| 112 | def test_url_properly_constructed(self, mock_urlopen, *args, **dargs): |
| 113 | """Test that the url is properly constructed. |
| 114 | |
| 115 | Let's make sure that the key is properly cleaned before getting |
| 116 | inserted into the url by trying all the different dummy_key_files. |
| 117 | """ |
| 118 | info_type = hwid_lib.HWID_INFO_BOM |
| 119 | hwid = 'mock_hwid' |
| 120 | expected_url = ('%s/%s/%s/%s/?key=%s' % (hwid_lib.HWID_BASE_URL, |
| 121 | hwid_lib.HWID_VERSION, |
| 122 | info_type, hwid, |
| 123 | self.dummy_key)) |
| 124 | |
| 125 | for dummy_key_file in [self.dummy_key_file, |
| 126 | self.dummy_key_file_spaces, |
| 127 | self.dummy_key_file_newline]: |
| 128 | mock_page_contents = mock.Mock(wraps=cStringIO.StringIO('{}')) |
| 129 | mock_urlopen.return_value = mock_page_contents |
| 130 | hwid_lib.get_hwid_info(hwid, info_type, dummy_key_file) |
| 131 | mock_urlopen.assert_called_with(expected_url) |
| 132 | |
| 133 | |
Kevin Cheng | 80ad573 | 2016-03-31 16:01:56 -0700 | [diff] [blame] | 134 | # pylint: disable=missing-docstring |
| 135 | @mock.patch('urllib2.urlopen') |
| 136 | def test_url_properly_constructed_again(self, mock_urlopen, *args, **dargs): |
| 137 | """Test that the url is properly constructed with special hwid. |
| 138 | |
| 139 | Let's make sure that a hwid with a space is properly transformed. |
| 140 | """ |
| 141 | info_type = hwid_lib.HWID_INFO_BOM |
| 142 | hwid = 'mock hwid with space' |
| 143 | hwid_quoted = 'mock%20hwid%20with%20space' |
| 144 | expected_url = ('%s/%s/%s/%s/?key=%s' % (hwid_lib.HWID_BASE_URL, |
| 145 | hwid_lib.HWID_VERSION, |
| 146 | info_type, hwid_quoted, |
| 147 | self.dummy_key)) |
| 148 | |
| 149 | mock_page_contents = mock.Mock(wraps=cStringIO.StringIO('{}')) |
| 150 | mock_urlopen.return_value = mock_page_contents |
| 151 | hwid_lib.get_hwid_info(hwid, info_type, self.dummy_key_file) |
| 152 | mock_urlopen.assert_called_with(expected_url) |
| 153 | |
| 154 | |
| 155 | def test_dummy_key_file(self): |
| 156 | """Test that we get an empty dict with a dummy key file.""" |
| 157 | info_type = hwid_lib.HWID_INFO_BOM |
| 158 | hwid = 'mock hwid with space' |
| 159 | key_file = hwid_lib.KEY_FILENAME_NO_HWID |
| 160 | self.assertEqual(hwid_lib.get_hwid_info(hwid, info_type, key_file), {}) |
| 161 | |
| 162 | |
Kevin Cheng | 5272ca7 | 2016-01-11 11:55:31 -0800 | [diff] [blame] | 163 | if __name__ == '__main__': |
| 164 | unittest.main() |