Ejemplo n.º 1
0
 def testAutoUpdate(self):
     x = event_multiplexer.EventMultiplexer({
         'run1': 'path1',
         'run2': 'path2'
     })
     x.AutoUpdate(5)
     self.assertTrue(x._GetAccumulator('run1').autoupdate_called)
     self.assertEqual(x._GetAccumulator('run1').autoupdate_interval, 5)
     self.assertTrue(x._GetAccumulator('run2').autoupdate_called)
     self.assertEqual(x._GetAccumulator('run2').autoupdate_interval, 5)
Ejemplo n.º 2
0
def main(unused_argv=None):
    if FLAGS.debug:
        logging.set_verbosity(logging.DEBUG)
        logging.info('TensorBoard is in debug mode.')

    if not FLAGS.logdir:
        logging.error(
            'A logdir must be specified. Run `tensorboard --help` for '
            'details and examples.')
        return -1

    logging.info('Starting TensorBoard in directory %s', os.getcwd())

    path_to_run = ParseEventFilesFlag(FLAGS.logdir)
    logging.info('TensorBoard path_to_run is: %s', path_to_run)
    multiplexer = event_multiplexer.EventMultiplexer(
        size_guidance=TENSORBOARD_SIZE_GUIDANCE)

    def _Load():
        start = time.time()
        for (path, name) in six.iteritems(path_to_run):
            multiplexer.AddRunsFromDirectory(path, name)
        multiplexer.Reload()
        duration = time.time() - start
        logging.info('Multiplexer done loading. Load took %0.1f secs',
                     duration)
        t = threading.Timer(LOAD_INTERVAL, _Load)
        t.daemon = True
        t.start()

    t = threading.Timer(0, _Load)
    t.daemon = True
    t.start()

    factory = functools.partial(tensorboard_handler.TensorboardHandler,
                                multiplexer)
    try:
        server = ThreadedHTTPServer((FLAGS.host, FLAGS.port), factory)
    except socket.error:
        logging.error(
            'Tried to connect to port %d, but that address is in use.',
            FLAGS.port)
        return -2
    try:
        tag = resource_loader.load_resource('tensorboard/TAG').strip()
        logging.info('TensorBoard is tag: %s', tag)
    except IOError:
        logging.warning('Unable to read TensorBoard tag')
        tag = ''

    status_bar.SetupStatusBarInsideGoogle('TensorBoard %s' % tag, FLAGS.port)
    print('Starting TensorBoard %s on port %d' % (tag, FLAGS.port))
    print('(You can navigate to http://%s:%d)' % (FLAGS.host, FLAGS.port))
    server.serve_forever()
Ejemplo n.º 3
0
def main(unused_argv=None):
    if FLAGS.debug:
        logging.set_verbosity(logging.DEBUG)
        logging.info('TensorBoard is in debug mode.')

    if FLAGS.inspect:
        logging.info(
            'Not bringing up TensorBoard, but inspecting event files.')
        efi.inspect(logdir=FLAGS.logdir,
                    event_file=FLAGS.event_file,
                    tag=FLAGS.tag)
        return 0

    if not FLAGS.logdir:
        msg = ('A logdir must be specified. Run `tensorboard --help` for '
               'details and examples.')
        logging.error(msg)
        print(msg)
        return -1

    logging.info('Starting TensorBoard in directory %s', os.getcwd())
    path_to_run = server.ParseEventFilesSpec(FLAGS.logdir)
    logging.info('TensorBoard path_to_run is: %s', path_to_run)

    multiplexer = event_multiplexer.EventMultiplexer(
        size_guidance=server.TENSORBOARD_SIZE_GUIDANCE,
        purge_orphaned_data=FLAGS.purge_orphaned_data)
    server.StartMultiplexerReloadingThread(multiplexer, path_to_run,
                                           FLAGS.reload_interval)
    try:
        tb_server = server.BuildServer(multiplexer, FLAGS.host, FLAGS.port)
    except socket.error:
        if FLAGS.port == 0:
            msg = 'Unable to find any open ports.'
            logging.error(msg)
            print(msg)
            return -2
        else:
            msg = 'Tried to connect to port %d, but address is in use.' % FLAGS.port
            logging.error(msg)
            print(msg)
            return -3

    try:
        tag = resource_loader.load_resource('tensorboard/TAG').strip()
        logging.info('TensorBoard is tag: %s', tag)
    except IOError:
        logging.warning('Unable to read TensorBoard tag')
        tag = ''

    status_bar.SetupStatusBarInsideGoogle('TensorBoard %s' % tag, FLAGS.port)
    print('Starting TensorBoard %s on port %d' % (tag, FLAGS.port))
    print('(You can navigate to http://%s:%d)' % (FLAGS.host, FLAGS.port))
    tb_server.serve_forever()
Ejemplo n.º 4
0
 def setUp(self):
   self._GenerateTestData()
   self._multiplexer = event_multiplexer.EventMultiplexer(
       size_guidance=server.TENSORBOARD_SIZE_GUIDANCE)
   server.ReloadMultiplexer(self._multiplexer, {self.get_temp_dir(): None})
   # 0 to pick an unused port.
   self._server = server.BuildServer(self._multiplexer, 'localhost', 0)
   self._server_thread = threading.Thread(target=self._server.serve_forever)
   self._server_thread.daemon = True
   self._server_thread.start()
   self._connection = http_client.HTTPConnection(
       'localhost', self._server.server_address[1])
Ejemplo n.º 5
0
 def _SetupWSGIApp(self):
     multiplexer = event_multiplexer.EventMultiplexer(
         size_guidance=application.DEFAULT_SIZE_GUIDANCE,
         purge_orphaned_data=True)
     projector = projector_plugin.ProjectorPlugin()
     projector.get_plugin_apps({}, self.log_dir)
     plugins = {'projector': projector}
     wsgi_app = application.TensorBoardWSGIApp(self.log_dir,
                                               plugins,
                                               multiplexer,
                                               reload_interval=0)
     self.server = werkzeug_test.Client(wsgi_app, wrappers.BaseResponse)
 def testPluginRunToTagToContent(self):
   """Tests the method that produces the run to tag to content mapping."""
   x = event_multiplexer.EventMultiplexer({'run1': 'path1', 'run2': 'path2'})
   self.assertDictEqual({
       'run1': {
           'path1_foo': 'foo_content',
           'path1_bar': 'bar_content',
       },
       'run2': {
           'path2_foo': 'foo_content',
           'path2_bar': 'bar_content',
       }
   }, x.PluginRunToTagToContent('baz_plugin'))
Ejemplo n.º 7
0
def standard_tensorboard_wsgi(logdir, purge_orphaned_data, reload_interval):
    """Construct a TensorBoardWSGIApp with standard plugins and multiplexer."""
    multiplexer = event_multiplexer.EventMultiplexer(
        size_guidance=DEFAULT_SIZE_GUIDANCE,
        purge_orphaned_data=purge_orphaned_data)

    plugins = {
        debugger_plugin.PLUGIN_PREFIX_ROUTE:
        debugger_plugin.DebuggerPlugin(multiplexer),
        projector_plugin.PLUGIN_PREFIX_ROUTE:
        projector_plugin.ProjectorPlugin(),
    }

    return TensorBoardWSGIApp(logdir, plugins, multiplexer, reload_interval)
Ejemplo n.º 8
0
 def setUp(self):
   self.temp_dir = self._GenerateTestData()
   multiplexer = event_multiplexer.EventMultiplexer(
       size_guidance=application.DEFAULT_SIZE_GUIDANCE,
       purge_orphaned_data=True)
   plugins = {'projector': projector_plugin.ProjectorPlugin()}
   app = application.TensorBoardWSGIApp(
       self.temp_dir, plugins, multiplexer, reload_interval=0)
   self._server = serving.BaseWSGIServer('localhost', 0, app)
   # 0 to pick an unused port.
   self._server_thread = threading.Thread(target=self._server.serve_forever)
   self._server_thread.daemon = True
   self._server_thread.start()
   self._connection = http_client.HTTPConnection(
       'localhost', self._server.server_address[1])
  def testAddRunsFromDirectory(self):
    """Tests AddRunsFromDirectory function.

    Tests the following scenarios:
    - When the directory does not exist.
    - When the directory is empty.
    - When the directory has empty subdirectory.
    - Contains proper EventAccumulators after adding events.
    """
    x = event_multiplexer.EventMultiplexer()
    tmpdir = self.get_temp_dir()
    join = os.path.join
    fakedir = join(tmpdir, 'fake_accumulator_directory')
    realdir = join(tmpdir, 'real_accumulator_directory')
    self.assertEqual(x.Runs(), {})
    x.AddRunsFromDirectory(fakedir)
    self.assertEqual(x.Runs(), {}, 'loading fakedir had no effect')

    _CreateCleanDirectory(realdir)
    x.AddRunsFromDirectory(realdir)
    self.assertEqual(x.Runs(), {}, 'loading empty directory had no effect')

    path1 = join(realdir, 'path1')
    gfile.MkDir(path1)
    x.AddRunsFromDirectory(realdir)
    self.assertEqual(x.Runs(), {}, 'creating empty subdirectory had no effect')

    _AddEvents(path1)
    x.AddRunsFromDirectory(realdir)
    self.assertItemsEqual(x.Runs(), ['path1'], 'loaded run: path1')
    loader1 = x.GetAccumulator('path1')
    self.assertEqual(loader1._path, path1, 'has the correct path')

    path2 = join(realdir, 'path2')
    _AddEvents(path2)
    x.AddRunsFromDirectory(realdir)
    self.assertItemsEqual(x.Runs(), ['path1', 'path2'])
    self.assertEqual(
        x.GetAccumulator('path1'), loader1, 'loader1 not regenerated')

    path2_2 = join(path2, 'path2')
    _AddEvents(path2_2)
    x.AddRunsFromDirectory(realdir)
    self.assertItemsEqual(x.Runs(), ['path1', 'path2', 'path2/path2'])
    self.assertEqual(
        x.GetAccumulator('path2/path2')._path, path2_2, 'loader2 path correct')
Ejemplo n.º 10
0
    def testAddRunsFromDirectoryWithRunNames(self):
        x = event_multiplexer.EventMultiplexer()
        tmpdir = self.get_temp_dir()
        join = os.path.join
        realdir = join(tmpdir, 'event_containing_directory')

        _CreateCleanDirectory(realdir)

        self.assertEqual(x.Runs(), {})

        _AddEvents(realdir)
        x.AddRunsFromDirectory(realdir, 'foo')
        self.assertItemsEqual(x.Runs(), ['foo/.'])

        subdir = join(realdir, 'subdir')
        _AddEvents(subdir)
        x.AddRunsFromDirectory(realdir, 'foo')
        self.assertItemsEqual(x.Runs(), ['foo/.', 'foo/subdir'])
Ejemplo n.º 11
0
  def testAddRun(self):
    x = event_multiplexer.EventMultiplexer()
    x.AddRun('run1_path', 'run1')
    run1 = x._GetAccumulator('run1')
    self.assertEqual(x.Runs().keys(), ['run1'])
    self.assertEqual(run1._path, 'run1_path')

    x.AddRun('run1_path', 'run1')
    self.assertEqual(run1, x._GetAccumulator('run1'), 'loader not recreated')

    x.AddRun('run2_path', 'run1')
    new_run1 = x._GetAccumulator('run1')
    self.assertEqual(new_run1._path, 'run2_path')
    self.assertNotEqual(run1, new_run1)

    x.AddRun('runName3')
    self.assertItemsEqual(x.Runs().keys(), ['run1', 'runName3'])
    self.assertEqual(x._GetAccumulator('runName3')._path, 'runName3')
  def testAddRunsFromDirectoryWalksTree(self):
    x = event_multiplexer.EventMultiplexer()
    tmpdir = self.get_temp_dir()
    join = os.path.join
    realdir = join(tmpdir, 'event_containing_directory')

    _CreateCleanDirectory(realdir)
    _AddEvents(realdir)
    sub = join(realdir, 'subdirectory')
    sub1 = join(sub, '1')
    sub2 = join(sub, '2')
    sub1_1 = join(sub1, '1')
    _AddEvents(sub1)
    _AddEvents(sub2)
    _AddEvents(sub1_1)
    x.AddRunsFromDirectory(realdir)

    self.assertItemsEqual(x.Runs(), ['.', 'subdirectory/1', 'subdirectory/2',
                                     'subdirectory/1/1'])
Ejemplo n.º 13
0
    def initialize(self):
        """Setup the TensorBoard application."""
        path_to_run = parse_event_files_spec(self._logdir)
        multiplexer = event_multiplexer.EventMultiplexer(
            size_guidance=self._size, purge_orphaned_data=self._purge)
        if self._reload:
            start_reloading_multiplexer(multiplexer, path_to_run, self._reload)
        else:
            reload_multiplexer(multiplexer, path_to_run)
        self._multiplexer = multiplexer

        self.data_applications = {
            DATA_PREFIX + LOGDIR_ROUTE: self._serve_logdir,
            DATA_PREFIX + SCALARS_ROUTE: self._serve_scalars,
            DATA_PREFIX + GRAPH_ROUTE: self._serve_graph,
            DATA_PREFIX + RUN_METADATA_ROUTE: self._serve_run_metadata,
            DATA_PREFIX + HISTOGRAMS_ROUTE: self._serve_histograms,
            DATA_PREFIX + COMPRESSED_HISTOGRAMS_ROUTE:
            self._serve_compressed_histograms,
            DATA_PREFIX + IMAGES_ROUTE: self._serve_images,
            DATA_PREFIX + INDIVIDUAL_IMAGE_ROUTE: self._serve_image,
            DATA_PREFIX + AUDIO_ROUTE: self._serve_audio,
            DATA_PREFIX + INDIVIDUAL_AUDIO_ROUTE: self._serve_individual_audio,
            DATA_PREFIX + RUNS_ROUTE: self._serve_runs,
            '/app.js': self._serve_js
        }

        # Serve the routes from the registered plugins using their name as the route
        # prefix. For example if plugin z has two routes /a and /b, they will be
        # served as /data/plugin/z/a and /data/plugin/z/b.
        for name in self._registered_plugins:
            try:
                plugin = self._registered_plugins[name]
                plugin_apps = plugin.get_plugin_apps(
                    self._multiplexer.RunPaths(), self._logdir)
            except Exception as e:  # pylint: disable=broad-except
                logging.warning('Plugin %s failed. Exception: %s', name,
                                str(e))
                continue
            for route, app in plugin_apps.items():
                path = DATA_PREFIX + PLUGIN_PREFIX + '/' + name + route
                self.data_applications[path] = app
Ejemplo n.º 14
0
def main(unused_argv=None):
    target = FLAGS.target
    logdir = FLAGS.logdir
    if not target or not logdir:
        PrintAndLog('Both --target and --logdir are required.',
                    tf.logging.ERROR)
        return -1
    if os.path.exists(target):
        if FLAGS.overwrite:
            if os.path.isdir(target):
                shutil.rmtree(target)
            else:
                os.remove(target)
        else:
            PrintAndLog(
                'Refusing to overwrite target %s without --overwrite' % target,
                tf.logging.ERROR)
            return -2
    path_to_run = server.ParseEventFilesSpec(FLAGS.logdir)

    PrintAndLog('About to load Multiplexer. This may take some time.')
    multiplexer = event_multiplexer.EventMultiplexer(
        size_guidance=server.TENSORBOARD_SIZE_GUIDANCE,
        purge_orphaned_data=FLAGS.purge_orphaned_data)
    server.ReloadMultiplexer(multiplexer, path_to_run)

    PrintAndLog('Multiplexer load finished. Starting TensorBoard server.')
    s = server.BuildServer(multiplexer, 'localhost', 0)
    server_thread = threading.Thread(target=s.serve_forever)
    server_thread.daemon = True
    server_thread.start()
    connection = http_client.HTTPConnection('localhost', s.server_address[1])

    PrintAndLog('Server setup! Downloading data from the server.')
    x = TensorBoardStaticSerializer(connection, target)
    x.Run()

    PrintAndLog('Done downloading data.')
    connection.close()
    s.shutdown()
    s.server_close()
Ejemplo n.º 15
0
  def testAddRunsFromDirectoryWithRunNames(self):
    x = event_multiplexer.EventMultiplexer()
    tmpdir = self.get_temp_dir()
    join = os.path.join
    realdir = join(tmpdir, 'event_containing_directory')

    if gfile.IsDirectory(realdir):
      gfile.DeleteRecursively(realdir)
    gfile.MkDir(realdir)

    self.assertEqual(x.Runs(), {})

    with gfile.GFile(join(realdir, 'hypothetical.tfevents.out'), 'w'):
      pass
    x.AddRunsFromDirectory(realdir, 'foo')
    self.assertItemsEqual(x.Runs(), ['foo'])

    subdir = join(realdir, 'subdir')
    gfile.MkDir(subdir)
    x.AddRunsFromDirectory(realdir, 'foo')
    self.assertItemsEqual(x.Runs(), ['foo', 'foo/subdir'])
Ejemplo n.º 16
0
    def testDeletingDirectoryRemovesRun(self):
        x = event_multiplexer.EventMultiplexer()
        tmpdir = self.get_temp_dir()
        join = os.path.join
        run1_dir = join(tmpdir, 'run1')
        run2_dir = join(tmpdir, 'run2')
        run3_dir = join(tmpdir, 'run3')

        for dirname in [run1_dir, run2_dir, run3_dir]:
            _AddEvents(dirname)

        x.AddRun(run1_dir, 'run1')
        x.AddRun(run2_dir, 'run2')
        x.AddRun(run3_dir, 'run3')

        x.Reload()

        # Delete the directory, then reload.
        shutil.rmtree(run2_dir)
        x.Reload()
        self.assertNotIn('run2', x.Runs().keys())
Ejemplo n.º 17
0
    def testDeletingDirectoryDoesntThrowException(self):
        x = event_multiplexer.EventMultiplexer()
        tmpdir = self.get_temp_dir()
        join = os.path.join
        run1_dir = join(tmpdir, 'run1')
        run2_dir = join(tmpdir, 'run2')
        run3_dir = join(tmpdir, 'run3')

        for dirname in [run1_dir, run2_dir, run3_dir]:
            _AddEvents(dirname)

        x.AddRun(run1_dir, 'run1')
        x.AddRun(run2_dir, 'run2')
        x.AddRun(run3_dir, 'run3')

        x.Reload()

        # Delete the directory, then reload.
        shutil.rmtree(run2_dir)

        x.Reload()
Ejemplo n.º 18
0
    def testAddRunsFromDirectory(self):
        x = event_multiplexer.EventMultiplexer()
        tmpdir = self.get_temp_dir()
        join = os.path.join
        fakedir = join(tmpdir, 'fake_accumulator_directory')
        realdir = join(tmpdir, 'real_accumulator_directory')
        self.assertEqual(x.Runs(), {})
        x.AddRunsFromDirectory(fakedir)
        self.assertEqual(x.Runs(), {}, 'loading fakedir had no effect')

        if gfile.IsDirectory(realdir):
            gfile.DeleteRecursively(realdir)
        gfile.MkDir(realdir)
        x.AddRunsFromDirectory(realdir)
        self.assertEqual(x.Runs(), {}, 'loading empty directory had no effect')

        path1 = join(realdir, 'path1')
        gfile.MkDir(path1)
        x.AddRunsFromDirectory(realdir)
        self.assertEqual(sorted(x.Runs().keys()), ['path1'],
                         'loaded run: path1')
        loader1 = x._GetAccumulator('path1')
        self.assertEqual(loader1._path, path1, 'has the correct path')

        path2 = join(realdir, 'path2')
        gfile.MkDir(path2)
        x.AddRunsFromDirectory(realdir)
        self.assertItemsEqual(sorted(x.Runs().keys()), ['path1', 'path2'])
        self.assertEqual(x._GetAccumulator('path1'), loader1,
                         'loader1 not regenerated')
        loader2 = x._GetAccumulator('path2')

        path2_2 = join(path2, 'path2')
        gfile.MkDir(path2_2)
        x.AddRunsFromDirectory(path2)
        self.assertItemsEqual(sorted(x.Runs().keys()), ['path1', 'path2'])
        self.assertNotEqual(loader2, x._GetAccumulator('path2'),
                            'loader2 regenerated')
        self.assertEqual(
            x._GetAccumulator('path2')._path, path2_2, 'loader2 path correct')
Ejemplo n.º 19
0
    def testAddRunsFromDirectory(self):
        x = event_multiplexer.EventMultiplexer()
        tmpdir = self.get_temp_dir()
        join = os.path.join
        fakedir = join(tmpdir, 'fake_accumulator_directory')
        realdir = join(tmpdir, 'real_accumulator_directory')
        self.assertEqual(x.Runs(), {})
        x.AddRunsFromDirectory(fakedir)
        self.assertEqual(x.Runs(), {}, 'loading fakedir had no effect')

        _CreateCleanDirectory(realdir)
        x.AddRunsFromDirectory(realdir)
        self.assertEqual(x.Runs(), {}, 'loading empty directory had no effect')

        path1 = join(realdir, 'path1')
        gfile.MkDir(path1)
        x.AddRunsFromDirectory(realdir)
        self.assertEqual(x.Runs(), {},
                         'creating empty subdirectory had no effect')

        _AddEvents(path1)
        x.AddRunsFromDirectory(realdir)
        self.assertItemsEqual(x.Runs(), ['path1'], 'loaded run: path1')
        loader1 = x._GetAccumulator('path1')
        self.assertEqual(loader1._path, path1, 'has the correct path')

        path2 = join(realdir, 'path2')
        _AddEvents(path2)
        x.AddRunsFromDirectory(realdir)
        self.assertItemsEqual(x.Runs(), ['path1', 'path2'])
        self.assertEqual(x._GetAccumulator('path1'), loader1,
                         'loader1 not regenerated')

        path2_2 = join(path2, 'path2')
        _AddEvents(path2_2)
        x.AddRunsFromDirectory(realdir)
        self.assertItemsEqual(x.Runs(), ['path1', 'path2', 'path2/path2'])
        self.assertEqual(
            x._GetAccumulator('path2/path2')._path, path2_2,
            'loader2 path correct')
Ejemplo n.º 20
0
 def testEmptyLoader(self):
     x = event_multiplexer.EventMultiplexer()
     self.assertEqual(x.Runs(), {})
Ejemplo n.º 21
0
 def testHealthPills(self):
   x = event_multiplexer.EventMultiplexer({'run1': 'path1', 'run2': 'path2'})
   self.assertEqual(['path1/hp1', 'path1/hp2'], x.HealthPills('run1', 'Add'))
Ejemplo n.º 22
0
# log_parent_dirs = [elem for elem in log_parent_dirs
#                    if '4_20' in elem]

# log_parent_dirs = ['logdir_exper_4_20_GRU/',
#                    'logdir_exper_4_20_GRU_bidir/',
#                    'logdir_exper_4_20_LSTM/',
#                    'logdir_exper_4_20_LSTM_bidir/']

# print('cutting short the number of log dirs (else crash)')
# log_parent_dirs = log_parent_dirs[:2]
# log_parent_dirs = log_parent_dirs[:3]


# In[10]:

event_accum = event_multiplexer.EventMultiplexer()
for log_dir in log_parent_dirs:
    event_accum = event_accum.AddRunsFromDirectory(log_dir)

# load
event_accum.Reload()  # this might take a bit, depending on number of runs

# event_accum = {index: event_multiplexer\
#                .EventMultiplexer()\
#                .AddRunsFromDirectory(log_dir)\
#                .Reload()
#                for index, log_dir in enumerate(log_parent_dirs)}


# In[11]:
 def testEmptyLoader(self):
   """Tests empty EventMultiplexer creation."""
   x = event_multiplexer.EventMultiplexer()
   self.assertEqual(x.Runs(), {})
 def testRunNamesRespected(self):
   """Tests two EventAccumulators inserted/accessed in EventMultiplexer."""
   x = event_multiplexer.EventMultiplexer({'run1': 'path1', 'run2': 'path2'})
   self.assertItemsEqual(sorted(x.Runs().keys()), ['run1', 'run2'])
   self.assertEqual(x.GetAccumulator('run1')._path, 'path1')
   self.assertEqual(x.GetAccumulator('run2')._path, 'path2')
 def testExceptions(self):
   """KeyError should be raised when accessing non-existing keys."""
   x = event_multiplexer.EventMultiplexer({'run1': 'path1', 'run2': 'path2'})
   with self.assertRaises(KeyError):
     x.Scalars('sv1', 'xxx')
Ejemplo n.º 26
0
 def testExceptions(self):
   x = event_multiplexer.EventMultiplexer({'run1': 'path1', 'run2': 'path2'})
   with self.assertRaises(KeyError):
     x.Scalars('sv1', 'xxx')
Ejemplo n.º 27
0
 def testRunNamesRespected(self):
   x = event_multiplexer.EventMultiplexer({'run1': 'path1', 'run2': 'path2'})
   self.assertItemsEqual(x.Runs().keys(), ['run1', 'run2'])
   self.assertEqual(x._GetAccumulator('run1')._path, 'path1')
   self.assertEqual(x._GetAccumulator('run2')._path, 'path2')