Set summary markdown in presubmit recipe using errors returned.

Using the json output from the presubmit step an error summary
is created. This summary is then set to the RawResult's
summary_markdown.

R=martiniss@google.com

Bug:971895
Change-Id: I8ee5f739b69f017af02223d7a2eb81e43cb80554
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/tools/build/+/1674291
Commit-Queue: Debrian Figueroa <debrian@google.com>
Reviewed-by: Robbie Iannucci <iannucci@chromium.org>
Reviewed-by: Garrett Beaty <gbeaty@chromium.org>
Reviewed-by: Stephen Martinis <martiniss@chromium.org>
diff --git a/scripts/slave/README.recipes.md b/scripts/slave/README.recipes.md
index 9e08c8b..bb51eba 100644
--- a/scripts/slave/README.recipes.md
+++ b/scripts/slave/README.recipes.md
@@ -5252,9 +5252,9 @@
 &mdash; **def [RunSteps](/scripts/slave/recipe_modules/repo/examples/full.py#19)(api):**
 ### *recipes* / [run\_presubmit](/scripts/slave/recipes/run_presubmit.py)
 
-[DEPS](/scripts/slave/recipes/run_presubmit.py#5): [v8](#recipe_modules-v8), [webrtc](#recipe_modules-webrtc), [depot\_tools/bot\_update][depot_tools/recipe_modules/bot_update], [depot\_tools/gclient][depot_tools/recipe_modules/gclient], [depot\_tools/git][depot_tools/recipe_modules/git], [depot\_tools/presubmit][depot_tools/recipe_modules/presubmit], [depot\_tools/tryserver][depot_tools/recipe_modules/tryserver], [recipe\_engine/buildbucket][recipe_engine/recipe_modules/buildbucket], [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/cq][recipe_engine/recipe_modules/cq], [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/json][recipe_engine/recipe_modules/json], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/runtime][recipe_engine/recipe_modules/runtime], [recipe\_engine/step][recipe_engine/recipe_modules/step]
+[DEPS](/scripts/slave/recipes/run_presubmit.py#10): [v8](#recipe_modules-v8), [webrtc](#recipe_modules-webrtc), [depot\_tools/bot\_update][depot_tools/recipe_modules/bot_update], [depot\_tools/gclient][depot_tools/recipe_modules/gclient], [depot\_tools/git][depot_tools/recipe_modules/git], [depot\_tools/presubmit][depot_tools/recipe_modules/presubmit], [depot\_tools/tryserver][depot_tools/recipe_modules/tryserver], [recipe\_engine/buildbucket][recipe_engine/recipe_modules/buildbucket], [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/cq][recipe_engine/recipe_modules/cq], [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/json][recipe_engine/recipe_modules/json], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/runtime][recipe_engine/recipe_modules/runtime], [recipe\_engine/step][recipe_engine/recipe_modules/step]
 
-&mdash; **def [RunSteps](/scripts/slave/recipes/run_presubmit.py#125)(api):**
+&mdash; **def [RunSteps](/scripts/slave/recipes/run_presubmit.py#164)(api):**
 ### *recipes* / [swarming/deterministic\_build](/scripts/slave/recipes/swarming/deterministic_build.py)
 
 [DEPS](/scripts/slave/recipes/swarming/deterministic_build.py#14): [chromium](#recipe_modules-chromium), [chromium\_android](#recipe_modules-chromium_android), [isolate](#recipe_modules-isolate), [depot\_tools/bot\_update][depot_tools/recipe_modules/bot_update], [depot\_tools/gclient][depot_tools/recipe_modules/gclient], [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/json][recipe_engine/recipe_modules/json], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/python][recipe_engine/recipe_modules/python], [recipe\_engine/step][recipe_engine/recipe_modules/step]
diff --git a/scripts/slave/recipes/run_presubmit.expected/build.json b/scripts/slave/recipes/run_presubmit.expected/build.json
index d33b7ef..d5556a7 100644
--- a/scripts/slave/recipes/run_presubmit.expected/build.json
+++ b/scripts/slave/recipes/run_presubmit.expected/build.json
@@ -158,7 +158,11 @@
     "name": "presubmit",
     "timeout": 480,
     "~followup_annotations": [
-      "@@@STEP_LOG_LINE@json.output@{}@@@",
+      "@@@STEP_LOG_LINE@json.output@{@@@",
+      "@@@STEP_LOG_LINE@json.output@  \"errors\": [], @@@",
+      "@@@STEP_LOG_LINE@json.output@  \"notifications\": [], @@@",
+      "@@@STEP_LOG_LINE@json.output@  \"warnings\": []@@@",
+      "@@@STEP_LOG_LINE@json.output@}@@@",
       "@@@STEP_LOG_END@json.output@@@"
     ]
   },
diff --git a/scripts/slave/recipes/run_presubmit.expected/build_internal.json b/scripts/slave/recipes/run_presubmit.expected/build_internal.json
index 5f89e6b..f2a970e 100644
--- a/scripts/slave/recipes/run_presubmit.expected/build_internal.json
+++ b/scripts/slave/recipes/run_presubmit.expected/build_internal.json
@@ -172,7 +172,11 @@
     "name": "presubmit",
     "timeout": 480,
     "~followup_annotations": [
-      "@@@STEP_LOG_LINE@json.output@{}@@@",
+      "@@@STEP_LOG_LINE@json.output@{@@@",
+      "@@@STEP_LOG_LINE@json.output@  \"errors\": [], @@@",
+      "@@@STEP_LOG_LINE@json.output@  \"notifications\": [], @@@",
+      "@@@STEP_LOG_LINE@json.output@  \"warnings\": []@@@",
+      "@@@STEP_LOG_LINE@json.output@}@@@",
       "@@@STEP_LOG_END@json.output@@@"
     ]
   },
diff --git a/scripts/slave/recipes/run_presubmit.expected/build_internal_scripts_slave.json b/scripts/slave/recipes/run_presubmit.expected/build_internal_scripts_slave.json
index 793c0e9..4386ef7 100644
--- a/scripts/slave/recipes/run_presubmit.expected/build_internal_scripts_slave.json
+++ b/scripts/slave/recipes/run_presubmit.expected/build_internal_scripts_slave.json
@@ -172,7 +172,11 @@
     "name": "presubmit",
     "timeout": 480,
     "~followup_annotations": [
-      "@@@STEP_LOG_LINE@json.output@{}@@@",
+      "@@@STEP_LOG_LINE@json.output@{@@@",
+      "@@@STEP_LOG_LINE@json.output@  \"errors\": [], @@@",
+      "@@@STEP_LOG_LINE@json.output@  \"notifications\": [], @@@",
+      "@@@STEP_LOG_LINE@json.output@  \"warnings\": []@@@",
+      "@@@STEP_LOG_LINE@json.output@}@@@",
       "@@@STEP_LOG_END@json.output@@@"
     ]
   },
diff --git a/scripts/slave/recipes/run_presubmit.expected/catapult.json b/scripts/slave/recipes/run_presubmit.expected/catapult.json
index 51cbe76..827aca1 100644
--- a/scripts/slave/recipes/run_presubmit.expected/catapult.json
+++ b/scripts/slave/recipes/run_presubmit.expected/catapult.json
@@ -155,7 +155,11 @@
     "name": "presubmit",
     "timeout": 480,
     "~followup_annotations": [
-      "@@@STEP_LOG_LINE@json.output@{}@@@",
+      "@@@STEP_LOG_LINE@json.output@{@@@",
+      "@@@STEP_LOG_LINE@json.output@  \"errors\": [], @@@",
+      "@@@STEP_LOG_LINE@json.output@  \"notifications\": [], @@@",
+      "@@@STEP_LOG_LINE@json.output@  \"warnings\": []@@@",
+      "@@@STEP_LOG_LINE@json.output@}@@@",
       "@@@STEP_LOG_END@json.output@@@"
     ]
   },
diff --git a/scripts/slave/recipes/run_presubmit.expected/chrome_golo.json b/scripts/slave/recipes/run_presubmit.expected/chrome_golo.json
index c0181ad..46e6421 100644
--- a/scripts/slave/recipes/run_presubmit.expected/chrome_golo.json
+++ b/scripts/slave/recipes/run_presubmit.expected/chrome_golo.json
@@ -155,7 +155,11 @@
     "name": "presubmit",
     "timeout": 480,
     "~followup_annotations": [
-      "@@@STEP_LOG_LINE@json.output@{}@@@",
+      "@@@STEP_LOG_LINE@json.output@{@@@",
+      "@@@STEP_LOG_LINE@json.output@  \"errors\": [], @@@",
+      "@@@STEP_LOG_LINE@json.output@  \"notifications\": [], @@@",
+      "@@@STEP_LOG_LINE@json.output@  \"warnings\": []@@@",
+      "@@@STEP_LOG_LINE@json.output@}@@@",
       "@@@STEP_LOG_END@json.output@@@"
     ]
   },
diff --git a/scripts/slave/recipes/run_presubmit.expected/chromium.json b/scripts/slave/recipes/run_presubmit.expected/chromium.json
index 62149b9..29ac823 100644
--- a/scripts/slave/recipes/run_presubmit.expected/chromium.json
+++ b/scripts/slave/recipes/run_presubmit.expected/chromium.json
@@ -253,7 +253,11 @@
     "name": "presubmit",
     "timeout": 480,
     "~followup_annotations": [
-      "@@@STEP_LOG_LINE@json.output@{}@@@",
+      "@@@STEP_LOG_LINE@json.output@{@@@",
+      "@@@STEP_LOG_LINE@json.output@  \"errors\": [], @@@",
+      "@@@STEP_LOG_LINE@json.output@  \"notifications\": [], @@@",
+      "@@@STEP_LOG_LINE@json.output@  \"warnings\": []@@@",
+      "@@@STEP_LOG_LINE@json.output@}@@@",
       "@@@STEP_LOG_END@json.output@@@"
     ]
   },
diff --git a/scripts/slave/recipes/run_presubmit.expected/chromium_dry_run.json b/scripts/slave/recipes/run_presubmit.expected/chromium_dry_run.json
index 04e454c..409d45c 100644
--- a/scripts/slave/recipes/run_presubmit.expected/chromium_dry_run.json
+++ b/scripts/slave/recipes/run_presubmit.expected/chromium_dry_run.json
@@ -254,7 +254,11 @@
     "name": "presubmit",
     "timeout": 480,
     "~followup_annotations": [
-      "@@@STEP_LOG_LINE@json.output@{}@@@",
+      "@@@STEP_LOG_LINE@json.output@{@@@",
+      "@@@STEP_LOG_LINE@json.output@  \"errors\": [], @@@",
+      "@@@STEP_LOG_LINE@json.output@  \"notifications\": [], @@@",
+      "@@@STEP_LOG_LINE@json.output@  \"warnings\": []@@@",
+      "@@@STEP_LOG_LINE@json.output@}@@@",
       "@@@STEP_LOG_END@json.output@@@"
     ]
   },
diff --git a/scripts/slave/recipes/run_presubmit.expected/chromium_timeout.json b/scripts/slave/recipes/run_presubmit.expected/chromium_timeout.json
deleted file mode 100644
index f958706..0000000
--- a/scripts/slave/recipes/run_presubmit.expected/chromium_timeout.json
+++ /dev/null
@@ -1,268 +0,0 @@
-[
-  {
-    "cmd": [
-      "python",
-      "-u",
-      "RECIPE_REPO[depot_tools]/gerrit_client.py",
-      "changes",
-      "--host",
-      "https://chromium-review.googlesource.com",
-      "--json_file",
-      "/path/to/tmp/json",
-      "--limit",
-      "1",
-      "-p",
-      "change=456789",
-      "-o",
-      "ALL_REVISIONS",
-      "-o",
-      "DOWNLOAD_COMMANDS"
-    ],
-    "env": {
-      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
-    },
-    "infra_step": true,
-    "name": "gerrit fetch current CL info",
-    "timeout": 600,
-    "~followup_annotations": [
-      "@@@STEP_LOG_LINE@json.output@[@@@",
-      "@@@STEP_LOG_LINE@json.output@  {@@@",
-      "@@@STEP_LOG_LINE@json.output@    \"branch\": \"master\", @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"revisions\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@      \"184ebe53805e102605d11f6b143486d15c23a09c\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@        \"_number\": \"12\", @@@",
-      "@@@STEP_LOG_LINE@json.output@        \"ref\": \"refs/changes/89/456789/12\"@@@",
-      "@@@STEP_LOG_LINE@json.output@      }@@@",
-      "@@@STEP_LOG_LINE@json.output@    }@@@",
-      "@@@STEP_LOG_LINE@json.output@  }@@@",
-      "@@@STEP_LOG_LINE@json.output@]@@@",
-      "@@@STEP_LOG_END@json.output@@@"
-    ]
-  },
-  {
-    "cmd": [
-      "python",
-      "-u",
-      "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec-path",
-      "cache_dir = '[CACHE]/git'\nsolutions = [{'custom_vars': {'checkout_telemetry_dependencies': 'True'}, 'deps_file': '.DEPS.git', 'managed': True, 'name': 'src', 'url': 'https://chromium.googlesource.com/chromium/src.git'}]",
-      "--patch_root",
-      "src",
-      "--revision_mapping_file",
-      "{\"got_angle_revision\": \"src/third_party/angle\", \"got_buildtools_revision\": \"src/buildtools\", \"got_dawn_revision\": \"src/third_party/dawn\", \"got_nacl_revision\": \"src/native_client\", \"got_revision\": \"src\", \"got_swarming_client_revision\": \"src/tools/swarming_client\", \"got_v8_revision\": \"src/v8\", \"got_webrtc_revision\": \"src/third_party/webrtc\"}",
-      "--git-cache-dir",
-      "[CACHE]/git",
-      "--cleanup-dir",
-      "[CLEANUP]/bot_update",
-      "--output_json",
-      "/path/to/tmp/json",
-      "--patch_ref",
-      "https://chromium.googlesource.com/chromium/src@refs/heads/master:refs/changes/89/456789/12",
-      "--revision",
-      "src@HEAD"
-    ],
-    "env_prefixes": {
-      "PATH": [
-        "RECIPE_REPO[depot_tools]"
-      ]
-    },
-    "infra_step": true,
-    "name": "bot_update",
-    "~followup_annotations": [
-      "@@@STEP_TEXT@Some step text@@@",
-      "@@@STEP_LOG_LINE@json.output@{@@@",
-      "@@@STEP_LOG_LINE@json.output@  \"did_run\": true, @@@",
-      "@@@STEP_LOG_LINE@json.output@  \"fixed_revisions\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@    \"src\": \"HEAD\"@@@",
-      "@@@STEP_LOG_LINE@json.output@  }, @@@",
-      "@@@STEP_LOG_LINE@json.output@  \"manifest\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@    \"src\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@      \"repository\": \"https://fake.org/src.git\", @@@",
-      "@@@STEP_LOG_LINE@json.output@      \"revision\": \"f27fede2220bcd326aee3e86ddfd4ebd0fe58cb9\"@@@",
-      "@@@STEP_LOG_LINE@json.output@    }, @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"src/buildtools\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@      \"repository\": \"https://fake.org/src/buildtools.git\", @@@",
-      "@@@STEP_LOG_LINE@json.output@      \"revision\": \"f0319a328b2809876916353cb994259692140934\"@@@",
-      "@@@STEP_LOG_LINE@json.output@    }, @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"src/native_client\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@      \"repository\": \"https://fake.org/src/native_client.git\", @@@",
-      "@@@STEP_LOG_LINE@json.output@      \"revision\": \"d998e125e8253980d76e269b7982aeeefc1b9b50\"@@@",
-      "@@@STEP_LOG_LINE@json.output@    }, @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"src/third_party/angle\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@      \"repository\": \"https://fake.org/src/third_party/angle.git\", @@@",
-      "@@@STEP_LOG_LINE@json.output@      \"revision\": \"fac9503c46405f77757b9a728eb85b8d7bc6080c\"@@@",
-      "@@@STEP_LOG_LINE@json.output@    }, @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"src/third_party/dawn\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@      \"repository\": \"https://fake.org/src/third_party/dawn.git\", @@@",
-      "@@@STEP_LOG_LINE@json.output@      \"revision\": \"1b5c932bc9a9a35c66edea3914fb675742d57cc2\"@@@",
-      "@@@STEP_LOG_LINE@json.output@    }, @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"src/third_party/webrtc\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@      \"repository\": \"https://fake.org/src/third_party/webrtc.git\", @@@",
-      "@@@STEP_LOG_LINE@json.output@      \"revision\": \"0f90628433546e61d9268596da93418c623137f4\"@@@",
-      "@@@STEP_LOG_LINE@json.output@    }, @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"src/tools/swarming_client\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@      \"repository\": \"https://fake.org/src/tools/swarming_client.git\", @@@",
-      "@@@STEP_LOG_LINE@json.output@      \"revision\": \"a0ee5d99f1d4b38ddaa4c759c837980b63b99566\"@@@",
-      "@@@STEP_LOG_LINE@json.output@    }, @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"src/v8\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@      \"repository\": \"https://fake.org/src/v8.git\", @@@",
-      "@@@STEP_LOG_LINE@json.output@      \"revision\": \"801ada225ddc271c132c3a35f03975671d43e399\"@@@",
-      "@@@STEP_LOG_LINE@json.output@    }@@@",
-      "@@@STEP_LOG_LINE@json.output@  }, @@@",
-      "@@@STEP_LOG_LINE@json.output@  \"patch_failure\": false, @@@",
-      "@@@STEP_LOG_LINE@json.output@  \"patch_root\": \"src\", @@@",
-      "@@@STEP_LOG_LINE@json.output@  \"properties\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@    \"got_angle_revision\": \"fac9503c46405f77757b9a728eb85b8d7bc6080c\", @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"got_angle_revision_cp\": \"refs/heads/master@{#297276}\", @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"got_buildtools_revision\": \"f0319a328b2809876916353cb994259692140934\", @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"got_buildtools_revision_cp\": \"refs/heads/master@{#182578}\", @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"got_dawn_revision\": \"1b5c932bc9a9a35c66edea3914fb675742d57cc2\", @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"got_dawn_revision_cp\": \"refs/heads/master@{#51819}\", @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"got_nacl_revision\": \"d998e125e8253980d76e269b7982aeeefc1b9b50\", @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"got_nacl_revision_cp\": \"refs/heads/master@{#274981}\", @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"got_revision\": \"f27fede2220bcd326aee3e86ddfd4ebd0fe58cb9\", @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"got_revision_cp\": \"refs/heads/master@{#170242}\", @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"got_swarming_client_revision\": \"a0ee5d99f1d4b38ddaa4c759c837980b63b99566\", @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"got_swarming_client_revision_cp\": \"refs/heads/master@{#276089}\", @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"got_v8_revision\": \"801ada225ddc271c132c3a35f03975671d43e399\", @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"got_v8_revision_cp\": \"refs/heads/master@{#43426}\", @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"got_webrtc_revision\": \"0f90628433546e61d9268596da93418c623137f4\", @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"got_webrtc_revision_cp\": \"refs/heads/master@{#120644}\"@@@",
-      "@@@STEP_LOG_LINE@json.output@  }, @@@",
-      "@@@STEP_LOG_LINE@json.output@  \"root\": \"src\", @@@",
-      "@@@STEP_LOG_LINE@json.output@  \"source_manifest\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@    \"directories\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@      \"src\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@        \"git_checkout\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@          \"repo_url\": \"https://fake.org/src.git\", @@@",
-      "@@@STEP_LOG_LINE@json.output@          \"revision\": \"f27fede2220bcd326aee3e86ddfd4ebd0fe58cb9\"@@@",
-      "@@@STEP_LOG_LINE@json.output@        }@@@",
-      "@@@STEP_LOG_LINE@json.output@      }, @@@",
-      "@@@STEP_LOG_LINE@json.output@      \"src/buildtools\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@        \"git_checkout\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@          \"repo_url\": \"https://fake.org/src/buildtools.git\", @@@",
-      "@@@STEP_LOG_LINE@json.output@          \"revision\": \"f0319a328b2809876916353cb994259692140934\"@@@",
-      "@@@STEP_LOG_LINE@json.output@        }@@@",
-      "@@@STEP_LOG_LINE@json.output@      }, @@@",
-      "@@@STEP_LOG_LINE@json.output@      \"src/native_client\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@        \"git_checkout\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@          \"repo_url\": \"https://fake.org/src/native_client.git\", @@@",
-      "@@@STEP_LOG_LINE@json.output@          \"revision\": \"d998e125e8253980d76e269b7982aeeefc1b9b50\"@@@",
-      "@@@STEP_LOG_LINE@json.output@        }@@@",
-      "@@@STEP_LOG_LINE@json.output@      }, @@@",
-      "@@@STEP_LOG_LINE@json.output@      \"src/third_party/angle\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@        \"git_checkout\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@          \"repo_url\": \"https://fake.org/src/third_party/angle.git\", @@@",
-      "@@@STEP_LOG_LINE@json.output@          \"revision\": \"fac9503c46405f77757b9a728eb85b8d7bc6080c\"@@@",
-      "@@@STEP_LOG_LINE@json.output@        }@@@",
-      "@@@STEP_LOG_LINE@json.output@      }, @@@",
-      "@@@STEP_LOG_LINE@json.output@      \"src/third_party/dawn\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@        \"git_checkout\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@          \"repo_url\": \"https://fake.org/src/third_party/dawn.git\", @@@",
-      "@@@STEP_LOG_LINE@json.output@          \"revision\": \"1b5c932bc9a9a35c66edea3914fb675742d57cc2\"@@@",
-      "@@@STEP_LOG_LINE@json.output@        }@@@",
-      "@@@STEP_LOG_LINE@json.output@      }, @@@",
-      "@@@STEP_LOG_LINE@json.output@      \"src/third_party/webrtc\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@        \"git_checkout\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@          \"repo_url\": \"https://fake.org/src/third_party/webrtc.git\", @@@",
-      "@@@STEP_LOG_LINE@json.output@          \"revision\": \"0f90628433546e61d9268596da93418c623137f4\"@@@",
-      "@@@STEP_LOG_LINE@json.output@        }@@@",
-      "@@@STEP_LOG_LINE@json.output@      }, @@@",
-      "@@@STEP_LOG_LINE@json.output@      \"src/tools/swarming_client\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@        \"git_checkout\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@          \"repo_url\": \"https://fake.org/src/tools/swarming_client.git\", @@@",
-      "@@@STEP_LOG_LINE@json.output@          \"revision\": \"a0ee5d99f1d4b38ddaa4c759c837980b63b99566\"@@@",
-      "@@@STEP_LOG_LINE@json.output@        }@@@",
-      "@@@STEP_LOG_LINE@json.output@      }, @@@",
-      "@@@STEP_LOG_LINE@json.output@      \"src/v8\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@        \"git_checkout\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@          \"repo_url\": \"https://fake.org/src/v8.git\", @@@",
-      "@@@STEP_LOG_LINE@json.output@          \"revision\": \"801ada225ddc271c132c3a35f03975671d43e399\"@@@",
-      "@@@STEP_LOG_LINE@json.output@        }@@@",
-      "@@@STEP_LOG_LINE@json.output@      }@@@",
-      "@@@STEP_LOG_LINE@json.output@    }, @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"version\": 0@@@",
-      "@@@STEP_LOG_LINE@json.output@  }, @@@",
-      "@@@STEP_LOG_LINE@json.output@  \"step_text\": \"Some step text\"@@@",
-      "@@@STEP_LOG_LINE@json.output@}@@@",
-      "@@@STEP_LOG_END@json.output@@@",
-      "@@@SET_BUILD_PROPERTY@got_angle_revision@\"fac9503c46405f77757b9a728eb85b8d7bc6080c\"@@@",
-      "@@@SET_BUILD_PROPERTY@got_angle_revision_cp@\"refs/heads/master@{#297276}\"@@@",
-      "@@@SET_BUILD_PROPERTY@got_buildtools_revision@\"f0319a328b2809876916353cb994259692140934\"@@@",
-      "@@@SET_BUILD_PROPERTY@got_buildtools_revision_cp@\"refs/heads/master@{#182578}\"@@@",
-      "@@@SET_BUILD_PROPERTY@got_dawn_revision@\"1b5c932bc9a9a35c66edea3914fb675742d57cc2\"@@@",
-      "@@@SET_BUILD_PROPERTY@got_dawn_revision_cp@\"refs/heads/master@{#51819}\"@@@",
-      "@@@SET_BUILD_PROPERTY@got_nacl_revision@\"d998e125e8253980d76e269b7982aeeefc1b9b50\"@@@",
-      "@@@SET_BUILD_PROPERTY@got_nacl_revision_cp@\"refs/heads/master@{#274981}\"@@@",
-      "@@@SET_BUILD_PROPERTY@got_revision@\"f27fede2220bcd326aee3e86ddfd4ebd0fe58cb9\"@@@",
-      "@@@SET_BUILD_PROPERTY@got_revision_cp@\"refs/heads/master@{#170242}\"@@@",
-      "@@@SET_BUILD_PROPERTY@got_swarming_client_revision@\"a0ee5d99f1d4b38ddaa4c759c837980b63b99566\"@@@",
-      "@@@SET_BUILD_PROPERTY@got_swarming_client_revision_cp@\"refs/heads/master@{#276089}\"@@@",
-      "@@@SET_BUILD_PROPERTY@got_v8_revision@\"801ada225ddc271c132c3a35f03975671d43e399\"@@@",
-      "@@@SET_BUILD_PROPERTY@got_v8_revision_cp@\"refs/heads/master@{#43426}\"@@@",
-      "@@@SET_BUILD_PROPERTY@got_webrtc_revision@\"0f90628433546e61d9268596da93418c623137f4\"@@@",
-      "@@@SET_BUILD_PROPERTY@got_webrtc_revision_cp@\"refs/heads/master@{#120644}\"@@@"
-    ]
-  },
-  {
-    "cmd": [
-      "git",
-      "-c",
-      "user.email=commit-bot@chromium.org",
-      "-c",
-      "user.name=The Commit Bot",
-      "commit",
-      "-a",
-      "-m",
-      "Committed patch"
-    ],
-    "cwd": "[START_DIR]/src",
-    "name": "commit-git-patch"
-  },
-  {
-    "cmd": [
-      "python",
-      "-u",
-      "RECIPE_REPO[depot_tools]/presubmit_support.py",
-      "--issue",
-      "456789",
-      "--patchset",
-      "12",
-      "--gerrit_url",
-      "https://chromium-review.googlesource.com",
-      "--gerrit_fetch",
-      "--root",
-      "[START_DIR]/src",
-      "--commit",
-      "--verbose",
-      "--verbose",
-      "--skip_canned",
-      "CheckTreeIsOpen",
-      "--skip_canned",
-      "CheckBuildbotPendingBuilds",
-      "--upstream",
-      "f27fede2220bcd326aee3e86ddfd4ebd0fe58cb9",
-      "--json_output",
-      "/path/to/tmp/json"
-    ],
-    "env_prefixes": {
-      "PATH": [
-        "RECIPE_REPO[depot_tools]"
-      ]
-    },
-    "name": "presubmit",
-    "timeout": 480,
-    "~followup_annotations": [
-      "@@@STEP_LOG_LINE@json.output@{}@@@",
-      "@@@STEP_LOG_END@json.output@@@",
-      "@@@STEP_FAILURE@@@"
-    ]
-  },
-  {
-    "failure": {
-      "failure": {},
-      "humanReason": "Step('presubmit') (timeout)"
-    },
-    "name": "$result"
-  }
-]
\ No newline at end of file
diff --git a/scripts/slave/recipes/run_presubmit.expected/depot_tools.json b/scripts/slave/recipes/run_presubmit.expected/depot_tools.json
index 2c7e37a..8b2a5ea 100644
--- a/scripts/slave/recipes/run_presubmit.expected/depot_tools.json
+++ b/scripts/slave/recipes/run_presubmit.expected/depot_tools.json
@@ -155,7 +155,11 @@
     "name": "presubmit",
     "timeout": 480,
     "~followup_annotations": [
-      "@@@STEP_LOG_LINE@json.output@{}@@@",
+      "@@@STEP_LOG_LINE@json.output@{@@@",
+      "@@@STEP_LOG_LINE@json.output@  \"errors\": [], @@@",
+      "@@@STEP_LOG_LINE@json.output@  \"notifications\": [], @@@",
+      "@@@STEP_LOG_LINE@json.output@  \"warnings\": []@@@",
+      "@@@STEP_LOG_LINE@json.output@}@@@",
       "@@@STEP_LOG_END@json.output@@@"
     ]
   },
diff --git a/scripts/slave/recipes/run_presubmit.expected/gyp.json b/scripts/slave/recipes/run_presubmit.expected/gyp.json
index 20c3408..4566d1f 100644
--- a/scripts/slave/recipes/run_presubmit.expected/gyp.json
+++ b/scripts/slave/recipes/run_presubmit.expected/gyp.json
@@ -155,7 +155,11 @@
     "name": "presubmit",
     "timeout": 480,
     "~followup_annotations": [
-      "@@@STEP_LOG_LINE@json.output@{}@@@",
+      "@@@STEP_LOG_LINE@json.output@{@@@",
+      "@@@STEP_LOG_LINE@json.output@  \"errors\": [], @@@",
+      "@@@STEP_LOG_LINE@json.output@  \"notifications\": [], @@@",
+      "@@@STEP_LOG_LINE@json.output@  \"warnings\": []@@@",
+      "@@@STEP_LOG_LINE@json.output@}@@@",
       "@@@STEP_LOG_END@json.output@@@"
     ]
   },
diff --git a/scripts/slave/recipes/run_presubmit.expected/infra_with_runhooks.json b/scripts/slave/recipes/run_presubmit.expected/infra_with_runhooks.json
index f6812f9..2dadfa3 100644
--- a/scripts/slave/recipes/run_presubmit.expected/infra_with_runhooks.json
+++ b/scripts/slave/recipes/run_presubmit.expected/infra_with_runhooks.json
@@ -170,7 +170,11 @@
     "name": "presubmit",
     "timeout": 480,
     "~followup_annotations": [
-      "@@@STEP_LOG_LINE@json.output@{}@@@",
+      "@@@STEP_LOG_LINE@json.output@{@@@",
+      "@@@STEP_LOG_LINE@json.output@  \"errors\": [], @@@",
+      "@@@STEP_LOG_LINE@json.output@  \"notifications\": [], @@@",
+      "@@@STEP_LOG_LINE@json.output@  \"warnings\": []@@@",
+      "@@@STEP_LOG_LINE@json.output@}@@@",
       "@@@STEP_LOG_END@json.output@@@"
     ]
   },
diff --git a/scripts/slave/recipes/run_presubmit.expected/internal_deps.json b/scripts/slave/recipes/run_presubmit.expected/internal_deps.json
index 9ed41a8..2d4b314 100644
--- a/scripts/slave/recipes/run_presubmit.expected/internal_deps.json
+++ b/scripts/slave/recipes/run_presubmit.expected/internal_deps.json
@@ -155,7 +155,11 @@
     "name": "presubmit",
     "timeout": 480,
     "~followup_annotations": [
-      "@@@STEP_LOG_LINE@json.output@{}@@@",
+      "@@@STEP_LOG_LINE@json.output@{@@@",
+      "@@@STEP_LOG_LINE@json.output@  \"errors\": [], @@@",
+      "@@@STEP_LOG_LINE@json.output@  \"notifications\": [], @@@",
+      "@@@STEP_LOG_LINE@json.output@  \"warnings\": []@@@",
+      "@@@STEP_LOG_LINE@json.output@}@@@",
       "@@@STEP_LOG_END@json.output@@@"
     ]
   },
diff --git a/scripts/slave/recipes/run_presubmit.expected/luci-py.json b/scripts/slave/recipes/run_presubmit.expected/luci-py.json
index 89d1b55..3ce8882 100644
--- a/scripts/slave/recipes/run_presubmit.expected/luci-py.json
+++ b/scripts/slave/recipes/run_presubmit.expected/luci-py.json
@@ -160,7 +160,11 @@
     "name": "presubmit",
     "timeout": 900,
     "~followup_annotations": [
-      "@@@STEP_LOG_LINE@json.output@{}@@@",
+      "@@@STEP_LOG_LINE@json.output@{@@@",
+      "@@@STEP_LOG_LINE@json.output@  \"errors\": [], @@@",
+      "@@@STEP_LOG_LINE@json.output@  \"notifications\": [], @@@",
+      "@@@STEP_LOG_LINE@json.output@  \"warnings\": []@@@",
+      "@@@STEP_LOG_LINE@json.output@}@@@",
       "@@@STEP_LOG_END@json.output@@@"
     ]
   },
diff --git a/scripts/slave/recipes/run_presubmit.expected/master_deps.json b/scripts/slave/recipes/run_presubmit.expected/master_deps.json
index a1d7e69..46b4444 100644
--- a/scripts/slave/recipes/run_presubmit.expected/master_deps.json
+++ b/scripts/slave/recipes/run_presubmit.expected/master_deps.json
@@ -155,7 +155,11 @@
     "name": "presubmit",
     "timeout": 480,
     "~followup_annotations": [
-      "@@@STEP_LOG_LINE@json.output@{}@@@",
+      "@@@STEP_LOG_LINE@json.output@{@@@",
+      "@@@STEP_LOG_LINE@json.output@  \"errors\": [], @@@",
+      "@@@STEP_LOG_LINE@json.output@  \"notifications\": [], @@@",
+      "@@@STEP_LOG_LINE@json.output@  \"warnings\": []@@@",
+      "@@@STEP_LOG_LINE@json.output@}@@@",
       "@@@STEP_LOG_END@json.output@@@"
     ]
   },
diff --git a/scripts/slave/recipes/run_presubmit.expected/nacl.json b/scripts/slave/recipes/run_presubmit.expected/nacl.json
index bd3e5c4b..c629210 100644
--- a/scripts/slave/recipes/run_presubmit.expected/nacl.json
+++ b/scripts/slave/recipes/run_presubmit.expected/nacl.json
@@ -155,7 +155,11 @@
     "name": "presubmit",
     "timeout": 480,
     "~followup_annotations": [
-      "@@@STEP_LOG_LINE@json.output@{}@@@",
+      "@@@STEP_LOG_LINE@json.output@{@@@",
+      "@@@STEP_LOG_LINE@json.output@  \"errors\": [], @@@",
+      "@@@STEP_LOG_LINE@json.output@  \"notifications\": [], @@@",
+      "@@@STEP_LOG_LINE@json.output@  \"warnings\": []@@@",
+      "@@@STEP_LOG_LINE@json.output@}@@@",
       "@@@STEP_LOG_END@json.output@@@"
     ]
   },
diff --git a/scripts/slave/recipes/run_presubmit.expected/openscreen.json b/scripts/slave/recipes/run_presubmit.expected/openscreen.json
index bb3912f..9d3fd31 100644
--- a/scripts/slave/recipes/run_presubmit.expected/openscreen.json
+++ b/scripts/slave/recipes/run_presubmit.expected/openscreen.json
@@ -155,7 +155,11 @@
     "name": "presubmit",
     "timeout": 480,
     "~followup_annotations": [
-      "@@@STEP_LOG_LINE@json.output@{}@@@",
+      "@@@STEP_LOG_LINE@json.output@{@@@",
+      "@@@STEP_LOG_LINE@json.output@  \"errors\": [], @@@",
+      "@@@STEP_LOG_LINE@json.output@  \"notifications\": [], @@@",
+      "@@@STEP_LOG_LINE@json.output@  \"warnings\": []@@@",
+      "@@@STEP_LOG_LINE@json.output@}@@@",
       "@@@STEP_LOG_END@json.output@@@"
     ]
   },
diff --git a/scripts/slave/recipes/run_presubmit.expected/pdfium.json b/scripts/slave/recipes/run_presubmit.expected/pdfium.json
index 664deca..61fe265 100644
--- a/scripts/slave/recipes/run_presubmit.expected/pdfium.json
+++ b/scripts/slave/recipes/run_presubmit.expected/pdfium.json
@@ -155,7 +155,11 @@
     "name": "presubmit",
     "timeout": 480,
     "~followup_annotations": [
-      "@@@STEP_LOG_LINE@json.output@{}@@@",
+      "@@@STEP_LOG_LINE@json.output@{@@@",
+      "@@@STEP_LOG_LINE@json.output@  \"errors\": [], @@@",
+      "@@@STEP_LOG_LINE@json.output@  \"notifications\": [], @@@",
+      "@@@STEP_LOG_LINE@json.output@  \"warnings\": []@@@",
+      "@@@STEP_LOG_LINE@json.output@}@@@",
       "@@@STEP_LOG_END@json.output@@@"
     ]
   },
diff --git a/scripts/slave/recipes/run_presubmit.expected/presubmit-failure.json b/scripts/slave/recipes/run_presubmit.expected/presubmit-failure.json
deleted file mode 100644
index 0dcfc22..0000000
--- a/scripts/slave/recipes/run_presubmit.expected/presubmit-failure.json
+++ /dev/null
@@ -1,277 +0,0 @@
-[
-  {
-    "cmd": [
-      "python",
-      "-u",
-      "RECIPE_REPO[depot_tools]/gerrit_client.py",
-      "changes",
-      "--host",
-      "https://chromium-review.googlesource.com",
-      "--json_file",
-      "/path/to/tmp/json",
-      "--limit",
-      "1",
-      "-p",
-      "change=456789",
-      "-o",
-      "ALL_REVISIONS",
-      "-o",
-      "DOWNLOAD_COMMANDS"
-    ],
-    "env": {
-      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
-    },
-    "infra_step": true,
-    "name": "gerrit fetch current CL info",
-    "timeout": 600,
-    "~followup_annotations": [
-      "@@@STEP_LOG_LINE@json.output@[@@@",
-      "@@@STEP_LOG_LINE@json.output@  {@@@",
-      "@@@STEP_LOG_LINE@json.output@    \"branch\": \"master\", @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"revisions\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@      \"184ebe53805e102605d11f6b143486d15c23a09c\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@        \"_number\": \"12\", @@@",
-      "@@@STEP_LOG_LINE@json.output@        \"ref\": \"refs/changes/89/456789/12\"@@@",
-      "@@@STEP_LOG_LINE@json.output@      }@@@",
-      "@@@STEP_LOG_LINE@json.output@    }@@@",
-      "@@@STEP_LOG_LINE@json.output@  }@@@",
-      "@@@STEP_LOG_LINE@json.output@]@@@",
-      "@@@STEP_LOG_END@json.output@@@"
-    ]
-  },
-  {
-    "cmd": [
-      "python",
-      "-u",
-      "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec-path",
-      "cache_dir = '[CACHE]/git'\nsolutions = [{'custom_vars': {'checkout_telemetry_dependencies': 'True'}, 'deps_file': '.DEPS.git', 'managed': True, 'name': 'src', 'url': 'https://chromium.googlesource.com/chromium/src.git'}]",
-      "--patch_root",
-      "src",
-      "--revision_mapping_file",
-      "{\"got_angle_revision\": \"src/third_party/angle\", \"got_buildtools_revision\": \"src/buildtools\", \"got_dawn_revision\": \"src/third_party/dawn\", \"got_nacl_revision\": \"src/native_client\", \"got_revision\": \"src\", \"got_swarming_client_revision\": \"src/tools/swarming_client\", \"got_v8_revision\": \"src/v8\", \"got_webrtc_revision\": \"src/third_party/webrtc\"}",
-      "--git-cache-dir",
-      "[CACHE]/git",
-      "--cleanup-dir",
-      "[CLEANUP]/bot_update",
-      "--output_json",
-      "/path/to/tmp/json",
-      "--patch_ref",
-      "https://chromium.googlesource.com/chromium/src@refs/heads/master:refs/changes/89/456789/12",
-      "--revision",
-      "src@HEAD"
-    ],
-    "env_prefixes": {
-      "PATH": [
-        "RECIPE_REPO[depot_tools]"
-      ]
-    },
-    "infra_step": true,
-    "name": "bot_update",
-    "~followup_annotations": [
-      "@@@STEP_TEXT@Some step text@@@",
-      "@@@STEP_LOG_LINE@json.output@{@@@",
-      "@@@STEP_LOG_LINE@json.output@  \"did_run\": true, @@@",
-      "@@@STEP_LOG_LINE@json.output@  \"fixed_revisions\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@    \"src\": \"HEAD\"@@@",
-      "@@@STEP_LOG_LINE@json.output@  }, @@@",
-      "@@@STEP_LOG_LINE@json.output@  \"manifest\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@    \"src\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@      \"repository\": \"https://fake.org/src.git\", @@@",
-      "@@@STEP_LOG_LINE@json.output@      \"revision\": \"f27fede2220bcd326aee3e86ddfd4ebd0fe58cb9\"@@@",
-      "@@@STEP_LOG_LINE@json.output@    }, @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"src/buildtools\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@      \"repository\": \"https://fake.org/src/buildtools.git\", @@@",
-      "@@@STEP_LOG_LINE@json.output@      \"revision\": \"f0319a328b2809876916353cb994259692140934\"@@@",
-      "@@@STEP_LOG_LINE@json.output@    }, @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"src/native_client\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@      \"repository\": \"https://fake.org/src/native_client.git\", @@@",
-      "@@@STEP_LOG_LINE@json.output@      \"revision\": \"d998e125e8253980d76e269b7982aeeefc1b9b50\"@@@",
-      "@@@STEP_LOG_LINE@json.output@    }, @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"src/third_party/angle\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@      \"repository\": \"https://fake.org/src/third_party/angle.git\", @@@",
-      "@@@STEP_LOG_LINE@json.output@      \"revision\": \"fac9503c46405f77757b9a728eb85b8d7bc6080c\"@@@",
-      "@@@STEP_LOG_LINE@json.output@    }, @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"src/third_party/dawn\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@      \"repository\": \"https://fake.org/src/third_party/dawn.git\", @@@",
-      "@@@STEP_LOG_LINE@json.output@      \"revision\": \"1b5c932bc9a9a35c66edea3914fb675742d57cc2\"@@@",
-      "@@@STEP_LOG_LINE@json.output@    }, @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"src/third_party/webrtc\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@      \"repository\": \"https://fake.org/src/third_party/webrtc.git\", @@@",
-      "@@@STEP_LOG_LINE@json.output@      \"revision\": \"0f90628433546e61d9268596da93418c623137f4\"@@@",
-      "@@@STEP_LOG_LINE@json.output@    }, @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"src/tools/swarming_client\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@      \"repository\": \"https://fake.org/src/tools/swarming_client.git\", @@@",
-      "@@@STEP_LOG_LINE@json.output@      \"revision\": \"a0ee5d99f1d4b38ddaa4c759c837980b63b99566\"@@@",
-      "@@@STEP_LOG_LINE@json.output@    }, @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"src/v8\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@      \"repository\": \"https://fake.org/src/v8.git\", @@@",
-      "@@@STEP_LOG_LINE@json.output@      \"revision\": \"801ada225ddc271c132c3a35f03975671d43e399\"@@@",
-      "@@@STEP_LOG_LINE@json.output@    }@@@",
-      "@@@STEP_LOG_LINE@json.output@  }, @@@",
-      "@@@STEP_LOG_LINE@json.output@  \"patch_failure\": false, @@@",
-      "@@@STEP_LOG_LINE@json.output@  \"patch_root\": \"src\", @@@",
-      "@@@STEP_LOG_LINE@json.output@  \"properties\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@    \"got_angle_revision\": \"fac9503c46405f77757b9a728eb85b8d7bc6080c\", @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"got_angle_revision_cp\": \"refs/heads/master@{#297276}\", @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"got_buildtools_revision\": \"f0319a328b2809876916353cb994259692140934\", @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"got_buildtools_revision_cp\": \"refs/heads/master@{#182578}\", @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"got_dawn_revision\": \"1b5c932bc9a9a35c66edea3914fb675742d57cc2\", @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"got_dawn_revision_cp\": \"refs/heads/master@{#51819}\", @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"got_nacl_revision\": \"d998e125e8253980d76e269b7982aeeefc1b9b50\", @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"got_nacl_revision_cp\": \"refs/heads/master@{#274981}\", @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"got_revision\": \"f27fede2220bcd326aee3e86ddfd4ebd0fe58cb9\", @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"got_revision_cp\": \"refs/heads/master@{#170242}\", @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"got_swarming_client_revision\": \"a0ee5d99f1d4b38ddaa4c759c837980b63b99566\", @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"got_swarming_client_revision_cp\": \"refs/heads/master@{#276089}\", @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"got_v8_revision\": \"801ada225ddc271c132c3a35f03975671d43e399\", @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"got_v8_revision_cp\": \"refs/heads/master@{#43426}\", @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"got_webrtc_revision\": \"0f90628433546e61d9268596da93418c623137f4\", @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"got_webrtc_revision_cp\": \"refs/heads/master@{#120644}\"@@@",
-      "@@@STEP_LOG_LINE@json.output@  }, @@@",
-      "@@@STEP_LOG_LINE@json.output@  \"root\": \"src\", @@@",
-      "@@@STEP_LOG_LINE@json.output@  \"source_manifest\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@    \"directories\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@      \"src\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@        \"git_checkout\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@          \"repo_url\": \"https://fake.org/src.git\", @@@",
-      "@@@STEP_LOG_LINE@json.output@          \"revision\": \"f27fede2220bcd326aee3e86ddfd4ebd0fe58cb9\"@@@",
-      "@@@STEP_LOG_LINE@json.output@        }@@@",
-      "@@@STEP_LOG_LINE@json.output@      }, @@@",
-      "@@@STEP_LOG_LINE@json.output@      \"src/buildtools\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@        \"git_checkout\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@          \"repo_url\": \"https://fake.org/src/buildtools.git\", @@@",
-      "@@@STEP_LOG_LINE@json.output@          \"revision\": \"f0319a328b2809876916353cb994259692140934\"@@@",
-      "@@@STEP_LOG_LINE@json.output@        }@@@",
-      "@@@STEP_LOG_LINE@json.output@      }, @@@",
-      "@@@STEP_LOG_LINE@json.output@      \"src/native_client\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@        \"git_checkout\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@          \"repo_url\": \"https://fake.org/src/native_client.git\", @@@",
-      "@@@STEP_LOG_LINE@json.output@          \"revision\": \"d998e125e8253980d76e269b7982aeeefc1b9b50\"@@@",
-      "@@@STEP_LOG_LINE@json.output@        }@@@",
-      "@@@STEP_LOG_LINE@json.output@      }, @@@",
-      "@@@STEP_LOG_LINE@json.output@      \"src/third_party/angle\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@        \"git_checkout\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@          \"repo_url\": \"https://fake.org/src/third_party/angle.git\", @@@",
-      "@@@STEP_LOG_LINE@json.output@          \"revision\": \"fac9503c46405f77757b9a728eb85b8d7bc6080c\"@@@",
-      "@@@STEP_LOG_LINE@json.output@        }@@@",
-      "@@@STEP_LOG_LINE@json.output@      }, @@@",
-      "@@@STEP_LOG_LINE@json.output@      \"src/third_party/dawn\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@        \"git_checkout\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@          \"repo_url\": \"https://fake.org/src/third_party/dawn.git\", @@@",
-      "@@@STEP_LOG_LINE@json.output@          \"revision\": \"1b5c932bc9a9a35c66edea3914fb675742d57cc2\"@@@",
-      "@@@STEP_LOG_LINE@json.output@        }@@@",
-      "@@@STEP_LOG_LINE@json.output@      }, @@@",
-      "@@@STEP_LOG_LINE@json.output@      \"src/third_party/webrtc\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@        \"git_checkout\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@          \"repo_url\": \"https://fake.org/src/third_party/webrtc.git\", @@@",
-      "@@@STEP_LOG_LINE@json.output@          \"revision\": \"0f90628433546e61d9268596da93418c623137f4\"@@@",
-      "@@@STEP_LOG_LINE@json.output@        }@@@",
-      "@@@STEP_LOG_LINE@json.output@      }, @@@",
-      "@@@STEP_LOG_LINE@json.output@      \"src/tools/swarming_client\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@        \"git_checkout\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@          \"repo_url\": \"https://fake.org/src/tools/swarming_client.git\", @@@",
-      "@@@STEP_LOG_LINE@json.output@          \"revision\": \"a0ee5d99f1d4b38ddaa4c759c837980b63b99566\"@@@",
-      "@@@STEP_LOG_LINE@json.output@        }@@@",
-      "@@@STEP_LOG_LINE@json.output@      }, @@@",
-      "@@@STEP_LOG_LINE@json.output@      \"src/v8\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@        \"git_checkout\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@          \"repo_url\": \"https://fake.org/src/v8.git\", @@@",
-      "@@@STEP_LOG_LINE@json.output@          \"revision\": \"801ada225ddc271c132c3a35f03975671d43e399\"@@@",
-      "@@@STEP_LOG_LINE@json.output@        }@@@",
-      "@@@STEP_LOG_LINE@json.output@      }@@@",
-      "@@@STEP_LOG_LINE@json.output@    }, @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"version\": 0@@@",
-      "@@@STEP_LOG_LINE@json.output@  }, @@@",
-      "@@@STEP_LOG_LINE@json.output@  \"step_text\": \"Some step text\"@@@",
-      "@@@STEP_LOG_LINE@json.output@}@@@",
-      "@@@STEP_LOG_END@json.output@@@",
-      "@@@SET_BUILD_PROPERTY@got_angle_revision@\"fac9503c46405f77757b9a728eb85b8d7bc6080c\"@@@",
-      "@@@SET_BUILD_PROPERTY@got_angle_revision_cp@\"refs/heads/master@{#297276}\"@@@",
-      "@@@SET_BUILD_PROPERTY@got_buildtools_revision@\"f0319a328b2809876916353cb994259692140934\"@@@",
-      "@@@SET_BUILD_PROPERTY@got_buildtools_revision_cp@\"refs/heads/master@{#182578}\"@@@",
-      "@@@SET_BUILD_PROPERTY@got_dawn_revision@\"1b5c932bc9a9a35c66edea3914fb675742d57cc2\"@@@",
-      "@@@SET_BUILD_PROPERTY@got_dawn_revision_cp@\"refs/heads/master@{#51819}\"@@@",
-      "@@@SET_BUILD_PROPERTY@got_nacl_revision@\"d998e125e8253980d76e269b7982aeeefc1b9b50\"@@@",
-      "@@@SET_BUILD_PROPERTY@got_nacl_revision_cp@\"refs/heads/master@{#274981}\"@@@",
-      "@@@SET_BUILD_PROPERTY@got_revision@\"f27fede2220bcd326aee3e86ddfd4ebd0fe58cb9\"@@@",
-      "@@@SET_BUILD_PROPERTY@got_revision_cp@\"refs/heads/master@{#170242}\"@@@",
-      "@@@SET_BUILD_PROPERTY@got_swarming_client_revision@\"a0ee5d99f1d4b38ddaa4c759c837980b63b99566\"@@@",
-      "@@@SET_BUILD_PROPERTY@got_swarming_client_revision_cp@\"refs/heads/master@{#276089}\"@@@",
-      "@@@SET_BUILD_PROPERTY@got_v8_revision@\"801ada225ddc271c132c3a35f03975671d43e399\"@@@",
-      "@@@SET_BUILD_PROPERTY@got_v8_revision_cp@\"refs/heads/master@{#43426}\"@@@",
-      "@@@SET_BUILD_PROPERTY@got_webrtc_revision@\"0f90628433546e61d9268596da93418c623137f4\"@@@",
-      "@@@SET_BUILD_PROPERTY@got_webrtc_revision_cp@\"refs/heads/master@{#120644}\"@@@"
-    ]
-  },
-  {
-    "cmd": [
-      "git",
-      "-c",
-      "user.email=commit-bot@chromium.org",
-      "-c",
-      "user.name=The Commit Bot",
-      "commit",
-      "-a",
-      "-m",
-      "Committed patch"
-    ],
-    "cwd": "[START_DIR]/src",
-    "name": "commit-git-patch"
-  },
-  {
-    "cmd": [
-      "python",
-      "-u",
-      "RECIPE_REPO[depot_tools]/presubmit_support.py",
-      "--issue",
-      "456789",
-      "--patchset",
-      "12",
-      "--gerrit_url",
-      "https://chromium-review.googlesource.com",
-      "--gerrit_fetch",
-      "--root",
-      "[START_DIR]/src",
-      "--commit",
-      "--verbose",
-      "--verbose",
-      "--skip_canned",
-      "CheckTreeIsOpen",
-      "--skip_canned",
-      "CheckBuildbotPendingBuilds",
-      "--upstream",
-      "f27fede2220bcd326aee3e86ddfd4ebd0fe58cb9",
-      "--json_output",
-      "/path/to/tmp/json"
-    ],
-    "env_prefixes": {
-      "PATH": [
-        "RECIPE_REPO[depot_tools]"
-      ]
-    },
-    "name": "presubmit",
-    "timeout": 480,
-    "~followup_annotations": [
-      "@@@STEP_LOG_LINE@json.output@{}@@@",
-      "@@@STEP_LOG_END@json.output@@@",
-      "@@@STEP_FAILURE@@@"
-    ]
-  },
-  {
-    "cmd": [],
-    "name": "TRYJOB FAILURE",
-    "~followup_annotations": [
-      "@@@STEP_TEXT@TEST_FAILURE@@@",
-      "@@@SET_BUILD_PROPERTY@failure_type@\"TEST_FAILURE\"@@@",
-      "@@@STEP_FAILURE@@@"
-    ]
-  },
-  {
-    "failure": {
-      "failure": {},
-      "humanReason": "Step('presubmit') (retcode: 1)"
-    },
-    "name": "$result"
-  }
-]
\ No newline at end of file
diff --git a/scripts/slave/recipes/run_presubmit.expected/presubmit-infra-failure.json b/scripts/slave/recipes/run_presubmit.expected/presubmit-infra-failure.json
deleted file mode 100644
index a12adc8..0000000
--- a/scripts/slave/recipes/run_presubmit.expected/presubmit-infra-failure.json
+++ /dev/null
@@ -1,277 +0,0 @@
-[
-  {
-    "cmd": [
-      "python",
-      "-u",
-      "RECIPE_REPO[depot_tools]/gerrit_client.py",
-      "changes",
-      "--host",
-      "https://chromium-review.googlesource.com",
-      "--json_file",
-      "/path/to/tmp/json",
-      "--limit",
-      "1",
-      "-p",
-      "change=456789",
-      "-o",
-      "ALL_REVISIONS",
-      "-o",
-      "DOWNLOAD_COMMANDS"
-    ],
-    "env": {
-      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
-    },
-    "infra_step": true,
-    "name": "gerrit fetch current CL info",
-    "timeout": 600,
-    "~followup_annotations": [
-      "@@@STEP_LOG_LINE@json.output@[@@@",
-      "@@@STEP_LOG_LINE@json.output@  {@@@",
-      "@@@STEP_LOG_LINE@json.output@    \"branch\": \"master\", @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"revisions\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@      \"184ebe53805e102605d11f6b143486d15c23a09c\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@        \"_number\": \"12\", @@@",
-      "@@@STEP_LOG_LINE@json.output@        \"ref\": \"refs/changes/89/456789/12\"@@@",
-      "@@@STEP_LOG_LINE@json.output@      }@@@",
-      "@@@STEP_LOG_LINE@json.output@    }@@@",
-      "@@@STEP_LOG_LINE@json.output@  }@@@",
-      "@@@STEP_LOG_LINE@json.output@]@@@",
-      "@@@STEP_LOG_END@json.output@@@"
-    ]
-  },
-  {
-    "cmd": [
-      "python",
-      "-u",
-      "RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
-      "--spec-path",
-      "cache_dir = '[CACHE]/git'\nsolutions = [{'custom_vars': {'checkout_telemetry_dependencies': 'True'}, 'deps_file': '.DEPS.git', 'managed': True, 'name': 'src', 'url': 'https://chromium.googlesource.com/chromium/src.git'}]",
-      "--patch_root",
-      "src",
-      "--revision_mapping_file",
-      "{\"got_angle_revision\": \"src/third_party/angle\", \"got_buildtools_revision\": \"src/buildtools\", \"got_dawn_revision\": \"src/third_party/dawn\", \"got_nacl_revision\": \"src/native_client\", \"got_revision\": \"src\", \"got_swarming_client_revision\": \"src/tools/swarming_client\", \"got_v8_revision\": \"src/v8\", \"got_webrtc_revision\": \"src/third_party/webrtc\"}",
-      "--git-cache-dir",
-      "[CACHE]/git",
-      "--cleanup-dir",
-      "[CLEANUP]/bot_update",
-      "--output_json",
-      "/path/to/tmp/json",
-      "--patch_ref",
-      "https://chromium.googlesource.com/chromium/src@refs/heads/master:refs/changes/89/456789/12",
-      "--revision",
-      "src@HEAD"
-    ],
-    "env_prefixes": {
-      "PATH": [
-        "RECIPE_REPO[depot_tools]"
-      ]
-    },
-    "infra_step": true,
-    "name": "bot_update",
-    "~followup_annotations": [
-      "@@@STEP_TEXT@Some step text@@@",
-      "@@@STEP_LOG_LINE@json.output@{@@@",
-      "@@@STEP_LOG_LINE@json.output@  \"did_run\": true, @@@",
-      "@@@STEP_LOG_LINE@json.output@  \"fixed_revisions\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@    \"src\": \"HEAD\"@@@",
-      "@@@STEP_LOG_LINE@json.output@  }, @@@",
-      "@@@STEP_LOG_LINE@json.output@  \"manifest\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@    \"src\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@      \"repository\": \"https://fake.org/src.git\", @@@",
-      "@@@STEP_LOG_LINE@json.output@      \"revision\": \"f27fede2220bcd326aee3e86ddfd4ebd0fe58cb9\"@@@",
-      "@@@STEP_LOG_LINE@json.output@    }, @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"src/buildtools\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@      \"repository\": \"https://fake.org/src/buildtools.git\", @@@",
-      "@@@STEP_LOG_LINE@json.output@      \"revision\": \"f0319a328b2809876916353cb994259692140934\"@@@",
-      "@@@STEP_LOG_LINE@json.output@    }, @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"src/native_client\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@      \"repository\": \"https://fake.org/src/native_client.git\", @@@",
-      "@@@STEP_LOG_LINE@json.output@      \"revision\": \"d998e125e8253980d76e269b7982aeeefc1b9b50\"@@@",
-      "@@@STEP_LOG_LINE@json.output@    }, @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"src/third_party/angle\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@      \"repository\": \"https://fake.org/src/third_party/angle.git\", @@@",
-      "@@@STEP_LOG_LINE@json.output@      \"revision\": \"fac9503c46405f77757b9a728eb85b8d7bc6080c\"@@@",
-      "@@@STEP_LOG_LINE@json.output@    }, @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"src/third_party/dawn\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@      \"repository\": \"https://fake.org/src/third_party/dawn.git\", @@@",
-      "@@@STEP_LOG_LINE@json.output@      \"revision\": \"1b5c932bc9a9a35c66edea3914fb675742d57cc2\"@@@",
-      "@@@STEP_LOG_LINE@json.output@    }, @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"src/third_party/webrtc\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@      \"repository\": \"https://fake.org/src/third_party/webrtc.git\", @@@",
-      "@@@STEP_LOG_LINE@json.output@      \"revision\": \"0f90628433546e61d9268596da93418c623137f4\"@@@",
-      "@@@STEP_LOG_LINE@json.output@    }, @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"src/tools/swarming_client\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@      \"repository\": \"https://fake.org/src/tools/swarming_client.git\", @@@",
-      "@@@STEP_LOG_LINE@json.output@      \"revision\": \"a0ee5d99f1d4b38ddaa4c759c837980b63b99566\"@@@",
-      "@@@STEP_LOG_LINE@json.output@    }, @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"src/v8\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@      \"repository\": \"https://fake.org/src/v8.git\", @@@",
-      "@@@STEP_LOG_LINE@json.output@      \"revision\": \"801ada225ddc271c132c3a35f03975671d43e399\"@@@",
-      "@@@STEP_LOG_LINE@json.output@    }@@@",
-      "@@@STEP_LOG_LINE@json.output@  }, @@@",
-      "@@@STEP_LOG_LINE@json.output@  \"patch_failure\": false, @@@",
-      "@@@STEP_LOG_LINE@json.output@  \"patch_root\": \"src\", @@@",
-      "@@@STEP_LOG_LINE@json.output@  \"properties\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@    \"got_angle_revision\": \"fac9503c46405f77757b9a728eb85b8d7bc6080c\", @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"got_angle_revision_cp\": \"refs/heads/master@{#297276}\", @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"got_buildtools_revision\": \"f0319a328b2809876916353cb994259692140934\", @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"got_buildtools_revision_cp\": \"refs/heads/master@{#182578}\", @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"got_dawn_revision\": \"1b5c932bc9a9a35c66edea3914fb675742d57cc2\", @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"got_dawn_revision_cp\": \"refs/heads/master@{#51819}\", @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"got_nacl_revision\": \"d998e125e8253980d76e269b7982aeeefc1b9b50\", @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"got_nacl_revision_cp\": \"refs/heads/master@{#274981}\", @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"got_revision\": \"f27fede2220bcd326aee3e86ddfd4ebd0fe58cb9\", @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"got_revision_cp\": \"refs/heads/master@{#170242}\", @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"got_swarming_client_revision\": \"a0ee5d99f1d4b38ddaa4c759c837980b63b99566\", @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"got_swarming_client_revision_cp\": \"refs/heads/master@{#276089}\", @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"got_v8_revision\": \"801ada225ddc271c132c3a35f03975671d43e399\", @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"got_v8_revision_cp\": \"refs/heads/master@{#43426}\", @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"got_webrtc_revision\": \"0f90628433546e61d9268596da93418c623137f4\", @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"got_webrtc_revision_cp\": \"refs/heads/master@{#120644}\"@@@",
-      "@@@STEP_LOG_LINE@json.output@  }, @@@",
-      "@@@STEP_LOG_LINE@json.output@  \"root\": \"src\", @@@",
-      "@@@STEP_LOG_LINE@json.output@  \"source_manifest\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@    \"directories\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@      \"src\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@        \"git_checkout\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@          \"repo_url\": \"https://fake.org/src.git\", @@@",
-      "@@@STEP_LOG_LINE@json.output@          \"revision\": \"f27fede2220bcd326aee3e86ddfd4ebd0fe58cb9\"@@@",
-      "@@@STEP_LOG_LINE@json.output@        }@@@",
-      "@@@STEP_LOG_LINE@json.output@      }, @@@",
-      "@@@STEP_LOG_LINE@json.output@      \"src/buildtools\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@        \"git_checkout\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@          \"repo_url\": \"https://fake.org/src/buildtools.git\", @@@",
-      "@@@STEP_LOG_LINE@json.output@          \"revision\": \"f0319a328b2809876916353cb994259692140934\"@@@",
-      "@@@STEP_LOG_LINE@json.output@        }@@@",
-      "@@@STEP_LOG_LINE@json.output@      }, @@@",
-      "@@@STEP_LOG_LINE@json.output@      \"src/native_client\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@        \"git_checkout\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@          \"repo_url\": \"https://fake.org/src/native_client.git\", @@@",
-      "@@@STEP_LOG_LINE@json.output@          \"revision\": \"d998e125e8253980d76e269b7982aeeefc1b9b50\"@@@",
-      "@@@STEP_LOG_LINE@json.output@        }@@@",
-      "@@@STEP_LOG_LINE@json.output@      }, @@@",
-      "@@@STEP_LOG_LINE@json.output@      \"src/third_party/angle\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@        \"git_checkout\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@          \"repo_url\": \"https://fake.org/src/third_party/angle.git\", @@@",
-      "@@@STEP_LOG_LINE@json.output@          \"revision\": \"fac9503c46405f77757b9a728eb85b8d7bc6080c\"@@@",
-      "@@@STEP_LOG_LINE@json.output@        }@@@",
-      "@@@STEP_LOG_LINE@json.output@      }, @@@",
-      "@@@STEP_LOG_LINE@json.output@      \"src/third_party/dawn\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@        \"git_checkout\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@          \"repo_url\": \"https://fake.org/src/third_party/dawn.git\", @@@",
-      "@@@STEP_LOG_LINE@json.output@          \"revision\": \"1b5c932bc9a9a35c66edea3914fb675742d57cc2\"@@@",
-      "@@@STEP_LOG_LINE@json.output@        }@@@",
-      "@@@STEP_LOG_LINE@json.output@      }, @@@",
-      "@@@STEP_LOG_LINE@json.output@      \"src/third_party/webrtc\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@        \"git_checkout\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@          \"repo_url\": \"https://fake.org/src/third_party/webrtc.git\", @@@",
-      "@@@STEP_LOG_LINE@json.output@          \"revision\": \"0f90628433546e61d9268596da93418c623137f4\"@@@",
-      "@@@STEP_LOG_LINE@json.output@        }@@@",
-      "@@@STEP_LOG_LINE@json.output@      }, @@@",
-      "@@@STEP_LOG_LINE@json.output@      \"src/tools/swarming_client\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@        \"git_checkout\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@          \"repo_url\": \"https://fake.org/src/tools/swarming_client.git\", @@@",
-      "@@@STEP_LOG_LINE@json.output@          \"revision\": \"a0ee5d99f1d4b38ddaa4c759c837980b63b99566\"@@@",
-      "@@@STEP_LOG_LINE@json.output@        }@@@",
-      "@@@STEP_LOG_LINE@json.output@      }, @@@",
-      "@@@STEP_LOG_LINE@json.output@      \"src/v8\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@        \"git_checkout\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@          \"repo_url\": \"https://fake.org/src/v8.git\", @@@",
-      "@@@STEP_LOG_LINE@json.output@          \"revision\": \"801ada225ddc271c132c3a35f03975671d43e399\"@@@",
-      "@@@STEP_LOG_LINE@json.output@        }@@@",
-      "@@@STEP_LOG_LINE@json.output@      }@@@",
-      "@@@STEP_LOG_LINE@json.output@    }, @@@",
-      "@@@STEP_LOG_LINE@json.output@    \"version\": 0@@@",
-      "@@@STEP_LOG_LINE@json.output@  }, @@@",
-      "@@@STEP_LOG_LINE@json.output@  \"step_text\": \"Some step text\"@@@",
-      "@@@STEP_LOG_LINE@json.output@}@@@",
-      "@@@STEP_LOG_END@json.output@@@",
-      "@@@SET_BUILD_PROPERTY@got_angle_revision@\"fac9503c46405f77757b9a728eb85b8d7bc6080c\"@@@",
-      "@@@SET_BUILD_PROPERTY@got_angle_revision_cp@\"refs/heads/master@{#297276}\"@@@",
-      "@@@SET_BUILD_PROPERTY@got_buildtools_revision@\"f0319a328b2809876916353cb994259692140934\"@@@",
-      "@@@SET_BUILD_PROPERTY@got_buildtools_revision_cp@\"refs/heads/master@{#182578}\"@@@",
-      "@@@SET_BUILD_PROPERTY@got_dawn_revision@\"1b5c932bc9a9a35c66edea3914fb675742d57cc2\"@@@",
-      "@@@SET_BUILD_PROPERTY@got_dawn_revision_cp@\"refs/heads/master@{#51819}\"@@@",
-      "@@@SET_BUILD_PROPERTY@got_nacl_revision@\"d998e125e8253980d76e269b7982aeeefc1b9b50\"@@@",
-      "@@@SET_BUILD_PROPERTY@got_nacl_revision_cp@\"refs/heads/master@{#274981}\"@@@",
-      "@@@SET_BUILD_PROPERTY@got_revision@\"f27fede2220bcd326aee3e86ddfd4ebd0fe58cb9\"@@@",
-      "@@@SET_BUILD_PROPERTY@got_revision_cp@\"refs/heads/master@{#170242}\"@@@",
-      "@@@SET_BUILD_PROPERTY@got_swarming_client_revision@\"a0ee5d99f1d4b38ddaa4c759c837980b63b99566\"@@@",
-      "@@@SET_BUILD_PROPERTY@got_swarming_client_revision_cp@\"refs/heads/master@{#276089}\"@@@",
-      "@@@SET_BUILD_PROPERTY@got_v8_revision@\"801ada225ddc271c132c3a35f03975671d43e399\"@@@",
-      "@@@SET_BUILD_PROPERTY@got_v8_revision_cp@\"refs/heads/master@{#43426}\"@@@",
-      "@@@SET_BUILD_PROPERTY@got_webrtc_revision@\"0f90628433546e61d9268596da93418c623137f4\"@@@",
-      "@@@SET_BUILD_PROPERTY@got_webrtc_revision_cp@\"refs/heads/master@{#120644}\"@@@"
-    ]
-  },
-  {
-    "cmd": [
-      "git",
-      "-c",
-      "user.email=commit-bot@chromium.org",
-      "-c",
-      "user.name=The Commit Bot",
-      "commit",
-      "-a",
-      "-m",
-      "Committed patch"
-    ],
-    "cwd": "[START_DIR]/src",
-    "name": "commit-git-patch"
-  },
-  {
-    "cmd": [
-      "python",
-      "-u",
-      "RECIPE_REPO[depot_tools]/presubmit_support.py",
-      "--issue",
-      "456789",
-      "--patchset",
-      "12",
-      "--gerrit_url",
-      "https://chromium-review.googlesource.com",
-      "--gerrit_fetch",
-      "--root",
-      "[START_DIR]/src",
-      "--commit",
-      "--verbose",
-      "--verbose",
-      "--skip_canned",
-      "CheckTreeIsOpen",
-      "--skip_canned",
-      "CheckBuildbotPendingBuilds",
-      "--upstream",
-      "f27fede2220bcd326aee3e86ddfd4ebd0fe58cb9",
-      "--json_output",
-      "/path/to/tmp/json"
-    ],
-    "env_prefixes": {
-      "PATH": [
-        "RECIPE_REPO[depot_tools]"
-      ]
-    },
-    "name": "presubmit",
-    "timeout": 480,
-    "~followup_annotations": [
-      "@@@STEP_LOG_LINE@json.output@{}@@@",
-      "@@@STEP_LOG_END@json.output@@@",
-      "@@@STEP_FAILURE@@@"
-    ]
-  },
-  {
-    "cmd": [],
-    "name": "TRYJOB FAILURE",
-    "~followup_annotations": [
-      "@@@STEP_TEXT@INVALID_TEST_RESULTS@@@",
-      "@@@SET_BUILD_PROPERTY@failure_type@\"INVALID_TEST_RESULTS\"@@@",
-      "@@@STEP_FAILURE@@@"
-    ]
-  },
-  {
-    "failure": {
-      "failure": {},
-      "humanReason": "Step('presubmit') (retcode: 2)"
-    },
-    "name": "$result"
-  }
-]
\ No newline at end of file
diff --git a/scripts/slave/recipes/run_presubmit.expected/recipes-py-windows.json b/scripts/slave/recipes/run_presubmit.expected/recipes-py-windows.json
index 696c842..9b05c56 100644
--- a/scripts/slave/recipes/run_presubmit.expected/recipes-py-windows.json
+++ b/scripts/slave/recipes/run_presubmit.expected/recipes-py-windows.json
@@ -173,7 +173,11 @@
     "name": "presubmit",
     "timeout": 480,
     "~followup_annotations": [
-      "@@@STEP_LOG_LINE@json.output@{}@@@",
+      "@@@STEP_LOG_LINE@json.output@{@@@",
+      "@@@STEP_LOG_LINE@json.output@  \"errors\": [], @@@",
+      "@@@STEP_LOG_LINE@json.output@  \"notifications\": [], @@@",
+      "@@@STEP_LOG_LINE@json.output@  \"warnings\": []@@@",
+      "@@@STEP_LOG_LINE@json.output@}@@@",
       "@@@STEP_LOG_END@json.output@@@"
     ]
   },
diff --git a/scripts/slave/recipes/run_presubmit.expected/recipes-py.json b/scripts/slave/recipes/run_presubmit.expected/recipes-py.json
index 27feba39..a5ead0e 100644
--- a/scripts/slave/recipes/run_presubmit.expected/recipes-py.json
+++ b/scripts/slave/recipes/run_presubmit.expected/recipes-py.json
@@ -173,7 +173,11 @@
     "name": "presubmit",
     "timeout": 480,
     "~followup_annotations": [
-      "@@@STEP_LOG_LINE@json.output@{}@@@",
+      "@@@STEP_LOG_LINE@json.output@{@@@",
+      "@@@STEP_LOG_LINE@json.output@  \"errors\": [], @@@",
+      "@@@STEP_LOG_LINE@json.output@  \"notifications\": [], @@@",
+      "@@@STEP_LOG_LINE@json.output@  \"warnings\": []@@@",
+      "@@@STEP_LOG_LINE@json.output@}@@@",
       "@@@STEP_LOG_END@json.output@@@"
     ]
   },
diff --git a/scripts/slave/recipes/run_presubmit.expected/repository_url_with_solution_name.json b/scripts/slave/recipes/run_presubmit.expected/repository_url_with_solution_name.json
index cebbb65..dc8a2bb 100644
--- a/scripts/slave/recipes/run_presubmit.expected/repository_url_with_solution_name.json
+++ b/scripts/slave/recipes/run_presubmit.expected/repository_url_with_solution_name.json
@@ -155,7 +155,11 @@
     "name": "presubmit",
     "timeout": 480,
     "~followup_annotations": [
-      "@@@STEP_LOG_LINE@json.output@{}@@@",
+      "@@@STEP_LOG_LINE@json.output@{@@@",
+      "@@@STEP_LOG_LINE@json.output@  \"errors\": [], @@@",
+      "@@@STEP_LOG_LINE@json.output@  \"notifications\": [], @@@",
+      "@@@STEP_LOG_LINE@json.output@  \"warnings\": []@@@",
+      "@@@STEP_LOG_LINE@json.output@}@@@",
       "@@@STEP_LOG_END@json.output@@@"
     ]
   },
diff --git a/scripts/slave/recipes/run_presubmit.expected/skia.json b/scripts/slave/recipes/run_presubmit.expected/skia.json
index cebbb65..dc8a2bb 100644
--- a/scripts/slave/recipes/run_presubmit.expected/skia.json
+++ b/scripts/slave/recipes/run_presubmit.expected/skia.json
@@ -155,7 +155,11 @@
     "name": "presubmit",
     "timeout": 480,
     "~followup_annotations": [
-      "@@@STEP_LOG_LINE@json.output@{}@@@",
+      "@@@STEP_LOG_LINE@json.output@{@@@",
+      "@@@STEP_LOG_LINE@json.output@  \"errors\": [], @@@",
+      "@@@STEP_LOG_LINE@json.output@  \"notifications\": [], @@@",
+      "@@@STEP_LOG_LINE@json.output@  \"warnings\": []@@@",
+      "@@@STEP_LOG_LINE@json.output@}@@@",
       "@@@STEP_LOG_END@json.output@@@"
     ]
   },
diff --git a/scripts/slave/recipes/run_presubmit.expected/slave_deps.json b/scripts/slave/recipes/run_presubmit.expected/slave_deps.json
index 9a42cbb..9bada15 100644
--- a/scripts/slave/recipes/run_presubmit.expected/slave_deps.json
+++ b/scripts/slave/recipes/run_presubmit.expected/slave_deps.json
@@ -155,7 +155,11 @@
     "name": "presubmit",
     "timeout": 480,
     "~followup_annotations": [
-      "@@@STEP_LOG_LINE@json.output@{}@@@",
+      "@@@STEP_LOG_LINE@json.output@{@@@",
+      "@@@STEP_LOG_LINE@json.output@  \"errors\": [], @@@",
+      "@@@STEP_LOG_LINE@json.output@  \"notifications\": [], @@@",
+      "@@@STEP_LOG_LINE@json.output@  \"warnings\": []@@@",
+      "@@@STEP_LOG_LINE@json.output@}@@@",
       "@@@STEP_LOG_END@json.output@@@"
     ]
   },
diff --git a/scripts/slave/recipes/run_presubmit.expected/v8.json b/scripts/slave/recipes/run_presubmit.expected/v8.json
index a91f309..36eb64d 100644
--- a/scripts/slave/recipes/run_presubmit.expected/v8.json
+++ b/scripts/slave/recipes/run_presubmit.expected/v8.json
@@ -155,7 +155,11 @@
     "name": "presubmit",
     "timeout": 480,
     "~followup_annotations": [
-      "@@@STEP_LOG_LINE@json.output@{}@@@",
+      "@@@STEP_LOG_LINE@json.output@{@@@",
+      "@@@STEP_LOG_LINE@json.output@  \"errors\": [], @@@",
+      "@@@STEP_LOG_LINE@json.output@  \"notifications\": [], @@@",
+      "@@@STEP_LOG_LINE@json.output@  \"warnings\": []@@@",
+      "@@@STEP_LOG_LINE@json.output@}@@@",
       "@@@STEP_LOG_END@json.output@@@"
     ]
   },
diff --git a/scripts/slave/recipes/run_presubmit.expected/webports.json b/scripts/slave/recipes/run_presubmit.expected/webports.json
index dae54ea..7d98d2b 100644
--- a/scripts/slave/recipes/run_presubmit.expected/webports.json
+++ b/scripts/slave/recipes/run_presubmit.expected/webports.json
@@ -155,7 +155,11 @@
     "name": "presubmit",
     "timeout": 480,
     "~followup_annotations": [
-      "@@@STEP_LOG_LINE@json.output@{}@@@",
+      "@@@STEP_LOG_LINE@json.output@{@@@",
+      "@@@STEP_LOG_LINE@json.output@  \"errors\": [], @@@",
+      "@@@STEP_LOG_LINE@json.output@  \"notifications\": [], @@@",
+      "@@@STEP_LOG_LINE@json.output@  \"warnings\": []@@@",
+      "@@@STEP_LOG_LINE@json.output@}@@@",
       "@@@STEP_LOG_END@json.output@@@"
     ]
   },
diff --git a/scripts/slave/recipes/run_presubmit.expected/webrtc.json b/scripts/slave/recipes/run_presubmit.expected/webrtc.json
index 3347fb0..c249c6b 100644
--- a/scripts/slave/recipes/run_presubmit.expected/webrtc.json
+++ b/scripts/slave/recipes/run_presubmit.expected/webrtc.json
@@ -155,7 +155,11 @@
     "name": "presubmit",
     "timeout": 480,
     "~followup_annotations": [
-      "@@@STEP_LOG_LINE@json.output@{}@@@",
+      "@@@STEP_LOG_LINE@json.output@{@@@",
+      "@@@STEP_LOG_LINE@json.output@  \"errors\": [], @@@",
+      "@@@STEP_LOG_LINE@json.output@  \"notifications\": [], @@@",
+      "@@@STEP_LOG_LINE@json.output@  \"warnings\": []@@@",
+      "@@@STEP_LOG_LINE@json.output@}@@@",
       "@@@STEP_LOG_END@json.output@@@"
     ]
   },
diff --git a/scripts/slave/recipes/run_presubmit.py b/scripts/slave/recipes/run_presubmit.py
index b09bdd6..2adfbc2 100644
--- a/scripts/slave/recipes/run_presubmit.py
+++ b/scripts/slave/recipes/run_presubmit.py
@@ -2,6 +2,12 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+from PB.recipe_engine import result as result_pb2
+from PB.go.chromium.org.luci.buildbucket.proto import common as common_pb2
+
+from recipe_engine import post_process
+import textwrap
+
 DEPS = [
   'depot_tools/bot_update',
   'depot_tools/gclient',
@@ -25,6 +31,87 @@
   'webrtc',
 ]
 
+def _limitSize(message_list, char_limit=450):
+  """Returns a list of strings within a certain character length.
+
+  Args:
+     * message_list (List[str]) - The message to truncate as a list
+       of lines (without line endings).
+  """
+  hint = ('The complete output can be'
+          ' found at the bottom of the presubmit stdout.')
+  char_count = 0
+  for index, message in enumerate(message_list):
+    char_count += len(message)
+    if char_count > char_limit:
+      total_errors = len(message_list)
+      oversized_msg = '... %d more error(s) (%d total)' % (
+        total_errors - index, total_errors
+      )
+      return message_list[:index] + [oversized_msg, hint]
+  return message_list
+
+
+def _createSummaryMarkdown(step_json):
+  """Returns a string with data on errors, warnings, and notifications.
+
+  Extracts the number of errors, warnings and notifications
+  from the dictionary(step_json).
+
+  Then it lists all the errors line by line.
+
+  Args:
+      * step_json = {
+        'errors': [
+          {
+            'message': string,
+            'long_text': string,
+            'items: [string],
+            'fatal': boolean
+          }
+        ],
+        'notifications': [
+          {
+            'message': string,
+            'long_text': string,
+            'items: [string],
+            'fatal': boolean
+          }
+        ],
+        'warnings': [
+          {
+            'message': string,
+            'long_text': string,
+            'items: [string],
+            'fatal': boolean
+          }
+        ]
+      }
+  """
+  errors = step_json['errors']
+  warning_count = len(step_json['warnings'])
+  notif_count = len(step_json['notifications'])
+  description = (
+    'There are %d error(s), %d warning(s),'
+    ' and %d notifications(s). Here are the errors:') % (
+      len(errors), warning_count, notif_count
+  )
+  error_messages = []
+
+  for error in errors:
+    error_message = '** ERROR **\n%s\n%s' % (
+      error['message'], error['long_text'])
+    error_messages.append(error_message)
+
+  error_messages = _limitSize(error_messages)
+  error_messages.insert(0, description)
+  if warning_count or notif_count:
+    error_messages.append(
+      ('To see notifications and warnings,'
+      ' look at the stdout of the presubmit step.')
+    )
+  return '\n\n'.join(error_messages)
+
 
 def _RunStepsInternal(api):
   repo_name = api.properties.get('repo_name')
@@ -98,29 +185,48 @@
   if repo_name == 'luci_py':
     venv = abs_root.join('.vpython')
 
-  try:
-    with api.context(env=env):
-      # 8 minutes seems like a reasonable upper bound on presubmit timings.
-      # According to event mon data we have, it seems like anything longer than
-      # this is a bug, and should just instant fail.
-      #
-      # https://crbug.com/917479 This is a problem on luci-py, bump to 15
-      # minutes.
-      timeout = 900 if repo_name == 'luci_py' else 480
-      api.presubmit(*presubmit_args, venv=venv, timeout=timeout)
-  except api.step.StepFailure:
-    step_data = api.step.active_result
-    if step_data.exc_result.had_timeout:
+  raw_result = result_pb2.RawResult()
+  with api.context(env=env):
+    # 8 minutes seems like a reasonable upper bound on presubmit timings.
+    # According to event mon data we have, it seems like anything longer than
+    # this is a bug, and should just instant fail.
+    #
+    # https://crbug.com/917479 This is a problem on luci-py, bump to 15
+    # minutes.
+    timeout = 900 if repo_name == 'luci_py' else 480
+    # ok_ret='any' causes all exceptions to be ignored in this step
+    step_json = api.presubmit(*presubmit_args,
+      venv=venv, timeout=timeout, ok_ret='any')
+    # Set recipe result values
+    if step_json:
+      raw_result.summary_markdown = _createSummaryMarkdown(step_json)
+
+    retcode = api.step.active_result.retcode
+    if retcode == 0:
+      raw_result.status = common_pb2.SUCCESS
+      return raw_result
+
+    api.step.active_result.presentation.status = 'FAILURE'
+    if api.step.active_result.exc_result.had_timeout:
       # TODO(iannucci): Shouldn't we also mark failure on timeouts?
-      raise
-    if step_data.exc_result.retcode == 1:
+      raw_result.summary_markdown += '\nTimeout occurred during presubmit step.'
+    if retcode == 1:
+      raw_result.status = common_pb2.FAILURE
       api.tryserver.set_test_failure_tryjob_result()
     else:
-      # Script presubmit_support.py returns 2 on infra failures, but if we get
-      # something else or nothing at all, then it's also an infra failure.
+      raw_result.status = common_pb2.INFRA_FAILURE
       api.tryserver.set_invalid_test_results_tryjob_result()
-    raise
-
+    # Handle unexpected errors not caught by json output
+    if raw_result.summary_markdown == '':
+      raw_result.status = common_pb2.INFRA_FAILURE
+      raw_result.summary_markdown = (
+        'Something unexpected occurred'
+        ' while running presubmit checks.'
+        ' Please [file a bug](https://bugs.chromium.org'
+        '/p/chromium/issues/entry?components='
+        'Infra%3EClient%3EChrome&status=Untriaged)'
+      )
+  return raw_result
 
 def RunSteps(api):
   try:
@@ -184,7 +290,9 @@
           buildername='%s_presubmit' % repo_name,
           repo_name=repo_name,
           gerrit_project=repo_name) +
-      api.step_data('presubmit', api.json.output({}))
+      api.step_data('presubmit', api.json.output(
+        {'errors': [], 'notifications': [], 'warnings': []}
+      ))
     )
 
   yield (
@@ -194,7 +302,15 @@
         buildername='chromium_presubmit',
         repo_name='chromium',
         gerrit_project='chromium/src') +
-    api.step_data('presubmit', api.json.output({}), times_out_after=60*20)
+    api.step_data('presubmit', api.json.output(
+      {'errors': [], 'notifications': [], 'warnings': []}),
+      times_out_after=60*20) +
+    api.post_process(post_process.StatusFailure) +
+    api.post_process(post_process.ResultReason,
+     ('There are 0 error(s), 0 warning(s), and 0 notifications(s).'
+      ' Here are the errors:'
+      '\nTimeout occurred during presubmit step.')) +
+    api.post_process(post_process.DropExpectation)
   )
 
   yield (
@@ -206,7 +322,9 @@
         repo_name='chromium',
         gerrit_project='chromium/src',
         dry_run=True) +
-    api.step_data('presubmit', api.json.output({}))
+    api.step_data('presubmit', api.json.output(
+      {'errors': [], 'notifications': [], 'warnings': []}
+    ))
   )
 
   yield (
@@ -217,7 +335,9 @@
         repo_name='infra',
         gerrit_project='infra/infra',
         runhooks=True) +
-    api.step_data('presubmit', api.json.output({}))
+    api.step_data('presubmit', api.json.output(
+      {'errors': [], 'notifications': [], 'warnings': []}
+    ))
   )
 
   yield (
@@ -228,7 +348,9 @@
         repo_name='recipes_py',
         gerrit_project='infra/luci/recipes-py',
         runhooks=True) +
-    api.step_data('presubmit', api.json.output({}))
+    api.step_data('presubmit', api.json.output(
+      {'errors': [], 'notifications': [], 'warnings': []}
+    ))
   )
 
   yield (
@@ -240,7 +362,9 @@
         gerrit_project='infra/luci/recipes-py',
         runhooks=True) +
     api.platform('win', 64) +
-    api.step_data('presubmit', api.json.output({}))
+    api.step_data('presubmit', api.json.output(
+      {'errors': [], 'notifications': [], 'warnings': []}
+    ))
   )
 
   yield (
@@ -250,7 +374,9 @@
         buildername='Luci-py Presubmit',
         repo_name='luci_py',
         gerrit_project='infra/luci/luci-py') +
-    api.step_data('presubmit', api.json.output({}))
+    api.step_data('presubmit', api.json.output(
+      {'errors': [], 'notifications': [], 'warnings': []}
+    ))
   )
 
   yield (
@@ -260,7 +386,90 @@
         buildername='chromium_presubmit',
         repo_name='chromium',
         gerrit_project='chromium/src') +
-    api.step_data('presubmit', api.json.output({}, retcode=1))
+    api.step_data('presubmit', api.json.output(
+        {
+          'errors': [
+            {
+              'message': 'Missing LGTM',
+              'long_text': 'Here are some suggested OWNERS: fake@',
+              'items': [],
+              'fatal': True
+            },
+            {
+              'message': 'Syntax error in fake.py',
+              'long_text': 'Expected "," after item in list',
+              'items': [],
+              'fatal': True
+            }
+          ],
+          'notifications': [
+            {
+              'message': 'If there is a bug associated please add it.',
+              'long_text': '',
+              'items': [],
+              'fatal': False
+            }
+          ],
+          'warnings': [
+            {
+              'message': 'Line 100 has more than 81 characters',
+              'long_text': '',
+              'items': [],
+              'fatal': False
+            }
+          ]
+        }, retcode=1)
+    ) +
+    api.post_process(post_process.StatusFailure) +
+    api.post_process(post_process.ResultReason, textwrap.dedent('''
+        There are 2 error(s), 1 warning(s), and 1 notifications(s). Here are the errors:
+
+        ** ERROR **
+        Missing LGTM
+        Here are some suggested OWNERS: fake@
+
+        ** ERROR **
+        Syntax error in fake.py
+        Expected "," after item in list
+
+        To see notifications and warnings, look at the stdout of the presubmit step.
+      ''').strip()
+    ) +
+    api.post_process(post_process.DropExpectation)
+  )
+
+  long_message = 'Here are some suggested OWNERS:' + '\nfake@' * 100
+  yield (
+    api.test('presubmit-failure-long-message') +
+    api.properties.tryserver(
+        mastername='tryserver.chromium.linux',
+        buildername='chromium_presubmit',
+        repo_name='chromium',
+        gerrit_project='chromium/src') +
+    api.step_data('presubmit', api.json.output(
+        {
+          'errors': [
+            {
+              'message': 'Missing LGTM',
+              'long_text': long_message,
+              'items': [],
+              'fatal': True
+            }
+          ],
+          'notifications': [],
+          'warnings': []
+        }, retcode=1)
+    ) +
+    api.post_process(post_process.StatusFailure) +
+    api.post_process(post_process.ResultReason, textwrap.dedent('''
+        There are 1 error(s), 0 warning(s), and 0 notifications(s). Here are the errors:
+
+        ... 1 more error(s) (1 total)
+
+        The complete output can be found at the bottom of the presubmit stdout.
+      ''').strip()
+    ) +
+    api.post_process(post_process.DropExpectation)
   )
 
   yield (
@@ -270,7 +479,62 @@
         buildername='chromium_presubmit',
         repo_name='chromium',
         gerrit_project='chromium/src') +
-    api.step_data('presubmit', api.json.output({}, retcode=2))
+    api.step_data('presubmit', api.json.output(
+        {
+          'errors': [
+            {
+              'message': 'Infra Failure',
+              'long_text': '',
+              'items': [],
+              'fatal': True
+            }
+          ],
+          'notifications': [],
+          'warnings': []
+        }, retcode=2)
+    ) +
+    api.post_process(post_process.StatusFailure) +
+    api.post_process(post_process.ResultReason, textwrap.dedent('''
+        There are 1 error(s), 0 warning(s), and 0 notifications(s). Here are the errors:
+
+        ** ERROR **
+        Infra Failure
+      ''').lstrip()
+    ) +
+    api.post_process(post_process.DropExpectation)
+  )
+
+  bug_msg = (
+    'Something unexpected occurred'
+    ' while running presubmit checks.'
+    ' Please [file a bug](https://bugs.chromium.org'
+    '/p/chromium/issues/entry?components='
+    'Infra%3EClient%3EChrome&status=Untriaged)'
+  )
+  yield (
+    api.test('presubmit-failure-no-json') +
+    api.properties.tryserver(
+        mastername='tryserver.chromium.linux',
+        buildername='chromium_presubmit',
+        repo_name='chromium',
+        gerrit_project='chromium/src') +
+    api.step_data('presubmit', api.json.output(None, retcode=1)) +
+    api.post_process(post_process.StatusFailure) +
+    api.post_process(post_process.ResultReason, bug_msg) +
+    api.post_process(post_process.DropExpectation)
+  )
+
+  yield (
+    api.test('presubmit-infra-failure-no-json') +
+    api.properties.tryserver(
+        mastername='tryserver.chromium.linux',
+        buildername='chromium_presubmit',
+        repo_name='chromium',
+        gerrit_project='chromium/src') +
+    api.step_data('presubmit', api.json.output(None, retcode=2)) +
+    api.post_process(post_process.StatusFailure) +
+    api.post_process(post_process.ResultReason, bug_msg) +
+    api.post_process(post_process.DropExpectation)
   )
 
   yield (
@@ -281,7 +545,9 @@
         repository_url='https://skia.googlesource.com/skia.git',
         gerrit_project='skia',
         solution_name='skia') +
-    api.step_data('presubmit', api.json.output({}))
+    api.step_data('presubmit', api.json.output(
+      {'errors': [], 'notifications': [], 'warnings': []}
+    ))
   )
 
   yield (