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