コード例 #1
0
def TestNamespaceFiles(filter):
    idldir = os.path.split(sys.argv[0])[0]
    idldir = os.path.join(idldir, 'test_namespace', '*.idl')
    filenames = glob.glob(idldir)
    testnames = []

    for filename in filenames:
        if filter and filename not in filter: continue
        testnames.append(filename)

    # If we have no files to test, then skip this test
    if not testnames:
        InfoOut.Log('No files to test for namespace.')
        return 0

    InfoOut.SetConsole(False)
    ast = ParseFiles(testnames)
    InfoOut.SetConsole(True)

    errs = ast.GetProperty('ERRORS')
    if errs:
        ErrOut.Log("Failed namespace test.")
    else:
        InfoOut.Log("Passed namespace test.")
    return errs
コード例 #2
0
    def DetermineInterfaces(self, ast, releases):
        """Get a list of interfaces along with whatever metadata we need.
    """
        iface_releases = []
        for filenode in ast.GetListOf('File'):
            # If this file has errors, skip it
            if filenode in self.skip_list:
                if GetOption('verbose'):
                    InfoOut.Log('WrapperGen: Skipping %s due to errors\n' %
                                filenode.GetName())
                continue

            file_name = self.GetHeaderName(filenode.GetName())
            ifaces = filenode.GetListOf('Interface')
            for iface in ifaces:
                releases_for_iface = iface.GetUniqueReleases(releases)
                for release in releases_for_iface:
                    version = iface.GetVersion(release)
                    struct_name = self.cgen.GetStructName(iface,
                                                          release,
                                                          include_version=True)
                    needs_wrap = self.InterfaceVersionNeedsWrapping(
                        iface, version)
                    if not needs_wrap:
                        if GetOption('verbose'):
                            InfoOut.Log(
                                'Interface %s ver %s does not need wrapping' %
                                (struct_name, version))
                    iface_releases.append(
                        Interface(iface, release, version, struct_name,
                                  needs_wrap, file_name))
        return iface_releases
コード例 #3
0
ファイル: idl_generator.py プロジェクト: Devic1573/Chromium
  def Generate(self, ast, options):
    self.errors = 0

    rangestr = GetOption('range')
    releasestr = GetOption('release')

    print "Found releases: %s" % ast.releases

    # Generate list of files to ignore due to errors
    for filenode in ast.GetListOf('File'):
      # If this file has errors, skip it
      if filenode.GetProperty('ERRORS') > 0:
        self.skip_list.append(filenode)
        continue

    # Check for a range option which over-rides a release option
    if not releasestr and rangestr:
      range_list = rangestr.split(',')
      if len(range_list) != 2:
        self.Error('Failed to generate for %s, incorrect range: "%s"' %
                   (self.name, rangestr))
      else:
        vmin = range_list[0]
        vmax = range_list[1]

        # Generate 'start' and 'end' represent first and last found.
        if vmin == 'start':
            vmin = ast.releases[0]
        if vmax == 'end':
            vmax = ast.releases[-1]

        vmin = ast.releases.index(vmin)
        vmax = ast.releases.index(vmax) + 1
        releases = ast.releases[vmin:vmax]
        InfoOut.Log('Generate range %s of %s.' % (rangestr, self.name))
        ret = self.GenerateRange(ast, releases, options)
        if ret < 0:
          self.Error('Failed to generate range %s : %s.' %(vmin, vmax))
        else:
          InfoOut.Log('%s wrote %d files.' % (self.name, ret))
    # Otherwise this should be a single release generation
    else:
      if releasestr == 'start':
        releasestr = ast.releases[0]
      if releasestr == 'end':
        releasestr = ast.releases[-1]
      if releasestr:
        InfoOut.Log('Generate release %s of %s.' % (releasestr, self.name))
        ret = self.GenerateRelease(ast, releasestr, options)
        if ret < 0:
          self.Error('Failed to generate release %s.' % releasestr)
        else:
          InfoOut.Log('%s wrote %d files.' % (self.name, ret))

      else:
        self.Error('No range or release specified for %s.' % releasestr)
    return self.errors
コード例 #4
0
def DumpReduction(cls, p):
    if p[0] is None:
        InfoOut.Log("OBJ: %s(%d) - None\n" % (cls, len(p)))
        InfoOut.Log("  [%s]\n" % [str(x) for x in p[1:]])
    else:
        out = ""
        for index in range(len(p) - 1):
            out += " >%s< " % str(p[index + 1])
        InfoOut.Log("OBJ: %s(%d) - %s : %s\n" % (cls, len(p), str(p[0]), out))
コード例 #5
0
 def token(self):
     tok = self.lexobj.token()
     if tok:
         self.last = tok
         if self.token_debug:
             InfoOut.Log("TOKEN %s(%s)" % (tok.type, tok.value))
     return tok
コード例 #6
0
ファイル: idl_node.py プロジェクト: yubb/chromium.src
def ChildTest():
  errors = 0
  child = IDLNode('child', 'no file', 1, 0)
  parent = IDLNode('parent', 'no file', 1, 0, [child])

  if child.parent != parent:
    ErrOut.Log('Failed to connect parent.')
    errors += 1

  if [child] != parent.GetChildren():
    ErrOut.Log('Failed GetChildren.')
    errors += 1

  if child != parent.GetOneOf('child'):
    ErrOut.Log('Failed GetOneOf(child)')
    errors += 1

  if parent.GetOneOf('bogus'):
    ErrOut.Log('Failed GetOneOf(bogus)')
    errors += 1

  if not parent.IsA('parent'):
    ErrOut.Log('Expecting parent type')
    errors += 1

  parent = IDLNode('parent', 'no file', 1, 0, [child, child])
  if [child, child] != parent.GetChildren():
    ErrOut.Log('Failed GetChildren2.')
    errors += 1

  if not errors: InfoOut.Log('Passed ChildTest')
  return errors
コード例 #7
0
 def IsRelease(self, release):
     if self.rmax and self.rmax <= release:
         return False
     if self.rmin and self.rmin > release:
         return False
     if GetOption('release_debug'):
         InfoOut.Log('%f is in %s' % (release, self))
     return True
コード例 #8
0
ファイル: idl_option.py プロジェクト: Havok380/chromium-test
def DumpOption(option):
  if len(option.name) > 1:
    out = '  --%-15.15s\t%s' % (option.name, option.desc)
  else:
    out = '   -%-15.15s\t%s' % (option.name, option.desc)
  if option.default:
    out = '%s\n\t\t\t(Default: %s)\n' % (out, option.default)
  InfoOut.Log(out)
コード例 #9
0
    def Close(self):
        filename = os.path.realpath(self.filename)
        self.open = False
        outtext = ''.join(self.outlist)
        oldtext = ''

        if not self.always_write:
            if os.path.isfile(filename):
                oldtext = open(filename, 'rb').read()
                if self.IsEquivalent_(oldtext):
                    if GetOption('verbose'):
                        InfoOut.Log('Output %s unchanged.' % self.filename)
                    return False

        if GetOption('diff'):
            for line in difflib.unified_diff(oldtext.split('\n'),
                                             outtext.split('\n'),
                                             'OLD ' + self.filename,
                                             'NEW ' + self.filename,
                                             n=1,
                                             lineterm=''):
                ErrOut.Log(line)

        try:
            # If the directory does not exit, try to create it, if we fail, we
            # still get the exception when the file is openned.
            basepath, leafname = os.path.split(filename)
            if basepath and not os.path.isdir(basepath) and self.create_dir:
                InfoOut.Log('Creating directory: %s\n' % basepath)
                os.makedirs(basepath)

            if not GetOption('test'):
                outfile = open(filename, 'wb')
                outfile.write(outtext)
                outfile.close()
                InfoOut.Log('Output %s written.' % self.filename)
            return True

        except IOError as e:
            ErrOut.Log("I/O error(%d): %s" % (e.errno, e.strerror))
        except:
            ErrOut.Log("Unexpected error: %s" % sys.exc_info()[0])
            raise

        return False
コード例 #10
0
 def BuildProduction(self, cls, p, index, childlist=None):
     if not childlist: childlist = []
     filename = self.lexobj.filename
     lineno = p.lineno(index)
     pos = p.lexpos(index)
     out = IDLNode(cls, filename, lineno, pos, childlist)
     if self.build_debug:
         InfoOut.Log("Building %s" % out)
     return out
コード例 #11
0
    def AddNode(self, node):
        if GetOption('release_debug'):
            InfoOut.Log('\nAdding %s %s' % (node.Location(), node))
        last = None

        # Check current releases in that namespace
        for cver in self.nodes:
            if GetOption('release_debug'): InfoOut.Log('  Checking %s' % cver)

            # We should only be missing a 'release' tag for the first item.
            if not node.rmin:
                node.Error('Missing release on overload of previous %s.' %
                           cver.Location())
                return False

            # If the node has no max, then set it to this one
            if not cver.rmax:
                cver.rmax = node.rmin
                if GetOption('release_debug'):
                    InfoOut.Log('  Update %s' % cver)

            # if the max and min overlap, than's an error
            if cver.rmax > node.rmin:
                if node.rmax and cver.rmin >= node.rmax:
                    node.Error('Declarations out of order.')
                else:
                    node.Error('Overlap in releases: %s vs %s when adding %s' %
                               (cver.rmax, node.rmin, node))
                return False
            last = cver

        # Otherwise, the previous max and current min should match
        # unless this is the unlikely case of something being only
        # temporarily deprecated.
        if last and last.rmax != node.rmin:
            node.Warn('Gap in release numbers.')

        # If we made it here, this new node must be the 'newest'
        # and does not overlap with anything previously added, so
        # we can add it to the end of the list.
        if GetOption('release_debug'): InfoOut.Log('Done %s' % node)
        self.nodes.append(node)
        return True
コード例 #12
0
    def Generate(self, ast, options):
        self.errors = 0

        rangestr = GetOption('range')
        releasestr = GetOption('release')

        # Check for a range option which over-rides a release option
        if not releasestr and rangestr:
            range_list = rangestr.split(',')
            if len(range_list) != 2:
                self.Error('Failed to generate for %s, incorrect range: "%s"' %
                           (self.name, rangestr))
            else:
                vmin = range_list[0]
                vmax = range_list[1]
                vmin = ast.releases.index(vmin)
                vmax = ast.releases.index(vmax) + 1
                range = ast.releases[vmin:vmax]
                InfoOut.Log('Generate range %s of %s.' % (range, self.name))
                ret = self.GenerateRange(ast, range, options)
                if ret < 0:
                    self.Error('Failed to generate range %s : %s.' %
                               (vmin, vmax))
                else:
                    InfoOut.Log('%s wrote %d files.' % (self.name, ret))
        # Otherwise this should be a single release generation
        else:
            if releasestr:
                InfoOut.Log('Generate release %s of %s.' %
                            (releasestr, self.name))
                ret = self.GenerateRelease(ast, releasestr, options)
                if ret < 0:
                    self.Error('Failed to generate release %s.' % releasestr)
                else:
                    InfoOut.Log('%s wrote %d files.' % (self.name, ret))

            else:
                self.Error('No range or release specified for %s.' %
                           releasestr)
        return self.errors
コード例 #13
0
def TestFiles(filenames, test_releases):
    ast = ParseFiles(filenames)
    iface_releases = pnaclgen.DetermineInterfaces(ast, test_releases)
    new_output = CleanString(
        pnaclgen.GenerateWrapperForMethods(iface_releases, comments=False))
    old_output = GetOldTestOutput(ast)
    if new_output != old_output:
        PrintErrorDiff(old_output, new_output)
        ErrOut.Log('Failed pnacl generator test.')
        return 1
    else:
        InfoOut.Log('Passed pnacl generator test.')
        return 0
コード例 #14
0
ファイル: idl_parser.py プロジェクト: yubb/chromium.src
def TestVersionFiles(filter):
    idldir = os.path.split(sys.argv[0])[0]
    idldir = os.path.join(idldir, 'test_version', '*.idl')
    filenames = glob.glob(idldir)
    testnames = []

    for filename in filenames:
        if filter and filename not in filter: continue
        testnames.append(filename)

    # If we have no files to test, then skip this test
    if not testnames:
        InfoOut.Log('No files to test for version.')
        return 0

    ast = ParseFiles(testnames)
    errs = FindVersionError(ast.releases, ast)

    if errs:
        ErrOut.Log("Failed version test.")
    else:
        InfoOut.Log("Passed version test.")
    return errs
コード例 #15
0
    def InRange(self, rmin, rmax):
        assert (rmin == None) or rmin < rmax

        # An min of None always passes a min bound test
        # An max of None always passes a max bound test
        if rmin is not None and self.rmax is not None:
            if self.rmax <= rmin:
                return False
        if rmax is not None and self.rmin is not None:
            if self.rmin >= rmax:
                return False

        if GetOption('release_debug'):
            InfoOut.Log('%f to %f is in %s' % (rmin, rmax, self))
        return True
コード例 #16
0
    def GenerateRange(self, ast, releases, options):
        """Generate shim code for a range of releases.
    """

        # Remember to set the output filename before running this.
        out_filename = self.output_file
        if out_filename is None:
            ErrOut.Log('Did not set filename for writing out wrapper\n')
            return 1

        InfoOut.Log("Generating %s for %s" %
                    (out_filename, self.wrapper_prefix))

        out = IDLOutFile(out_filename)

        # Get a list of all the interfaces along with metadata.
        iface_releases = self.DetermineInterfaces(ast, releases)

        # Generate the includes.
        self.GenerateIncludes(iface_releases, out)

        out.Write(self.GetGuardStart())

        # Write out static helper functions (mystrcmp).
        self.GenerateHelperFunctions(out)

        # Declare list of WrapperInfo before actual wrapper methods, since
        # they reference each other.
        self.DeclareWrapperInfos(iface_releases, out)

        # Generate wrapper functions for each wrapped method in the interfaces.
        result = self.GenerateWrapperForMethods(iface_releases)
        out.Write(result)

        # Collect all the wrapper functions into interface structs.
        self.GenerateWrapperInterfaces(iface_releases, out)

        # Generate a table of the wrapped interface structs that can be looked up.
        self.GenerateWrapperInfoAndCollection(iface_releases, out)

        # Write out the IDL-invariant functions.
        self.GenerateFixedFunctions(out)

        out.Write(self.GetGuardEnd())
        out.Close()
        return 0
コード例 #17
0
def ReplaceTest():
  errors = 0
  left = BuildNode('Left', ['Left=Left'])
  right = BuildNode('Right', ['Right=Right'])
  top = BuildNode('Top', ['Left=Top', 'Right=Top'], [left, right])

  errors += ExpectText(top, '$Left$', 'Top')
  errors += ExpectText(top, '$Right$', 'Top')

  errors += ExpectText(left, '$Left$', 'Left')
  errors += ExpectText(left, '$Right$', 'Top')

  errors += ExpectText(right, '$Left$', 'Top')
  errors += ExpectText(right, '$Right$', 'Right')

  if not errors: InfoOut.Log('Passed ReplaceTest')
  return errors
コード例 #18
0
def PropertyTest():
  errors = 0
  left = BuildNode('Left', ['Left=Left'])
  right = BuildNode('Right', ['Right=Right'])
  top = BuildNode('Top', ['Left=Top', 'Right=Top'], [left, right])

  errors += ExpectProp(top, 'Left', 'Top')
  errors += ExpectProp(top, 'Right', 'Top')

  errors += ExpectProp(left, 'Left', 'Left')
  errors += ExpectProp(left, 'Right', 'Top')

  errors += ExpectProp(right, 'Left', 'Top')
  errors += ExpectProp(right, 'Right', 'Right')

  if not errors: InfoOut.Log('Passed PropertyTest')
  return errors
コード例 #19
0
def MultiParentTest():
  errors = 0

  parent1 = BuildNode('parent1', ['PARENT1=parent1', 'TOPMOST=$TOP$'])
  parent2 = BuildNode('parent2', ['PARENT1=parent2', 'PARENT2=parent2'])
  child = BuildNode('child', ['CHILD=child'], parents=[parent1, parent2])
  BuildNode('top', ['TOP=top'], children=[parent1])

  errors += ExpectText(child, '$CHILD$', 'child')
  errors += ExpectText(child, '$PARENT1$', 'parent1')
  errors += ExpectText(child, '$PARENT2$', 'parent2')

  # Verify recursive resolution
  errors += ExpectText(child, '$TOPMOST$', 'top')

  if not errors: InfoOut.Log('Passed MultiParentTest')
  return errors
コード例 #20
0
ファイル: idl_node.py プロジェクト: yubb/chromium.src
def StringTest():
  errors = 0
  name_str = 'MyName'
  text_str = 'MyNode(%s)' % name_str
  name_node = IDLAttribute('NAME', name_str)
  node = IDLNode('MyNode', 'no file', 1, 0, [name_node])
  if node.GetName() != name_str:
    ErrOut.Log('GetName returned >%s< not >%s<' % (node.GetName(), name_str))
    errors += 1
  if node.GetProperty('NAME') != name_str:
    ErrOut.Log('Failed to get name property.')
    errors += 1
  if str(node) != text_str:
    ErrOut.Log('str() returned >%s< not >%s<' % (str(node), text_str))
    errors += 1
  if not errors: InfoOut.Log('Passed StringTest')
  return errors
コード例 #21
0
def main():
    errors = 0
    stringlist = ['Test', 'Testing\n', 'Test']
    filename = 'outtest.txt'

    # Test forcibly writing a file
    errors += TestFile(filename, stringlist, force=True, update=True)

    # Test conditionally writing the file skipping
    errors += TestFile(filename, stringlist, force=False, update=False)

    # Test conditionally writing the file updating
    errors += TestFile(filename, stringlist + ['X'], force=False, update=True)

    # Clean up file
    os.remove(filename)
    if not errors: InfoOut.Log('All tests pass.')
    return errors
コード例 #22
0
def TestErrorFiles(filter):
    idldir = os.path.split(sys.argv[0])[0]
    idldir = os.path.join(idldir, 'test_parser', '*.idl')
    filenames = glob.glob(idldir)
    parser = IDLParser()
    total_errs = 0
    for filename in filenames:
        if filter and filename not in filter: continue
        errs = TestFile(parser, filename)
        if errs:
            ErrOut.Log("%s test failed with %d error(s)." % (filename, errs))
            total_errs += errs

    if total_errs:
        ErrOut.Log("Failed parsing test.")
    else:
        InfoOut.Log("Passed parsing test.")
    return total_errs
コード例 #23
0
ファイル: idl_parser.py プロジェクト: Devic1573/Chromium
def Main(args):
    filenames = ParseOptions(args)

    # If testing...
    if GetOption('test'):
        errs = TestErrorFiles(filenames)
        errs = TestNamespaceFiles(filenames)
        if errs:
            ErrOut.Log("Parser failed with %d errors." % errs)
            return -1
        return 0

    # Otherwise, build the AST
    ast = ParseFiles(filenames)
    errs = ast.GetProperty('ERRORS')
    if errs:
        ErrOut.Log('Found %d error(s).' % errs)
    InfoOut.Log("%d files processed." % len(filenames))
    return errs
コード例 #24
0
  def ParseFile(self, filename):
    date = time.ctime(os.path.getmtime(filename))
    data = open(filename).read()
    if self.verbose:
      InfoOut.Log("Parsing %s" % filename)
    try:
      out = self.ParseData(data, filename)

      # If we have a src root specified, remove it from the path
      srcroot = GetOption('srcroot')
      if srcroot and filename.find(srcroot) == 0:
        filename = filename[len(srcroot) + 1:]
      filenode = IDLFile(filename, out, self.parse_errors + self.lex_errors)
      filenode.SetProperty('DATETIME', date)
      return filenode

    except Exception as e:
      ErrOut.LogLine(filename, self.last.lineno, self.last.lexpos,
                     'Internal parsing error - %s.' % str(e))
      raise
コード例 #25
0
def TestFiles(filenames):
    if not filenames:
        idldir = os.path.split(sys.argv[0])[0]
        idldir = os.path.join(idldir, 'test_cgen', '*.idl')
        filenames = glob.glob(idldir)

    filenames = sorted(filenames)
    ast = ParseFiles(filenames)

    total_errs = 0
    for filenode in ast.GetListOf('File'):
        errs = TestFile(filenode)
        if errs:
            ErrOut.Log('%s test failed with %d error(s).' %
                       (filenode.GetName(), errs))
            total_errs += errs

    if total_errs:
        ErrOut.Log('Failed generator test.')
    else:
        InfoOut.Log('Passed generator test.')
    return total_errs
コード例 #26
0
ファイル: idl_option.py プロジェクト: Havok380/chromium-test
def DumpHelp(option=None):
  InfoOut.Log('Usage:')
  for opt in sorted(OptionMap.keys()):
    DumpOption(OptionMap[opt])
  sys.exit(0)
コード例 #27
0
ファイル: idl_namespace.py プロジェクト: AlexxNica/gecko
 def Dump(self):
     for name in self._name_to_releases:
         InfoOut.Log('NAME=%s' % name)
         for cver in self._name_to_releases[name].GetReleases():
             InfoOut.Log('  %s' % cver)
         InfoOut.Log('')
コード例 #28
0
def TestErrors(filename, filenode):
    nodelist = filenode.GetChildren()

    lexer = IDLLexer()
    data = open(filename).read()
    lexer.SetData(filename, data)

    pass_comments = []
    fail_comments = []
    while True:
        tok = lexer.lexobj.token()
        if tok == None: break
        if tok.type == 'COMMENT':
            args = tok.value[3:-3].split()
            if args[0] == 'OK':
                pass_comments.append((tok.lineno, ' '.join(args[1:])))
            else:
                if args[0] == 'FAIL':
                    fail_comments.append((tok.lineno, ' '.join(args[1:])))
    obj_list = []
    for node in nodelist:
        obj_list.extend(FlattenTree(node))

    errors = 0

    #
    # Check for expected successes
    #
    obj_cnt = len(obj_list)
    pass_cnt = len(pass_comments)
    if obj_cnt != pass_cnt:
        InfoOut.Log("Mismatched pass (%d) vs. nodes built (%d)." %
                    (pass_cnt, obj_cnt))
        InfoOut.Log("PASS: %s" % [x[1] for x in pass_comments])
        InfoOut.Log("OBJS: %s" % obj_list)
        errors += 1
        if pass_cnt > obj_cnt: pass_cnt = obj_cnt

    for i in range(pass_cnt):
        line, comment = pass_comments[i]
        if obj_list[i] != comment:
            ErrOut.LogLine(filename, line, None,
                           "OBJ %s : EXPECTED %s\n" % (obj_list[i], comment))
            errors += 1

    #
    # Check for expected errors
    #
    err_list = ErrOut.DrainLog()
    err_cnt = len(err_list)
    fail_cnt = len(fail_comments)
    if err_cnt != fail_cnt:
        InfoOut.Log("Mismatched fail (%d) vs. errors seen (%d)." %
                    (fail_cnt, err_cnt))
        InfoOut.Log("FAIL: %s" % [x[1] for x in fail_comments])
        InfoOut.Log("ERRS: %s" % err_list)
        errors += 1
        if fail_cnt > err_cnt: fail_cnt = err_cnt

    for i in range(fail_cnt):
        line, comment = fail_comments[i]
        err = err_list[i].strip()

        if err_list[i] != comment:
            ErrOut.Log("%s(%d) Error\n\tERROR : %s\n\tEXPECT: %s" %
                       (filename, line, err_list[i], comment))
            errors += 1

    # Clear the error list for the next run
    err_list = []
    return errors
コード例 #29
0
 def Dump(self):
     for name in self.namespace:
         InfoOut.Log('NAME=%s' % name)
         for cver in self.namespace[name].nodes:
             InfoOut.Log('  %s' % cver)
         InfoOut.Log('')
コード例 #30
0
def Main(args):
    global errors
    ParseOptions(args)

    InfoOut.SetConsole(True)

    namespace = IDLNamespace(None)

    FooXX = MockNode('foo', None, None)
    Foo1X = MockNode('foo', 1.0, None)
    Foo2X = MockNode('foo', 2.0, None)
    Foo3X = MockNode('foo', 3.0, None)

    # Verify we succeed with undeprecated adds
    AddOkay(namespace, FooXX)
    AddOkay(namespace, Foo1X)
    AddOkay(namespace, Foo3X)
    # Verify we fail to add a node between undeprecated releases
    AddError(namespace, Foo2X,
             'Overlap in releases: 3.0 vs 2.0 when adding foo (2.0 : None)')

    BarXX = MockNode('bar', None, None)
    Bar12 = MockNode('bar', 1.0, 2.0)
    Bar23 = MockNode('bar', 2.0, 3.0)
    Bar34 = MockNode('bar', 3.0, 4.0)

    # Verify we succeed with fully qualified releases
    namespace = IDLNamespace(namespace)
    AddOkay(namespace, BarXX)
    AddOkay(namespace, Bar12)
    # Verify we warn when detecting a gap
    AddWarn(namespace, Bar34, 'Gap in release numbers.')
    # Verify we fail when inserting into this gap
    # (NOTE: while this could be legal, it is sloppy so we disallow it)
    AddError(namespace, Bar23, 'Declarations out of order.')

    # Verify local namespace
    VerifyFindOne(namespace, 'bar', 0.0, BarXX)
    VerifyFindAll(namespace, 'bar', 0.5, 1.5, [BarXX, Bar12])

    # Verify the correct release of the object is found recursively
    VerifyFindOne(namespace, 'foo', 0.0, FooXX)
    VerifyFindOne(namespace, 'foo', 0.5, FooXX)
    VerifyFindOne(namespace, 'foo', 1.0, Foo1X)
    VerifyFindOne(namespace, 'foo', 1.5, Foo1X)
    VerifyFindOne(namespace, 'foo', 3.0, Foo3X)
    VerifyFindOne(namespace, 'foo', 100.0, Foo3X)

    # Verify the correct range of objects is found
    VerifyFindAll(namespace, 'foo', 0.0, 1.0, [FooXX])
    VerifyFindAll(namespace, 'foo', 0.5, 1.0, [FooXX])
    VerifyFindAll(namespace, 'foo', 1.0, 1.1, [Foo1X])
    VerifyFindAll(namespace, 'foo', 0.5, 1.5, [FooXX, Foo1X])
    VerifyFindAll(namespace, 'foo', 0.0, 3.0, [FooXX, Foo1X])
    VerifyFindAll(namespace, 'foo', 3.0, 100.0, [Foo3X])

    FooBar = MockNode('foobar', 1.0, 2.0)
    namespace = IDLNamespace(namespace)
    AddOkay(namespace, FooBar)

    if errors:
        print 'Test failed with %d errors.' % errors
    else:
        print 'Passed.'
    return errors