blob: 27f52c51334a69e4ac54eb21fc4f568a330c4f7a [file] [log] [blame]
#!/usr/bin/env python
# Copyright 2013 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import os
import sys
import unittest
import api_schema_graph
from availability_finder import AvailabilityFinder, AvailabilityInfo
from branch_utility import BranchUtility, ChannelInfo
from compiled_file_system import CompiledFileSystem
from fake_host_file_system_provider import FakeHostFileSystemProvider
from fake_url_fetcher import FakeUrlFetcher
from host_file_system_iterator import HostFileSystemIterator
from mock_function import MockFunction
from object_store_creator import ObjectStoreCreator
from platform_util import GetPlatforms
from test_data.canned_data import (CANNED_API_FILE_SYSTEM_DATA, CANNED_BRANCHES)
from test_data.object_level_availability.tabs import TABS_SCHEMA_BRANCHES
from test_util import Server2Path
from schema_processor import SchemaProcessorFactoryForTest
TABS_UNMODIFIED_VERSIONS = (16, 20, 23, 24)
class AvailabilityFinderTest(unittest.TestCase):
def _create_availability_finder(self,
host_fs_creator,
host_fs_iterator,
platform):
test_object_store = ObjectStoreCreator.ForTest()
return AvailabilityFinder(
self._branch_utility,
CompiledFileSystem.Factory(test_object_store),
host_fs_iterator,
host_fs_creator.GetMaster(),
test_object_store,
platform,
SchemaProcessorFactoryForTest())
def setUp(self):
self._branch_utility = BranchUtility(
os.path.join('branch_utility', 'first.json'),
os.path.join('branch_utility', 'second.json'),
FakeUrlFetcher(Server2Path('test_data')),
ObjectStoreCreator.ForTest())
self._api_fs_creator = FakeHostFileSystemProvider(
CANNED_API_FILE_SYSTEM_DATA)
self._node_fs_creator = FakeHostFileSystemProvider(TABS_SCHEMA_BRANCHES)
self._api_fs_iterator = HostFileSystemIterator(self._api_fs_creator,
self._branch_utility)
self._node_fs_iterator = HostFileSystemIterator(self._node_fs_creator,
self._branch_utility)
# Imitate the actual SVN file system by incrementing the stats for paths
# where an API schema has changed.
last_stat = type('last_stat', (object,), {'val': 0})
def stat_paths(file_system, channel_info):
if channel_info.version not in TABS_UNMODIFIED_VERSIONS:
last_stat.val += 1
# HACK: |file_system| is a MockFileSystem backed by a TestFileSystem.
# Increment the TestFileSystem stat count.
file_system._file_system.IncrementStat(by=last_stat.val)
# Continue looping. The iterator will stop after 'master' automatically.
return True
# Use the HostFileSystemIterator created above to change global stat values
# for the TestFileSystems that it creates.
self._node_fs_iterator.Ascending(
# The earliest version represented with the tabs' test data is 13.
self._branch_utility.GetStableChannelInfo(13),
stat_paths)
def testGraphOptimization(self):
for platform in GetPlatforms():
# Keep track of how many times the APISchemaGraph constructor is called.
original_constructor = api_schema_graph.APISchemaGraph
mock_constructor = MockFunction(original_constructor)
api_schema_graph.APISchemaGraph = mock_constructor
node_avail_finder = self._create_availability_finder(
self._node_fs_creator, self._node_fs_iterator, platform)
try:
# The test data includes an extra branch where the API does not exist.
num_versions = len(TABS_SCHEMA_BRANCHES) - 1
# We expect an APISchemaGraph to be created only when an API schema file
# has different stat data from the previous version's schema file.
num_graphs_created = num_versions - len(TABS_UNMODIFIED_VERSIONS)
# Run the logic for object-level availability for an API.
node_avail_finder.GetAPINodeAvailability('tabs')
self.assertTrue(*api_schema_graph.APISchemaGraph.CheckAndReset(
num_graphs_created))
finally:
# Ensure that the APISchemaGraph constructor is reset to be the original
# constructor.
api_schema_graph.APISchemaGraph = original_constructor
def testGetAPIAvailability(self):
# Key: Using 'channel' (i.e. 'beta') to represent an availability listing
# for an API in a _features.json file, and using |channel| (i.e. |dev|) to
# represent the development channel, or phase of development, where an API's
# availability is being checked.
def assertGet(ch_info, api, only_on=None, scheduled=None):
for platform in GetPlatforms():
get_availability = self._create_availability_finder(
self._api_fs_creator,
self._api_fs_iterator,
platform if only_on is None else only_on).GetAPIAvailability
self.assertEqual(AvailabilityInfo(ch_info, scheduled=scheduled),
get_availability(api))
# Testing APIs with predetermined availability.
assertGet(ChannelInfo('master', 'master', 'master'), 'jsonMasterAPI')
assertGet(ChannelInfo('dev', CANNED_BRANCHES[31], 31), 'jsonDevAPI')
assertGet(ChannelInfo('beta', CANNED_BRANCHES[30], 30), 'jsonBetaAPI')
assertGet(ChannelInfo('stable', CANNED_BRANCHES[20], 20), 'jsonStableAPI')
# Testing a whitelisted API.
assertGet(ChannelInfo('beta', CANNED_BRANCHES[30], 30),
'declarativeWebRequest')
# Testing APIs found only by checking file system existence.
assertGet(ChannelInfo('stable', CANNED_BRANCHES[23], 23), 'windows')
assertGet(ChannelInfo('stable', CANNED_BRANCHES[18], 18), 'tabs')
assertGet(ChannelInfo('stable', CANNED_BRANCHES[18], 18), 'input.ime')
# Testing API channel existence for _api_features.json.
# Listed as 'dev' on |beta|, 'dev' on |dev|.
assertGet(ChannelInfo('dev', CANNED_BRANCHES[31], 31), 'systemInfo.stuff')
# Listed as 'stable' on |beta|.
assertGet(ChannelInfo('beta', CANNED_BRANCHES[30], 30),
'systemInfo.cpu',
scheduled=31)
# Testing API channel existence for _manifest_features.json.
# Listed as 'master' on all channels.
assertGet(ChannelInfo('master', 'master', 'master'), 'sync')
# No records of API until |master|.
assertGet(ChannelInfo('master', 'master', 'master'), 'history')
# Listed as 'dev' on |dev|.
assertGet(ChannelInfo('dev', CANNED_BRANCHES[31], 31), 'storage')
# Stable in _manifest_features and into pre-18 versions.
assertGet(ChannelInfo('stable', CANNED_BRANCHES[8], 8), 'pageAction')
# Testing API channel existence for _permission_features.json.
# Listed as 'beta' on |master|.
assertGet(ChannelInfo('master', 'master', 'master'), 'falseBetaAPI')
# Listed as 'master' on |master|.
assertGet(ChannelInfo('master', 'master', 'master'), 'masterAPI')
# Listed as 'master' on all development channels.
assertGet(ChannelInfo('master', 'master', 'master'), 'declarativeContent')
# Listed as 'dev' on all development channels.
assertGet(ChannelInfo('dev', CANNED_BRANCHES[31], 31), 'bluetooth')
# Listed as 'dev' on |dev|.
assertGet(ChannelInfo('dev', CANNED_BRANCHES[31], 31), 'cookies')
# Treated as 'stable' APIs.
assertGet(ChannelInfo('stable', CANNED_BRANCHES[24], 24), 'alarms')
assertGet(ChannelInfo('stable', CANNED_BRANCHES[21], 21), 'bookmarks')
# Testing older API existence using extension_api.json.
assertGet(ChannelInfo('stable', CANNED_BRANCHES[6], 6), 'menus')
assertGet(ChannelInfo('stable', CANNED_BRANCHES[5], 5), 'idle')
# Switches between _features.json files across branches.
# Listed as 'master' on all channels, in _api, _permission, or _manifest.
assertGet(ChannelInfo('master', 'master', 'master'), 'contextMenus')
# Moves between _permission and _manifest as file system is traversed.
assertGet(ChannelInfo('stable', CANNED_BRANCHES[23], 23),
'systemInfo.display')
assertGet(ChannelInfo('stable', CANNED_BRANCHES[17], 17), 'webRequest')
# Mid-upgrade cases:
# Listed as 'dev' on |beta| and 'beta' on |dev|.
assertGet(ChannelInfo('dev', CANNED_BRANCHES[31], 31), 'notifications')
# Listed as 'beta' on |stable|, 'dev' on |beta|...until |stable| on master.
assertGet(ChannelInfo('master', 'master', 'master'), 'events')
# Check for differing availability across apps|extensions
assertGet(ChannelInfo('stable', CANNED_BRANCHES[26], 26),
'appsFirst',
only_on='extensions')
assertGet(ChannelInfo('stable', CANNED_BRANCHES[25], 25),
'appsFirst',
only_on='apps')
def testGetAPINodeAvailability(self):
def assertEquals(found, channel_info, actual, scheduled=None):
lookup_result = api_schema_graph.LookupResult
if channel_info is None:
self.assertEquals(lookup_result(found, None), actual)
else:
self.assertEquals(lookup_result(found, AvailabilityInfo(channel_info,
scheduled=scheduled)), actual)
for platform in GetPlatforms():
# Allow the LookupResult constructions below to take just one line.
avail_finder = self._create_availability_finder(
self._node_fs_creator,
self._node_fs_iterator,
platform)
tabs_graph = avail_finder.GetAPINodeAvailability('tabs')
fake_tabs_graph = avail_finder.GetAPINodeAvailability('fakeTabs')
# Test an API node with predetermined availability.
assertEquals(True, self._branch_utility.GetStableChannelInfo(27),
tabs_graph.Lookup('tabs', 'properties', 'fakeTabsProperty4'))
assertEquals(True, self._branch_utility.GetChannelInfo('master'),
tabs_graph.Lookup('tabs', 'properties', 'fakeTabsProperty3'))
assertEquals(True, self._branch_utility.GetChannelInfo('dev'),
tabs_graph.Lookup('tabs', 'events', 'onActivated', 'parameters',
'activeInfo', 'properties', 'windowId'), scheduled=31)
assertEquals(True, self._branch_utility.GetChannelInfo('dev'),
tabs_graph.Lookup('tabs', 'events', 'onUpdated', 'parameters', 'tab'),
scheduled=31)
assertEquals(True, self._branch_utility.GetChannelInfo('beta'),
tabs_graph.Lookup('tabs', 'events', 'onActivated'), scheduled=30)
assertEquals(True, self._branch_utility.GetChannelInfo('beta'),
tabs_graph.Lookup('tabs', 'functions', 'get', 'parameters', 'tabId'),
scheduled=30)
assertEquals(True, self._branch_utility.GetChannelInfo('stable'),
tabs_graph.Lookup('tabs', 'types', 'InjectDetails', 'properties',
'code'))
assertEquals(True, self._branch_utility.GetChannelInfo('stable'),
tabs_graph.Lookup('tabs', 'types', 'InjectDetails', 'properties',
'file'))
assertEquals(True, self._branch_utility.GetStableChannelInfo(25),
tabs_graph.Lookup('tabs', 'types', 'InjectDetails'))
# Test inlined type.
assertEquals(True, self._branch_utility.GetChannelInfo('master'),
tabs_graph.Lookup('tabs', 'types', 'InlinedType'))
# Test implicitly inlined type.
assertEquals(True, self._branch_utility.GetStableChannelInfo(25),
fake_tabs_graph.Lookup('fakeTabs', 'types',
'WasImplicitlyInlinedType'))
# Test a node that was restricted to dev channel when it was introduced.
assertEquals(True, self._branch_utility.GetChannelInfo('beta'),
tabs_graph.Lookup('tabs', 'functions', 'restrictedFunc'),
scheduled=30)
# Test an explicitly scheduled node.
assertEquals(True, self._branch_utility.GetChannelInfo('dev'),
tabs_graph.Lookup('tabs', 'functions', 'scheduledFunc'),
scheduled=31)
# Nothing new in version 24 or 23.
assertEquals(True, self._branch_utility.GetStableChannelInfo(22),
tabs_graph.Lookup('tabs', 'types', 'Tab', 'properties', 'windowId'))
assertEquals(True, self._branch_utility.GetStableChannelInfo(21),
tabs_graph.Lookup('tabs', 'types', 'Tab', 'properties', 'selected'))
# Nothing new in version 20.
assertEquals(True, self._branch_utility.GetStableChannelInfo(19),
tabs_graph.Lookup('tabs', 'functions', 'getCurrent'))
assertEquals(True, self._branch_utility.GetStableChannelInfo(18),
tabs_graph.Lookup('tabs', 'types', 'Tab', 'properties', 'index'))
assertEquals(True, self._branch_utility.GetStableChannelInfo(17),
tabs_graph.Lookup('tabs', 'events', 'onUpdated', 'parameters',
'changeInfo'))
# Nothing new in version 16.
assertEquals(True, self._branch_utility.GetStableChannelInfo(15),
tabs_graph.Lookup('tabs', 'properties', 'fakeTabsProperty2'))
# Everything else is available at the API's release, version 14 here.
assertEquals(True, self._branch_utility.GetStableChannelInfo(14),
tabs_graph.Lookup('tabs', 'types', 'Tab'))
assertEquals(True, self._branch_utility.GetStableChannelInfo(14),
tabs_graph.Lookup('tabs', 'types', 'Tab', 'properties', 'url'))
assertEquals(True, self._branch_utility.GetStableChannelInfo(14),
tabs_graph.Lookup('tabs', 'properties', 'fakeTabsProperty1'))
assertEquals(True, self._branch_utility.GetStableChannelInfo(14),
tabs_graph.Lookup('tabs', 'functions', 'get', 'parameters',
'callback'))
assertEquals(True, self._branch_utility.GetStableChannelInfo(14),
tabs_graph.Lookup('tabs', 'events', 'onUpdated'))
# Test things that aren't available.
assertEquals(False, None, tabs_graph.Lookup('tabs', 'types',
'UpdateInfo'))
assertEquals(False, None, tabs_graph.Lookup('tabs', 'functions', 'get',
'parameters', 'callback', 'parameters', 'tab', 'id'))
assertEquals(False, None, tabs_graph.Lookup('functions'))
assertEquals(False, None, tabs_graph.Lookup('events', 'onActivated',
'parameters', 'activeInfo', 'tabId'))
if __name__ == '__main__':
unittest.main()