cbuildbot_run: Support changing attribute values in parallel stages.

This change creates a generic mechanism for setting values in stages
that are run in parallel and having those values available to both
co-parallel stages and subsequent stages.  The values are stored as
"parallel" run attributes on the BuilderRun object.  The new attributes
can be accessed with new {Set|Has|Get}Parallel methods on RunAttributes.

New unittests added to test this functionality extensively.

BUG=chromium:341996
TEST=`buildbot/run_tests`
TEST=Tested with subsequent CL that manages breakpad symbols and debug
tarball notifications using this mechanism.

Change-Id: I29e0d8ff0de42ae6ec9ebd0a46c49a1e82ca2920
Reviewed-on: https://chromium-review.googlesource.com/183861
Reviewed-by: Matt Tennant <mtennant@chromium.org>
Tested-by: Matt Tennant <mtennant@chromium.org>
Commit-Queue: Matt Tennant <mtennant@chromium.org>
diff --git a/scripts/cbuildbot.py b/scripts/cbuildbot.py
index a90da1c..21b120c 100644
--- a/scripts/cbuildbot.py
+++ b/scripts/cbuildbot.py
@@ -400,6 +400,7 @@
     steps = [stage.Run for stage in stage_objs]
     try:
       parallel.RunParallelSteps(steps)
+
     except BaseException as ex:
       # If a stage threw an exception, it might not have correctly reported
       # results (e.g. because it was killed before it could report the
@@ -834,14 +835,15 @@
   # to the start of the script (e.g. in or after _PostParseCheck).
   options.Freeze()
 
-  builder_run = cbuildbot_run.BuilderRun(options, build_config)
-  if _IsDistributedBuilder(options, chrome_rev, build_config):
-    builder_cls = DistributedBuilder
-  else:
-    builder_cls = SimpleBuilder
-  builder = builder_cls(builder_run)
-  if not builder.Run():
-    sys.exit(1)
+  with parallel.Manager() as manager:
+    builder_run = cbuildbot_run.BuilderRun(options, build_config, manager)
+    if _IsDistributedBuilder(options, chrome_rev, build_config):
+      builder_cls = DistributedBuilder
+    else:
+      builder_cls = SimpleBuilder
+    builder = builder_cls(builder_run)
+    if not builder.Run():
+      sys.exit(1)
 
 
 # Parser related functions