Exemplo n.º 1
0
        def update_availability_graph(file_system, channel_info):
            version_filename = assert_not_none(
                self._GetApiSchemaFilename(api_name, file_system,
                                           channel_info.version))
            version_stat = assert_not_none(file_system.Stat(version_filename))

            # Important optimisation: only re-parse the graph if the file changed in
            # the last revision. Parsing the same schema and forming a graph on every
            # iteration is really expensive.
            if version_stat == previous.stat:
                version_graph = previous.graph
            else:
                # Keep track of any new schema elements from this version by adding
                # them to |availability_graph|.
                #
                # Calling |availability_graph|.Lookup() on the nodes being updated
                # will return the |annotation| object -- the current |channel_info|.
                version_graph = APISchemaGraph(
                    self._GetApiSchema(api_name, file_system,
                                       channel_info.version))
                availability_graph.Update(
                    version_graph.Subtract(availability_graph),
                    annotation=channel_info)

            previous.stat = version_stat
            previous.graph = version_graph

            # Continue looping until there are no longer differences between this
            # version and trunk.
            return version_stat != trunk_stat
Exemplo n.º 2
0
 def GetAPINodeAvailability(self, api_name):
     schema_graph = APISchemaGraph()
     api_graph = APISchemaGraph(
         json.loads(CANNED_MASTER_FS_DATA['api'][api_name + '.json']))
     # Give the graph fake ChannelInfo; it's not used in tests.
     channel_info = ChannelInfo('stable', '28', 28)
     schema_graph.Update(api_graph, lambda _: channel_info)
     return schema_graph
Exemplo n.º 3
0
        def update_availability_graph(file_system, channel_info):
            version_graph = APISchemaGraph(get_schema(api_name, file_system))
            # Keep track of any new schema elements from this version by adding
            # them to |availability_graph|.
            #
            # Calling |availability_graph|.Lookup() on the nodes being updated
            # will return the |annotation| object.
            availability_graph.Update(
                version_graph.Subtract(availability_graph),
                annotation=channel_info)

            # Continue looping until there are no longer differences between this
            # version and trunk.
            return trunk_graph != version_graph
Exemplo n.º 4
0
    def GetAPINodeAvailability(self, api_name):
        '''Returns an APISchemaGraph annotated with each node's availability (the
    ChannelInfo at the oldest channel it's available in).
    '''
        availability_graph = self._node_level_object_store.Get(api_name).Get()
        if availability_graph is not None:
            return availability_graph

        def assert_not_none(value):
            assert value is not None
            return value

        availability_graph = APISchemaGraph()

        host_fs = self._host_file_system
        trunk_stat = assert_not_none(
            host_fs.Stat(self._GetAPISchemaFilename(api_name, host_fs,
                                                    'trunk')))

        # Weird object thing here because nonlocal is Python 3.
        previous = type('previous', (object, ), {'stat': None, 'graph': None})

        def update_availability_graph(file_system, channel_info):
            version_filename = assert_not_none(
                self._GetAPISchemaFilename(api_name, file_system,
                                           channel_info.version))
            version_stat = assert_not_none(file_system.Stat(version_filename))

            # Important optimisation: only re-parse the graph if the file changed in
            # the last revision. Parsing the same schema and forming a graph on every
            # iteration is really expensive.
            if version_stat == previous.stat:
                version_graph = previous.graph
            else:
                # Keep track of any new schema elements from this version by adding
                # them to |availability_graph|.
                #
                # Calling |availability_graph|.Lookup() on the nodes being updated
                # will return the |annotation| object -- the current |channel_info|.
                version_graph = APISchemaGraph(
                    self._GetAPISchema(api_name, file_system,
                                       channel_info.version))
                availability_graph.Update(
                    version_graph.Subtract(availability_graph),
                    annotation=channel_info)

            previous.stat = version_stat
            previous.graph = version_graph

            # Continue looping until there are no longer differences between this
            # version and trunk.
            return version_stat != trunk_stat

        self._file_system_iterator.Ascending(
            self.GetAPIAvailability(api_name).channel_info,
            update_availability_graph)

        self._node_level_object_store.Set(api_name, availability_graph)
        return availability_graph
Exemplo n.º 5
0
    def update_availability_graph(file_system, channel_info):
      # If we can't find a filename, skip checking at this branch.
      # For example, something could have a predetermined availability of 23,
      # but it doesn't show up in the file system until 26.
      # We know that the file will become available at some point.
      #
      # The problem with this is that at the first version where the API file
      # exists, we'll get a huge chunk of new objects that don't match
      # the predetermined API availability.
      version_filename = _GetAPISchemaFilename(api_name,
                                               file_system,
                                               channel_info.version)
      if version_filename is None:
        # Continue the loop at the next version.
        return True

      version_stat = assert_not_none(file_system.Stat(version_filename))

      # Important optimisation: only re-parse the graph if the file changed in
      # the last revision. Parsing the same schema and forming a graph on every
      # iteration is really expensive.
      if version_stat == previous.stat:
        version_graph = previous.graph
      else:
        # Keep track of any new schema elements from this version by adding
        # them to |availability_graph|.
        #
        # Calling |availability_graph|.Lookup() on the nodes being updated
        # will return the |annotation| object -- the current |channel_info|.
        version_graph = APISchemaGraph(
            api_schema=self._GetAPISchema(api_name,
                                          file_system,
                                          channel_info.version))
        def annotator(node_name):
          return self._CheckAPINodeAvailability('%s.%s' % (api_name, node_name),
                                                channel_info)

        availability_graph.Update(version_graph.Subtract(availability_graph),
                                  annotator)

      previous.stat = version_stat
      previous.graph = version_graph

      # Continue looping until there are no longer differences between this
      # version and master.
      return version_stat != master_stat
Exemplo n.º 6
0
    def GetApiNodeAvailability(self, api_name):
        '''Returns an APISchemaGraph annotated with each node's availability (the
    ChannelInfo at the oldest channel it's available in).
    '''
        availability_graph = self._node_level_object_store.Get(api_name).Get()
        if availability_graph is not None:
            return availability_graph

        def get_schema(api_name, file_system):
            return _GetApiSchema(
                api_name, self._compiled_fs_factory.ForApiSchema(file_system))

        availability_graph = APISchemaGraph()
        trunk_graph = APISchemaGraph(
            get_schema(api_name, self._host_file_system))

        def update_availability_graph(file_system, channel_info):
            version_graph = APISchemaGraph(get_schema(api_name, file_system))
            # Keep track of any new schema elements from this version by adding
            # them to |availability_graph|.
            #
            # Calling |availability_graph|.Lookup() on the nodes being updated
            # will return the |annotation| object.
            availability_graph.Update(
                version_graph.Subtract(availability_graph),
                annotation=channel_info)

            # Continue looping until there are no longer differences between this
            # version and trunk.
            return trunk_graph != version_graph

        self._file_system_iterator.Ascending(self.GetApiAvailability(api_name),
                                             update_availability_graph)

        self._node_level_object_store.Set(api_name, availability_graph)
        return availability_graph
Exemplo n.º 7
0
 def testIsEmpty(self):
   # A few assertions to make sure that Lookup works on empty sets.
   empty_graph = APISchemaGraph({})
   self.assertTrue(empty_graph.IsEmpty())
   self.assertEqual(LookupResult(False, None),
                    empty_graph.Lookup('tabs', 'properties',
                                       'TAB_PROPERTY_ONE'))
   self.assertEqual(LookupResult(False, None),
                    empty_graph.Lookup('tabs', 'functions', 'get',
                                       'parameters', 'tab'))
   self.assertEqual(LookupResult(False, None),
                    empty_graph.Lookup('tabs', 'functions', 'get',
                                       'parameters', 'tabId'))
   self.assertEqual(LookupResult(False, None),
                    empty_graph.Lookup('tabs', 'events', 'onActivated',
                                       'parameters', 'activeInfo'))
   self.assertEqual(LookupResult(False, None),
                    empty_graph.Lookup('tabs', 'events', 'onUpdated',
                                       'parameters', 'updateInfo'))
Exemplo n.º 8
0
    def GetAPINodeAvailability(self, api_name):
        '''Returns an APISchemaGraph annotated with each node's availability (the
    ChannelInfo at the oldest channel it's available in).
    '''
        availability_graph = self._node_level_object_store.Get(api_name).Get()
        if availability_graph is not None:
            return availability_graph

        def assert_not_none(value):
            assert value is not None
            return value

        availability_graph = APISchemaGraph()
        host_fs = self._host_file_system
        master_stat = assert_not_none(
            host_fs.Stat(_GetAPISchemaFilename(api_name, host_fs, 'master')))

        # Weird object thing here because nonlocal is Python 3.
        previous = type('previous', (object, ), {'stat': None, 'graph': None})

        def update_availability_graph(file_system, channel_info):
            # If we can't find a filename, skip checking at this branch.
            # For example, something could have a predetermined availability of 23,
            # but it doesn't show up in the file system until 26.
            # We know that the file will become available at some point.
            #
            # The problem with this is that at the first version where the API file
            # exists, we'll get a huge chunk of new objects that don't match
            # the predetermined API availability.
            version_filename = _GetAPISchemaFilename(api_name, file_system,
                                                     channel_info.version)
            if version_filename is None:
                # Continue the loop at the next version.
                return True

            version_stat = assert_not_none(file_system.Stat(version_filename))

            # Important optimisation: only re-parse the graph if the file changed in
            # the last revision. Parsing the same schema and forming a graph on every
            # iteration is really expensive.
            if version_stat == previous.stat:
                version_graph = previous.graph
            else:
                # Keep track of any new schema elements from this version by adding
                # them to |availability_graph|.
                #
                # Calling |availability_graph|.Lookup() on the nodes being updated
                # will return the |annotation| object -- the current |channel_info|.
                version_graph = APISchemaGraph(api_schema=self._GetAPISchema(
                    api_name, file_system, channel_info.version))

                def annotator(node_name):
                    return self._CheckAPINodeAvailability(
                        '%s.%s' % (api_name, node_name), channel_info)

                availability_graph.Update(
                    version_graph.Subtract(availability_graph), annotator)

            previous.stat = version_stat
            previous.graph = version_graph

            # Continue looping until there are no longer differences between this
            # version and master.
            return version_stat != master_stat

        self._file_system_iterator.Ascending(
            self.GetAPIAvailability(api_name).channel_info,
            update_availability_graph)

        self._node_level_object_store.Set(api_name, availability_graph)
        return availability_graph
 def testSubtractEmpty(self):
     self._testAPISchema(
         APISchemaGraph(API_SCHEMA).Subtract(APISchemaGraph({})))
 def testLookup(self):
     self._testAPISchema(APISchemaGraph(API_SCHEMA))
    def testUpdate(self):
        result = APISchemaGraph(API_SCHEMA)
        to_add = APISchemaGraph({
            'tabs': {
                'properties': {
                    'TAB_PROPERTY_THREE': {
                        'description': 'better than two'
                    },
                    'TAB_PROPERTY_FOUR': {
                        'value': 4
                    }
                },
                'functions': {
                    'get': {
                        'name': {},
                        'parameters': {
                            'tab': {
                                'type': {},
                                'name': {},
                                'description': {},
                                'surprise': {}
                            }
                        }
                    },
                    'getAllInWindow': {
                        'parameters': {
                            'windowId': {
                                'type': 'object'
                            }
                        }
                    }
                }
            }
        })
        result.Update(to_add, annotation='first')
        # Looking up elements that were originally available in |result|. Because
        # of this, no |annotation| object should be attached to the LookupResult
        # object.
        self.assertEqual(LookupResult(True, None), result.Lookup('tabs'))
        self.assertEqual(
            LookupResult(True, None),
            result.Lookup('tabs', 'functions', 'get', 'parameters'))
        self.assertEqual(
            LookupResult(True, None),
            result.Lookup('tabs', 'properties', 'TAB_PROPERTY_ONE'))
        self.assertEqual(
            LookupResult(True, None),
            result.Lookup('tabs', 'properties', 'TAB_PROPERTY_ONE'))
        self.assertEqual(
            LookupResult(True, None),
            result.Lookup('tabs', 'functions', 'get', 'parameters', 'tabId'))

        # Looking up elements that were just added to |result|.
        self.assertEqual(
            LookupResult(True, 'first'),
            result.Lookup('tabs', 'properties', 'TAB_PROPERTY_THREE'))
        self.assertEqual(
            LookupResult(True, 'first'),
            result.Lookup('tabs', 'properties', 'TAB_PROPERTY_FOUR'))
        self.assertEqual(
            LookupResult(True, 'first'),
            result.Lookup('tabs', 'functions', 'getAllInWindow', 'parameters',
                          'windowId'))
        self.assertEqual(
            LookupResult(True, 'first'),
            result.Lookup('tabs', 'functions', 'get', 'parameters', 'tab',
                          'surprise'))

        to_add = APISchemaGraph({
            'tabs': {
                'properties': {
                    'TAB_PROPERTY_FIVE': {
                        'description': 'stayin\' alive'
                    }
                },
                'functions': {
                    'getAllInWindow': {
                        'parameters': {
                            'callback': {
                                'type': 'function'
                            }
                        }
                    }
                }
            }
        })
        result.Update(to_add, annotation='second')
        # Looking up the second group of elements added to |result|.
        self.assertEqual(
            LookupResult(True, 'first'),
            result.Lookup('tabs', 'properties', 'TAB_PROPERTY_FOUR'))
        self.assertEqual(
            LookupResult(True, 'second'),
            result.Lookup('tabs', 'properties', 'TAB_PROPERTY_FIVE'))
        self.assertEqual(
            LookupResult(True, 'first'),
            result.Lookup('tabs', 'functions', 'getAllInWindow', 'parameters',
                          'windowId'))
        self.assertEqual(
            LookupResult(True, 'second'),
            result.Lookup('tabs', 'functions', 'getAllInWindow', 'parameters',
                          'callback'))
        self.assertEqual(LookupResult(True, 'first'),
                         result.Lookup('tabs', 'functions', 'getAllInWindow'))
 def testSubtractSuperset(self):
     difference = APISchemaGraph(API_SCHEMA).Subtract(
         APISchemaGraph({
             'tabs': {
                 'namespace': {},
                 'properties': {
                     'lowercase': {
                         'properties': {
                             'one': {
                                 'value': {}
                             },
                             'two': {
                                 'description': {}
                             }
                         }
                     },
                     'TAB_PROPERTY_ONE': {
                         'value': {}
                     },
                     'TAB_PROPERTY_TWO': {},
                     'TAB_PROPERTY_THREE': {}
                 },
                 'types': {
                     'Tab': {
                         'id': {},
                         'properties': {
                             'id': {},
                             'url': {}
                         }
                     },
                     'UpdateInfo': {}
                 },
                 'functions': {
                     'get': {
                         'name': {},
                         'parameters': {
                             'tab': {
                                 'name': {},
                                 'type': {},
                                 'description': {}
                             },
                             'tabId': {
                                 'name': {}
                             }
                         }
                     },
                     'getById': {
                         'parameters': {
                             'tabId': {}
                         }
                     }
                 },
                 'events': {
                     'onActivated': {
                         'name': {},
                         'parameters': {
                             'activeInfo': {
                                 'name': {}
                             }
                         }
                     },
                     'onUpdated': {
                         'name': {},
                         'parameters': {
                             'updateInfo': {
                                 'name': {}
                             }
                         }
                     },
                     'onClicked': {
                         'name': {},
                         'parameters': {
                             'clickInfo': {}
                         }
                     }
                 }
             }
         }))
     self.assertEqual(LookupResult(False, None), difference.Lookup('tabs'))
     self.assertEqual(
         LookupResult(False, None),
         difference.Lookup('tabs', 'properties', 'TAB_PROPERTY_TWO'))
     self.assertEqual(LookupResult(False, None),
                      difference.Lookup('tabs', 'properties'))
     self.assertEqual(
         LookupResult(False, None),
         difference.Lookup('tabs', 'types', 'Tab', 'properties', 'url'))
     self.assertEqual(
         LookupResult(False, None),
         difference.Lookup('tabs', 'types', 'Tab', 'properties', 'id'))
     self.assertEqual(
         LookupResult(False, None),
         difference.Lookup('tabs', 'events', 'onUpdated', 'parameters',
                           'updateInfo'))
     self.assertEqual(
         LookupResult(False, None),
         difference.Lookup('tabs', 'properties', 'TAB_PROPERTY_ONE'))
     self.assertEqual(
         LookupResult(False, None),
         difference.Lookup('tabs', 'functions', 'get', 'parameters',
                           'tabId'))
     self.assertEqual(
         LookupResult(False, None),
         difference.Lookup('events', 'onUpdated', 'parameters',
                           'updateInfo'))
 def testSubtractDisjointSet(self):
     difference = APISchemaGraph(API_SCHEMA).Subtract(
         APISchemaGraph({
             'contextMenus': {
                 'properties': {
                     'CONTEXT_MENU_PROPERTY_ONE': {}
                 },
                 'types': {
                     'Menu': {
                         'properties': {
                             'id': {},
                             'width': {}
                         }
                     }
                 },
                 'functions': {
                     'get': {
                         'parameters': {
                             'callback': {}
                         }
                     }
                 },
                 'events': {
                     'onClicked': {
                         'parameters': {
                             'clickInfo': {}
                         }
                     },
                     'onUpdated': {
                         'parameters': {
                             'updateInfo': {}
                         }
                     }
                 }
             }
         }))
     self.assertEqual(
         LookupResult(True, None),
         difference.Lookup('tabs', 'properties', 'TAB_PROPERTY_ONE'))
     self.assertEqual(
         LookupResult(True, None),
         difference.Lookup('tabs', 'functions', 'get', 'parameters', 'tab'))
     self.assertEqual(
         LookupResult(True, None),
         difference.Lookup('tabs', 'events', 'onUpdated', 'parameters',
                           'updateInfo'))
     self.assertEqual(
         LookupResult(True, None),
         difference.Lookup('tabs', 'functions', 'get', 'parameters',
                           'tabId'))
     self.assertEqual(
         LookupResult(False, None),
         difference.Lookup('contextMenus', 'properties',
                           'CONTEXT_MENU_PROPERTY_ONE'))
     self.assertEqual(LookupResult(False, None),
                      difference.Lookup('contextMenus', 'types', 'Menu'))
     self.assertEqual(
         LookupResult(False, None),
         difference.Lookup('contextMenus', 'types', 'Menu', 'properties',
                           'id'))
     self.assertEqual(LookupResult(False, None),
                      difference.Lookup('contextMenus', 'functions'))
     self.assertEqual(
         LookupResult(False, None),
         difference.Lookup('contextMenus', 'events', 'onClicked',
                           'parameters', 'clickInfo'))
     self.assertEqual(
         LookupResult(False, None),
         difference.Lookup('contextMenus', 'events', 'onUpdated',
                           'parameters', 'updateInfo'))
 def testSubtractSelf(self):
     self.assertTrue(
         APISchemaGraph(API_SCHEMA).Subtract(
             APISchemaGraph(API_SCHEMA)).IsEmpty())