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 11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)from extensions_paths import API, 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( 24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 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}, 300f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 'app.runtime.experimental': {}, 310f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 'app.runtime.experimental.foo': {}, 321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 'declarativeWebRequest': {}, 331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 'devtools.inspectedWindow': {}, 341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 'experimental.accessibility': {}, 351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 'storage': {}, 361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) }), 371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) '_manifest_features.json': '{}', 381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) '_permission_features.json': '{}', 39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 'alarms.idl': ReadFile(API, 'alarms.idl'), 40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 'declarative_web_request.json': ReadFile( 41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) API, 'declarative_web_request.json'), 42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 'experimental_accessibility.json': ReadFile( 43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) API, 'experimental_accessibility.json'), 44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 'page_action.json': ReadFile(API, 'page_action.json'), 451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) }, 461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 'docs': { 471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 'templates': { 481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 'json': { 491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 'manifest.json': '{}', 501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 'permissions.json': '{}', 511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) }, 541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)class APIModelsTest(unittest.TestCase): 581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) def setUp(self): 591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) object_store_creator = ObjectStoreCreator.ForTest() 601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) compiled_fs_factory = CompiledFileSystem.Factory(object_store_creator) 61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self._mock_file_system = MockFileSystem( 62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) TestFileSystem(_TEST_DATA, relative_to=EXTENSIONS)) 631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) features_bundle = FeaturesBundle( 640f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) self._mock_file_system, compiled_fs_factory, object_store_creator) 651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) self._api_models = APIModels( 660f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) features_bundle, compiled_fs_factory, self._mock_file_system) 671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) def testGetNames(self): 690f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) # Both 'app' and 'app.runtime' appear here because 'app.runtime' has 700f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) # noparent:true, but 'app.runtime.experimental' etc doesn't so it's a 710f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) # sub-feature of 'app.runtime' not a separate API. 720f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) # 'devtools.inspectedWindow' is an API because there is no 'devtools'. 731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) self.assertEqual( 740f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) ['alarms', 'app', 'app.runtime', 'declarativeWebRequest', 750f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 'devtools.inspectedWindow', 'experimental.accessibility', 'storage'], 761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) sorted(self._api_models.GetNames())) 771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) def testGetModel(self): 791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) def get_model_name(api_name): 801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return self._api_models.GetModel(api_name).Get().name 811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) self.assertEqual('devtools.inspectedWindow', 821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) get_model_name('devtools.inspectedWindow')) 831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) self.assertEqual('devtools.inspectedWindow', 841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) get_model_name('devtools/inspected_window.json')) 851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) self.assertEqual('devtools.inspectedWindow', 86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) get_model_name('%s/devtools/inspected_window.json' % API)) 871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) self.assertEqual('alarms', get_model_name('alarms')) 881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) self.assertEqual('alarms', get_model_name('alarms.idl')) 89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self.assertEqual('alarms', get_model_name('%s/alarms.idl' % API)) 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', 95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) get_model_name('%s/declarative_web_request.json' % API)) 961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) self.assertEqual('experimental.accessibility', 971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) get_model_name('experimental.accessibility')) 981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) self.assertEqual('experimental.accessibility', 991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) get_model_name('experimental_accessibility.json')) 1001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) self.assertEqual('experimental.accessibility', 101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) get_model_name('%s/experimental_accessibility.json' % API)) 1021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) self.assertEqual('pageAction', get_model_name('pageAction')) 1031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) self.assertEqual('pageAction', get_model_name('page_action.json')) 104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self.assertEqual('pageAction', get_model_name('%s/page_action.json' % API)) 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, 112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self._api_models.GetModel('%s/notfound.json' % API).Get) 1131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) self.assertRaises(FileNotFoundError, 114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self._api_models.GetModel('%s/alarms.json' % API).Get) 1151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) self.assertRaises(FileNotFoundError, 1161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) self._api_models.GetModel('storage').Get) 1171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) self.assertRaises(FileNotFoundError, 118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self._api_models.GetModel('%s/storage.json' % API).Get) 1191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) self.assertRaises(FileNotFoundError, 120f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self._api_models.GetModel('%s/storage.idl' % API).Get) 1211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1220f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) def testSingleFile(self): 1230f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) # 2 stats (1 for JSON and 1 for IDL), 1 read (for IDL file which existed). 1240f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) future = self._api_models.GetModel('alarms') 1250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) self.assertTrue(*self._mock_file_system.CheckAndReset( 1260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) read_count=1, stat_count=2)) 1270f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 1280f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) # 1 read-resolve (for the IDL file). 1290f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) # 1300f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) # The important part here and above is that it's only doing a single read; 1310f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) # any more would break the contract that only a single file is accessed - 1320f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) # see the SingleFile annotation in api_models._CreateAPIModel. 1330f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) future.Get() 1340f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) self.assertTrue(*self._mock_file_system.CheckAndReset( 1350f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) read_resolve_count=1)) 1360f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 1370f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) # 2 stats (1 for JSON and 1 for IDL), no reads (still cached). 1380f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) future = self._api_models.GetModel('alarms') 1390f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) self.assertTrue(*self._mock_file_system.CheckAndReset(stat_count=2)) 1400f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) future.Get() 1410f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) self.assertTrue(*self._mock_file_system.CheckAndReset()) 1420f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 1431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)if __name__ == '__main__': 1451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) unittest.main() 146