Home | History | Annotate | Download | only in site_utils
      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 
    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 
    163 if __name__ == '__main__':
    164     unittest.main()
    165