Home | History | Annotate | Download | only in server2
      1 #!/usr/bin/env python
      2 # Copyright 2013 The Chromium Authors. All rights reserved.
      3 # Use of this source code is governed by a BSD-style license that can be
      4 # found in the LICENSE file.
      5 
      6 import json
      7 import unittest
      8 
      9 from api_models import APIModels
     10 from compiled_file_system import CompiledFileSystem
     11 from extensions_paths import API_PATHS, CHROME_API, CHROME_EXTENSIONS
     12 from features_bundle import FeaturesBundle
     13 from file_system import FileNotFoundError
     14 from mock_file_system import MockFileSystem
     15 from object_store_creator import ObjectStoreCreator
     16 from test_file_system import TestFileSystem
     17 from test_util import ReadFile
     18 from future import Future
     19 from schema_processor import SchemaProcessorFactoryForTest
     20 
     21 
     22 _TEST_DATA = {
     23   'api': {
     24     'devtools': {
     25       'inspected_window.json': ReadFile(
     26           CHROME_API, 'devtools', 'inspected_window.json'),
     27     },
     28     '_api_features.json': json.dumps({
     29       'alarms': {},
     30       'app': {},
     31       'app.runtime': {'noparent': True},
     32       'app.runtime.foo': {},
     33       'declarativeWebRequest': {},
     34       'devtools.inspectedWindow': {},
     35       'input': {},
     36       'input.ime': {},
     37       'storage': {},
     38     }),
     39     '_manifest_features.json': '{}',
     40     '_permission_features.json': '{}',
     41     'alarms.idl': ReadFile(CHROME_API, 'alarms.idl'),
     42     'input_ime.json': ReadFile(CHROME_API, 'input_ime.json'),
     43     'page_action.json': ReadFile(CHROME_API, 'page_action.json'),
     44   },
     45   'docs': {
     46     'templates': {
     47       'json': {
     48         'manifest.json': '{}',
     49         'permissions.json': '{}',
     50       }
     51     }
     52   },
     53 }
     54 
     55 
     56 class APIModelsTest(unittest.TestCase):
     57   def setUp(self):
     58     object_store_creator = ObjectStoreCreator.ForTest()
     59     compiled_fs_factory = CompiledFileSystem.Factory(object_store_creator)
     60     self._mock_file_system = MockFileSystem(
     61         TestFileSystem(_TEST_DATA, relative_to=CHROME_EXTENSIONS))
     62     features_bundle = FeaturesBundle(self._mock_file_system,
     63                                      compiled_fs_factory,
     64                                      object_store_creator,
     65                                      'extensions')
     66     self._api_models = APIModels(features_bundle,
     67                                  compiled_fs_factory,
     68                                  self._mock_file_system,
     69                                  object_store_creator,
     70                                  'extensions',
     71                                  SchemaProcessorFactoryForTest())
     72 
     73   def testGetNames(self):
     74     # Both 'app' and 'app.runtime' appear here because 'app.runtime' has
     75     # noparent:true, but 'app.runtime.foo' etc doesn't so it's a sub-feature of
     76     # 'app.runtime' not a separate API. 'devtools.inspectedWindow' is an API
     77     # because there is no 'devtools'.
     78     self.assertEqual(
     79         ['alarms', 'app', 'app.runtime', 'declarativeWebRequest',
     80          'devtools.inspectedWindow', 'input', 'storage'],
     81         sorted(self._api_models.GetNames()))
     82 
     83   def testGetModel(self):
     84     def get_model_name(api_name):
     85       return self._api_models.GetModel(api_name).Get().name
     86     self.assertEqual('devtools.inspectedWindow',
     87                      get_model_name('devtools.inspectedWindow'))
     88     self.assertEqual('devtools.inspectedWindow',
     89                      get_model_name('devtools/inspected_window.json'))
     90     self.assertEqual('devtools.inspectedWindow',
     91                      get_model_name(CHROME_API +
     92                                     'devtools/inspected_window.json'))
     93     self.assertEqual('alarms', get_model_name('alarms'))
     94     self.assertEqual('alarms', get_model_name('alarms.idl'))
     95     self.assertEqual('alarms', get_model_name(CHROME_API + 'alarms.idl'))
     96     self.assertEqual('input.ime', get_model_name('input.ime'))
     97     self.assertEqual('input.ime', get_model_name('input_ime.json'))
     98     self.assertEqual('input.ime',
     99                      get_model_name(CHROME_API + 'input_ime.json'))
    100     self.assertEqual('pageAction', get_model_name('pageAction'))
    101     self.assertEqual('pageAction', get_model_name('page_action.json'))
    102     self.assertEqual('pageAction', get_model_name(CHROME_API +
    103                                                   'page_action.json'))
    104 
    105   def testGetNonexistentModel(self):
    106     self.assertRaises(FileNotFoundError,
    107                       self._api_models.GetModel('declarativeWebRequest').Get)
    108     self.assertRaises(FileNotFoundError,
    109                       self._api_models.GetModel(
    110                           'declarative_web_request.json').Get)
    111     self.assertRaises(FileNotFoundError,
    112                       self._api_models.GetModel(
    113                           CHROME_API + 'declarative_web_request.json').Get)
    114     self.assertRaises(FileNotFoundError,
    115                       self._api_models.GetModel('notfound').Get)
    116     self.assertRaises(FileNotFoundError,
    117                       self._api_models.GetModel('notfound.json').Get)
    118     self.assertRaises(FileNotFoundError,
    119                       self._api_models.GetModel(CHROME_API +
    120                                                 'notfound.json').Get)
    121     self.assertRaises(FileNotFoundError,
    122                       self._api_models.GetModel(CHROME_API +
    123                                                 'alarms.json').Get)
    124     self.assertRaises(FileNotFoundError,
    125                       self._api_models.GetModel('storage').Get)
    126     self.assertRaises(FileNotFoundError,
    127                       self._api_models.GetModel(CHROME_API +
    128                                                 'storage.json').Get)
    129     self.assertRaises(FileNotFoundError,
    130                       self._api_models.GetModel(CHROME_API +
    131                                                 'storage.idl').Get)
    132 
    133   def testSingleFile(self):
    134     # 2 stats (1 for JSON and 1 for IDL) for each available API path.
    135     # 1 read (for IDL file which existed).
    136     future = self._api_models.GetModel('alarms')
    137     self.assertTrue(*self._mock_file_system.CheckAndReset(
    138         read_count=1, stat_count=len(API_PATHS)*2))
    139 
    140     # 1 read-resolve (for the IDL file).
    141     #
    142     # The important part here and above is that it's only doing a single read;
    143     # any more would break the contract that only a single file is accessed -
    144     # see the SingleFile annotation in api_models._CreateAPIModel.
    145     future.Get()
    146     self.assertTrue(*self._mock_file_system.CheckAndReset(
    147         read_resolve_count=1))
    148 
    149     # 2 stats (1 for JSON and 1 for IDL) for each available API path.
    150     # No reads (still cached).
    151     future = self._api_models.GetModel('alarms')
    152     self.assertTrue(*self._mock_file_system.CheckAndReset(
    153         stat_count=len(API_PATHS)*2))
    154     future.Get()
    155     self.assertTrue(*self._mock_file_system.CheckAndReset())
    156 
    157 
    158 if __name__ == '__main__':
    159   unittest.main()
    160