api_models_test.py revision f2477e01787aa58f445919b809d89e252beef54f
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 6import os 7import json 8import unittest 9 10from api_models import APIModels 11from compiled_file_system import CompiledFileSystem 12from extensions_paths import API, EXTENSIONS 13from features_bundle import FeaturesBundle 14from file_system import FileNotFoundError 15from mock_file_system import MockFileSystem 16from object_store_creator import ObjectStoreCreator 17from test_file_system import TestFileSystem 18from test_util import ReadFile 19 20 21_TEST_DATA = { 22 'api': { 23 'devtools': { 24 'inspected_window.json': ReadFile( 25 API, 'devtools', 'inspected_window.json'), 26 }, 27 '_api_features.json': json.dumps({ 28 'alarms': {}, 29 'app': {}, 30 'app.runtime': {'noparent': True}, 31 'app.runtime.experimental': {}, 32 'app.runtime.experimental.foo': {}, 33 'declarativeWebRequest': {}, 34 'devtools.inspectedWindow': {}, 35 'experimental.accessibility': {}, 36 'storage': {}, 37 }), 38 '_manifest_features.json': '{}', 39 '_permission_features.json': '{}', 40 'alarms.idl': ReadFile(API, 'alarms.idl'), 41 'declarative_web_request.json': ReadFile( 42 API, 'declarative_web_request.json'), 43 'experimental_accessibility.json': ReadFile( 44 API, 'experimental_accessibility.json'), 45 'page_action.json': ReadFile(API, 'page_action.json'), 46 }, 47 'docs': { 48 'templates': { 49 'json': { 50 'manifest.json': '{}', 51 'permissions.json': '{}', 52 } 53 } 54 }, 55} 56 57 58class APIModelsTest(unittest.TestCase): 59 def setUp(self): 60 object_store_creator = ObjectStoreCreator.ForTest() 61 compiled_fs_factory = CompiledFileSystem.Factory(object_store_creator) 62 self._mock_file_system = MockFileSystem( 63 TestFileSystem(_TEST_DATA, relative_to=EXTENSIONS)) 64 features_bundle = FeaturesBundle( 65 self._mock_file_system, compiled_fs_factory, object_store_creator) 66 self._api_models = APIModels( 67 features_bundle, compiled_fs_factory, self._mock_file_system) 68 69 def testGetNames(self): 70 # Both 'app' and 'app.runtime' appear here because 'app.runtime' has 71 # noparent:true, but 'app.runtime.experimental' etc doesn't so it's a 72 # sub-feature of 'app.runtime' not a separate API. 73 # 'devtools.inspectedWindow' is an API because there is no 'devtools'. 74 self.assertEqual( 75 ['alarms', 'app', 'app.runtime', 'declarativeWebRequest', 76 'devtools.inspectedWindow', 'experimental.accessibility', 'storage'], 77 sorted(self._api_models.GetNames())) 78 79 def testGetModel(self): 80 def get_model_name(api_name): 81 return self._api_models.GetModel(api_name).Get().name 82 self.assertEqual('devtools.inspectedWindow', 83 get_model_name('devtools.inspectedWindow')) 84 self.assertEqual('devtools.inspectedWindow', 85 get_model_name('devtools/inspected_window.json')) 86 self.assertEqual('devtools.inspectedWindow', 87 get_model_name('%s/devtools/inspected_window.json' % API)) 88 self.assertEqual('alarms', get_model_name('alarms')) 89 self.assertEqual('alarms', get_model_name('alarms.idl')) 90 self.assertEqual('alarms', get_model_name('%s/alarms.idl' % API)) 91 self.assertEqual('declarativeWebRequest', 92 get_model_name('declarativeWebRequest')) 93 self.assertEqual('declarativeWebRequest', 94 get_model_name('declarative_web_request.json')) 95 self.assertEqual('declarativeWebRequest', 96 get_model_name('%s/declarative_web_request.json' % API)) 97 self.assertEqual('experimental.accessibility', 98 get_model_name('experimental.accessibility')) 99 self.assertEqual('experimental.accessibility', 100 get_model_name('experimental_accessibility.json')) 101 self.assertEqual('experimental.accessibility', 102 get_model_name('%s/experimental_accessibility.json' % API)) 103 self.assertEqual('pageAction', get_model_name('pageAction')) 104 self.assertEqual('pageAction', get_model_name('page_action.json')) 105 self.assertEqual('pageAction', get_model_name('%s/page_action.json' % API)) 106 107 def testGetNonexistentModel(self): 108 self.assertRaises(FileNotFoundError, 109 self._api_models.GetModel('notfound').Get) 110 self.assertRaises(FileNotFoundError, 111 self._api_models.GetModel('notfound.json').Get) 112 self.assertRaises(FileNotFoundError, 113 self._api_models.GetModel('%s/notfound.json' % API).Get) 114 self.assertRaises(FileNotFoundError, 115 self._api_models.GetModel('%s/alarms.json' % API).Get) 116 self.assertRaises(FileNotFoundError, 117 self._api_models.GetModel('storage').Get) 118 self.assertRaises(FileNotFoundError, 119 self._api_models.GetModel('%s/storage.json' % API).Get) 120 self.assertRaises(FileNotFoundError, 121 self._api_models.GetModel('%s/storage.idl' % API).Get) 122 123 def testSingleFile(self): 124 # 2 stats (1 for JSON and 1 for IDL), 1 read (for IDL file which existed). 125 future = self._api_models.GetModel('alarms') 126 self.assertTrue(*self._mock_file_system.CheckAndReset( 127 read_count=1, stat_count=2)) 128 129 # 1 read-resolve (for the IDL file). 130 # 131 # The important part here and above is that it's only doing a single read; 132 # any more would break the contract that only a single file is accessed - 133 # see the SingleFile annotation in api_models._CreateAPIModel. 134 future.Get() 135 self.assertTrue(*self._mock_file_system.CheckAndReset( 136 read_resolve_count=1)) 137 138 # 2 stats (1 for JSON and 1 for IDL), no reads (still cached). 139 future = self._api_models.GetModel('alarms') 140 self.assertTrue(*self._mock_file_system.CheckAndReset(stat_count=2)) 141 future.Get() 142 self.assertTrue(*self._mock_file_system.CheckAndReset()) 143 144 145if __name__ == '__main__': 146 unittest.main() 147