def run(self):

        # try reading various ranges (these are (start, end) absolute ranges, not offset/length)
        ranges = [
            (0, 16384),
            (1, 200),
            (0, 4096),
            (0, 8192),
            (0, 1000),
            (0, 6000),
            (100, 4000),
            (5000, 10000),
            (4096, 10000),
            (5000, 8192),
            (4096, 16834),
            (5000, 16384),
            (4096, 16000),
            (5000, 16000)
        ]

        self.exitcode = 0

        for (start, end) in ranges:

            if self.errors:
                break

            # only clear reader's cache
            testlib.clear_cache( self.config_dir, volume_id=self.volume_id, gateway_id=self.read_gateway_id )

            for i in xrange(0, 2):

                if self.errors:
                    break

                exitcode, out = testlib.run( READ_PATH, '-d2', '-f', '-c', os.path.join(self.config_dir, 'syndicate.conf'),
                                            '-u', testconf.SYNDICATE_ADMIN, '-v', self.volume_name, '-g', self.read_gateway_name,
                                            self.output_path, start, end - start, valgrind=True )

                out_name = "uncached"
                if i > 0:
                    out_name = "cached"

                testlib.save_output( self.output_dir, 'syndicate-read-thread-%s-%s-%s-%s' % (self.get_ident(), start, end, out_name), out )
                if exitcode != 0:
                    self.exitcode = exitcode
                    self.errormsg = "syndicate-read exit code %s on %s-%s-%s" % (exitcode, start, end, out_name)
                    break

                # correctness 
                if expected_data[start:end] not in out:
                    self.exitcode = -1
                    self.errormsg = "Thread %s missing data for %s-%s-%s" % (self.get_ident(), start, end, out_name)
                    break

            
            if self.exitcode != 0:
                break

        return
        (0, 1000),  # 1 block, tail unaligned
        (0, 6000),  # 2 blocks, tail unaligned
        (100, 4000), # 1 block, head unaligned
        (5000, 10000), # 2 blocks, head and tail unaligned
        (4096, 10000), # 2 blocks, tail unaligned
        (5000, 8192),  # 2 blocks, head unalighed
        (4096, 16834), # 3 blocks, aligned
        (5000, 16384), # 3 blocks, head unaligned
        (4096, 16000), # 3 blocks, tail unaligned
        (5000, 16000), # 3 blocks, head and tail unaligned
    ]

    for (start, end) in ranges:

        # only clear reader's cache
        testlib.clear_cache( config_dir, volume_id=volume_id, gateway_id=read_gateway_id )

        # do each read twice--once uncached, and one cached 
        for i in xrange(0, 2):
            exitcode, out = testlib.run( READ_PATH, '-d2', '-f', '-c', os.path.join(config_dir, 'syndicate.conf'),
                                        '-u', testconf.SYNDICATE_ADMIN, '-v', volume_name, '-g', read_gateway_name,
                                        output_path, start, end - start, valgrind=True )

            out_name = "uncached"
            if i > 0:
                out_name = "cached"

            testlib.save_output( output_dir, 'syndicate-read-%s-%s-%s' % (start, end, out_name), out )
            if exitcode != 0:
                stop_and_save( output_dir, ag_proc, ag_out_path, "syndicate-ag")
                raise Exception("%s exited %s" % (READ_PATH, exitcode))
        (0, 8192),  # 2 blocks, aligned
        (0, 1000),  # 1 block, tail unaligned
        (0, 6000),  # 2 blocks, tail unaligned
        (100, 4000), # 1 block, head unaligned
        (5000, 10000), # 2 blocks, head and tail unaligned
        (4096, 10000), # 2 blocks, tail unaligned
        (5000, 8192),  # 2 blocks, head unalighed
        (4096, 16834), # 3 blocks, aligned
        (5000, 16384), # 3 blocks, head unaligned
        (4096, 16000), # 3 blocks, tail unaligned
        (5000, 16000), # 3 blocks, head and tail unaligned
    ]

    for (start, end) in ranges:

        testlib.clear_cache( config_dir )
        exitcode, out = testlib.run( READ_PATH, '-d2', '-f', '-c', os.path.join(config_dir, 'syndicate.conf'),
                                    '-u', testconf.SYNDICATE_ADMIN, '-v', volume_name, '-g', read_gateway_name,
                                    output_path, start, end - start, valgrind=True )
        testlib.save_output( output_dir, 'syndicate-read-%s-%s' % (start, end), out )
        if exitcode != 0:
            stop_and_save( output_dir, rg_proc, rg_out_path, "syndicate-rg")
            raise Exception("%s exited %s" % (READ_PATH, exitcode))

        # correctness 
        if expected_data[start:end] not in out:
            stop_and_save( output_dir, rg_proc, rg_out_path, "syndicate-rg")
            raise Exception("Missing data for %s-%s" % (start, end))

    rg_exitcode, rg_out = testlib.stop_gateway( rg_proc, rg_out_path )
                raise Exception("%s exited %s" % (RENAME_PATH, exitcode) )


    for i in xrange(0, NUM_FILES):
        output_path_samedir = output_paths[i] + "-renamed"
        output_path_newdir = "/newdir/" + output_paths[i] + "-renamed"
        path = None
        
        # select the correct path to read, based on the above generation
        if i % 2 == 0:
            path = output_path_samedir
        else:
            path = output_path_newdir

        # clear the cache first, to make sure we fetch the new manifest from the RG
        testlib.clear_cache( config_dir, gateway_id=cat_gateway_id, volume_id=volume_id )
        testlib.clear_cache( config_dir, gateway_id=rg_gateway_id, volume_id=volume_id )

        exitcode, out = testlib.run( CAT_PATH, '-d2', '-f', '-c', os.path.join(config_dir, 'syndicate.conf'), '-u', testconf.SYNDICATE_ADMIN, '-v', volume_name, '-g', cat_gateway_name, path, valgrind=True )
        testlib.save_output( output_dir, 'syndicate-cat-%s' % i, out )
        
        if exitcode != 0:
            stop_and_save( output_dir, rg_proc, rg_out_path, "syndicate-rg")
            raise Exception("%s exited %s" % (CAT_PATH, exitcode)) 

        # check for correctnes 
        if expected_data not in out:
            stop_and_save( output_dir, rg_proc, rg_out_path, "syndicate-rg")
            raise Exception("data not found in output")

    rg_exitcode, rg_out = stop_and_save( output_dir, rg_proc, rg_out_path, "syndicate-rg")
                raise Exception("%s exited %s" % (RENAME_PATH, exitcode))

    for i in xrange(0, NUM_FILES):
        output_path_samedir = output_paths[i] + "-renamed"
        output_path_newdir = "/newdir/" + output_paths[i] + "-renamed"
        path = None

        # select the correct path to read, based on the above generation
        if i % 2 == 0:
            path = output_path_samedir
        else:
            path = output_path_newdir

        # clear the cache first, to make sure we fetch the new manifest from the RG
        testlib.clear_cache(config_dir,
                            gateway_id=cat_gateway_id,
                            volume_id=volume_id)
        testlib.clear_cache(config_dir,
                            gateway_id=rg_gateway_id,
                            volume_id=volume_id)

        exitcode, out = testlib.run(CAT_PATH,
                                    '-d2',
                                    '-f',
                                    '-c',
                                    os.path.join(config_dir, 'syndicate.conf'),
                                    '-u',
                                    testconf.SYNDICATE_ADMIN,
                                    '-v',
                                    volume_name,
                                    '-g',
    def run(self):

        # try reading various ranges (these are (start, end) absolute ranges, not offset/length)
        ranges = [(0, 16384), (1, 200), (0, 4096), (0, 8192), (0, 1000),
                  (0, 6000), (100, 4000), (5000, 10000), (4096, 10000),
                  (5000, 8192), (4096, 16834), (5000, 16384), (4096, 16000),
                  (5000, 16000)]

        self.exitcode = 0

        for (start, end) in ranges:

            if self.errors:
                break

            # only clear reader's cache
            testlib.clear_cache(self.config_dir,
                                volume_id=self.volume_id,
                                gateway_id=self.read_gateway_id)

            for i in xrange(0, 2):

                if self.errors:
                    break

                exitcode, out = testlib.run(READ_PATH,
                                            '-d2',
                                            '-f',
                                            '-c',
                                            os.path.join(
                                                self.config_dir,
                                                'syndicate.conf'),
                                            '-u',
                                            testconf.SYNDICATE_ADMIN,
                                            '-v',
                                            self.volume_name,
                                            '-g',
                                            self.read_gateway_name,
                                            self.output_path,
                                            start,
                                            end - start,
                                            valgrind=True)

                out_name = "uncached"
                if i > 0:
                    out_name = "cached"

                testlib.save_output(
                    self.output_dir, 'syndicate-read-thread-%s-%s-%s-%s' %
                    (self.get_ident(), start, end, out_name), out)
                if exitcode != 0:
                    self.exitcode = exitcode
                    self.errormsg = "syndicate-read exit code %s on %s-%s-%s" % (
                        exitcode, start, end, out_name)
                    break

                # correctness
                if expected_data[start:end] not in out:
                    self.exitcode = -1
                    self.errormsg = "Thread %s missing data for %s-%s-%s" % (
                        self.get_ident(), start, end, out_name)
                    break

            if self.exitcode != 0:
                break

        return