11e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#!/usr/bin/env python 21e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)# Copyright 2013 The Chromium Authors. All rights reserved. 31e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be 41e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)# found in the LICENSE file. 51e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 61e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)import json 71e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)import unittest 81e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 91e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)from api_models import APIModels 101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)from compiled_file_system import CompiledFileSystem 11effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochfrom extensions_paths import API_PATHS, CHROME_API, CHROME_EXTENSIONS 121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)from features_bundle import FeaturesBundle 131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)from file_system import FileNotFoundError 140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)from mock_file_system import MockFileSystem 151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)from object_store_creator import ObjectStoreCreator 161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)from test_file_system import TestFileSystem 171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)from test_util import ReadFile 181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)_TEST_DATA = { 211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 'api': { 221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 'devtools': { 23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 'inspected_window.json': ReadFile( 24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CHROME_API, 'devtools', 'inspected_window.json'), 251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) }, 261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) '_api_features.json': json.dumps({ 271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 'alarms': {}, 280f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 'app': {}, 290f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 'app.runtime': {'noparent': True}, 30c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 'app.runtime.foo': {}, 311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 'declarativeWebRequest': {}, 321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 'devtools.inspectedWindow': {}, 33c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 'input': {}, 34c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 'input.ime': {}, 351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 'storage': {}, 361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) }), 371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) '_manifest_features.json': '{}', 381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) '_permission_features.json': '{}', 39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 'alarms.idl': ReadFile(CHROME_API, 'alarms.idl'), 40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 'declarative_web_request.json': ReadFile( 41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CHROME_API, 'declarative_web_request.json'), 42c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 'input_ime.json': ReadFile(CHROME_API, 'input_ime.json'), 43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 'page_action.json': ReadFile(CHROME_API, 'page_action.json'), 441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) }, 451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 'docs': { 461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 'templates': { 471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 'json': { 481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 'manifest.json': '{}', 491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 'permissions.json': '{}', 501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) }, 531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)class APIModelsTest(unittest.TestCase): 571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) def setUp(self): 581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) object_store_creator = ObjectStoreCreator.ForTest() 591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) compiled_fs_factory = CompiledFileSystem.Factory(object_store_creator) 60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self._mock_file_system = MockFileSystem( 61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TestFileSystem(_TEST_DATA, relative_to=CHROME_EXTENSIONS)) 621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) features_bundle = FeaturesBundle( 630f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) self._mock_file_system, compiled_fs_factory, object_store_creator) 641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) self._api_models = APIModels( 650f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) features_bundle, compiled_fs_factory, self._mock_file_system) 661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) def testGetNames(self): 680f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) # Both 'app' and 'app.runtime' appear here because 'app.runtime' has 69c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch # noparent:true, but 'app.runtime.foo' etc doesn't so it's a sub-feature of 70c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch # 'app.runtime' not a separate API. 'devtools.inspectedWindow' is an API 71c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch # because there is no 'devtools'. 721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) self.assertEqual( 730f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) ['alarms', 'app', 'app.runtime', 'declarativeWebRequest', 74c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 'devtools.inspectedWindow', 'input', 'storage'], 751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) sorted(self._api_models.GetNames())) 761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) def testGetModel(self): 781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) def get_model_name(api_name): 791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return self._api_models.GetModel(api_name).Get().name 801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) self.assertEqual('devtools.inspectedWindow', 811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) get_model_name('devtools.inspectedWindow')) 821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) self.assertEqual('devtools.inspectedWindow', 831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) get_model_name('devtools/inspected_window.json')) 841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) self.assertEqual('devtools.inspectedWindow', 85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) get_model_name(CHROME_API + 86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 'devtools/inspected_window.json')) 871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) self.assertEqual('alarms', get_model_name('alarms')) 881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) self.assertEqual('alarms', get_model_name('alarms.idl')) 89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) self.assertEqual('alarms', get_model_name(CHROME_API + 'alarms.idl')) 901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) self.assertEqual('declarativeWebRequest', 911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) get_model_name('declarativeWebRequest')) 921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) self.assertEqual('declarativeWebRequest', 931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) get_model_name('declarative_web_request.json')) 941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) self.assertEqual('declarativeWebRequest', 95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) get_model_name(CHROME_API + 96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 'declarative_web_request.json')) 97c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch self.assertEqual('input.ime', get_model_name('input.ime')) 98c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch self.assertEqual('input.ime', get_model_name('input_ime.json')) 99c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch self.assertEqual('input.ime', 100c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch get_model_name(CHROME_API + 'input_ime.json')) 1011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) self.assertEqual('pageAction', get_model_name('pageAction')) 1021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) self.assertEqual('pageAction', get_model_name('page_action.json')) 103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) self.assertEqual('pageAction', get_model_name(CHROME_API + 104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 'page_action.json')) 1051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) def testGetNonexistentModel(self): 1071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) self.assertRaises(FileNotFoundError, 1081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) self._api_models.GetModel('notfound').Get) 1091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) self.assertRaises(FileNotFoundError, 1101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) self._api_models.GetModel('notfound.json').Get) 1111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) self.assertRaises(FileNotFoundError, 112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) self._api_models.GetModel(CHROME_API + 113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 'notfound.json').Get) 1141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) self.assertRaises(FileNotFoundError, 115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) self._api_models.GetModel(CHROME_API + 116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 'alarms.json').Get) 1171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) self.assertRaises(FileNotFoundError, 1181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) self._api_models.GetModel('storage').Get) 1191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) self.assertRaises(FileNotFoundError, 120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) self._api_models.GetModel(CHROME_API + 121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 'storage.json').Get) 1221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) self.assertRaises(FileNotFoundError, 123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) self._api_models.GetModel(CHROME_API + 124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 'storage.idl').Get) 1251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) def testSingleFile(self): 127effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch # 2 stats (1 for JSON and 1 for IDL) for each available API path. 128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) # 1 read (for IDL file which existed). 1290f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) future = self._api_models.GetModel('alarms') 1300f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) self.assertTrue(*self._mock_file_system.CheckAndReset( 131effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch read_count=1, stat_count=len(API_PATHS)*2)) 1320f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 1330f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) # 1 read-resolve (for the IDL file). 1340f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) # 1350f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) # The important part here and above is that it's only doing a single read; 1360f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) # any more would break the contract that only a single file is accessed - 1370f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) # see the SingleFile annotation in api_models._CreateAPIModel. 1380f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) future.Get() 1390f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) self.assertTrue(*self._mock_file_system.CheckAndReset( 1400f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) read_resolve_count=1)) 1410f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 142effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch # 2 stats (1 for JSON and 1 for IDL) for each available API path. 143effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch # No reads (still cached). 1440f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) future = self._api_models.GetModel('alarms') 145effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch self.assertTrue(*self._mock_file_system.CheckAndReset( 146effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch stat_count=len(API_PATHS)*2)) 1470f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) future.Get() 1480f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) self.assertTrue(*self._mock_file_system.CheckAndReset()) 1490f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 1501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)if __name__ == '__main__': 1521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) unittest.main() 153