diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index e780e23454bdcd777488459c8b5a6202874eff87..595edd0548184149941aa3e3ec370ca7cc37847f 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -217,20 +217,24 @@ unit test with race:
     CGO_ENABLED: "1"
     TESTFLAGS: "-cover -race"
 
-docs check links:
-  image: "registry.gitlab.com/gitlab-org/gitlab-build-images:gitlab-docs-lint"
-  stage: test
-  cache: {}
-  dependencies: []
-  before_script:
-    - unset GPG_KEY
-  script:
-    - mv docs/ /tmp/gitlab-docs/content/
-    - cd /tmp/gitlab-docs
-    # Build HTML from Markdown
-    - bundle exec nanoc
-    # Check the internal links
-    - bundle exec nanoc check internal_links
+#
+# Temporary disabling. Check https://gitlab.com/gitlab-org/gitlab-runner/merge_requests/1112
+# and https://gitlab.com/gitlab-com/gitlab-docs/issues/307 for context
+#
+#docs check links:
+#  image: "registry.gitlab.com/gitlab-org/gitlab-build-images:gitlab-docs-lint"
+#  stage: test
+#  cache: {}
+#  dependencies: []
+#  before_script:
+#    - unset GPG_KEY
+#  script:
+#    - mv docs/ /tmp/gitlab-docs/content/
+#    - cd /tmp/gitlab-docs
+#    # Build HTML from Markdown
+#    - bundle exec nanoc
+#    # Check the internal links
+#    - bundle exec nanoc check internal_links
 
 integration windows:
   <<: *except_docs
diff --git a/.gitlab/issue_templates/Release Checklist.md b/.gitlab/issue_templates/Release Checklist.md
index 11613219f12d9f9483f124f33e0249bd6505fa10..1b068698060e7731933b099eac2c5b5bd02e1c09 100644
--- a/.gitlab/issue_templates/Release Checklist.md	
+++ b/.gitlab/issue_templates/Release Checklist.md	
@@ -27,6 +27,7 @@ https://gitlab.com/gitlab-org/gitlab-runner/blob/master/docs/release_process/how
       use the eraliest one.
 
 - [ ] Update the `.Major` and `.Minor` to a specific release version
+- [ ] Update the `.HelmChartMajor`, `.HelmChartMinor` and `.HelmChartPatch` to a specific release version
 
 ## First working day after 7th - **v{{.Major}}.{{.Minor}}.0-rc1 release**
 
@@ -72,13 +73,71 @@ https://gitlab.com/gitlab-org/gitlab-runner/blob/master/docs/release_process/how
 - [ ] wait for Pipeline for `v{{.Major}}.{{.Minor}}.0-rc1` to pass [![pipeline status](https://gitlab.com/gitlab-org/gitlab-runner/badges/v{{.Major}}.{{.Minor}}.0-rc1/pipeline.svg)](https://gitlab.com/gitlab-org/gitlab-runner/commits/v{{.Major}}.{{.Minor}}.0-rc1)
     - [ ] add all required fixes to make `v{{.Major}}.{{.Minor}}.0-rc1` passing
 - [ ] deploy **v{{.Major}}.{{.Minor}}.0-rc1** (https://gitlab.com/gitlab-com/runbooks/blob/master/howto/update-gitlab-runner-on-managers.md)
+- [ ] update runner [helm chart](https://gitlab.com/charts/gitlab-runner) to use `v{{.Major}}.{{.Minor}}.0-rc1` version
+    - [ ] check if Pipeline for `master` is passing: [![pipeline status](https://gitlab.com/charts/gitlab-runner/badges/master/pipeline.svg)](https://gitlab.com/charts/gitlab-runner/commits/master)
+        - [ ] add all required fixes to make `master` Pipeline passing
+    - [ ] go to your local working copy of https://gitlab.com/charts/gitlab-runner
+    - [ ] `git checkout master && git pull` in your local working copy!
+    - [ ] set Helm Chart to use `v{{.Major}}.{{.Minor}}.0-rc1` version of Runner
+        - [ ] create new branch, update Runner version and push the branch:
+
+            ```bash
+            git checkout -b update-runner-to-{{.Major}}-{{.Minor}}-0-rc1 && sed "s/^appVersion: .*/appVersion: {{.Major}}.{{.Minor}}.0-rc1/" Chart.yaml && git add Chart.yaml && git commit -m "Bump used Runner version to {{.Major}}.{{.Minor}}.0-rc1" -S && git push
+            ```
+
+        - [ ] create Merge Request pointing `master`: [link to MR here]
+        - [ ] manage to merge the MR
+    - [ ] check if Pipeline for `master` is passing: [![pipeline status](https://gitlab.com/charts/gitlab-runner/badges/master/pipeline.svg)](https://gitlab.com/charts/gitlab-runner/commits/master)
+        - [ ] add all required fixes to make `master` Pipeline passing
+    - [ ] `git checkout master && git pull` in your local working copy!
+    - [ ] prepare CHANGELOG entries
+
+        ```bash
+        ./scripts/prepare-changelog-entries.rb
+        ```
+
+        Copy the lines to the beginning of `CHANGELOG.md` file and add a proper header:
+
+        ```markdown
+        ## v{{.HelmChartMajor}}.{{.HelmChartMinor}}.{{.HelmChartPatch}}-rc1 (TODAY_DATE_HERE)
+        ```
+
+    - [ ] add **v{{.HelmChartMajor}}.{{.HelmChartMinor}}.{{.HelmChartPatch}}-rc1** CHANGELOG entries and commit
+
+        ```bash
+        git add CHANGELOG.md && git commit -m "Update CHANGELOG for v{{.HelmChartMajor}}.{{.HelmChartMinor}}.{{.HelmChartPatch}}-rc1" -S
+        ```
+
+    - [ ] bump version of the Helm Chart to `{{.HelmChartMajor}}.{{.HelmChartMinor}}.{{.HelmChartPatch}}-rc1`
+
+        ```bash
+        sed "s/^version: .*/version: {{.HelmChartMajor}}.{{.HelmChartMinor}}.{{.HelmChartPatch}}-rc1/" Chart.yaml && git add Chart.yaml && git commit -m "Bump version to {{.HelmChartMajor}}.{{.HelmChartMinor}}.{{.HelmChartPatch}}-rc1" -S && git push
+        ```
+
+    - [ ] tag and push **v{{.HelmChartMajor}}.{{.HelmChartMinor}}.{{.HelmChartPatch}}-rc1**:
+
+        ```bash
+        git tag -s v{{.HelmChartMajor}}.{{.HelmChartMinor}}.{{.HelmChartPatch}}-rc1 -m "Version v{{.HelmChartMajor}}.{{.HelmChartMinor}}.{{.HelmChartPatch}}-rc1" && git push origin v{{.HelmChartMajor}}.{{.HelmChartMinor}}.{{.HelmChartPatch}}-rc1
+        ```
+
+    - [ ] create and push `{{.HelmChartMajor}}-{{.HelmChartMinor}}-{{.HelmChartPatch}}-stable` branch:
+
+        ```bash
+        git checkout -b {{.HelmChartMajor}}-{{.HelmChartMinor}}-{{.HelmChartPatch}}-stable && git push -u origin {{.HelmChartMajor}}-{{.HelmChartMinor}}-{{.HelmChartPatch}}-stable
+        ```
+
+    - [ ] checkout to `master`, bump version of the Helm Chart to `{{.HelmChartMajor}}.{{.HelmChartMinor}}.{{inc .HelmChartPatch}}-beta` and push `master`:
+
+        ```bash
+        git checkout master; sed "s/^version: .*/version: {{.HelmChartMajor}}.{{.HelmChartMinor}}.{{inc .HelmChartPatch}}-beta/" Chart.yaml && git add Chart.yaml && git commit -m "Bump version to {{.HelmChartMajor}}.{{.HelmChartMinor}}.{{inc .HelmChartPatch}}-beta" -S && git push
+        ```
 
 _New features_ window is closed - things not merged into `master` up to
 this day, will be released with next release.
 
 ## 7 working days before 22th (**{{.ReleaseBlogPostDeadline}}**)
 
-- [ ] prepare entries for the release blog post. Items can be generated with `./scripts/changelog2releasepost | less`
+- [ ] prepare GitLab Runner entries for the release blog post. Items can be generated with `./scripts/changelog2releasepost | less` (executed in Runner's local working copy directory)
 - [ ] add release entry:
 
     Add description to the `SECONDARY FEATURES` list using following template:
@@ -132,12 +191,58 @@ to the one that already exists.
 - [ ] tag and push **v{{.Major}}.{{.Minor}}.0-rcZ** and **{{.Major}}-{{.Minor}}-stable**:
 
     ```bash
-    git tag -s v{{.Major}}.{{.Minor}}.0-rcZ -m "Version v{{.Major}}.{{.Minor}}.0-rcZ" && git push origin {{.Major}}-{{.Minor}}-stable v{{.Major}}.{{.Minor}}.0-rcZ
+    git tag -s v{{.Major}}.{{.Minor}}.0-rcZ -m "Version v{{.Major}}.{{.Minor}}.0-rcZ" && git push origin v{{.Major}}.{{.Minor}}.0-rcZ {{.Major}}-{{.Minor}}-stable
     ```
 
 - [ ] wait for Pipeline for `v{{.Major}}.{{.Minor}}.0-rcZ` to pass [![pipeline status](https://gitlab.com/gitlab-org/gitlab-runner/badges/v{{.Major}}.{{.Minor}}.0-rcZ/pipeline.svg)](https://gitlab.com/gitlab-org/gitlab-runner/commits/v{{.Major}}.{{.Minor}}.0-rcZ)
     - [ ] add all required fixes to make `v{{.Major}}.{{.Minor}}.0-rcZ` passing
 - [ ] deploy **v{{.Major}}.{{.Minor}}.0-rcZ** (https://gitlab.com/gitlab-com/runbooks/blob/master/howto/update-gitlab-runner-on-managers.md)
+- [ ] update runner [helm chart](https://gitlab.com/charts/gitlab-runner) to use `v{{.Major}}.{{.Minor}}.0-rcZ` version
+    - [ ] check if Pipeline for `{{.HelmChartMajor}}-{{.HelmChartMinor}}-{{.HelmChartPatch}}-stable` is passing: [![pipeline status](https://gitlab.com/charts/gitlab-runner/badges/{{.HelmChartMajor}}-{{.HelmChartMinor}}-{{.HelmChartPatch}}-stable/pipeline.svg)](https://gitlab.com/charts/gitlab-runner/commits/{{.HelmChartMajor}}-{{.HelmChartMinor}}-{{.HelmChartPatch}}-stable)
+        - [ ] add all required fixes to make `{{.HelmChartMajor}}-{{.HelmChartMinor}}-{{.HelmChartPatch}}-stable` Pipeline passing
+    - [ ] go to your local working copy of https://gitlab.com/charts/gitlab-runner
+    - [ ] `git checkout {{.HelmChartMajor}}-{{.HelmChartMinor}}-{{.HelmChartPatch}}-stable && git pull` in your local working copy!
+    - [ ] set Helm Chart to use `v{{.Major}}.{{.Minor}}.0-rcZ` version of Runner
+        - [ ] create new branch, update Runner version and push the branch:
+
+            ```bash
+            git checkout -b update-runner-to-{{.Major}}-{{.Minor}}-0-rcZ && sed "s/^appVersion: .*/appVersion: {{.Major}}.{{.Minor}}.0-rcZ/" Chart.yaml && git add Chart.yaml && git commit -m "Bump used Runner version to {{.Major}}.{{.Minor}}.0-rcZ" -S && git push
+            ```
+
+        - [ ] create Merge Request pointing `{{.HelmChartMajor}}-{{.HelmChartMinor}}-{{.HelmChartPatch}}-stable`: [link to MR here]
+        - [ ] manage to merge the MR
+    - [ ] check if Pipeline for `{{.HelmChartMajor}}-{{.HelmChartMinor}}-{{.HelmChartPatch}}-stable` is passing: [![pipeline status](https://gitlab.com/charts/gitlab-runner/badges/{{.HelmChartMajor}}-{{.HelmChartMinor}}-{{.HelmChartPatch}}-stable/pipeline.svg)](https://gitlab.com/charts/gitlab-runner/commits/{{.HelmChartMajor}}-{{.HelmChartMinor}}-{{.HelmChartPatch}}-stable)
+        - [ ] add all required fixes to make `{{.HelmChartMajor}}-{{.HelmChartMinor}}-{{.HelmChartPatch}}-stable` Pipeline passing
+    - [ ] `git checkout {{.HelmChartMajor}}-{{.HelmChartMinor}}-{{.HelmChartPatch}}-stable && git pull` in your local working copy!
+    - [ ] prepare CHANGELOG entries
+
+        ```bash
+        ./scripts/prepare-changelog-entries.rb
+        ```
+
+        Copy the lines to the beginning of `CHANGELOG.md` file and add a proper header:
+
+        ```markdown
+        ## v{{.HelmChartMajor}}.{{.HelmChartMinor}}.{{.HelmChartPatch}}-rcZ (TODAY_DATE_HERE)
+        ```
+
+    - [ ] add **v{{.HelmChartMajor}}.{{.HelmChartMinor}}.{{.HelmChartPatch}}-rcZ** CHANGELOG entries and commit
+
+        ```bash
+        git add CHANGELOG.md && git commit -m "Update CHANGELOG for v{{.HelmChartMajor}}.{{.HelmChartMinor}}.{{.HelmChartPatch}}-rcZ" -S
+        ```
+
+    - [ ] bump version of the Helm Chart to `{{.HelmChartMajor}}.{{.HelmChartMinor}}.{{.HelmChartPatch}}-rcZ`
+
+        ```bash
+        sed "s/^version: .*/version: {{.HelmChartMajor}}.{{.HelmChartMinor}}.{{.HelmChartPatch}}-rcZ/" Chart.yaml && git add Chart.yaml && git commit -m "Bump version to {{.HelmChartMajor}}.{{.HelmChartMinor}}.{{.HelmChartPatch}}-rcZ" -S && git push
+        ```
+
+    - [ ] tag and push **v{{.HelmChartMajor}}.{{.HelmChartMinor}}.{{.HelmChartPatch}}-rcZ** and **{{.HelmChartMajor}}-{{.HelmChartMinor}}-{{.HelmChartPatch}}-stable**:
+
+        ```bash
+        git tag -s v{{.HelmChartMajor}}.{{.HelmChartMinor}}.{{.HelmChartPatch}}-rcZ -m "Version v{{.HelmChartMajor}}.{{.HelmChartMinor}}.{{.HelmChartPatch}}-rcZ" && git push origin v{{.HelmChartMajor}}.{{.HelmChartMinor}}.{{.HelmChartPatch}}-rcZ {{.HelmChartMajor}}-{{.HelmChartMinor}}-{{.HelmChartPatch}}-stable
+        ```
 
 ## At 22th - the release day
 
@@ -163,7 +268,7 @@ to the one that already exists.
 - [ ] tag and push **v{{.Major}}.{{.Minor}}.0** and **{{.Major}}-{{.Minor}}-stable**:
 
     ```bash
-    git tag -s v{{.Major}}.{{.Minor}}.0 -m "Version v{{.Major}}.{{.Minor}}.0" && git push origin {{.Major}}-{{.Minor}}-stable v{{.Major}}.{{.Minor}}.0
+    git tag -s v{{.Major}}.{{.Minor}}.0 -m "Version v{{.Major}}.{{.Minor}}.0" && git push origin v{{.Major}}.{{.Minor}}.0 {{.Major}}-{{.Minor}}-stable
     ```
 
 - [ ] checkout to `master` and merge `{{.Major}}-{{.Minor}}-stable` into `master` (only this one time, to update CHANGELOG.md and make the tag available for ./scripts/prepare-changelog-entries.rb in next stable release), push `master`:
@@ -174,7 +279,58 @@ to the one that already exists.
     git push
     ```
 
-- [ ] update runner [helm chart](https://gitlab.com/charts/gitlab-runner) to latest production version: [link to MR]
+- [ ] update runner [helm chart](https://gitlab.com/charts/gitlab-runner) to use `v{{.Major}}.{{.Minor}}.0` version
+    - [ ] check if Pipeline for `{{.HelmChartMajor}}-{{.HelmChartMinor}}-{{.HelmChartPatch}}-stable` is passing: [![pipeline status](https://gitlab.com/charts/gitlab-runner/badges/{{.HelmChartMajor}}-{{.HelmChartMinor}}-{{.HelmChartPatch}}-stable/pipeline.svg)](https://gitlab.com/charts/gitlab-runner/commits/{{.HelmChartMajor}}-{{.HelmChartMinor}}-{{.HelmChartPatch}}-stable)
+        - [ ] add all required fixes to make `{{.HelmChartMajor}}-{{.HelmChartMinor}}-{{.HelmChartPatch}}-stable` Pipeline passing
+    - [ ] go to your local working copy of https://gitlab.com/charts/gitlab-runner
+    - [ ] `git checkout {{.HelmChartMajor}}-{{.HelmChartMinor}}-{{.HelmChartPatch}}-stable && git pull` in your local working copy!
+    - [ ] set Helm Chart to use `v{{.Major}}.{{.Minor}}.0` version of Runner
+        - [ ] create new branch, update Runner version and push the branch:
+
+            ```bash
+            git checkout -b update-runner-to-{{.Major}}-{{.Minor}}-0 && sed "s/^appVersion: .*/appVersion: {{.Major}}.{{.Minor}}.0/" Chart.yaml && git add Chart.yaml && git commit -m "Bump used Runner version to {{.Major}}.{{.Minor}}.0" -S && git push
+            ```
+
+        - [ ] create Merge Request pointing `{{.HelmChartMajor}}-{{.HelmChartMinor}}-{{.HelmChartPatch}}-stable`: [link to MR here]
+        - [ ] manage to merge the MR
+    - [ ] check if Pipeline for `{{.HelmChartMajor}}-{{.HelmChartMinor}}-{{.HelmChartPatch}}-stable` is passing: [![pipeline status](https://gitlab.com/charts/gitlab-runner/badges/{{.HelmChartMajor}}-{{.HelmChartMinor}}-{{.HelmChartPatch}}-stable/pipeline.svg)](https://gitlab.com/charts/gitlab-runner/commits/{{.HelmChartMajor}}-{{.HelmChartMinor}}-{{.HelmChartPatch}}-stable)
+        - [ ] add all required fixes to make `{{.HelmChartMajor}}-{{.HelmChartMinor}}-{{.HelmChartPatch}}-stable` Pipeline passing
+    - [ ] `git checkout {{.HelmChartMajor}}-{{.HelmChartMinor}}-{{.HelmChartPatch}}-stable && git pull` in your local working copy!
+    - [ ] merge all RCx CHANGELOG entries into release entry
+
+        Put a proper header at the begining:
+
+        ```markdown
+        ## v{{.HelmChartMajor}}.{{.HelmChartMinor}}.{{.HelmChartPatch}} (TODAY_DATE_HERE)
+        ```
+
+    - [ ] add **v{{.HelmChartMajor}}.{{.HelmChartMinor}}.{{.HelmChartPatch}}** CHANGELOG entries and commit
+
+        ```bash
+        git add CHANGELOG.md && git commit -m "Update CHANGELOG for v{{.HelmChartMajor}}.{{.HelmChartMinor}}.{{.HelmChartPatch}}" -S
+        ```
+
+    - [ ] bump version of the Helm Chart to `{{.HelmChartMajor}}.{{.HelmChartMinor}}.{{.HelmChartPatch}}`
+
+        ```bash
+        sed "s/^version: .*/version: {{.HelmChartMajor}}.{{.HelmChartMinor}}.{{.HelmChartPatch}}/" Chart.yaml && git add Chart.yaml && git commit -m "Bump version to {{.HelmChartMajor}}.{{.HelmChartMinor}}.{{.HelmChartPatch}}" -S && git push
+        ```
+
+    - [ ] tag and push **v{{.HelmChartMajor}}.{{.HelmChartMinor}}.{{.HelmChartPatch}}** and **{{.HelmChartMajor}}-{{.HelmChartMinor}}-{{.HelmChartPatch}}-stable**:
+
+        ```bash
+        git tag -s v{{.HelmChartMajor}}.{{.HelmChartMinor}}.{{.HelmChartPatch}} -m "Version v{{.HelmChartMajor}}.{{.HelmChartMinor}}.{{.HelmChartPatch}}" && git push origin v{{.HelmChartMajor}}.{{.HelmChartMinor}}.{{.HelmChartPatch}} {{.HelmChartMajor}}-{{.HelmChartMinor}}-{{.HelmChartPatch}}-stable
+        ```
+
+    - [ ] checkout to `master` and merge `{{.HelmChartMajor}}-{{.HelmChartMinor}}-{{.HelmChartPatch}}-stable` into `master` (only this one time, to update CHANGELOG.md and make the tag available for ./scripts/prepare-changelog-entries.rb in next stable release), push `master`:
+
+        ```bash
+        git checkout master; git merge --no-ff {{.HelmChartMajor}}-{{.HelmChartMinor}}-{{.HelmChartPatch}}-stable
+        # check that the only changes are in CHANGELOG.md
+        git push
+        ```
+
+    - [ ] update Runner's chart version [used by GitLab](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/app/models/clusters/applications/runner.rb): [link to MR here]
 
 #### Before 15:00 UTC
 
@@ -182,10 +338,6 @@ to the one that already exists.
     - [ ] add all required fixes to make `v{{.Major}}.{{.Minor}}.0` passing
 - [ ] deploy stable version to all production Runners
 
-#### After helm chart MR is merged
-
-- [ ] update Runner's chart version [used by GitLab](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/app/models/clusters/applications/runner.rb): [link to MR]
-
 
 ## RC release template
 
@@ -224,10 +376,56 @@ template:
 - [ ] tag and push **v{{.Major}}.{{.Minor}}.0-rcZ** and **{{.Major}}-{{.Minor}}-stable**:
 
     ```bash
-    git tag -s v{{.Major}}.{{.Minor}}.0-rcZ -m "Version v{{.Major}}.{{.Minor}}.0-rcZ" && git push origin  {{.Major}}-{{.Minor}}-stable v{{.Major}}.{{.Minor}}.0-rcZ
+    git tag -s v{{.Major}}.{{.Minor}}.0-rcZ -m "Version v{{.Major}}.{{.Minor}}.0-rcZ" && git push origin v{{.Major}}.{{.Minor}}.0-rcZ {{.Major}}-{{.Minor}}-stable
     ```
 
 - [ ] wait for Pipeline for `v{{.Major}}.{{.Minor}}.0-rcZ` to pass [![pipeline status](https://gitlab.com/gitlab-org/gitlab-runner/badges/v{{.Major}}.{{.Minor}}.0-rcZ/pipeline.svg)](https://gitlab.com/gitlab-org/gitlab-runner/commits/v{{.Major}}.{{.Minor}}.0-rcZ)
     - [ ] add all required fixes to make `v{{.Major}}.{{.Minor}}.0-rcZ` passing
 - [ ] deploy **v{{.Major}}.{{.Minor}}.0-rcZ** (https://gitlab.com/gitlab-com/runbooks/blob/master/howto/update-gitlab-runner-on-managers.md)
+- [ ] update runner [helm chart](https://gitlab.com/charts/gitlab-runner) to use `v{{.Major}}.{{.Minor}}.0-rcZ` version
+    - [ ] check if Pipeline for `{{.HelmChartMajor}}-{{.HelmChartMinor}}-{{.HelmChartPatch}}-stable` is passing: [![pipeline status](https://gitlab.com/charts/gitlab-runner/badges/{{.HelmChartMajor}}-{{.HelmChartMinor}}-{{.HelmChartPatch}}-stable/pipeline.svg)](https://gitlab.com/charts/gitlab-runner/commits/{{.HelmChartMajor}}-{{.HelmChartMinor}}-{{.HelmChartPatch}}-stable)
+        - [ ] add all required fixes to make `{{.HelmChartMajor}}-{{.HelmChartMinor}}-{{.HelmChartPatch}}-stable` Pipeline passing
+    - [ ] go to your local working copy of https://gitlab.com/charts/gitlab-runner
+    - [ ] `git checkout {{.HelmChartMajor}}-{{.HelmChartMinor}}-{{.HelmChartPatch}}-stable && git pull` in your local working copy!
+    - [ ] set Helm Chart to use `v{{.Major}}.{{.Minor}}.0-rcZ` version of Runner
+        - [ ] create new branch, update Runner version and push the branch:
+
+            ```bash
+            git checkout -b update-runner-to-{{.Major}}-{{.Minor}}-0-rcZ && sed "s/^appVersion: .*/appVersion: {{.Major}}.{{.Minor}}.0-rcZ/" Chart.yaml && git add Chart.yaml && git commit -m "Bump used Runner version to {{.Major}}.{{.Minor}}.0-rcZ" -S && git push
+            ```
+
+        - [ ] create Merge Request pointing `{{.HelmChartMajor}}-{{.HelmChartMinor}}-{{.HelmChartPatch}}-stable`: [link to MR here]
+        - [ ] manage to merge the MR
+    - [ ] check if Pipeline for `{{.HelmChartMajor}}-{{.HelmChartMinor}}-{{.HelmChartPatch}}-stable` is passing: [![pipeline status](https://gitlab.com/charts/gitlab-runner/badges/{{.HelmChartMajor}}-{{.HelmChartMinor}}-{{.HelmChartPatch}}-stable/pipeline.svg)](https://gitlab.com/charts/gitlab-runner/commits/{{.HelmChartMajor}}-{{.HelmChartMinor}}-{{.HelmChartPatch}}-stable)
+        - [ ] add all required fixes to make `{{.HelmChartMajor}}-{{.HelmChartMinor}}-{{.HelmChartPatch}}-stable` Pipeline passing
+    - [ ] `git checkout {{.HelmChartMajor}}-{{.HelmChartMinor}}-{{.HelmChartPatch}}-stable && git pull` in your local working copy!
+    - [ ] prepare CHANGELOG entries
+
+        ```bash
+        ./scripts/prepare-changelog-entries.rb
+        ```
+
+        Copy the lines to the beginning of `CHANGELOG.md` file and add a proper header:
+
+        ```markdown
+        ## v{{.HelmChartMajor}}.{{.HelmChartMinor}}.{{.HelmChartPatch}}-rcZ (TODAY_DATE_HERE)
+        ```
+
+    - [ ] add **v{{.HelmChartMajor}}.{{.HelmChartMinor}}.{{.HelmChartPatch}}-rcZ** CHANGELOG entries and commit
+
+        ```bash
+        git add CHANGELOG.md && git commit -m "Update CHANGELOG for v{{.HelmChartMajor}}.{{.HelmChartMinor}}.{{.HelmChartPatch}}-rcZ" -S
+        ```
+
+    - [ ] bump version of the Helm Chart to `{{.HelmChartMajor}}.{{.HelmChartMinor}}.{{.HelmChartPatch}}-rcZ`
+
+        ```bash
+        sed "s/^version: .*/version: {{.HelmChartMajor}}.{{.HelmChartMinor}}.{{.HelmChartPatch}}-rcZ/" Chart.yaml && git add Chart.yaml && git commit -m "Bump version to {{.HelmChartMajor}}.{{.HelmChartMinor}}.{{.HelmChartPatch}}-rcZ" -S && git push
+        ```
+
+    - [ ] tag and push **v{{.HelmChartMajor}}.{{.HelmChartMinor}}.{{.HelmChartPatch}}-rcZ** and **{{.HelmChartMajor}}-{{.HelmChartMinor}}-{{.HelmChartPatch}}-stable**:
+
+        ```bash
+        git tag -s v{{.HelmChartMajor}}.{{.HelmChartMinor}}.{{.HelmChartPatch}}-rcZ -m "Version v{{.HelmChartMajor}}.{{.HelmChartMinor}}.{{.HelmChartPatch}}-rcZ" && git push origin v{{.HelmChartMajor}}.{{.HelmChartMinor}}.{{.HelmChartPatch}}-rcZ {{.HelmChartMajor}}-{{.HelmChartMinor}}-{{.HelmChartPatch}}-stable
+        ```
 ```
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 07bae450fe94f0869c2998c40bb3086864400f5f..937f0aa4ec8d09507101ec1e90c9c10888c077bc 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,31 @@
+v11.7.0-rc1 (2019-01-08)
+- Docs: Cleaning up the executors doc !1114
+- Update to testify v1.2.2 !1119
+- Fix a typo in VirtualBox Executor docs !1124
+- Use the term `macOS` instead of `OS X` or `OSX` !1125
+- Update github.com/sirupsen/logrus dependency !1129
+- Docs update release checklist !1131
+- Kill session when build is cancelled !1058
+- Fix path separator for CI_PROJECT_DIR in Windows !1128
+
+v11.6.0 (2018-12-22)
+- Make compatibility chart super clear and remove old entries !1078
+- Add slack notification option for 'dep status' check failures !1072
+- Docker executor: use DNS, DNSSearch and ExtraHosts settings from configuration !1075
+- Fix some invalid links in documentation !1085
+- Fix SC2155 where shellcheck warns about errors !1063
+- Change parallel tests configuration ENV names !1095
+- Improve documentation of IAM instance profile usage for caching !1071
+- Remove duplicate builds_dir definition from docs !952
+- Make k8s object names DNS-1123 compatible !1105
+- Docs: working example of helper image with CI_RUNNER_REVISION !1032
+- Docs: omit ImagePullPolicy !1107
+- Disable the docs lint job for now !1112
+- Docs: comment about how listen_address works !1076
+- Fix the indented bullet points of the features list in documentation !1093
+- Add note on the branch naming for documentation changes !1113
+- Docs: add session-server link to advanced list in index !1108
+
 v11.5.0 (2018-11-22)
 - Support RAW artifacts !1057
 - Docs: changing secret variable to just variable in advanced-configuration.md !1055
diff --git a/Gopkg.lock b/Gopkg.lock
index bb5cd8cf6402ddf49d7a5145540136c425ac6165..0d37068848aeb1958f7c07b76fa09f9b4a0bbe51 100644
--- a/Gopkg.lock
+++ b/Gopkg.lock
@@ -414,6 +414,14 @@
   pruneopts = "N"
   revision = "c2c54e542fb797ad986b31721e1baedf214ca413"
 
+[[projects]]
+  digest = "1:4643b94ee9e1e291b3f35558faddf6882cb7c2c759a416c0427bc13c2b992a24"
+  name = "github.com/konsorten/go-windows-terminal-sequences"
+  packages = ["."]
+  pruneopts = "N"
+  revision = "5c8c8bd35d3832f5d134ae1e1e375b69a4d25242"
+  version = "v1.0.1"
+
 [[projects]]
   digest = "1:e215f2f34720b08b497951d2193705d6c542766213627947b9f065f749821b53"
   name = "github.com/kr/pty"
@@ -555,15 +563,15 @@
   revision = "abf152e5f3e97f2fafac028d2cc06c1feb87ffa5"
 
 [[projects]]
-  branch = "master"
-  digest = "1:bd1ebbb301e1a33a22f5e8026d64c7b48d8ed105790ab01f4ad8d3a9c28d8abf"
+  digest = "1:5f3253413123167546a72c2702f2c38980a5170b5d3d92ca074f8115dbc700da"
   name = "github.com/sirupsen/logrus"
   packages = [
     ".",
     "hooks/test",
   ]
   pruneopts = "N"
-  revision = "78fa2915c1fa231f62e0438da493688c21ca678e"
+  revision = "e1e72e9de974bd926e5c56f83753fba2df402ce5"
+  version = "v1.3.0"
 
 [[projects]]
   digest = "1:e86042cb61313f9315878e33f2713cc1a1a1c29feeb04b64c164ed55266822d9"
@@ -580,7 +588,7 @@
   revision = "cbeaeb16a013161a98496fad62933b1d21786672"
 
 [[projects]]
-  digest = "1:41b23b4dd808ad26fbac40f014e05a541815f5475dc7c20065a1e468ed131fc5"
+  digest = "1:af816109ede76072cf29dd2116e0cc386668690b81e5a4fc05ae10dfac22aee4"
   name = "github.com/stretchr/testify"
   packages = [
     "assert",
@@ -588,7 +596,8 @@
     "require",
   ]
   pruneopts = "N"
-  revision = "b1f989447a57594c728884458a39abf3a73447f7"
+  revision = "ffdc059bfe9ce6a4e144ba849dbedead332c6053"
+  version = "v1.3.0"
 
 [[projects]]
   digest = "1:0e6bfd9ff4db873948cf1fe1a3727f893eb776440dd1085759bd6e8aa7f045e0"
diff --git a/Gopkg.toml b/Gopkg.toml
index 29b437df42d7b7ab05605b817ca42db93c59c754..93d62762b0b381de5b4835bacc8accde81a95ba6 100644
--- a/Gopkg.toml
+++ b/Gopkg.toml
@@ -32,7 +32,7 @@ ignored = ["test", "appengine"]
 
 [[constraint]]
   name = "github.com/sirupsen/logrus"
-  branch = "master"
+  version = "1.3.0"
 
 [[constraint]]
   branch = "master"
@@ -94,7 +94,7 @@ ignored = ["test", "appengine"]
 
 [[constraint]]
   name = "github.com/stretchr/testify"
-  revision = "b1f989447a57594c728884458a39abf3a73447f7"
+  version = "1.3.0"
 
 [[constraint]]
   # branch = "master"
@@ -178,10 +178,6 @@ ignored = ["test", "appengine"]
   name = "github.com/docker/docker-credential-helpers"
   revision = "b7c53e02cd1a9a01500a58f22d83c6e964bc59db"
 
-[[override]]
-  name = "github.com/docker/engine-api"
-  revision = "4290f40c056686fcaa5c9caf02eac1dde9315adf"
-
 [[override]]
   name = "github.com/docker/spdystream"
   revision = "449fdfce4d962303d702fec724ef0ad181c92528"
diff --git a/LICENSE b/LICENSE
index 4b52cfab6d1e336e6ce442c9174fed6e6ad6ae5f..03738b846a33decdfa58c7e3e4df7a5e4ab2ed7f 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
 The MIT License (MIT)
 
-Copyright (c) 2015-2018 GitLab B.V.
+Copyright (c) 2015-2019 GitLab B.V.
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
@@ -20,7 +20,3 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE.
 
----
-
-All Documentation content that resides under the docs/ directory of this
-repository is licensed under Creative Commons: CC BY-SA 4.0.
diff --git a/Makefile b/Makefile
index 41c3c4279a3caaab32e02faa331de0c57631d7ba..b279799e0a56ae6b4c2aa735de19ccc900a3de00 100644
--- a/Makefile
+++ b/Makefile
@@ -366,8 +366,8 @@ prepare_release_checklist_issue_dry_run:
 	make prepare_release_checklist_issue opts="-dry-run"
 
 prepare_release_checklist_issue: opts ?= ""
-prepare_release_checklist_issue:
-	@go run ./scripts/prepare_release_checklist_issue.go \
+prepare_release_checklist_issue: $(GOPATH_SETUP)
+	@go run $(PKG)/scripts/prepare-release-checklist-issue \
 		-issue-template-file ".gitlab/issue_templates/Release Checklist.md" \
 		$(opts)
 
diff --git a/NOTICE b/NOTICE
index 8a1a7fa7dfc146f799446f91cab984191d028fb3..bcd3e5ea57d17ec536bfee6b300fe8cb6c25edf4 100644
--- a/NOTICE
+++ b/NOTICE
@@ -1,7 +1,9 @@
-Copyright (c) 2015-2017 GitLab B.V.
-
 With regard to the GitLab Software:
 
+The MIT License (MIT)
+
+Copyright (c) 2015-2019 GitLab B.V.
+
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
 in the Software without restriction, including without limitation the rights
@@ -20,6 +22,13 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE.
 
+---
+
 For all third party components incorporated into the GitLab Software, those
 components are licensed under the original license provided by the owner of the
 applicable component.
+
+---
+
+All Documentation content that resides under the docs/ directory of this
+repository is licensed under Creative Commons: CC BY-SA 4.0.
diff --git a/README.md b/README.md
index 1c87d53976e75baffa6739081cc4e04d4861db0c..a89295444f0c6aa711a6f2393f614c47c45cdfe9 100644
--- a/README.md
+++ b/README.md
@@ -39,6 +39,11 @@ try upgrading to the latest version. If the issue persists, reopen this issue
 or merge request with the relevant information.
 ```
 
+### Contributing to documentation
+
+If your contribution contains only documentation changes, you can speed up the CI process
+by following some branch naming conventions, as described in https://docs.gitlab.com/ce/development/documentation/index.html#branch-naming
+
 ## Documentation
 
 The documentation source files can be found under the [docs/](docs/) directory. You can
@@ -91,10 +96,8 @@ Visit the [Changelog](CHANGELOG.md) to view recent changes.
 
 ## Author
 
-```
-2014 - 2015   : [Kamil Trzciński](mailto:ayufan@ayufan.eu)
-2015 - now    : GitLab Inc. team and contributors
-```
+- 2014 - 2015   : [Kamil Trzciński](mailto:ayufan@ayufan.eu)
+- 2015 - now    : GitLab Inc. team and contributors
 
 ## License
 
diff --git a/VERSION b/VERSION
index 500d2aba1d873c1252d04af1f8f32d8128f4e592..0f62d34000f04184c2fa4a8bfdcf66cfd5b0d87f 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-11.6.0
\ No newline at end of file
+11.8.0
\ No newline at end of file
diff --git a/common/build.go b/common/build.go
index 1aaf29e182f72aab2cc34ae481f49e6ec92a6047..48be28ca8a76485c08288b26f0f1fe6c82541937 100644
--- a/common/build.go
+++ b/common/build.go
@@ -7,6 +7,7 @@ import (
 	"net/url"
 	"os"
 	"path"
+	"path/filepath"
 	"strconv"
 	"strings"
 	"time"
@@ -350,36 +351,60 @@ func (b *Build) retryCreateExecutor(options ExecutorPrepareOptions, provider Exe
 	return
 }
 
-func (b *Build) waitForTerminal(timeout time.Duration) {
+func (b *Build) waitForTerminal(ctx context.Context, timeout time.Duration) error {
 	if b.Session == nil || !b.Session.Connected() {
-		return
+		return nil
 	}
 
+	timeout = b.getTerminalTimeout(ctx, timeout)
+
 	b.logger.Infoln(
 		fmt.Sprintf(
 			"Terminal is connected, will time out in %s...",
-			timeout,
+			// TODO: switch to timeout.Round(time.Second) after upgrading to Go 1.9+
+			roundDuration(timeout, time.Second),
 		),
 	)
 
 	select {
+	case <-ctx.Done():
+		err := b.Session.Kill()
+		if err != nil {
+			b.Log().WithError(err).Warn("Failed to kill session")
+		}
+		return errors.New("build cancelled, killing session")
 	case <-time.After(timeout):
 		err := fmt.Errorf(
 			"Terminal session timed out (maximum time allowed - %s)",
-			timeout,
+			// TODO: switch to timeout.Round(time.Second) after upgrading to Go 1.9+
+			roundDuration(timeout, time.Second),
 		)
 		b.logger.Infoln(err.Error())
-		b.Log().WithError(err).Debugln("Connection closed")
 		b.Session.TimeoutCh <- err
+		return err
 	case err := <-b.Session.DisconnectCh:
 		b.logger.Infoln("Terminal disconnected")
-		b.Log().WithError(err).Debugln("Terminal disconnected")
+		return fmt.Errorf("terminal disconnected: %v", err)
 	case signal := <-b.SystemInterrupt:
-		err := fmt.Errorf("aborted: %v", signal)
 		b.logger.Infoln("Terminal disconnected")
-		b.Log().WithError(err).Debugln("Terminal disconnected")
-		b.Session.Kill()
+		err := b.Session.Kill()
+		if err != nil {
+			b.Log().WithError(err).Warn("Failed to kill session")
+		}
+		return fmt.Errorf("terminal disconnected by system signal: %v", signal)
+	}
+}
+
+// getTerminalTimeout checks if the the job timeout comes before the
+// configured terminal timeout.
+func (b *Build) getTerminalTimeout(ctx context.Context, timeout time.Duration) time.Duration {
+	expiryTime, _ := ctx.Deadline()
+
+	if expiryTime.Before(time.Now().Add(timeout)) {
+		timeout = expiryTime.Sub(time.Now())
 	}
+
+	return timeout
 }
 
 func (b *Build) setTraceStatus(trace JobTrace, err error) {
@@ -463,11 +488,15 @@ func (b *Build) Run(globalConfig *Config, trace JobTrace) (err error) {
 	executor, err = b.retryCreateExecutor(options, provider, b.logger)
 	if err == nil {
 		err = b.run(ctx, executor)
-		b.waitForTerminal(globalConfig.SessionServer.GetSessionTimeout())
+		if err := b.waitForTerminal(ctx, globalConfig.SessionServer.GetSessionTimeout()); err != nil {
+			b.Log().WithError(err).Debug("Stopped waiting for terminal")
+		}
 	}
+
 	if executor != nil {
 		executor.Finish(err)
 	}
+
 	return err
 }
 
@@ -477,7 +506,7 @@ func (b *Build) String() string {
 
 func (b *Build) GetDefaultVariables() JobVariables {
 	return JobVariables{
-		{Key: "CI_PROJECT_DIR", Value: b.FullProjectDir(), Public: true, Internal: true, File: false},
+		{Key: "CI_PROJECT_DIR", Value: filepath.FromSlash(b.FullProjectDir()), Public: true, Internal: true, File: false},
 		{Key: "CI_SERVER", Value: "yes", Public: true, Internal: true, File: false},
 	}
 }
diff --git a/common/build_test.go b/common/build_test.go
index 695d1b28d8f1972143e5ca3cee72b7cfb5fb72b0..241b9e5e5f41e1194ae03c5755c7019a220ecdb2 100644
--- a/common/build_test.go
+++ b/common/build_test.go
@@ -1,16 +1,25 @@
 package common
 
 import (
+	"context"
 	"errors"
 	"fmt"
+	"net/http"
+	"net/http/httptest"
+	"net/url"
 	"os"
+	"path/filepath"
 	"testing"
 	"time"
 
+	"github.com/gorilla/websocket"
 	"github.com/sirupsen/logrus/hooks/test"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/mock"
 	"github.com/stretchr/testify/require"
+
+	"gitlab.com/gitlab-org/gitlab-runner/session"
+	"gitlab.com/gitlab-org/gitlab-runner/session/terminal"
 )
 
 func init() {
@@ -629,6 +638,18 @@ func TestDebugTrace(t *testing.T) {
 	assert.True(t, build.IsDebugTraceEnabled(), "IsDebugTraceEnabled should be true if CI_DEBUG_TRACE is set to true")
 }
 
+func TestDefaultEnvVariables(t *testing.T) {
+	buildDir := "/tmp/test-build/dir"
+	build := Build{
+		BuildDir: buildDir,
+	}
+
+	vars := build.GetAllVariables().StringList()
+
+	assert.Contains(t, vars, "CI_PROJECT_DIR="+filepath.FromSlash(buildDir))
+	assert.Contains(t, vars, "CI_SERVER=yes")
+}
+
 func TestSharedEnvVariables(t *testing.T) {
 	for _, shared := range [...]bool{true, false} {
 		t.Run(fmt.Sprintf("Value:%v", shared), func(t *testing.T) {
@@ -765,5 +786,124 @@ func TestIsFeatureFlagOn(t *testing.T) {
 			hook.Reset()
 		})
 	}
+}
+
+func TestWaitForTerminal(t *testing.T) {
+	cases := []struct {
+		name                   string
+		cancelFn               func(ctxCancel context.CancelFunc, build *Build)
+		jobTimeout             int
+		waitForTerminalTimeout time.Duration
+		expectedErr            string
+	}{
+		{
+			name: "Cancel build",
+			cancelFn: func(ctxCancel context.CancelFunc, build *Build) {
+				ctxCancel()
+			},
+			jobTimeout:             3600,
+			waitForTerminalTimeout: time.Hour,
+			expectedErr:            "build cancelled, killing session",
+		},
+		{
+			name: "Terminal Timeout",
+			cancelFn: func(ctxCancel context.CancelFunc, build *Build) {
+				// noop
+			},
+			jobTimeout:             3600,
+			waitForTerminalTimeout: time.Second,
+			expectedErr:            "Terminal session timed out (maximum time allowed - 1s)",
+		},
+		{
+			name: "System Interrupt",
+			cancelFn: func(ctxCancel context.CancelFunc, build *Build) {
+				build.SystemInterrupt <- os.Interrupt
+			},
+			jobTimeout:             3600,
+			waitForTerminalTimeout: time.Hour,
+			expectedErr:            "terminal disconnected by system signal: interrupt",
+		},
+		{
+			name: "Terminal Disconnect",
+			cancelFn: func(ctxCancel context.CancelFunc, build *Build) {
+				build.Session.DisconnectCh <- errors.New("user disconnect")
+			},
+			jobTimeout:             3600,
+			waitForTerminalTimeout: time.Hour,
+			expectedErr:            "terminal disconnected: user disconnect",
+		},
+	}
 
+	for _, c := range cases {
+		t.Run(c.name, func(t *testing.T) {
+			build := Build{
+				Runner: &RunnerConfig{
+					RunnerSettings: RunnerSettings{
+						Executor: "shell",
+					},
+				},
+				JobResponse: JobResponse{
+					RunnerInfo: RunnerInfo{
+						Timeout: c.jobTimeout,
+					},
+				},
+				SystemInterrupt: make(chan os.Signal),
+			}
+
+			trace := Trace{Writer: os.Stdout}
+			build.logger = NewBuildLogger(&trace, build.Log())
+			sess, err := session.NewSession(nil)
+			require.NoError(t, err)
+			build.Session = sess
+
+			srv := httptest.NewServer(build.Session.Mux())
+			defer srv.Close()
+
+			mockConn := terminal.MockConn{}
+			defer mockConn.AssertExpectations(t)
+			mockConn.On("Close").Maybe().Return(nil)
+			// On Start upgrade the web socket connection and wait for the
+			// timeoutCh to exit, to mock real work made on the websocket.
+			mockConn.On("Start", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Run(func(args mock.Arguments) {
+				upgrader := &websocket.Upgrader{}
+				r := args[1].(*http.Request)
+				w := args[0].(http.ResponseWriter)
+
+				_, _ = upgrader.Upgrade(w, r, nil)
+				timeoutCh := args[2].(chan error)
+
+				<-timeoutCh
+			}).Once()
+
+			mockTerminal := terminal.MockInteractiveTerminal{}
+			defer mockTerminal.AssertExpectations(t)
+			mockTerminal.On("Connect").Return(&mockConn, nil)
+			sess.SetInteractiveTerminal(&mockTerminal)
+
+			u := url.URL{
+				Scheme: "ws",
+				Host:   srv.Listener.Addr().String(),
+				Path:   build.Session.Endpoint + "/exec",
+			}
+			headers := http.Header{
+				"Authorization": []string{build.Session.Token},
+			}
+
+			conn, _, err := websocket.DefaultDialer.Dial(u.String(), headers)
+			require.NotNil(t, conn)
+			require.NoError(t, err)
+			defer conn.Close()
+
+			ctx, cancel := context.WithTimeout(context.Background(), build.GetBuildTimeout())
+
+			errCh := make(chan error)
+			go func() {
+				errCh <- build.waitForTerminal(ctx, c.waitForTerminalTimeout)
+			}()
+
+			c.cancelFn(cancel, &build)
+
+			assert.EqualError(t, <-errCh, c.expectedErr)
+		})
+	}
 }
diff --git a/common/config.go b/common/config.go
index 4587428a1131f1a72e06901d052d1de06f68285d..5746938aa4c26a95a4ace987586dc9a6bce0fe0d 100644
--- a/common/config.go
+++ b/common/config.go
@@ -10,11 +10,13 @@ import (
 	"os"
 	"path/filepath"
 	"strconv"
+	"strings"
 	"time"
 
 	"github.com/BurntSushi/toml"
 	"github.com/docker/go-units"
 	log "github.com/sirupsen/logrus"
+	api "k8s.io/api/core/v1"
 
 	"gitlab.com/gitlab-org/gitlab-runner/helpers"
 	"gitlab.com/gitlab-org/gitlab-runner/helpers/docker"
@@ -158,7 +160,8 @@ type KubernetesConfig struct {
 	HelperCPURequest               string               `toml:"helper_cpu_request,omitempty" json:"helper_cpu_request" long:"helper-cpu-request" env:"KUBERNETES_HELPER_CPU_REQUEST" description:"The CPU allocation requested for build helper containers"`
 	HelperMemoryRequest            string               `toml:"helper_memory_request,omitempty" json:"helper_memory_request" long:"helper-memory-request" env:"KUBERNETES_HELPER_MEMORY_REQUEST" description:"The amount of memory requested for build helper containers"`
 	PullPolicy                     KubernetesPullPolicy `toml:"pull_policy,omitempty" json:"pull_policy" long:"pull-policy" env:"KUBERNETES_PULL_POLICY" description:"Policy for if/when to pull a container image (never, if-not-present, always). The cluster default will be used if not set"`
-	NodeSelector                   map[string]string    `toml:"node_selector,omitempty" json:"node_selector" long:"node-selector" description:"A toml table/json object of key=value. Value is expected to be a string. When set this will create pods on k8s nodes that match all the key=value pairs."`
+	NodeSelector                   map[string]string    `toml:"node_selector,omitempty" json:"node_selector" long:"node-selector" env:"KUBERNETES_NODE_SELECTOR" description:"A toml table/json object of key=value. Value is expected to be a string. When set this will create pods on k8s nodes that match all the key=value pairs."`
+	NodeTolerations                map[string]string    `toml:"node_tolerations,omitempty" json:"node_tolerations" long:"node-tolerations" env:"KUBERNETES_NODE_TOLERATIONS" description:"A toml table/json object of key=value:effect. Value and effect are expected to be strings. When set, pods will tolerate the given taints. Only one toleration is supported through environment variable configuration."`
 	ImagePullSecrets               []string             `toml:"image_pull_secrets,omitempty" json:"image_pull_secrets" long:"image-pull-secrets" env:"KUBERNETES_IMAGE_PULL_SECRETS" description:"A list of image pull secrets that are used for pulling docker image"`
 	HelperImage                    string               `toml:"helper_image,omitempty" json:"helper_image" long:"helper-image" env:"KUBERNETES_HELPER_IMAGE" description:"[ADVANCED] Override the default helper image used to clone repos and upload artifacts"`
 	TerminationGracePeriodSeconds  int64                `toml:"terminationGracePeriodSeconds,omitzero" json:"terminationGracePeriodSeconds" long:"terminationGracePeriodSeconds" env:"KUBERNETES_TERMINATIONGRACEPERIODSECONDS" description:"Duration after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal."`
@@ -521,6 +524,32 @@ func (c *KubernetesConfig) GetPollInterval() int {
 	return c.PollInterval
 }
 
+func (c *KubernetesConfig) GetNodeTolerations() []api.Toleration {
+	var tolerations []api.Toleration
+
+	for toleration, effect := range c.NodeTolerations {
+		newToleration := api.Toleration{
+			Effect: api.TaintEffect(effect),
+		}
+
+		if strings.Contains(toleration, "=") {
+			parts := strings.Split(toleration, "=")
+			newToleration.Key = parts[0]
+			if len(parts) > 1 {
+				newToleration.Value = parts[1]
+			}
+			newToleration.Operator = api.TolerationOpEqual
+		} else {
+			newToleration.Key = toleration
+			newToleration.Operator = api.TolerationOpExists
+		}
+
+		tolerations = append(tolerations, newToleration)
+	}
+
+	return tolerations
+}
+
 func (c *DockerMachine) GetIdleCount() int {
 	if c.isOffPeak() {
 		return c.OffPeakIdleCount
diff --git a/common/time.go b/common/time.go
new file mode 100644
index 0000000000000000000000000000000000000000..90c7063b656f6d0f88c21b065594ba5d02cb9d81
--- /dev/null
+++ b/common/time.go
@@ -0,0 +1,49 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in https://github.com/golang/go/blob/master/LICENSE.
+// The original code can be found in https://github.com/golang/go/blob/master/src/time/time.go
+// TODO: remove file after upgrading to Go 1.9+
+
+package common
+
+import "time"
+
+const (
+	minDuration time.Duration = -1 << 63
+	maxDuration time.Duration = 1<<63 - 1
+)
+
+// roundDuration does exactly the same as time.Duration#Round in go.1.9+ since we are
+// still on go1.8 we do not have this available. You can check the actual
+// implementation in
+// https://github.com/golang/go/blob/dev.boringcrypto.go1.9/src/time/time.go#L819-L841
+// and the it can be found in go1.9 change log https://golang.org/doc/go1.9
+func roundDuration(d time.Duration, m time.Duration) time.Duration {
+	if m <= 0 {
+		return d
+	}
+	r := d % m
+	if d < 0 {
+		r = -r
+		if lessThanHalf(r, m) {
+			return d + r
+		}
+		if d1 := d - m + r; d1 < d {
+			return d1
+		}
+		return minDuration // overflow
+	}
+	if lessThanHalf(r, m) {
+		return d - r
+	}
+	if d1 := d + m - r; d1 > d {
+		return d1
+	}
+	return maxDuration // overflow
+}
+
+// lessThanHalf reports whether x+x < y but avoids overflow,
+// assuming x and y are both positive (Duration is signed).
+func lessThanHalf(x, y time.Duration) bool {
+	return uint64(x)+uint64(x) < uint64(y)
+}
diff --git a/common/time_test.go b/common/time_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..75ad197c3eef5babef3c358961cc7e32f98eb2e8
--- /dev/null
+++ b/common/time_test.go
@@ -0,0 +1,46 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in https://github.com/golang/go/blob/master/LICENSE.
+// The original code can be found in https://github.com/golang/go/blob/master/src/time/time_test.go
+// TODO: remove file after upgrading to Go 1.9+
+
+package common
+
+import (
+	"testing"
+	"time"
+)
+
+// Original tests can be found in https://github.com/golang/go/blob/master/src/time/time_test.go
+var durationRoundTests = []struct {
+	d    time.Duration
+	m    time.Duration
+	want time.Duration
+}{
+	{0, time.Second, 0},
+	{time.Minute, -11 * time.Second, time.Minute},
+	{time.Minute, 0, time.Minute},
+	{time.Minute, 1, time.Minute},
+	{2 * time.Minute, time.Minute, 2 * time.Minute},
+	{2*time.Minute + 10*time.Second, time.Minute, 2 * time.Minute},
+	{2*time.Minute + 30*time.Second, time.Minute, 3 * time.Minute},
+	{2*time.Minute + 50*time.Second, time.Minute, 3 * time.Minute},
+	{-time.Minute, 1, -time.Minute},
+	{-2 * time.Minute, time.Minute, -2 * time.Minute},
+	{-2*time.Minute - 10*time.Second, time.Minute, -2 * time.Minute},
+	{-2*time.Minute - 30*time.Second, time.Minute, -3 * time.Minute},
+	{-2*time.Minute - 50*time.Second, time.Minute, -3 * time.Minute},
+	{8e18, 3e18, 9e18},
+	{9e18, 5e18, 1<<63 - 1},
+	{-8e18, 3e18, -9e18},
+	{-9e18, 5e18, -1 << 63},
+	{3<<61 - 1, 3 << 61, 3 << 61},
+}
+
+func TestDurationRound(t *testing.T) {
+	for _, tt := range durationRoundTests {
+		if got := roundDuration(tt.d, tt.m); got != tt.want {
+			t.Errorf("Duration(%s).Round(%s) = %s; want: %s", tt.d, tt.m, got, tt.want)
+		}
+	}
+}
diff --git a/docs/configuration/advanced-configuration.md b/docs/configuration/advanced-configuration.md
index 55bee918a2c5bf20a42cecc294d6a229b5429d57..8e47554dcad37e72590f9aacea7d53a18014bc50 100644
--- a/docs/configuration/advanced-configuration.md
+++ b/docs/configuration/advanced-configuration.md
@@ -88,7 +88,7 @@ Example:
 
 ```bash
 [session_server]
-  listen_address = "0.0.0.0:8093"
+  listen_address = "0.0.0.0:8093" #  listen on all available interfaces on port 8093
   advertise_address = "runner-host-name.tld:8093"
   session_timeout = 1800
 ```
@@ -517,6 +517,20 @@ With GitLab Runner 11.3.0, the configuration parameters related to S3 were moved
 The old format of the configuration with S3 configured directly in `[runners.cache]` section is still supported,
 but is deprecated with GitLab Runner 11.3.0. **This support will be removed in GitLab Runner 12.0.0**.
 
+NOTE: **Note:**
+The cache mechanism uses pre-signed URLs to upload and download cache. URLs are being signed by GitLab Runner on its **own instance**.
+No matter if the job's script - so also the cache upload/download script - are being executed on local or external
+machines (e.g. `shell` or `docker` executors are running their scripts on the same
+machine where GitLab Runner process is running, while `virtualbox` or `docker+machine`
+connects to a separate VM to execute the script). This is done for security reasons:
+minimizing the possibility of leaking the cache adapter's credentials.
+
+NOTE: **Note:**
+Previous note implies [S3 cache adapter](#the-runnerscaches3-section), if configured to use
+IAM instance profile, will use the profile attached with GitLab Runner's machine. 
+Similarly for [GCS cache adapter](#the-runnerscachegcs-section), if configured to
+use the `CredentialsFile`, the file needs to be present on GitLab Runner's machine.
+
 Bellow is a table containing a summary of `config.toml`, cli options and ENV variables deprecations:
 
 | Setting             | TOML field                               | CLI option for `register`      | ENV for `register`                | deprecated TOML field               | deprecated CLI option   | deprecated ENV        |
@@ -535,7 +549,6 @@ Bellow is a table containing a summary of `config.toml`, cli options and ENV var
 | GCS.CredentialsFile | `[runners.cache.gcs] -> CredentialsFile` | `--cache-gcs-credentials-file` | `$GOOGLE_APPLICATION_CREDENTIALS` |                                     |                         |                       |
 | GCS.BucketName      | `[runners.cache.gcs] -> BucketName`      | `--cache-gcs-bucket-name`      | `$CACHE_GCS_BUCKET_NAME`          |                                     |                         |                       |
 
-
 ### The `[runners.cache.s3]` section
 
 NOTE: **Note:**
@@ -575,7 +588,7 @@ get bucket metadata and modify the URL to point to the valid region (eg. `s3-eu-
 
 NOTE: **Note:**
 If any of `ServerAddress`, `AccessKey` or `SecretKey` aren't specified, then the S3 client will use the
-IAM instance profile available to the instance.
+IAM instance profile available to the `gitlab-runner` instance.
 
 ### The `[runners.cache.gcs]` section
 
@@ -720,10 +733,10 @@ of used image automatically, by using one of the
   executor = "docker"
   [runners.docker]
     (...)
-    helper_image = "my.registry.local/gitlab/gitlab-runner-helper:${CI_RUNNER_REVISION}"
+    helper_image = "my.registry.local/gitlab/gitlab-runner-helper:x86_64-${CI_RUNNER_REVISION}"
 ```
 
-With that configuration, GitLab Runner will instruct the executor to use the image in version `${CI_RUNNER_REVISION}`,
+With that configuration, GitLab Runner will instruct the executor to use the image in version `x86_64-${CI_RUNNER_REVISION}`,
 which is based on its compilation data. After updating the Runner to a new version, this will ensure that the
 Runner will try to download the proper image. This of course means that the image should be uploaded to the registry
 before upgrading the Runner, otherwise the jobs will start failing with a "No such image" error.
diff --git a/docs/configuration/autoscale.md b/docs/configuration/autoscale.md
index c69f98daf7df494e4391d4c82c8015662c2d8bf4..9648ceb679de79c639dccad0c4227b495319bea0 100644
--- a/docs/configuration/autoscale.md
+++ b/docs/configuration/autoscale.md
@@ -396,12 +396,13 @@ concurrent = 50   # All registered Runners can run up to 50 concurrent jobs
         "engine-registry-mirror=http://10.11.12.13:12345"   # Docker Machine is using registry mirroring
     ]
   [runners.cache]
-    Type = "s3"   # The Runner is using a distributed cache with Amazon S3 service
-    ServerAddress = "s3-eu-west-1.amazonaws.com"
-    AccessKey = "AMAZON_S3_ACCESS_KEY"
-    SecretKey = "AMAZON_S3_SECRET_KEY"
-    BucketName = "runners"
-    Insecure = false
+    Type = "s3"
+    [runners.cache.s3]
+      ServerAddress = "s3-eu-west-1.amazonaws.com"
+      AccessKey = "AMAZON_S3_ACCESS_KEY"
+      SecretKey = "AMAZON_S3_SECRET_KEY"
+      BucketName = "runner"
+      Insecure = false
 ```
 
 Note that the `MachineOptions` parameter contains options for the `digitalocean`
diff --git a/docs/configuration/runner_autoscale_aws/index.md b/docs/configuration/runner_autoscale_aws/index.md
index be4e6588171ff3e4f7194a4c7017e0f7a92135b9..ce7ac433170a1167b161ff6b89eed6aba1c507e0 100644
--- a/docs/configuration/runner_autoscale_aws/index.md
+++ b/docs/configuration/runner_autoscale_aws/index.md
@@ -1,5 +1,5 @@
 ---
-last_updated: 2017-11-24
+last_updated: 2019-01-11
 ---
 
 > **[Article Type](https://docs.gitlab.com/ee/development/writing_documentation.html#types-of-technical-articles):** Admin guide ||
@@ -31,6 +31,11 @@ NOTE: **Note:**
 A familiarity with Amazon Web Services (AWS) is required as this is where most
 of the configuration will take place.
 
+TIP: **Tip:**
+We suggest a quick read through docker machine [`amazonec2` driver
+documentation](https://docs.docker.com/machine/drivers/aws/) to familiarize
+yourself with the parameters we will set later in this article.
+
 Your GitLab instance is going to need to talk to the Runners over the network,
 and that is something you need think about when configuring any AWS security
 groups or when setting up your DNS configuration.
@@ -231,9 +236,10 @@ Here's an example of the `runners.machine` section:
       "amazonec2-region=us-central-1",
       "amazonec2-vpc-id=vpc-xxxxx",
       "amazonec2-subnet-id=subnet-xxxxx",
+      "amazonec2-zone=x",
       "amazonec2-use-private-address=true",
       "amazonec2-tags=runner-manager-name,gitlab-aws-autoscaler,gitlab,true,gitlab-runner-autoscale,true",
-      "amazonec2-security-group=docker-machine-scaler",
+      "amazonec2-security-group=xxxxx",
       "amazonec2-instance-type=m4.2xlarge",
     ]
 ```
@@ -252,9 +258,10 @@ under `MachineOptions`. Below you can see the most common ones.
 | `amazonec2-region=eu-central-1` | The region to use when launching the instance. You can omit this entirely and the default `us-east-1` will be used. |
 | `amazonec2-vpc-id=vpc-xxxxx` | Your [VPC ID](https://docs.docker.com/machine/drivers/aws/#vpc-id) to launch the instance in. |
 | `amazonec2-subnet-id=subnet-xxxx` | The AWS VPC subnet ID. |
+| `amazonec2-zone=x` | If not specified, the [availability zone is `a`](https://docs.docker.com/machine/drivers/aws/#environment-variables-and-default-values), it needs to be set to the same availability zone as the specified subnet, for example when the zone is `eu-west-1b` it has to be `amazonec2-zone=b` |
 | `amazonec2-use-private-address=true` | Use the private IP address of Docker Machines, but still create a public IP address. Useful to keep the traffic internal and avoid extra costs.|
 | `amazonec2-tags=runner-manager-name,gitlab-aws-autoscaler,gitlab,true,gitlab-runner-autoscale,true` | AWS extra tag key-value pairs, useful to identify the instances on the AWS console. The "Name" tag is set to the machine name by default. We set the "runner-manager-name" to match the Runner name set in `[[runners]]`, so that we can filter all the EC2 instances created by a specific manager setup. Read more about [using tags in AWS](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Using_Tags.html). |
-| `amazonec2-security-group=docker-machine-scaler` | AWS VPC security group name, see [AWS security groups](#aws-security-groups). |
+| `amazonec2-security-group=xxxx` | AWS VPC security group name, see [AWS security groups](#aws-security-groups). |
 | `amazonec2-instance-type=m4.2xlarge` | The instance type that the child Runners will run on. |
 
 TIP: **Tip:**
diff --git a/docs/executors/README.md b/docs/executors/README.md
index f30526f63f33ea349c594ef17c50dad2568d1bc5..06bd8e668349b07182d7c8b14bc6e1b135299108 100644
--- a/docs/executors/README.md
+++ b/docs/executors/README.md
@@ -4,9 +4,9 @@ GitLab Runner implements a number of executors that can be used to run your
 builds in different scenarios. If you are not sure what to select, read the
 [I am not sure](#i-am-not-sure) section.
 Visit the [compatibility chart](#compatibility-chart) to find
-out what features each executor supports and what not.
+out what features each executor does and does not support.
 
-To jump into the specific documentation of each executor, visit:
+To jump into the specific documentation for each executor, visit:
 
 - [SSH](ssh.md)
 - [Shell](shell.md)
@@ -20,7 +20,7 @@ To jump into the specific documentation of each executor, visit:
 
 The executors support different platforms and methodologies for building a
 project. The table below shows the key facts for each executor which will help
-you decide.
+you decide which executor to use.
 
 | Executor                                          | SSH  | Shell   | VirtualBox | Parallels | Docker | Kubernetes |
 |:--------------------------------------------------|:----:|:-------:|:----------:|:---------:|:------:|:----------:|
@@ -37,37 +37,31 @@ you decide.
 
 ### I am not sure
 
-#### SSH Executor
-
-The **SSH** executor is added for completeness. It's the least supported
-among all executors. It makes GitLab Runner to connect to some external server
-and run the builds there. We have some success stories from organizations using
-that executor, but generally we advise to use any other.
-
 #### Shell Executor
 
 **Shell** is the simplest executor to configure. All required dependencies for
-your builds need to be installed manually on the machine that the Runner is
-installed.
+your builds need to be installed manually on the same machine that the Runner is
+installed on.
 
 #### Virtual Machine Executor (VirtualBox / Parallels)
 
-We also offer two full system virtualization options: **VirtualBox** and
-**Parallels**. This type of executor allows you to use an already created
-virtual machine, which will be cloned and used to run your build. It can prove
-useful if you want to run your builds on different Operating Systems since it
-allows to create virtual machines with Windows, Linux, OSX or FreeBSD and make
-GitLab Runner to connect to the virtual machine and run the build on it. Its
-usage can also be useful to reduce the cost of infrastructure.
+This type of executor allows you to use an already created virtual machine, which
+is cloned and used to run your build. We offer two full system virtualization
+options: **VirtualBox** and **Parallels**. They can prove useful if you want to run
+your builds on different operating systems, since it allows the creation of virtual
+machines on Windows, Linux, OSX or FreeBSD, then GitLab Runner connects to the
+virtual machine and runs the build on it. Its usage can also be useful for reducing
+infrastructure costs.
 
 #### Docker Executor
 
-A better way is to use **Docker** as it allows to have a clean build environment,
-with easy dependency management (all dependencies for building the project could
+A great option is to use **Docker** as it allows a clean build environment,
+with easy dependency management (all dependencies for building the project can
 be put in the Docker image). The Docker executor allows you to easily create
-a build environment with dependent [services], like MySQL.
+a build environment with dependent [services](https://docs.gitlab.com/ee/ci/services/README.html),
+like MySQL.
 
-##### Docker Machine
+#### Docker Machine
 
 The **Docker Machine** is a special version of the **Docker** executor
 with support for auto-scaling. It works like the normal **Docker** executor
@@ -75,11 +69,18 @@ but with build hosts created on demand by _Docker Machine_.
 
 #### Kubernetes Executor
 
-The **Kubernetes**  executor allows you to use an existing Kubernetes cluster
+The **Kubernetes** executor allows you to use an existing Kubernetes cluster
 for your builds. The executor will call the Kubernetes cluster API
-and create a new Pod (with build container and services containers) for
+and create a new Pod (with a build container and services containers) for
 each GitLab CI job.
 
+#### SSH Executor
+
+The **SSH** executor is added for completeness, but it's the least supported
+among all executors. It makes GitLab Runner connect to an external server
+and runs the builds there. We have some success stories from organizations using
+this executor, but usually we recommend using one of the other types.
+
 ## Compatibility chart
 
 Supported features by different executors:
@@ -114,5 +115,3 @@ Supported systems for interactive web terminals by different shells:
 | Linux   | ✓           | ✗             | ✗          |
 | OSX     | ✓           | ✗             | ✗          |
 | FreeBSD | ✓           | ✗             | ✗          |
-
-[services]: https://docs.gitlab.com/ee/ci/services/README.html
diff --git a/docs/executors/kubernetes.md b/docs/executors/kubernetes.md
index ba6764a2be502759afd9b2a72eebbde7003cc938..c61651ceab748114b93a6c795d78fc7cd8214f67 100644
--- a/docs/executors/kubernetes.md
+++ b/docs/executors/kubernetes.md
@@ -76,6 +76,7 @@ The following keywords help to define the behaviour of the Runner within Kuberne
 - `helper_memory_request`: The amount of memory requested for build helper containers
 - `pull_policy`: specify the image pull policy: `never`, `if-not-present`, `always`. The cluster default will be used if not set.
 - `node_selector`: A `table` of `key=value` pairs of `string=string`. Setting this limits the creation of pods to kubernetes nodes matching all the `key=value` pairs
+- `node_tolerations`: A `table` of `key=value:Effect` pairs in the format of `string=string:string`. Setting this allows pods to schedule to nodes with all or a subset of tolerated taints. Only one toleration can be supplied through environment variable configuration. The `key`, `value`, and `effect` match with the corresponding field names in kubernetes pod toleration configuration.
 - `image_pull_secrets`: A array of secrets that are used to authenticate docker image pulling
 - `helper_image`: [ADVANCED] Override the default helper image used to clone repos and upload artifacts. Read the [helper image][advanced-configuration-helper-image] section of _advanced configuration_ page for more details
 - `terminationGracePeriodSeconds`: Duration after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal
@@ -121,7 +122,7 @@ disabled.
 Additionally, Kubernetes service account can be overwritten on `.gitlab-ci.yml` file, by using the variable
 `KUBERNETES_SERVICE_ACCOUNT_OVERWRITE`.
 
-This approach allow you to specify a service account that is attached to the namespace, usefull when dealing
+This approach allow you to specify a service account that is attached to the namespace, useful when dealing
 with complex RBAC configurations.
 ``` yaml
 variables:
@@ -363,7 +364,10 @@ when running in privileged mode or by exposing `/var/run/docker.sock` is to use
 the `node_selector` option to set one or more labels that have to match a node
 before any containers are deployed to it. For example build containers may only run
 on nodes that are labeled with `role=ci` while running all other production services
-on other nodes.
+on other nodes. Further separation of build containers can be achieved using node
+[taints](https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/).
+This will disallow other pods from scheduling on the same nodes as the
+build pods without extra configuration for the other pods.
 
 [k8s-host-path-volume-docs]: https://kubernetes.io/docs/concepts/storage/volumes/#hostpath
 [k8s-pvc-volume-docs]: https://kubernetes.io/docs/concepts/storage/volumes/#persistentvolumeclaim
diff --git a/docs/executors/virtualbox.md b/docs/executors/virtualbox.md
index 30279e6233f506f07b6e70786ff2290d317fa376..e876bf6b26caf4fd49b0352e09e805b3ca5cb04d 100644
--- a/docs/executors/virtualbox.md
+++ b/docs/executors/virtualbox.md
@@ -18,7 +18,7 @@ Where:
 - `<namespace>` is the namespace where the project is stored on GitLab
 - `<project-name>` is the name of the project as it is stored on GitLab
 
-To overwrite the `~/builds` directory, specify the `builds_dir` option under
+To override the `~/builds` directory, specify the `builds_dir` option under
 the `[[runners]]` section in
 [`config.toml`](../configuration/advanced-configuration.md).
 
diff --git a/docs/index.md b/docs/index.md
index 875d9492e0b22b1b4a152b68ebdc0a476203cee9..012c62997c246bd98fd32c4be96341a19f27f6b9 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -28,23 +28,23 @@ installed.
 ## Features
 
 - Allows to run:
- - multiple jobs concurrently
- - use multiple tokens with multiple server (even per-project)
- - limit number of concurrent jobs per-token
+  - multiple jobs concurrently
+  - use multiple tokens with multiple server (even per-project)
+  - limit number of concurrent jobs per-token
 - Jobs can be run:
- - locally
- - using Docker containers
- - using Docker containers and executing job over SSH
- - using Docker containers with autoscaling on different clouds and virtualization hypervisors
- - connecting to remote SSH server
+  - locally
+  - using Docker containers
+  - using Docker containers and executing job over SSH
+  - using Docker containers with autoscaling on different clouds and virtualization hypervisors
+  - connecting to remote SSH server
 - Is written in Go and distributed as single binary without any other requirements
 - Supports Bash, Windows Batch and Windows PowerShell
-- Works on GNU/Linux, OS X and Windows (pretty much anywhere you can run Docker)
+- Works on GNU/Linux, macOS and Windows (pretty much anywhere you can run Docker)
 - Allows to customize the job running environment
 - Automatic configuration reload without restart
 - Easy to use setup with support for Docker, Docker-SSH, Parallels or SSH running environments
 - Enables caching of Docker containers
-- Easy installation as a service for GNU/Linux, OSX and Windows
+- Easy installation as a service for GNU/Linux, macOS and Windows
 - Embedded Prometheus metrics HTTP server
 
 ## Compatibility chart
@@ -113,6 +113,7 @@ To jump into the specific documentation of each executor, visit:
 - [Cleanup the Docker images automatically](https://gitlab.com/gitlab-org/gitlab-runner-docker-cleanup) A simple Docker application that automatically garbage collects the GitLab Runner caches and images when running low on disk space.
 - [Configure GitLab Runner to run behind a proxy](configuration/proxy.md) Learn how to set up a Linux proxy and configure GitLab Runner. Especially useful for the Docker executor.
 - [Feature Flags](configuration/feature-flags.md) Learn how to use feature flags to get access to features in beta stage or to enable breaking changes before the full deprecation and replacement is handled.
+- [Configure Session Server](configuration/advanced-configuration.md#the-session_server-section) Learn how to configure a session server for interacting with jobs the Runner is responsible for.
 
 ## Troubleshooting
 
diff --git a/docs/install/docker.md b/docs/install/docker.md
index 445b730f29ef4338a2ba5aa30237a24443f3e366..f8a376a2de343e11548a0c9056bc3f89ac766b47 100644
--- a/docs/install/docker.md
+++ b/docs/install/docker.md
@@ -84,7 +84,9 @@ Docker container.
         gitlab/gitlab-runner:latest
     ```
 
-1. [Register the Runner](../register/index.md#docker)
+1. Register the runner you just launched by following the instructions in the
+    [Docker section of Registering Runners](../register/index.md#docker).
+    The runner won't pick up any jobs until it's registered.
 
 Make sure that you read the [FAQ](../faq/README.md) section which describes
 some of the most common problems with GitLab Runner.
@@ -115,7 +117,7 @@ docker run -d --name gitlab-runner --restart always \
 NOTE: **Note:**
 You need to use the same method for mounting you data volume as you
 did originally (`-v /srv/gitlab-runner/config:/etc/gitlab-runner` or
-`--volumes-from gitlab-runner`).
+`--volumes-from gitlab-runner-config`).
 
 ## Reading GitLab Runner logs
 
diff --git a/docs/install/kubernetes.md b/docs/install/kubernetes.md
index 3920108a3aa1710ab18dd65f32d907c20d180bb4..9c3db168bd25c0234c6413b6493e6ffda1bc2d36 100644
--- a/docs/install/kubernetes.md
+++ b/docs/install/kubernetes.md
@@ -59,7 +59,6 @@ spec:
       - args:
         - run
         image: gitlab/gitlab-runner:latest
-        imagePullPolicy: Always
         name: gitlab-runner
         volumeMounts:
         - mountPath: /etc/gitlab-runner
diff --git a/docs/install/linux-repository.md b/docs/install/linux-repository.md
index 1e7e318c4ae70dbbbcc3c90ba7975db27d10ef60..4f3937f421469e79c8602d061a794aed68783739 100644
--- a/docs/install/linux-repository.md
+++ b/docs/install/linux-repository.md
@@ -66,7 +66,7 @@ To install the Runner:
     be done manually or automatically - will be done using the same source:
     >
     ```bash
-    cat > /etc/apt/preferences.d/pin-gitlab-runner.pref <<EOF
+    cat <<EOF | sudo tee /etc/apt/preferences.d/pin-gitlab-runner.pref
     Explanation: Prefer GitLab provided packages over the Debian native ones
     Package: gitlab-runner
     Pin: origin packages.gitlab.com
diff --git a/docs/register/index.md b/docs/register/index.md
index 819b2d9b4edd866465d672b98fdbef75ee6b3ad9..5a92b9b3abbc2e6e7d24b74fe3fa5cd61dbe7cbf 100644
--- a/docs/register/index.md
+++ b/docs/register/index.md
@@ -23,14 +23,14 @@ To register a Runner under GNU/Linux:
 
 1. Enter your GitLab instance URL:
 
-    ```
+    ```text
     Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com )
     https://gitlab.com
     ```
 
 1. Enter the token you obtained to register the Runner:
 
-    ```
+    ```text
     Please enter the gitlab-ci token for this runner
     xxx
     ```
@@ -38,21 +38,21 @@ To register a Runner under GNU/Linux:
 1. Enter a description for the Runner, you can change this later in GitLab's
    UI:
 
-    ```
+    ```text
     Please enter the gitlab-ci description for this runner
     [hostame] my-runner
     ```
 
 1. Enter the [tags associated with the Runner][tags], you can change this later in GitLab's UI:
 
-    ```
+    ```text
     Please enter the gitlab-ci tags for this runner (comma separated):
     my-tag,another-tag
     ```
 
 1. Enter the [Runner executor](../executors/README.md):
 
-    ```
+    ```text
     Please enter the executor: ssh, docker+machine, docker-ssh+machine, kubernetes, docker, parallels, virtualbox, docker-ssh, shell:
     docker
     ```
@@ -60,7 +60,7 @@ To register a Runner under GNU/Linux:
 1. If you chose Docker as your executor, you'll be asked for the default
    image to be used for projects that do not define one in `.gitlab-ci.yml`:
 
-    ```
+    ```text
     Please enter the Docker image (eg. ruby:2.1):
     alpine:latest
     ```
@@ -77,14 +77,14 @@ To register a Runner under macOS:
 
 1. Enter your GitLab instance URL:
 
-    ```
+    ```text
     Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com )
     https://gitlab.com
     ```
 
 1. Enter the token you obtained to register the Runner:
 
-    ```
+    ```text
     Please enter the gitlab-ci token for this runner
     xxx
     ```
@@ -92,21 +92,21 @@ To register a Runner under macOS:
 1. Enter a description for the Runner, you can change this later in GitLab's
    UI:
 
-    ```
+    ```text
     Please enter the gitlab-ci description for this runner
     [hostame] my-runner
     ```
 
 1. Enter the [tags associated with the Runner][tags], you can change this later in GitLab's UI:
 
-    ```
+    ```text
     Please enter the gitlab-ci tags for this runner (comma separated):
     my-tag,another-tag
     ```
 
 1. Enter the [Runner executor](../executors/README.md):
 
-    ```
+    ```text
     Please enter the executor: ssh, docker+machine, docker-ssh+machine, kubernetes, docker, parallels, virtualbox, docker-ssh, shell:
     docker
     ```
@@ -114,7 +114,7 @@ To register a Runner under macOS:
 1. If you chose Docker as your executor, you'll be asked for the default
    image to be used for projects that do not define one in `.gitlab-ci.yml`:
 
-    ```
+    ```text
     Please enter the Docker image (eg. ruby:2.1):
     alpine:latest
     ```
@@ -132,14 +132,14 @@ To register a Runner under Windows:
 
 1. Enter your GitLab instance URL:
 
-    ```
+    ```text
     Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com )
     https://gitlab.com
     ```
 
 1. Enter the token you obtained to register the Runner:
 
-    ```
+    ```text
     Please enter the gitlab-ci token for this runner
     xxx
     ```
@@ -147,21 +147,21 @@ To register a Runner under Windows:
 1. Enter a description for the Runner, you can change this later in GitLab's
    UI:
 
-    ```
+    ```text
     Please enter the gitlab-ci description for this runner
     [hostame] my-runner
     ```
 
 1. Enter the [tags associated with the Runner][tags], you can change this later in GitLab's UI:
 
-    ```
+    ```text
     Please enter the gitlab-ci tags for this runner (comma separated):
     my-tag,another-tag
     ```
 
 1. Enter the [Runner executor](../executors/README.md):
 
-    ```
+    ```text
     Please enter the executor: ssh, docker+machine, docker-ssh+machine, kubernetes, docker, parallels, virtualbox, docker-ssh, shell:
     docker
     ```
@@ -169,7 +169,7 @@ To register a Runner under Windows:
 1. If you chose Docker as your executor, you'll be asked for the default
    image to be used for projects that do not define one in `.gitlab-ci.yml`:
 
-    ```
+    ```text
     Please enter the Docker image (eg. ruby:2.1):
     alpine:latest
     ```
@@ -189,14 +189,14 @@ To register a Runner under FreeBSD:
 
 1. Enter your GitLab instance URL:
 
-    ```
+    ```text
     Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com )
     https://gitlab.com
     ```
 
 1. Enter the token you obtained to register the Runner:
 
-    ```
+    ```text
     Please enter the gitlab-ci token for this runner
     xxx
     ```
@@ -204,21 +204,21 @@ To register a Runner under FreeBSD:
 1. Enter a description for the Runner, you can change this later in GitLab's
    UI:
 
-    ```
+    ```text
     Please enter the gitlab-ci description for this runner
     [hostame] my-runner
     ```
 
 1. Enter the [tags associated with the Runner][tags], you can change this later in GitLab's UI:
 
-    ```
+    ```text
     Please enter the gitlab-ci tags for this runner (comma separated):
     my-tag,another-tag
     ```
 
 1. Enter the [Runner executor](../executors/README.md):
 
-    ```
+    ```text
     Please enter the executor: ssh, docker+machine, docker-ssh+machine, kubernetes, docker, parallels, virtualbox, docker-ssh, shell:
     docker
     ```
@@ -226,32 +226,42 @@ To register a Runner under FreeBSD:
 1. If you chose Docker as your executor, you'll be asked for the default
    image to be used for projects that do not define one in `.gitlab-ci.yml`:
 
-    ```
+    ```text
     Please enter the Docker image (eg. ruby:2.1):
     alpine:latest
     ```
 
 ## Docker
 
+These instructions are meant to be followed after [Run GitLab Runner in a container](../install/docker.md).
+In this section, you will launch an ephemeral `gitlab-runner` container to
+register the container that you created during install. After you finish
+registration, the resulting configuration will be written to your chosen config
+volume (e.g. `/srv/gitlab-runner/config`), and will be automatically loaded by
+the runner using that config volume.
+
 To register a Runner using a Docker container:
 
-1. Run the following command which will mount the Runner's config directory
-   under `/path/to/config`:
+1. Run the register command:  
 
     ```sh
-    docker run --rm -t -i -v /path/to/config:/etc/gitlab-runner --name gitlab-runner gitlab/gitlab-runner register
+    docker run --rm -t -i -v /srv/gitlab-runner/config:/etc/gitlab-runner gitlab/gitlab-runner register
     ```
 
+    NOTE: **Note:**
+    If you used a config volume other than `/srv/gitlab-runner/config` during
+    install, then you should update the command with the correct volume.
+
 1. Enter your GitLab instance URL:
 
-    ```
+    ```text
     Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com )
     https://gitlab.com
     ```
 
 1. Enter the token you obtained to register the Runner:
 
-    ```
+    ```text
     Please enter the gitlab-ci token for this runner
     xxx
     ```
@@ -259,21 +269,21 @@ To register a Runner using a Docker container:
 1. Enter a description for the Runner, you can change this later in GitLab's
    UI:
 
-    ```
+    ```text
     Please enter the gitlab-ci description for this runner
     [hostame] my-runner
     ```
 
 1. Enter the [tags associated with the Runner][tags], you can change this later in GitLab's UI:
 
-    ```
+    ```text
     Please enter the gitlab-ci tags for this runner (comma separated):
     my-tag,another-tag
     ```
 
 1. Enter the [Runner executor](../executors/README.md):
 
-    ```
+    ```text
     Please enter the executor: ssh, docker+machine, docker-ssh+machine, kubernetes, docker, parallels, virtualbox, docker-ssh, shell:
     docker
     ```
@@ -281,7 +291,7 @@ To register a Runner using a Docker container:
 1. If you chose Docker as your executor, you'll be asked for the default
    image to be used for projects that do not define one in `.gitlab-ci.yml`:
 
-    ```
+    ```text
     Please enter the Docker image (eg. ruby:2.1):
     alpine:latest
     ```
@@ -317,7 +327,7 @@ If you're running the Runner in a Docker container, the `register` command would
 look like:
 
 ```sh
-docker run --rm -t -i -v /path/to/config:/etc/gitlab-runner --name gitlab-runner gitlab/gitlab-runner register \
+docker run --rm -t -i -v /srv/gitlab-runner/config:/etc/gitlab-runner gitlab/gitlab-runner register \
   --non-interactive \
   --executor "docker" \
   --docker-image alpine:3 \
diff --git a/docs/shells/README.md b/docs/shells/README.md
index 2f5720507ae5cd94931b9cc2b83c002bb7d54155..e3c4467537b6718a9f67168e50b7477f3e8179cb 100644
--- a/docs/shells/README.md
+++ b/docs/shells/README.md
@@ -86,7 +86,7 @@ SET CI_COMMIT_REF_NAME=master
 SET CI_JOB_ID=1
 SET CI_REPOSITORY_URL=http://gitlab.example.com/group/project.git
 SET CI_PROJECT_ID=1
-SET CI_PROJECT_DIR=Z:/Gitlab/tests/test/builds/0/project-1
+SET CI_PROJECT_DIR=Z:\Gitlab\tests\test\builds\0\project-1
 SET CI_SERVER=yes
 SET CI_SERVER_NAME=GitLab CI
 SET CI_SERVER_VERSION=
@@ -100,7 +100,7 @@ echo multiline!nl!tls!nl!chain > C:\GitLab-Runner\builds\0\project-1.tmp\CI_SERV
 SET CI_SERVER_TLS_CA_FILE=C:\GitLab-Runner\builds\0\project-1.tmp\CI_SERVER_TLS_CA_FILE
 echo Cloning repository...
 rd /s /q "C:\GitLab-Runner\builds\0\project-1" 2>NUL 1>NUL
-"git" "clone" "http://gitlab.example.com/group/project.git" "Z:/Gitlab/tests/test/builds/0/project-1"
+"git" "clone" "http://gitlab.example.com/group/project.git" "Z:\Gitlab\tests\test\builds\0\project-1"
 IF %errorlevel% NEQ 0 exit /b %errorlevel%
 
 cd /D "C:\GitLab-Runner\builds\0\project-1"
@@ -133,7 +133,7 @@ SET CI_COMMIT_REF_NAME=master
 SET CI_JOB_ID=1
 SET CI_REPOSITORY_URL=Z:\Gitlab\tests\test
 SET CI_PROJECT_ID=1
-SET CI_PROJECT_DIR=Z:/Gitlab/tests/test/builds/0/project-1
+SET CI_PROJECT_DIR=Z:\Gitlab\tests\test\builds\0\project-1
 SET CI_SERVER=yes
 SET CI_SERVER_NAME=GitLab CI
 SET CI_SERVER_VERSION=
@@ -160,7 +160,7 @@ SET CI_COMMIT_REF_NAME=master
 SET CI_JOB_ID=1
 SET CI_REPOSITORY_URL=Z:\Gitlab\tests\test
 SET CI_PROJECT_ID=1
-SET CI_PROJECT_DIR=Z:/Gitlab/tests/test/builds/0/project-1
+SET CI_PROJECT_DIR=Z:\Gitlab\tests\test\builds\0\project-1
 SET CI_SERVER=yes
 SET CI_SERVER_NAME=GitLab CI
 SET CI_SERVER_VERSION=
@@ -215,7 +215,7 @@ echo "Running on $env:computername..."
   $env:CI_REPOSITORY_URL=$CI_REPOSITORY_URL
   $CI_PROJECT_ID="1"
   $env:CI_PROJECT_ID=$CI_PROJECT_ID
-  $CI_PROJECT_DIR="Z:/Gitlab/tests/test/builds/0/project-1"
+  $CI_PROJECT_DIR="Z:\Gitlab\tests\test\builds\0\project-1"
   $env:CI_PROJECT_DIR=$CI_PROJECT_DIR
   $CI_SERVER="yes"
   $env:CI_SERVER=$CI_SERVER
@@ -244,7 +244,7 @@ echo "Running on $env:computername..."
     Remove-Item -Force -Recurse "C:\GitLab-Runner\builds\0\project-1"
   }
 
-  & "git" "clone" "https://gitlab.com/group/project.git" "Z:/Gitlab/tests/test/builds/0/project-1"
+  & "git" "clone" "https://gitlab.com/group/project.git" "Z:\Gitlab\tests\test\builds\0\project-1"
   if(!$?) { Exit $LASTEXITCODE }
 
   cd "C:\GitLab-Runner\builds\0\project-1"
@@ -285,7 +285,7 @@ if(!$?) { Exit $LASTEXITCODE }
   $env:CI_REPOSITORY_URL=$CI_REPOSITORY_URL
   $CI_PROJECT_ID="1"
   $env:CI_PROJECT_ID=$CI_PROJECT_ID
-  $CI_PROJECT_DIR="Z:/Gitlab/tests/test/builds/0/project-1"
+  $CI_PROJECT_DIR="Z:\Gitlab\tests\test\builds\0\project-1"
   $env:CI_PROJECT_DIR=$CI_PROJECT_DIR
   $CI_SERVER="yes"
   $env:CI_SERVER=$CI_SERVER
@@ -330,7 +330,7 @@ if(!$?) { Exit $LASTEXITCODE }
   $env:CI_REPOSITORY_URL=$CI_REPOSITORY_URL
   $CI_PROJECT_ID="1"
   $env:CI_PROJECT_ID=$CI_PROJECT_ID
-  $CI_PROJECT_DIR="Z:/Gitlab/tests/test/builds/0/project-1"
+  $CI_PROJECT_DIR="Z:\Gitlab\tests\test\builds\0\project-1"
   $env:CI_PROJECT_DIR=$CI_PROJECT_DIR
   $CI_SERVER="yes"
   $env:CI_SERVER=$CI_SERVER
diff --git a/executors/docker/machine/name.go b/executors/docker/machine/name.go
index 6f748b77c5b8afd2caaff0e3fbe447ba0ecc0427..0cafa2f4d9db577fa02aaa76961adde4c36e5793 100644
--- a/executors/docker/machine/name.go
+++ b/executors/docker/machine/name.go
@@ -7,6 +7,7 @@ import (
 	"time"
 
 	"gitlab.com/gitlab-org/gitlab-runner/common"
+	"gitlab.com/gitlab-org/gitlab-runner/helpers/dns"
 )
 
 func machineFormat(runner string, template string) string {
@@ -17,7 +18,7 @@ func machineFormat(runner string, template string) string {
 }
 
 func machineFilter(config *common.RunnerConfig) string {
-	return machineFormat(config.ShortDescription(), config.Machine.MachineName)
+	return machineFormat(dns.MakeRFC1123Compatible(config.ShortDescription()), config.Machine.MachineName)
 }
 
 func matchesMachineFilter(name, filter string) bool {
diff --git a/executors/docker/machine/name_test.go b/executors/docker/machine/name_test.go
index e002307a149ec0859a3f6d3c7df6ff8241642c64..106bd07a4c5b54ac4710d56ab3d2c080e3638186 100644
--- a/executors/docker/machine/name_test.go
+++ b/executors/docker/machine/name_test.go
@@ -1,12 +1,46 @@
 package machine
 
 import (
+	"testing"
+
 	"github.com/stretchr/testify/assert"
+
 	"gitlab.com/gitlab-org/gitlab-runner/common"
-	"testing"
+	dns_test "gitlab.com/gitlab-org/gitlab-runner/helpers/dns/test"
 )
 
-func TestMachineNewName(t *testing.T) {
+func TestNewMachineName(t *testing.T) {
+	testCases := map[string]struct {
+		token string
+	}{
+		"DNS-1123 compatible token": {
+			token: "token-of",
+		},
+		"non DNS-1123 compatible token": {
+			token: "ToK3_?OF",
+		},
+	}
+
+	for name, testCase := range testCases {
+		t.Run(name, func(t *testing.T) {
+			config := &common.RunnerConfig{
+				RunnerCredentials: common.RunnerCredentials{
+					Token: testCase.token,
+				},
+				RunnerSettings: common.RunnerSettings{
+					Machine: &common.DockerMachine{
+						MachineName: "test-machine-%s",
+					},
+				},
+			}
+
+			name := newMachineName(config)
+			dns_test.AssertRFC1123Compatibility(t, name)
+		})
+	}
+}
+
+func TestNewMachineNameIsUnique(t *testing.T) {
 	config := &common.RunnerConfig{
 		RunnerSettings: common.RunnerSettings{
 			Machine: &common.DockerMachine{
diff --git a/executors/kubernetes/executor_kubernetes.go b/executors/kubernetes/executor_kubernetes.go
index 89bd0c4091f369151effd9974c16935744f53804..4f9337258c54300b5dd17982aa5af3492b5a5681 100644
--- a/executors/kubernetes/executor_kubernetes.go
+++ b/executors/kubernetes/executor_kubernetes.go
@@ -20,6 +20,7 @@ import (
 
 	"gitlab.com/gitlab-org/gitlab-runner/common"
 	"gitlab.com/gitlab-org/gitlab-runner/executors"
+	"gitlab.com/gitlab-org/gitlab-runner/helpers/dns"
 	terminalsession "gitlab.com/gitlab-org/gitlab-runner/session/terminal"
 )
 
@@ -393,6 +394,10 @@ type dockerConfigEntry struct {
 	Username, Password string
 }
 
+func (s *executor) projectUniqueName() string {
+	return dns.MakeRFC1123Compatible(s.Build.ProjectUniqueName())
+}
+
 func (s *executor) setupCredentials() error {
 	authConfigs := make(map[string]dockerConfigEntry)
 
@@ -417,7 +422,7 @@ func (s *executor) setupCredentials() error {
 	}
 
 	secret := api.Secret{}
-	secret.GenerateName = s.Build.ProjectUniqueName()
+	secret.GenerateName = s.projectUniqueName()
 	secret.Namespace = s.configurationOverwrites.namespace
 	secret.Type = api.SecretTypeDockercfg
 	secret.Data = map[string][]byte{}
@@ -461,7 +466,7 @@ func (s *executor) setupBuildPod() error {
 
 	pod, err := s.kubeClient.CoreV1().Pods(s.configurationOverwrites.namespace).Create(&api.Pod{
 		ObjectMeta: metav1.ObjectMeta{
-			GenerateName: s.Build.ProjectUniqueName(),
+			GenerateName: s.projectUniqueName(),
 			Namespace:    s.configurationOverwrites.namespace,
 			Labels:       labels,
 			Annotations:  annotations,
@@ -471,6 +476,7 @@ func (s *executor) setupBuildPod() error {
 			ServiceAccountName: s.configurationOverwrites.serviceAccount,
 			RestartPolicy:      api.RestartPolicyNever,
 			NodeSelector:       s.Config.Kubernetes.NodeSelector,
+			Tolerations:        s.Config.Kubernetes.GetNodeTolerations(),
 			Containers: append([]api.Container{
 				// TODO use the build and helper template here
 				s.buildContainer("build", buildImage, s.options.Image, s.buildRequests, s.buildLimits, s.BuildShell.DockerCommand...),
diff --git a/executors/kubernetes/executor_kubernetes_test.go b/executors/kubernetes/executor_kubernetes_test.go
index 2dcf2ea2f40021af6abaa05018cbd554bad2ea3a..170bfd387a6d175e6d8ee71688373a2f80c4d526 100644
--- a/executors/kubernetes/executor_kubernetes_test.go
+++ b/executors/kubernetes/executor_kubernetes_test.go
@@ -20,7 +20,6 @@ import (
 	"github.com/sirupsen/logrus"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
-	"gitlab.com/gitlab-org/gitlab-runner/session"
 
 	api "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/api/resource"
@@ -30,6 +29,8 @@ import (
 	"gitlab.com/gitlab-org/gitlab-runner/common"
 	"gitlab.com/gitlab-org/gitlab-runner/executors"
 	"gitlab.com/gitlab-org/gitlab-runner/helpers"
+	dns_test "gitlab.com/gitlab-org/gitlab-runner/helpers/dns/test"
+	"gitlab.com/gitlab-org/gitlab-runner/session"
 )
 
 var (
@@ -892,15 +893,16 @@ func TestSetupCredentials(t *testing.T) {
 	version, _ := testVersionAndCodec()
 
 	type testDef struct {
-		Credentials []common.Credentials
-		VerifyFn    func(*testing.T, testDef, *api.Secret)
+		RunnerCredentials *common.RunnerCredentials
+		Credentials       []common.Credentials
+		VerifyFn          func(*testing.T, testDef, *api.Secret)
 	}
-	tests := []testDef{
-		{
+	tests := map[string]testDef{
+		"no credentials": {
 			// don't execute VerifyFn
 			VerifyFn: nil,
 		},
-		{
+		"registry credentials": {
 			Credentials: []common.Credentials{
 				{
 					Type:     "registry",
@@ -914,7 +916,7 @@ func TestSetupCredentials(t *testing.T) {
 				assert.NotEmpty(t, secret.Data[api.DockerConfigKey])
 			},
 		},
-		{
+		"other credentials": {
 			Credentials: []common.Credentials{
 				{
 					Type:     "other",
@@ -926,6 +928,22 @@ func TestSetupCredentials(t *testing.T) {
 			// don't execute VerifyFn
 			VerifyFn: nil,
 		},
+		"non-DNS-1123-compatible-token": {
+			RunnerCredentials: &common.RunnerCredentials{
+				Token: "ToK3_?OF",
+			},
+			Credentials: []common.Credentials{
+				{
+					Type:     "registry",
+					URL:      "http://example.com",
+					Username: "user",
+					Password: "password",
+				},
+			},
+			VerifyFn: func(t *testing.T, test testDef, secret *api.Secret) {
+				dns_test.AssertRFC1123Compatibility(t, secret.GetGenerateName())
+			},
+		},
 	}
 
 	executed := false
@@ -962,39 +980,50 @@ func TestSetupCredentials(t *testing.T) {
 		}
 	}
 
-	for _, test := range tests {
-		ex := executor{
-			kubeClient: testKubernetesClient(version, fake.CreateHTTPClient(fakeClientRoundTripper(test))),
-			options:    &kubernetesOptions{},
-			AbstractExecutor: executors.AbstractExecutor{
-				Config: common.RunnerConfig{
-					RunnerSettings: common.RunnerSettings{
-						Kubernetes: &common.KubernetesConfig{
-							Namespace: "default",
+	for testName, test := range tests {
+		t.Run(testName, func(t *testing.T) {
+			ex := executor{
+				kubeClient: testKubernetesClient(version, fake.CreateHTTPClient(fakeClientRoundTripper(test))),
+				options:    &kubernetesOptions{},
+				AbstractExecutor: executors.AbstractExecutor{
+					Config: common.RunnerConfig{
+						RunnerSettings: common.RunnerSettings{
+							Kubernetes: &common.KubernetesConfig{
+								Namespace: "default",
+							},
 						},
 					},
-				},
-				BuildShell: &common.ShellConfiguration{},
-				Build: &common.Build{
-					JobResponse: common.JobResponse{
-						Variables:   []common.JobVariable{},
-						Credentials: test.Credentials,
+					BuildShell: &common.ShellConfiguration{},
+					Build: &common.Build{
+						JobResponse: common.JobResponse{
+							Variables:   []common.JobVariable{},
+							Credentials: test.Credentials,
+						},
+						Runner: &common.RunnerConfig{},
 					},
-					Runner: &common.RunnerConfig{},
 				},
-			},
-		}
+			}
 
-		executed = false
-		err := ex.prepareOverwrites(make(common.JobVariables, 0))
-		assert.NoError(t, err)
-		err = ex.setupCredentials()
-		assert.NoError(t, err)
-		if test.VerifyFn != nil {
-			assert.True(t, executed)
-		} else {
-			assert.False(t, executed)
-		}
+			if test.RunnerCredentials != nil {
+				ex.Build.Runner = &common.RunnerConfig{
+					RunnerCredentials: *test.RunnerCredentials,
+				}
+			}
+
+			executed = false
+
+			err := ex.prepareOverwrites(make(common.JobVariables, 0))
+			assert.NoError(t, err)
+
+			err = ex.setupCredentials()
+			assert.NoError(t, err)
+
+			if test.VerifyFn != nil {
+				assert.True(t, executed)
+			} else {
+				assert.False(t, executed)
+			}
+		})
 	}
 }
 
@@ -1194,6 +1223,49 @@ func TestSetupBuildPod(t *testing.T) {
 				}
 			},
 		},
+		"support setting kubernetes pod taint tolerations": {
+			RunnerConfig: common.RunnerConfig{
+				RunnerSettings: common.RunnerSettings{
+					Kubernetes: &common.KubernetesConfig{
+						Namespace: "default",
+						NodeTolerations: map[string]string{
+							"node-role.kubernetes.io/master": "NoSchedule",
+							"custom.toleration=value":        "NoSchedule",
+							"empty.value=":                   "PreferNoSchedule",
+							"onlyKey":                        "",
+						},
+					},
+				},
+			},
+			VerifyFn: func(t *testing.T, test setupBuildPodTestDef, pod *api.Pod) {
+				expectedTolerations := []api.Toleration{
+					{
+						Key:      "node-role.kubernetes.io/master",
+						Operator: api.TolerationOpExists,
+						Effect:   api.TaintEffectNoSchedule,
+					},
+					{
+						Key:      "custom.toleration",
+						Operator: api.TolerationOpEqual,
+						Value:    "value",
+						Effect:   api.TaintEffectNoSchedule,
+					},
+					{
+
+						Key:      "empty.value",
+						Operator: api.TolerationOpEqual,
+						Value:    "",
+						Effect:   api.TaintEffectPreferNoSchedule,
+					},
+					{
+						Key:      "onlyKey",
+						Operator: api.TolerationOpExists,
+						Effect:   "",
+					},
+				}
+				assert.ElementsMatch(t, expectedTolerations, pod.Spec.Tolerations)
+			},
+		},
 		"supports extended docker configuration for image and services": {
 			RunnerConfig: common.RunnerConfig{
 				RunnerSettings: common.RunnerSettings{
@@ -1368,6 +1440,21 @@ func TestSetupBuildPod(t *testing.T) {
 				assert.Equal(t, []string{"argument1", "argument2"}, pod.Spec.Containers[4].Args)
 			},
 		},
+		"non-DNS-1123-compatible-token": {
+			RunnerConfig: common.RunnerConfig{
+				RunnerCredentials: common.RunnerCredentials{
+					Token: "ToK3_?OF",
+				},
+				RunnerSettings: common.RunnerSettings{
+					Kubernetes: &common.KubernetesConfig{
+						Namespace: "default",
+					},
+				},
+			},
+			VerifyFn: func(t *testing.T, test setupBuildPodTestDef, pod *api.Pod) {
+				dns_test.AssertRFC1123Compatibility(t, pod.GetGenerateName())
+			},
+		},
 	}
 
 	for testName, test := range tests {
@@ -1741,9 +1828,20 @@ func TestInteractiveTerminal(t *testing.T) {
 	srv := httptest.NewServer(build.Session.Mux())
 	defer srv.Close()
 
-	u := url.URL{Scheme: "ws", Host: srv.Listener.Addr().String(), Path: build.Session.Endpoint + "/exec"}
-	conn, resp, err := websocket.DefaultDialer.Dial(u.String(), http.Header{"Authorization": []string{build.Session.Token}})
-	defer conn.Close()
+	u := url.URL{
+		Scheme: "ws",
+		Host:   srv.Listener.Addr().String(),
+		Path:   build.Session.Endpoint + "/exec",
+	}
+	headers := http.Header{
+		"Authorization": []string{build.Session.Token},
+	}
+	conn, resp, err := websocket.DefaultDialer.Dial(u.String(), headers)
+	defer func() {
+		if conn != nil {
+			_ = conn.Close()
+		}
+	}()
 	require.NoError(t, err)
 	assert.Equal(t, resp.StatusCode, http.StatusSwitchingProtocols)
 
diff --git a/executors/shell/executor_shell_test.go b/executors/shell/executor_shell_test.go
index 6641e983d4074f1ec414c435e01be52e06a113fe..4d23847be0f9b1283cb0367f997662b50cdbda1b 100644
--- a/executors/shell/executor_shell_test.go
+++ b/executors/shell/executor_shell_test.go
@@ -732,14 +732,21 @@ func TestInteractiveTerminal(t *testing.T) {
 			srv := httptest.NewServer(build.Session.Mux())
 			defer srv.Close()
 
-			u := url.URL{Scheme: "ws", Host: srv.Listener.Addr().String(), Path: build.Session.Endpoint + "/exec"}
-			conn, resp, err := websocket.DefaultDialer.Dial(u.String(), http.Header{"Authorization": []string{build.Session.Token}})
+			u := url.URL{
+				Scheme: "ws",
+				Host:   srv.Listener.Addr().String(),
+				Path:   build.Session.Endpoint + "/exec",
+			}
+			headers := http.Header{
+				"Authorization": []string{build.Session.Token},
+			}
+			conn, resp, err := websocket.DefaultDialer.Dial(u.String(), headers)
 			assert.NoError(t, err)
 			assert.Equal(t, c.expectedStatusCode, resp.StatusCode)
 
 			defer func() {
 				if conn != nil {
-					defer conn.Close()
+					conn.Close()
 				}
 			}()
 
diff --git a/helpers/dns/test/test.go b/helpers/dns/test/test.go
new file mode 100644
index 0000000000000000000000000000000000000000..d51927b93d5362898c20121e2047a805d1a4ccb4
--- /dev/null
+++ b/helpers/dns/test/test.go
@@ -0,0 +1,16 @@
+package test
+
+import (
+	"regexp"
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func AssertRFC1123Compatibility(t *testing.T, name string) {
+	dns1123MaxLength := 63
+	dns1123FormatRegexp := regexp.MustCompile("^[a-z0-9]([-a-z0-9]*[a-z0-9])?$")
+
+	assert.True(t, len(name) <= dns1123MaxLength, "Name length needs to be shorter than %d", dns1123MaxLength)
+	assert.Regexp(t, dns1123FormatRegexp, name, "Name needs to be in RFC-1123 allowed format")
+}
diff --git a/helpers/dns/utils.go b/helpers/dns/utils.go
new file mode 100644
index 0000000000000000000000000000000000000000..f8201b26cd36d421538cf26921d6e6057c04347c
--- /dev/null
+++ b/helpers/dns/utils.go
@@ -0,0 +1,28 @@
+package dns
+
+import (
+	"regexp"
+	"strings"
+)
+
+const (
+	RFC1123NameMaximumLength         = 63
+	RFC1123NotAllowedCharacters      = "[^-a-z0-9]"
+	RFC1123NotAllowedStartCharacters = "^[^a-z0-9]+"
+)
+
+func MakeRFC1123Compatible(name string) string {
+	name = strings.ToLower(name)
+
+	nameNotAllowedChars := regexp.MustCompile(RFC1123NotAllowedCharacters)
+	name = nameNotAllowedChars.ReplaceAllString(name, "")
+
+	nameNotAllowedStartChars := regexp.MustCompile(RFC1123NotAllowedStartCharacters)
+	name = nameNotAllowedStartChars.ReplaceAllString(name, "")
+
+	if len(name) > RFC1123NameMaximumLength {
+		name = name[0:RFC1123NameMaximumLength]
+	}
+
+	return name
+}
diff --git a/helpers/dns/utils_test.go b/helpers/dns/utils_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..3c0c60eac03ea4daa674ca7705caf314266a8dc1
--- /dev/null
+++ b/helpers/dns/utils_test.go
@@ -0,0 +1,29 @@
+package dns
+
+import (
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+
+	"gitlab.com/gitlab-org/gitlab-runner/helpers/dns/test"
+)
+
+func TestMakeRFC1123Compatible(t *testing.T) {
+	examples := []struct {
+		name     string
+		expected string
+	}{
+		{name: "tOk3_?ofTHE-Runner", expected: "tok3ofthe-runner"},
+		{name: "----tOk3_?ofTHE-Runner", expected: "tok3ofthe-runner"},
+		{name: "very-long-token-----------------------------------------------end", expected: "very-long-token-----------------------------------------------e"},
+	}
+
+	for _, example := range examples {
+		t.Run(example.name, func(t *testing.T) {
+			name := MakeRFC1123Compatible(example.name)
+
+			assert.Equal(t, example.expected, name)
+			test.AssertRFC1123Compatibility(t, name)
+		})
+	}
+}
diff --git a/scripts/prepare_release_checklist_issue.go b/scripts/prepare-release-checklist-issue/main.go
similarity index 70%
rename from scripts/prepare_release_checklist_issue.go
rename to scripts/prepare-release-checklist-issue/main.go
index 431ff42ea5b8daa3df966237d602997ce8624f5b..e55586323262cd11ca56c962c081c7b26e7ee8c2 100644
--- a/scripts/prepare_release_checklist_issue.go
+++ b/scripts/prepare-release-checklist-issue/main.go
@@ -15,6 +15,8 @@ import (
 	"strings"
 	"text/template"
 	"time"
+
+	"gopkg.in/yaml.v2"
 )
 
 type ReleaseMetadata struct {
@@ -23,16 +25,22 @@ type ReleaseMetadata struct {
 	ReleaseManagerHandle    string
 	ReleaseBlogPostMR       int
 	ReleaseBlogPostDeadline string
+	HelmChartMajor          int
+	HelmChartMinor          int
+	HelmChartPatch          int
 }
 
 const (
-	GitLabRunnerProjectID = "gitlab-org/gitlab-runner"
-	WWWGitlabComProjectID = "gitlab-com/www-gitlab-com"
+	GitLabRunnerProjectID          = "gitlab-org/gitlab-runner"
+	GitLabRunnerHelmChartProjectID = "charts/gitlab-runner"
+	WWWGitlabComProjectID          = "gitlab-com/www-gitlab-com"
 
 	ReleasePostLabel = "release post"
 
 	ReleaseManagerHandleEnvVariable = "GITLAB_RUNNER_RELEASE_MANAGER_HANDLE"
-	VersionFile                     = "./VERSION"
+
+	VersionFile          = "./VERSION"
+	HelmChartVersionFile = "Chart.yaml"
 
 	LayoutDay = "2006-01-02"
 )
@@ -41,8 +49,9 @@ var (
 	reader          *bufio.Reader
 	releaseMetadata ReleaseMetadata
 
-	defaultVersion      []string
-	defaultMergeRequest []string
+	detectedVersion          []string
+	detectedMergeRequest     []string
+	detectedHelmChartVersion []string
 
 	templateFilePath = flag.String("issue-template-file", ".gitlab/issue_templates/Release Checklist.md", "Path to a file with issue template")
 
@@ -54,11 +63,15 @@ var (
 	releaseManagerHandle    = flag.String("release-manager-handle", defaultReleaseManagerHandle(), "GitLab.com handle of the release manager")
 	releaseBlogPostMR       = flag.String("release-blog-post-mr", detectBlogPostMergeRequest()[0], "ID of the Release Blog Post MR")
 	releaseBlogPostDeadline = flag.String("release-blog-post-deadline", detectReleaseMergeRequestDeadline(), "Deadline for adding Runner specific content to the Release Blog Post")
+
+	helmChartMajor = flag.String("helm-chart-major", detectHelmChartVersion()[0], "Major version number of GitLab Runner Helm Chart")
+	helmChartMinor = flag.String("helm-chart-minor", detectHelmChartVersion()[1], "Minor version number of GitLab Runner Helm Chart")
+	helmChartPatch = flag.String("helm-chart-patch", detectHelmChartVersion()[2], "Patch version number of GitLab Runner Helm Chart")
 )
 
 func detectVersion() []string {
-	if len(defaultVersion) > 0 {
-		return defaultVersion
+	if len(detectedVersion) > 0 {
+		return detectedVersion
 	}
 
 	fmt.Println("Auto-detecting version...")
@@ -72,9 +85,65 @@ func detectVersion() []string {
 
 	fmt.Printf("Found: %s\n", content)
 
-	defaultVersion = strings.Split(string(content), ".")
+	detectedVersion = strings.Split(string(content), ".")
+
+	return detectedVersion
+}
+
+type HelmChartData struct {
+	Version string `yaml:"version"`
+}
+
+func detectHelmChartVersion() []string {
+	if len(detectedHelmChartVersion) > 0 {
+		return detectedHelmChartVersion
+	}
+
+	fmt.Println("Auto-detecting Helm Chart version...")
+
+	charVersionFileURL := fmt.Sprintf("https://gitlab.com/%s/raw/master/%s", GitLabRunnerHelmChartProjectID, HelmChartVersionFile)
+	req, err := http.NewRequest(http.MethodGet, charVersionFileURL, nil)
+	if err != nil {
+		panic(fmt.Errorf("error while creating helm chart version detection request: %v", err))
+	}
+
+	resp, err := http.DefaultClient.Do(req)
+	if err != nil {
+		panic(fmt.Errorf("error while requesting helm chart version: %v", err))
+	}
+
+	defer resp.Body.Close()
+	content, err := ioutil.ReadAll(resp.Body)
+	if err != nil {
+		panic(fmt.Errorf("error while reading helm chart version response: %v", err))
+	}
+
+	helmChartData := new(HelmChartData)
+	err = yaml.Unmarshal(content, helmChartData)
+	if err != nil {
+		fmt.Printf("Error while parsing Helm Chart version file: %v", err)
+
+		return []string{"", "", ""}
+	}
+
+	fmt.Printf("Found: %s\n", helmChartData.Version)
+
+	versionRx := regexp.MustCompile(`([0-9]+)\.([0-9]+)\.([0-9]+)`)
+	versions := versionRx.FindAllStringSubmatch(helmChartData.Version, -1)
+
+	if len(versions) != 1 {
+		fmt.Printf("Couldn't parse the version string")
+
+		return []string{"", "", ""}
+	}
+
+	detectedHelmChartVersion = []string{
+		versions[0][1],
+		versions[0][2],
+		versions[0][3],
+	}
 
-	return defaultVersion
+	return detectedHelmChartVersion
 }
 
 func defaultReleaseManagerHandle() string {
@@ -96,8 +165,8 @@ type listMergeRequestsResponseEntry struct {
 }
 
 func detectBlogPostMergeRequest() []string {
-	if len(defaultMergeRequest) > 0 {
-		return defaultMergeRequest
+	if len(detectedMergeRequest) > 0 {
+		return detectedMergeRequest
 	}
 
 	fmt.Println("Auto-detecting Release Post merge request...")
@@ -171,12 +240,12 @@ func detectBlogPostMergeRequest() []string {
 	r := regexp.MustCompile("gitlab.com/gitlab-com/www-gitlab-com/blob/release-\\d+-\\d+/data/release_posts/(\\d+)_(\\d+)_(\\d+)_gitlab_\\d+_\\d+_released.yml")
 	dateParts := r.FindStringSubmatch(chosen.Description)
 
-	defaultMergeRequest = []string{
+	detectedMergeRequest = []string{
 		strconv.Itoa(chosen.ID),
 		fmt.Sprintf("%s-%s-%s", dateParts[1], dateParts[2], dateParts[3]),
 	}
 
-	return defaultMergeRequest
+	return detectedMergeRequest
 }
 
 func detectReleaseMergeRequestDeadline() string {
@@ -228,14 +297,19 @@ func main() {
 	}
 	flag.Parse()
 
+	if *noInteractive {
+		fmt.Println("Running in non-interactive mode.")
+	}
 	prepareMetadata()
 
 	content := prepareIssueContent()
 	title := prepareIssueTitle()
 
 	if *dryRun {
+		fmt.Println("Running in dry-run mode. No real changes will be done")
 		printIssue(title, content)
 	} else {
+		fmt.Println("Running in standard mode. A new issue will be created")
 		postIssue(title, content)
 	}
 }
@@ -243,40 +317,55 @@ func main() {
 func prepareMetadata() {
 	var err error
 
-	askOnce("Major version number:", major)
+	askOnce("Major version number", major)
 	releaseMetadata.Major, err = strconv.Atoi(*major)
 	if err != nil {
 		panic(err)
 	}
 
-	askOnce("Minor version number:", minor)
+	askOnce("Minor version number", minor)
 	releaseMetadata.Minor, err = strconv.Atoi(*minor)
 	if err != nil {
 		panic(err)
 	}
 
-	askOnce("GitLab.com handle of the release manager:", releaseManagerHandle)
+	askOnce("Helm Chart Major version number", helmChartMajor)
+	releaseMetadata.HelmChartMajor, err = strconv.Atoi(*helmChartMajor)
+	if err != nil {
+		panic(err)
+	}
+
+	askOnce("Helm Chart Minor version number", helmChartMinor)
+	releaseMetadata.HelmChartMinor, err = strconv.Atoi(*helmChartMinor)
+	if err != nil {
+		panic(err)
+	}
+
+	askOnce("Helm Chart Patch version number", helmChartPatch)
+	releaseMetadata.HelmChartPatch, err = strconv.Atoi(*helmChartPatch)
+	if err != nil {
+		panic(err)
+	}
+
+	askOnce("GitLab.com handle of the release manager", releaseManagerHandle)
 	releaseMetadata.ReleaseManagerHandle = *releaseManagerHandle
 
-	askOnce("ID of the Release Blog Post MR:", releaseBlogPostMR)
+	askOnce("ID of the Release Blog Post MR", releaseBlogPostMR)
 	releaseMetadata.ReleaseBlogPostMR, err = strconv.Atoi(*releaseBlogPostMR)
 	if err != nil {
 		panic(err)
 	}
 
-	askOnce("Deadline for adding Runner specific content to the Release Blog Post:", releaseBlogPostDeadline)
+	askOnce("Deadline for adding Runner specific content to the Release Blog Post", releaseBlogPostDeadline)
 	releaseMetadata.ReleaseBlogPostDeadline = *releaseBlogPostDeadline
 }
 
 func askOnce(prompt string, result *string) {
+	fmt.Printf("%s [%s]: ", prompt, *result)
 	if *noInteractive {
-		return
-	}
-
-	fmt.Println(prompt)
+		fmt.Println()
 
-	if *result != "" {
-		fmt.Printf("[%s]: ", *result)
+		return
 	}
 
 	if reader == nil {
diff --git a/vendor/github.com/konsorten/go-windows-terminal-sequences/LICENSE b/vendor/github.com/konsorten/go-windows-terminal-sequences/LICENSE
new file mode 100644
index 0000000000000000000000000000000000000000..14127cd831ec1fadb16089c51c41c5d4f33f337c
--- /dev/null
+++ b/vendor/github.com/konsorten/go-windows-terminal-sequences/LICENSE
@@ -0,0 +1,9 @@
+(The MIT License)
+
+Copyright (c) 2017 marvin + konsorten GmbH (open-source@konsorten.de)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/vendor/github.com/konsorten/go-windows-terminal-sequences/sequences.go b/vendor/github.com/konsorten/go-windows-terminal-sequences/sequences.go
new file mode 100644
index 0000000000000000000000000000000000000000..ef18d8f978762602a46a3d90f5ce9bd6c1bb4fff
--- /dev/null
+++ b/vendor/github.com/konsorten/go-windows-terminal-sequences/sequences.go
@@ -0,0 +1,36 @@
+// +build windows
+
+package sequences
+
+import (
+	"syscall"
+	"unsafe"
+)
+
+var (
+	kernel32Dll    *syscall.LazyDLL  = syscall.NewLazyDLL("Kernel32.dll")
+	setConsoleMode *syscall.LazyProc = kernel32Dll.NewProc("SetConsoleMode")
+)
+
+func EnableVirtualTerminalProcessing(stream syscall.Handle, enable bool) error {
+	const ENABLE_VIRTUAL_TERMINAL_PROCESSING uint32 = 0x4
+
+	var mode uint32
+	err := syscall.GetConsoleMode(syscall.Stdout, &mode)
+	if err != nil {
+		return err
+	}
+
+	if enable {
+		mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING
+	} else {
+		mode &^= ENABLE_VIRTUAL_TERMINAL_PROCESSING
+	}
+
+	ret, _, err := setConsoleMode.Call(uintptr(unsafe.Pointer(stream)), uintptr(mode))
+	if ret == 0 {
+		return err
+	}
+
+	return nil
+}
diff --git a/vendor/github.com/konsorten/go-windows-terminal-sequences/sequences_test.go b/vendor/github.com/konsorten/go-windows-terminal-sequences/sequences_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..aad41c5cf60dbbd9c90a9465c80ccaa865c220c0
--- /dev/null
+++ b/vendor/github.com/konsorten/go-windows-terminal-sequences/sequences_test.go
@@ -0,0 +1,48 @@
+// +build windows
+
+package sequences
+
+import (
+	"fmt"
+	"os"
+	"syscall"
+	"testing"
+)
+
+func TestStdoutSequencesOn(t *testing.T) {
+	err := EnableVirtualTerminalProcessing(syscall.Stdout, true)
+	if err != nil {
+		t.Fatalf("Failed to enable VTP: %v", err)
+	}
+	defer EnableVirtualTerminalProcessing(syscall.Stdout, false)
+
+	fmt.Fprintf(os.Stdout, "\x1b[34mHello \x1b[35mWorld\x1b[0m!\n")
+}
+
+func TestStdoutSequencesOff(t *testing.T) {
+	err := EnableVirtualTerminalProcessing(syscall.Stdout, false)
+	if err != nil {
+		t.Fatalf("Failed to enable VTP: %v", err)
+	}
+
+	fmt.Fprintf(os.Stdout, "\x1b[34mHello \x1b[35mWorld\x1b[0m!\n")
+}
+
+func TestStderrSequencesOn(t *testing.T) {
+	err := EnableVirtualTerminalProcessing(syscall.Stderr, true)
+	if err != nil {
+		t.Fatalf("Failed to enable VTP: %v", err)
+	}
+	defer EnableVirtualTerminalProcessing(syscall.Stderr, false)
+
+	fmt.Fprintf(os.Stderr, "\x1b[34mHello \x1b[35mWorld\x1b[0m!\n")
+}
+
+func TestStderrSequencesOff(t *testing.T) {
+	err := EnableVirtualTerminalProcessing(syscall.Stderr, false)
+	if err != nil {
+		t.Fatalf("Failed to enable VTP: %v", err)
+	}
+
+	fmt.Fprintf(os.Stderr, "\x1b[34mHello \x1b[35mWorld\x1b[0m!\n")
+}
diff --git a/vendor/github.com/sirupsen/logrus/alt_exit_test.go b/vendor/github.com/sirupsen/logrus/alt_exit_test.go
index a08b1a898f665878347a19952ab3037afc66ea62..0a2ff5650d2550bfd1f2ed97df8b22e96dffca01 100644
--- a/vendor/github.com/sirupsen/logrus/alt_exit_test.go
+++ b/vendor/github.com/sirupsen/logrus/alt_exit_test.go
@@ -6,6 +6,8 @@ import (
 	"os"
 	"os/exec"
 	"path/filepath"
+	"runtime"
+	"strings"
 	"testing"
 	"time"
 )
@@ -19,6 +21,9 @@ func TestRegister(t *testing.T) {
 }
 
 func TestHandler(t *testing.T) {
+	testprog := testprogleader
+	testprog = append(testprog, getPackage()...)
+	testprog = append(testprog, testprogtrailer...)
 	tempDir, err := ioutil.TempDir("", "test_handler")
 	if err != nil {
 		log.Fatalf("can't create temp dir. %q", err)
@@ -47,13 +52,24 @@ func TestHandler(t *testing.T) {
 	}
 }
 
-var testprog = []byte(`
+// getPackage returns the name of the current package, which makes running this
+// test in a fork simpler
+func getPackage() []byte {
+	pc, _, _, _ := runtime.Caller(0)
+	fullFuncName := runtime.FuncForPC(pc).Name()
+	idx := strings.LastIndex(fullFuncName, ".")
+	return []byte(fullFuncName[:idx]) // trim off function details
+}
+
+var testprogleader = []byte(`
 // Test program for atexit, gets output file and data as arguments and writes
 // data to output file in atexit handler.
 package main
 
 import (
-	"github.com/sirupsen/logrus"
+	"`)
+var testprogtrailer = []byte(
+	`"
 	"flag"
 	"fmt"
 	"io/ioutil"
diff --git a/vendor/github.com/sirupsen/logrus/entry.go b/vendor/github.com/sirupsen/logrus/entry.go
index 8c6a389ee08d603d895a08c16663aea48f670916..df6d188defe161e3f0fee8e7f6e4e345ec8c63f7 100644
--- a/vendor/github.com/sirupsen/logrus/entry.go
+++ b/vendor/github.com/sirupsen/logrus/entry.go
@@ -4,11 +4,30 @@ import (
 	"bytes"
 	"fmt"
 	"os"
+	"reflect"
+	"runtime"
+	"strings"
 	"sync"
 	"time"
 )
 
-var bufferPool *sync.Pool
+var (
+	bufferPool *sync.Pool
+
+	// qualified package name, cached at first use
+	logrusPackage string
+
+	// Positions in the call stack when tracing to report the calling method
+	minimumCallerDepth int
+
+	// Used for caller information initialisation
+	callerInitOnce sync.Once
+)
+
+const (
+	maximumCallerDepth int = 25
+	knownLogrusFrames  int = 4
+)
 
 func init() {
 	bufferPool = &sync.Pool{
@@ -16,15 +35,18 @@ func init() {
 			return new(bytes.Buffer)
 		},
 	}
+
+	// start at the bottom of the stack before the package-name cache is primed
+	minimumCallerDepth = 1
 }
 
 // Defines the key when adding errors using WithError.
 var ErrorKey = "error"
 
 // An entry is the final or intermediate Logrus logging entry. It contains all
-// the fields passed with WithField{,s}. It's finally logged when Debug, Info,
-// Warn, Error, Fatal or Panic is called on it. These objects can be reused and
-// passed around as much as you wish to avoid field duplication.
+// the fields passed with WithField{,s}. It's finally logged when Trace, Debug,
+// Info, Warn, Error, Fatal or Panic is called on it. These objects can be
+// reused and passed around as much as you wish to avoid field duplication.
 type Entry struct {
 	Logger *Logger
 
@@ -34,22 +56,28 @@ type Entry struct {
 	// Time at which the log entry was created
 	Time time.Time
 
-	// Level the log entry was logged at: Debug, Info, Warn, Error, Fatal or Panic
+	// Level the log entry was logged at: Trace, Debug, Info, Warn, Error, Fatal or Panic
 	// This field will be set on entry firing and the value will be equal to the one in Logger struct field.
 	Level Level
 
-	// Message passed to Debug, Info, Warn, Error, Fatal or Panic
+	// Calling method, with package name
+	Caller *runtime.Frame
+
+	// Message passed to Trace, Debug, Info, Warn, Error, Fatal or Panic
 	Message string
 
-	// When formatter is called in entry.log(), an Buffer may be set to entry
+	// When formatter is called in entry.log(), a Buffer may be set to entry
 	Buffer *bytes.Buffer
+
+	// err may contain a field formatting error
+	err string
 }
 
 func NewEntry(logger *Logger) *Entry {
 	return &Entry{
 		Logger: logger,
-		// Default is five fields, give a little extra room
-		Data: make(Fields, 5),
+		// Default is three fields, plus one optional.  Give a little extra room.
+		Data: make(Fields, 6),
 	}
 }
 
@@ -80,15 +108,85 @@ func (entry *Entry) WithFields(fields Fields) *Entry {
 	for k, v := range entry.Data {
 		data[k] = v
 	}
+	fieldErr := entry.err
 	for k, v := range fields {
-		data[k] = v
+		isErrField := false
+		if t := reflect.TypeOf(v); t != nil {
+			switch t.Kind() {
+			case reflect.Func:
+				isErrField = true
+			case reflect.Ptr:
+				isErrField = t.Elem().Kind() == reflect.Func
+			}
+		}
+		if isErrField {
+			tmp := fmt.Sprintf("can not add field %q", k)
+			if fieldErr != "" {
+				fieldErr = entry.err + ", " + tmp
+			} else {
+				fieldErr = tmp
+			}
+		} else {
+			data[k] = v
+		}
 	}
-	return &Entry{Logger: entry.Logger, Data: data, Time: entry.Time}
+	return &Entry{Logger: entry.Logger, Data: data, Time: entry.Time, err: fieldErr}
 }
 
 // Overrides the time of the Entry.
 func (entry *Entry) WithTime(t time.Time) *Entry {
-	return &Entry{Logger: entry.Logger, Data: entry.Data, Time: t}
+	return &Entry{Logger: entry.Logger, Data: entry.Data, Time: t, err: entry.err}
+}
+
+// getPackageName reduces a fully qualified function name to the package name
+// There really ought to be to be a better way...
+func getPackageName(f string) string {
+	for {
+		lastPeriod := strings.LastIndex(f, ".")
+		lastSlash := strings.LastIndex(f, "/")
+		if lastPeriod > lastSlash {
+			f = f[:lastPeriod]
+		} else {
+			break
+		}
+	}
+
+	return f
+}
+
+// getCaller retrieves the name of the first non-logrus calling function
+func getCaller() *runtime.Frame {
+	// Restrict the lookback frames to avoid runaway lookups
+	pcs := make([]uintptr, maximumCallerDepth)
+	depth := runtime.Callers(minimumCallerDepth, pcs)
+	frames := runtime.CallersFrames(pcs[:depth])
+
+	// cache this package's fully-qualified name
+	callerInitOnce.Do(func() {
+		logrusPackage = getPackageName(runtime.FuncForPC(pcs[0]).Name())
+
+		// now that we have the cache, we can skip a minimum count of known-logrus functions
+		// XXX this is dubious, the number of frames may vary store an entry in a logger interface
+		minimumCallerDepth = knownLogrusFrames
+	})
+
+	for f, again := frames.Next(); again; f, again = frames.Next() {
+		pkg := getPackageName(f.Function)
+
+		// If the caller isn't part of this package, we're done
+		if pkg != logrusPackage {
+			return &f
+		}
+	}
+
+	// if we got here, we failed to find the caller's context
+	return nil
+}
+
+func (entry Entry) HasCaller() (has bool) {
+	return entry.Logger != nil &&
+		entry.Logger.ReportCaller &&
+		entry.Caller != nil
 }
 
 // This function is not declared with a pointer value because otherwise
@@ -107,6 +205,9 @@ func (entry Entry) log(level Level, msg string) {
 
 	entry.Level = level
 	entry.Message = msg
+	if entry.Logger.ReportCaller {
+		entry.Caller = getCaller()
+	}
 
 	entry.fireHooks()
 
@@ -150,26 +251,30 @@ func (entry *Entry) write() {
 	}
 }
 
-func (entry *Entry) Debug(args ...interface{}) {
-	if entry.Logger.IsLevelEnabled(DebugLevel) {
-		entry.log(DebugLevel, fmt.Sprint(args...))
+func (entry *Entry) Log(level Level, args ...interface{}) {
+	if entry.Logger.IsLevelEnabled(level) {
+		entry.log(level, fmt.Sprint(args...))
 	}
 }
 
+func (entry *Entry) Trace(args ...interface{}) {
+	entry.Log(TraceLevel, args...)
+}
+
+func (entry *Entry) Debug(args ...interface{}) {
+	entry.Log(DebugLevel, args...)
+}
+
 func (entry *Entry) Print(args ...interface{}) {
 	entry.Info(args...)
 }
 
 func (entry *Entry) Info(args ...interface{}) {
-	if entry.Logger.IsLevelEnabled(InfoLevel) {
-		entry.log(InfoLevel, fmt.Sprint(args...))
-	}
+	entry.Log(InfoLevel, args...)
 }
 
 func (entry *Entry) Warn(args ...interface{}) {
-	if entry.Logger.IsLevelEnabled(WarnLevel) {
-		entry.log(WarnLevel, fmt.Sprint(args...))
-	}
+	entry.Log(WarnLevel, args...)
 }
 
 func (entry *Entry) Warning(args ...interface{}) {
@@ -177,37 +282,35 @@ func (entry *Entry) Warning(args ...interface{}) {
 }
 
 func (entry *Entry) Error(args ...interface{}) {
-	if entry.Logger.IsLevelEnabled(ErrorLevel) {
-		entry.log(ErrorLevel, fmt.Sprint(args...))
-	}
+	entry.Log(ErrorLevel, args...)
 }
 
 func (entry *Entry) Fatal(args ...interface{}) {
-	if entry.Logger.IsLevelEnabled(FatalLevel) {
-		entry.log(FatalLevel, fmt.Sprint(args...))
-	}
-	Exit(1)
+	entry.Log(FatalLevel, args...)
+	entry.Logger.Exit(1)
 }
 
 func (entry *Entry) Panic(args ...interface{}) {
-	if entry.Logger.IsLevelEnabled(PanicLevel) {
-		entry.log(PanicLevel, fmt.Sprint(args...))
-	}
+	entry.Log(PanicLevel, args...)
 	panic(fmt.Sprint(args...))
 }
 
 // Entry Printf family functions
 
+func (entry *Entry) Logf(level Level, format string, args ...interface{}) {
+	entry.Log(level, fmt.Sprintf(format, args...))
+}
+
+func (entry *Entry) Tracef(format string, args ...interface{}) {
+	entry.Logf(TraceLevel, format, args...)
+}
+
 func (entry *Entry) Debugf(format string, args ...interface{}) {
-	if entry.Logger.IsLevelEnabled(DebugLevel) {
-		entry.Debug(fmt.Sprintf(format, args...))
-	}
+	entry.Logf(DebugLevel, format, args...)
 }
 
 func (entry *Entry) Infof(format string, args ...interface{}) {
-	if entry.Logger.IsLevelEnabled(InfoLevel) {
-		entry.Info(fmt.Sprintf(format, args...))
-	}
+	entry.Logf(InfoLevel, format, args...)
 }
 
 func (entry *Entry) Printf(format string, args ...interface{}) {
@@ -215,9 +318,7 @@ func (entry *Entry) Printf(format string, args ...interface{}) {
 }
 
 func (entry *Entry) Warnf(format string, args ...interface{}) {
-	if entry.Logger.IsLevelEnabled(WarnLevel) {
-		entry.Warn(fmt.Sprintf(format, args...))
-	}
+	entry.Logf(WarnLevel, format, args...)
 }
 
 func (entry *Entry) Warningf(format string, args ...interface{}) {
@@ -225,36 +326,36 @@ func (entry *Entry) Warningf(format string, args ...interface{}) {
 }
 
 func (entry *Entry) Errorf(format string, args ...interface{}) {
-	if entry.Logger.IsLevelEnabled(ErrorLevel) {
-		entry.Error(fmt.Sprintf(format, args...))
-	}
+	entry.Logf(ErrorLevel, format, args...)
 }
 
 func (entry *Entry) Fatalf(format string, args ...interface{}) {
-	if entry.Logger.IsLevelEnabled(FatalLevel) {
-		entry.Fatal(fmt.Sprintf(format, args...))
-	}
-	Exit(1)
+	entry.Logf(FatalLevel, format, args...)
+	entry.Logger.Exit(1)
 }
 
 func (entry *Entry) Panicf(format string, args ...interface{}) {
-	if entry.Logger.IsLevelEnabled(PanicLevel) {
-		entry.Panic(fmt.Sprintf(format, args...))
-	}
+	entry.Logf(PanicLevel, format, args...)
 }
 
 // Entry Println family functions
 
-func (entry *Entry) Debugln(args ...interface{}) {
-	if entry.Logger.IsLevelEnabled(DebugLevel) {
-		entry.Debug(entry.sprintlnn(args...))
+func (entry *Entry) Logln(level Level, args ...interface{}) {
+	if entry.Logger.IsLevelEnabled(level) {
+		entry.Log(level, entry.sprintlnn(args...))
 	}
 }
 
+func (entry *Entry) Traceln(args ...interface{}) {
+	entry.Logln(TraceLevel, args...)
+}
+
+func (entry *Entry) Debugln(args ...interface{}) {
+	entry.Logln(DebugLevel, args...)
+}
+
 func (entry *Entry) Infoln(args ...interface{}) {
-	if entry.Logger.IsLevelEnabled(InfoLevel) {
-		entry.Info(entry.sprintlnn(args...))
-	}
+	entry.Logln(InfoLevel, args...)
 }
 
 func (entry *Entry) Println(args ...interface{}) {
@@ -262,9 +363,7 @@ func (entry *Entry) Println(args ...interface{}) {
 }
 
 func (entry *Entry) Warnln(args ...interface{}) {
-	if entry.Logger.IsLevelEnabled(WarnLevel) {
-		entry.Warn(entry.sprintlnn(args...))
-	}
+	entry.Logln(WarnLevel, args...)
 }
 
 func (entry *Entry) Warningln(args ...interface{}) {
@@ -272,22 +371,16 @@ func (entry *Entry) Warningln(args ...interface{}) {
 }
 
 func (entry *Entry) Errorln(args ...interface{}) {
-	if entry.Logger.IsLevelEnabled(ErrorLevel) {
-		entry.Error(entry.sprintlnn(args...))
-	}
+	entry.Logln(ErrorLevel, args...)
 }
 
 func (entry *Entry) Fatalln(args ...interface{}) {
-	if entry.Logger.IsLevelEnabled(FatalLevel) {
-		entry.Fatal(entry.sprintlnn(args...))
-	}
-	Exit(1)
+	entry.Logln(FatalLevel, args...)
+	entry.Logger.Exit(1)
 }
 
 func (entry *Entry) Panicln(args ...interface{}) {
-	if entry.Logger.IsLevelEnabled(PanicLevel) {
-		entry.Panic(entry.sprintlnn(args...))
-	}
+	entry.Logln(PanicLevel, args...)
 }
 
 // Sprintlnn => Sprint no newline. This is to get the behavior of how
diff --git a/vendor/github.com/sirupsen/logrus/entry_test.go b/vendor/github.com/sirupsen/logrus/entry_test.go
index a81e2b3834cfe89b77bd99f5d2bfba8b14d6e4ac..5e6634112ebc2c007ea0e3ec5c9a9d1c8074199e 100644
--- a/vendor/github.com/sirupsen/logrus/entry_test.go
+++ b/vendor/github.com/sirupsen/logrus/entry_test.go
@@ -4,6 +4,7 @@ import (
 	"bytes"
 	"fmt"
 	"testing"
+	"time"
 
 	"github.com/stretchr/testify/assert"
 )
@@ -113,3 +114,28 @@ func TestEntryHooksPanic(t *testing.T) {
 	entry := NewEntry(logger)
 	entry.Info(badMessage)
 }
+
+func TestEntryWithIncorrectField(t *testing.T) {
+	assert := assert.New(t)
+
+	fn := func() {}
+
+	e := Entry{}
+	eWithFunc := e.WithFields(Fields{"func": fn})
+	eWithFuncPtr := e.WithFields(Fields{"funcPtr": &fn})
+
+	assert.Equal(eWithFunc.err, `can not add field "func"`)
+	assert.Equal(eWithFuncPtr.err, `can not add field "funcPtr"`)
+
+	eWithFunc = eWithFunc.WithField("not_a_func", "it is a string")
+	eWithFuncPtr = eWithFuncPtr.WithField("not_a_func", "it is a string")
+
+	assert.Equal(eWithFunc.err, `can not add field "func"`)
+	assert.Equal(eWithFuncPtr.err, `can not add field "funcPtr"`)
+
+	eWithFunc = eWithFunc.WithTime(time.Now())
+	eWithFuncPtr = eWithFuncPtr.WithTime(time.Now())
+
+	assert.Equal(eWithFunc.err, `can not add field "func"`)
+	assert.Equal(eWithFuncPtr.err, `can not add field "funcPtr"`)
+}
diff --git a/vendor/github.com/sirupsen/logrus/example_basic_test.go b/vendor/github.com/sirupsen/logrus/example_basic_test.go
index a2acf550c95dfecb11132ec8578d2b6ef8d4c560..9ff56555b41fdf86e1eec2c5d941fcd49e7664ce 100644
--- a/vendor/github.com/sirupsen/logrus/example_basic_test.go
+++ b/vendor/github.com/sirupsen/logrus/example_basic_test.go
@@ -1,16 +1,18 @@
 package logrus_test
 
 import (
-	"github.com/sirupsen/logrus"
 	"os"
+
+	"github.com/sirupsen/logrus"
 )
 
 func Example_basic() {
 	var log = logrus.New()
 	log.Formatter = new(logrus.JSONFormatter)
 	log.Formatter = new(logrus.TextFormatter)                     //default
+	log.Formatter.(*logrus.TextFormatter).DisableColors = true    // remove colors
 	log.Formatter.(*logrus.TextFormatter).DisableTimestamp = true // remove timestamp from test output
-	log.Level = logrus.DebugLevel
+	log.Level = logrus.TraceLevel
 	log.Out = os.Stdout
 
 	// file, err := os.OpenFile("logrus.log", os.O_CREATE|os.O_WRONLY, 0666)
@@ -35,6 +37,11 @@ func Example_basic() {
 		}
 	}()
 
+	log.WithFields(logrus.Fields{
+		"animal": "walrus",
+		"number": 0,
+	}).Trace("Went to the beach")
+
 	log.WithFields(logrus.Fields{
 		"animal": "walrus",
 		"number": 8,
@@ -60,6 +67,7 @@ func Example_basic() {
 	}).Panic("It's over 9000!")
 
 	// Output:
+	// level=trace msg="Went to the beach" animal=walrus number=0
 	// level=debug msg="Started observing beach" animal=walrus number=8
 	// level=info msg="A group of walrus emerges from the ocean" animal=walrus size=10
 	// level=warning msg="The group's number increased tremendously!" number=122 omg=true
diff --git a/vendor/github.com/sirupsen/logrus/example_global_hook_test.go b/vendor/github.com/sirupsen/logrus/example_global_hook_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..c81e448c2d957bcb18a6915168546ab5f18e66fa
--- /dev/null
+++ b/vendor/github.com/sirupsen/logrus/example_global_hook_test.go
@@ -0,0 +1,36 @@
+package logrus_test
+
+import (
+	"github.com/sirupsen/logrus"
+	"os"
+)
+
+var (
+	mystring string
+)
+
+type GlobalHook struct {
+}
+
+func (h *GlobalHook) Levels() []logrus.Level {
+	return logrus.AllLevels
+}
+
+func (h *GlobalHook) Fire(e *logrus.Entry) error {
+	e.Data["mystring"] = mystring
+	return nil
+}
+
+func Example() {
+	l := logrus.New()
+	l.Out = os.Stdout
+	l.Formatter = &logrus.TextFormatter{DisableTimestamp: true, DisableColors: true}
+	l.AddHook(&GlobalHook{})
+	mystring = "first value"
+	l.Info("first log")
+	mystring = "another value"
+	l.Info("second log")
+	// Output:
+	// level=info msg="first log" mystring="first value"
+	// level=info msg="second log" mystring="another value"
+}
diff --git a/vendor/github.com/sirupsen/logrus/example_hook_test.go b/vendor/github.com/sirupsen/logrus/example_hook_test.go
index d4ddffca37ffe59a15a670d50a9c285a108c2e32..dc0e69f192ad32a1c42c8e9053875c9c10c03a97 100644
--- a/vendor/github.com/sirupsen/logrus/example_hook_test.go
+++ b/vendor/github.com/sirupsen/logrus/example_hook_test.go
@@ -1,16 +1,24 @@
+// +build !windows
+
 package logrus_test
 
 import (
-	"github.com/sirupsen/logrus"
-	"gopkg.in/gemnasium/logrus-airbrake-hook.v2"
+	"log/syslog"
 	"os"
+
+	"github.com/sirupsen/logrus"
+	slhooks "github.com/sirupsen/logrus/hooks/syslog"
 )
 
+// An example on how to use a hook
 func Example_hook() {
 	var log = logrus.New()
 	log.Formatter = new(logrus.TextFormatter)                     // default
+	log.Formatter.(*logrus.TextFormatter).DisableColors = true    // remove colors
 	log.Formatter.(*logrus.TextFormatter).DisableTimestamp = true // remove timestamp from test output
-	log.Hooks.Add(airbrake.NewHook(123, "xyz", "development"))
+	if sl, err := slhooks.NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, ""); err == nil {
+		log.Hooks.Add(sl)
+	}
 	log.Out = os.Stdout
 
 	log.WithFields(logrus.Fields{
diff --git a/vendor/github.com/sirupsen/logrus/exported.go b/vendor/github.com/sirupsen/logrus/exported.go
index fb2a7a1f07040ac5905a8f61c4c07f5cbf21874f..7342613c37259922c2c6cc4ab43ad5defc46fa90 100644
--- a/vendor/github.com/sirupsen/logrus/exported.go
+++ b/vendor/github.com/sirupsen/logrus/exported.go
@@ -24,6 +24,12 @@ func SetFormatter(formatter Formatter) {
 	std.SetFormatter(formatter)
 }
 
+// SetReportCaller sets whether the standard logger will include the calling
+// method as a field.
+func SetReportCaller(include bool) {
+	std.SetReportCaller(include)
+}
+
 // SetLevel sets the standard logger level.
 func SetLevel(level Level) {
 	std.SetLevel(level)
@@ -77,6 +83,11 @@ func WithTime(t time.Time) *Entry {
 	return std.WithTime(t)
 }
 
+// Trace logs a message at level Trace on the standard logger.
+func Trace(args ...interface{}) {
+	std.Trace(args...)
+}
+
 // Debug logs a message at level Debug on the standard logger.
 func Debug(args ...interface{}) {
 	std.Debug(args...)
@@ -117,6 +128,11 @@ func Fatal(args ...interface{}) {
 	std.Fatal(args...)
 }
 
+// Tracef logs a message at level Trace on the standard logger.
+func Tracef(format string, args ...interface{}) {
+	std.Tracef(format, args...)
+}
+
 // Debugf logs a message at level Debug on the standard logger.
 func Debugf(format string, args ...interface{}) {
 	std.Debugf(format, args...)
@@ -157,6 +173,11 @@ func Fatalf(format string, args ...interface{}) {
 	std.Fatalf(format, args...)
 }
 
+// Traceln logs a message at level Trace on the standard logger.
+func Traceln(args ...interface{}) {
+	std.Traceln(args...)
+}
+
 // Debugln logs a message at level Debug on the standard logger.
 func Debugln(args ...interface{}) {
 	std.Debugln(args...)
diff --git a/vendor/github.com/sirupsen/logrus/formatter.go b/vendor/github.com/sirupsen/logrus/formatter.go
index 83c74947beab291bffa8205e6646b35c1ef1536f..408883773ebbd70f8f5128ed74747039ec8ee0f1 100644
--- a/vendor/github.com/sirupsen/logrus/formatter.go
+++ b/vendor/github.com/sirupsen/logrus/formatter.go
@@ -2,7 +2,16 @@ package logrus
 
 import "time"
 
-const defaultTimestampFormat = time.RFC3339
+// Default key names for the default fields
+const (
+	defaultTimestampFormat = time.RFC3339
+	FieldKeyMsg            = "msg"
+	FieldKeyLevel          = "level"
+	FieldKeyTime           = "time"
+	FieldKeyLogrusError    = "logrus_error"
+	FieldKeyFunc           = "func"
+	FieldKeyFile           = "file"
+)
 
 // The Formatter interface is used to implement a custom Formatter. It takes an
 // `Entry`. It exposes all the fields, including the default ones:
@@ -18,7 +27,7 @@ type Formatter interface {
 	Format(*Entry) ([]byte, error)
 }
 
-// This is to not silently overwrite `time`, `msg` and `level` fields when
+// This is to not silently overwrite `time`, `msg`, `func` and `level` fields when
 // dumping it. If this code wasn't there doing:
 //
 //  logrus.WithField("level", 1).Info("hello")
@@ -30,7 +39,7 @@ type Formatter interface {
 //
 // It's not exported because it's still using Data in an opinionated way. It's to
 // avoid code duplication between the two default formatters.
-func prefixFieldClashes(data Fields, fieldMap FieldMap) {
+func prefixFieldClashes(data Fields, fieldMap FieldMap, reportCaller bool) {
 	timeKey := fieldMap.resolve(FieldKeyTime)
 	if t, ok := data[timeKey]; ok {
 		data["fields."+timeKey] = t
@@ -48,4 +57,22 @@ func prefixFieldClashes(data Fields, fieldMap FieldMap) {
 		data["fields."+levelKey] = l
 		delete(data, levelKey)
 	}
+
+	logrusErrKey := fieldMap.resolve(FieldKeyLogrusError)
+	if l, ok := data[logrusErrKey]; ok {
+		data["fields."+logrusErrKey] = l
+		delete(data, logrusErrKey)
+	}
+
+	// If reportCaller is not set, 'func' will not conflict.
+	if reportCaller {
+		funcKey := fieldMap.resolve(FieldKeyFunc)
+		if l, ok := data[funcKey]; ok {
+			data["fields."+funcKey] = l
+		}
+		fileKey := fieldMap.resolve(FieldKeyFile)
+		if l, ok := data[fileKey]; ok {
+			data["fields."+fileKey] = l
+		}
+	}
 }
diff --git a/vendor/github.com/sirupsen/logrus/hook_test.go b/vendor/github.com/sirupsen/logrus/hook_test.go
index 80b93b8c6e0e9f16a9ab1fdbdb43acb27c561fdd..b9675935b46768dda068abf3daf3ea02b2ea46d6 100644
--- a/vendor/github.com/sirupsen/logrus/hook_test.go
+++ b/vendor/github.com/sirupsen/logrus/hook_test.go
@@ -1,4 +1,4 @@
-package logrus
+package logrus_test
 
 import (
 	"bytes"
@@ -8,6 +8,9 @@ import (
 
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
+
+	. "github.com/sirupsen/logrus"
+	. "github.com/sirupsen/logrus/internal/testutils"
 )
 
 type TestHook struct {
@@ -21,6 +24,7 @@ func (hook *TestHook) Fire(entry *Entry) error {
 
 func (hook *TestHook) Levels() []Level {
 	return []Level{
+		TraceLevel,
 		DebugLevel,
 		InfoLevel,
 		WarnLevel,
@@ -53,6 +57,7 @@ func (hook *ModifyHook) Fire(entry *Entry) error {
 
 func (hook *ModifyHook) Levels() []Level {
 	return []Level{
+		TraceLevel,
 		DebugLevel,
 		InfoLevel,
 		WarnLevel,
diff --git a/vendor/github.com/sirupsen/logrus/hooks/syslog/syslog.go b/vendor/github.com/sirupsen/logrus/hooks/syslog/syslog.go
index 329ce0d60cb1f6bb413261bd615f8152fc257da8..02b8df38055fc99534ccfc2c9ee0caefc653060f 100644
--- a/vendor/github.com/sirupsen/logrus/hooks/syslog/syslog.go
+++ b/vendor/github.com/sirupsen/logrus/hooks/syslog/syslog.go
@@ -43,7 +43,7 @@ func (hook *SyslogHook) Fire(entry *logrus.Entry) error {
 		return hook.Writer.Warning(line)
 	case logrus.InfoLevel:
 		return hook.Writer.Info(line)
-	case logrus.DebugLevel:
+	case logrus.DebugLevel, logrus.TraceLevel:
 		return hook.Writer.Debug(line)
 	default:
 		return nil
diff --git a/vendor/github.com/sirupsen/logrus/hooks/syslog/syslog_test.go b/vendor/github.com/sirupsen/logrus/hooks/syslog/syslog_test.go
index 5ec3a44454883f1ba1c0edac541c80737b918987..bec6efd5ac8ceb0342b0f20efbbc45a0b785a6c7 100644
--- a/vendor/github.com/sirupsen/logrus/hooks/syslog/syslog_test.go
+++ b/vendor/github.com/sirupsen/logrus/hooks/syslog/syslog_test.go
@@ -1,3 +1,5 @@
+// +build !windows,!nacl,!plan9
+
 package syslog
 
 import (
diff --git a/vendor/github.com/sirupsen/logrus/hooks/test/test_test.go b/vendor/github.com/sirupsen/logrus/hooks/test/test_test.go
index d6f6d306d47bf862b21023b9ceb2538a6ab1348f..636bad5126cd7fcf0f122dd6546431b8f2eb5e38 100644
--- a/vendor/github.com/sirupsen/logrus/hooks/test/test_test.go
+++ b/vendor/github.com/sirupsen/logrus/hooks/test/test_test.go
@@ -71,3 +71,15 @@ func TestLoggingWithHooksRace(t *testing.T) {
 	entries := hook.AllEntries()
 	assert.Equal(100, len(entries))
 }
+
+func TestFatalWithAlternateExit(t *testing.T) {
+	assert := assert.New(t)
+
+	logger, hook := NewNullLogger()
+	logger.ExitFunc = func(code int) {}
+
+	logger.Fatal("something went very wrong")
+	assert.Equal(logrus.FatalLevel, hook.LastEntry().Level)
+	assert.Equal("something went very wrong", hook.LastEntry().Message)
+	assert.Equal(1, len(hook.Entries))
+}
diff --git a/vendor/github.com/sirupsen/logrus/internal/testutils/testutils.go b/vendor/github.com/sirupsen/logrus/internal/testutils/testutils.go
new file mode 100644
index 0000000000000000000000000000000000000000..20bc3c3b641f519108f0c3dbaaa76224ad4a1d59
--- /dev/null
+++ b/vendor/github.com/sirupsen/logrus/internal/testutils/testutils.go
@@ -0,0 +1,58 @@
+package testutils
+
+import (
+	"bytes"
+	"encoding/json"
+	"strconv"
+	"strings"
+	"testing"
+
+	. "github.com/sirupsen/logrus"
+
+	"github.com/stretchr/testify/require"
+)
+
+func LogAndAssertJSON(t *testing.T, log func(*Logger), assertions func(fields Fields)) {
+	var buffer bytes.Buffer
+	var fields Fields
+
+	logger := New()
+	logger.Out = &buffer
+	logger.Formatter = new(JSONFormatter)
+
+	log(logger)
+
+	err := json.Unmarshal(buffer.Bytes(), &fields)
+	require.Nil(t, err)
+
+	assertions(fields)
+}
+
+func LogAndAssertText(t *testing.T, log func(*Logger), assertions func(fields map[string]string)) {
+	var buffer bytes.Buffer
+
+	logger := New()
+	logger.Out = &buffer
+	logger.Formatter = &TextFormatter{
+		DisableColors: true,
+	}
+
+	log(logger)
+
+	fields := make(map[string]string)
+	for _, kv := range strings.Split(buffer.String(), " ") {
+		if !strings.Contains(kv, "=") {
+			continue
+		}
+		kvArr := strings.Split(kv, "=")
+		key := strings.TrimSpace(kvArr[0])
+		val := kvArr[1]
+		if kvArr[1][0] == '"' {
+			var err error
+			val, err = strconv.Unquote(val)
+			require.NoError(t, err)
+		}
+		fields[key] = val
+	}
+	assertions(fields)
+}
diff --git a/vendor/github.com/sirupsen/logrus/json_formatter.go b/vendor/github.com/sirupsen/logrus/json_formatter.go
index b13f0cda357bb5626b3cf91b890a43c953a1ace5..2605753599faf140f7a91f3fc462da4c0971ef64 100644
--- a/vendor/github.com/sirupsen/logrus/json_formatter.go
+++ b/vendor/github.com/sirupsen/logrus/json_formatter.go
@@ -11,13 +11,6 @@ type fieldKey string
 // FieldMap allows customization of the key names for default fields.
 type FieldMap map[fieldKey]string
 
-// Default key names for the default fields
-const (
-	FieldKeyMsg   = "msg"
-	FieldKeyLevel = "level"
-	FieldKeyTime  = "time"
-)
-
 func (f FieldMap) resolve(key fieldKey) string {
 	if k, ok := f[key]; ok {
 		return k
@@ -41,17 +34,21 @@ type JSONFormatter struct {
 	// As an example:
 	// formatter := &JSONFormatter{
 	//   	FieldMap: FieldMap{
-	// 		 FieldKeyTime: "@timestamp",
+	// 		 FieldKeyTime:  "@timestamp",
 	// 		 FieldKeyLevel: "@level",
-	// 		 FieldKeyMsg: "@message",
+	// 		 FieldKeyMsg:   "@message",
+	// 		 FieldKeyFunc:  "@caller",
 	//    },
 	// }
 	FieldMap FieldMap
+
+	// PrettyPrint will indent all json logs
+	PrettyPrint bool
 }
 
 // Format renders a single log entry
 func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
-	data := make(Fields, len(entry.Data)+3)
+	data := make(Fields, len(entry.Data)+4)
 	for k, v := range entry.Data {
 		switch v := v.(type) {
 		case error:
@@ -69,18 +66,25 @@ func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
 		data = newData
 	}
 
-	prefixFieldClashes(data, f.FieldMap)
+	prefixFieldClashes(data, f.FieldMap, entry.HasCaller())
 
 	timestampFormat := f.TimestampFormat
 	if timestampFormat == "" {
 		timestampFormat = defaultTimestampFormat
 	}
 
+	if entry.err != "" {
+		data[f.FieldMap.resolve(FieldKeyLogrusError)] = entry.err
+	}
 	if !f.DisableTimestamp {
 		data[f.FieldMap.resolve(FieldKeyTime)] = entry.Time.Format(timestampFormat)
 	}
 	data[f.FieldMap.resolve(FieldKeyMsg)] = entry.Message
 	data[f.FieldMap.resolve(FieldKeyLevel)] = entry.Level.String()
+	if entry.HasCaller() {
+		data[f.FieldMap.resolve(FieldKeyFunc)] = entry.Caller.Function
+		data[f.FieldMap.resolve(FieldKeyFile)] = fmt.Sprintf("%s:%d", entry.Caller.File, entry.Caller.Line)
+	}
 
 	var b *bytes.Buffer
 	if entry.Buffer != nil {
@@ -88,9 +92,14 @@ func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
 	} else {
 		b = &bytes.Buffer{}
 	}
-	err := json.NewEncoder(b).Encode(data)
-	if err != nil {
+
+	encoder := json.NewEncoder(b)
+	if f.PrettyPrint {
+		encoder.SetIndent("", "  ")
+	}
+	if err := encoder.Encode(data); err != nil {
 		return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err)
 	}
+
 	return b.Bytes(), nil
 }
diff --git a/vendor/github.com/sirupsen/logrus/json_formatter_test.go b/vendor/github.com/sirupsen/logrus/json_formatter_test.go
index 0dde3004cbccc291bc342a52191752fd7f4b4653..695c36e549f2eb343f43a690e6c6173e30295e6d 100644
--- a/vendor/github.com/sirupsen/logrus/json_formatter_test.go
+++ b/vendor/github.com/sirupsen/logrus/json_formatter_test.go
@@ -4,6 +4,7 @@ import (
 	"encoding/json"
 	"errors"
 	"fmt"
+	"runtime"
 	"strings"
 	"testing"
 )
@@ -167,8 +168,8 @@ func TestFieldsInNestedDictionary(t *testing.T) {
 	}
 
 	logEntry := WithFields(Fields{
-		"level":      "level",
-		"test":		  "test",
+		"level": "level",
+		"test":  "test",
 	})
 	logEntry.Level = InfoLevel
 
@@ -267,6 +268,55 @@ func TestJSONTimeKey(t *testing.T) {
 	}
 }
 
+func TestFieldDoesNotClashWithCaller(t *testing.T) {
+	SetReportCaller(false)
+	formatter := &JSONFormatter{}
+
+	b, err := formatter.Format(WithField("func", "howdy pardner"))
+	if err != nil {
+		t.Fatal("Unable to format entry: ", err)
+	}
+
+	entry := make(map[string]interface{})
+	err = json.Unmarshal(b, &entry)
+	if err != nil {
+		t.Fatal("Unable to unmarshal formatted entry: ", err)
+	}
+
+	if entry["func"] != "howdy pardner" {
+		t.Fatal("func field replaced when ReportCaller=false")
+	}
+}
+
+func TestFieldClashWithCaller(t *testing.T) {
+	SetReportCaller(true)
+	formatter := &JSONFormatter{}
+	e := WithField("func", "howdy pardner")
+	e.Caller = &runtime.Frame{Function: "somefunc"}
+	b, err := formatter.Format(e)
+	if err != nil {
+		t.Fatal("Unable to format entry: ", err)
+	}
+
+	entry := make(map[string]interface{})
+	err = json.Unmarshal(b, &entry)
+	if err != nil {
+		t.Fatal("Unable to unmarshal formatted entry: ", err)
+	}
+
+	if entry["fields.func"] != "howdy pardner" {
+		t.Fatalf("fields.func not set to original func field when ReportCaller=true (got '%s')",
+			entry["fields.func"])
+	}
+
+	if entry["func"] != "somefunc" {
+		t.Fatalf("func not set as expected when ReportCaller=true (got '%s')",
+			entry["func"])
+	}
+
+	SetReportCaller(false) // return to default value
+}
+
 func TestJSONDisableTimestamp(t *testing.T) {
 	formatter := &JSONFormatter{
 		DisableTimestamp: true,
diff --git a/vendor/github.com/sirupsen/logrus/level_test.go b/vendor/github.com/sirupsen/logrus/level_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..78915c4f2b80956b99b7e41a5806f848f0755a3c
--- /dev/null
+++ b/vendor/github.com/sirupsen/logrus/level_test.go
@@ -0,0 +1,62 @@
+package logrus_test
+
+import (
+	"bytes"
+	"encoding/json"
+	"testing"
+
+	"github.com/sirupsen/logrus"
+	"github.com/stretchr/testify/require"
+)
+
+func TestLevelJsonEncoding(t *testing.T) {
+	type X struct {
+		Level logrus.Level
+	}
+
+	var x X
+	x.Level = logrus.WarnLevel
+	var buf bytes.Buffer
+	enc := json.NewEncoder(&buf)
+	require.NoError(t, enc.Encode(x))
+	dec := json.NewDecoder(&buf)
+	var y X
+	require.NoError(t, dec.Decode(&y))
+}
+
+func TestLevelUnmarshalText(t *testing.T) {
+	var u logrus.Level
+	for _, level := range logrus.AllLevels {
+		t.Run(level.String(), func(t *testing.T) {
+			require.NoError(t, u.UnmarshalText([]byte(level.String())))
+			require.Equal(t, level, u)
+		})
+	}
+	t.Run("invalid", func(t *testing.T) {
+		require.Error(t, u.UnmarshalText([]byte("invalid")))
+	})
+}
+
+func TestLevelMarshalText(t *testing.T) {
+	levelStrings := []string{
+		"panic",
+		"fatal",
+		"error",
+		"warning",
+		"info",
+		"debug",
+		"trace",
+	}
+	for idx, val := range logrus.AllLevels {
+		level := val
+		t.Run(level.String(), func(t *testing.T) {
+			var cmp logrus.Level
+			b, err := level.MarshalText()
+			require.NoError(t, err)
+			require.Equal(t, levelStrings[idx], string(b))
+			err = cmp.UnmarshalText(b)
+			require.NoError(t, err)
+			require.Equal(t, level, cmp)
+		})
+	}
+}
diff --git a/vendor/github.com/sirupsen/logrus/logger.go b/vendor/github.com/sirupsen/logrus/logger.go
index b67bfcbd3c3cda325c0bcf273f53617ab7bcdbe6..9bf64e22ae921c802991db21692edd7a1c826a6c 100644
--- a/vendor/github.com/sirupsen/logrus/logger.go
+++ b/vendor/github.com/sirupsen/logrus/logger.go
@@ -24,6 +24,10 @@ type Logger struct {
 	// own that implements the `Formatter` interface, see the `README` or included
 	// formatters for examples.
 	Formatter Formatter
+
+	// Flag for whether to log caller info (off by default)
+	ReportCaller bool
+
 	// The logging level the logger should log at. This is typically (and defaults
 	// to) `logrus.Info`, which allows Info(), Warn(), Error() and Fatal() to be
 	// logged.
@@ -32,8 +36,12 @@ type Logger struct {
 	mu MutexWrap
 	// Reusable empty entry
 	entryPool sync.Pool
+	// Function to exit the application, defaults to `os.Exit()`
+	ExitFunc exitFunc
 }
 
+type exitFunc func(int)
+
 type MutexWrap struct {
 	lock     sync.Mutex
 	disabled bool
@@ -69,10 +77,12 @@ func (mw *MutexWrap) Disable() {
 // It's recommended to make this a global instance called `log`.
 func New() *Logger {
 	return &Logger{
-		Out:       os.Stderr,
-		Formatter: new(TextFormatter),
-		Hooks:     make(LevelHooks),
-		Level:     InfoLevel,
+		Out:          os.Stderr,
+		Formatter:    new(TextFormatter),
+		Hooks:        make(LevelHooks),
+		Level:        InfoLevel,
+		ExitFunc:     os.Exit,
+		ReportCaller: false,
 	}
 }
 
@@ -121,20 +131,24 @@ func (logger *Logger) WithTime(t time.Time) *Entry {
 	return entry.WithTime(t)
 }
 
-func (logger *Logger) Debugf(format string, args ...interface{}) {
-	if logger.IsLevelEnabled(DebugLevel) {
+func (logger *Logger) Logf(level Level, format string, args ...interface{}) {
+	if logger.IsLevelEnabled(level) {
 		entry := logger.newEntry()
-		entry.Debugf(format, args...)
+		entry.Logf(level, format, args...)
 		logger.releaseEntry(entry)
 	}
 }
 
+func (logger *Logger) Tracef(format string, args ...interface{}) {
+	logger.Logf(TraceLevel, format, args...)
+}
+
+func (logger *Logger) Debugf(format string, args ...interface{}) {
+	logger.Logf(DebugLevel, format, args...)
+}
+
 func (logger *Logger) Infof(format string, args ...interface{}) {
-	if logger.IsLevelEnabled(InfoLevel) {
-		entry := logger.newEntry()
-		entry.Infof(format, args...)
-		logger.releaseEntry(entry)
-	}
+	logger.Logf(InfoLevel, format, args...)
 }
 
 func (logger *Logger) Printf(format string, args ...interface{}) {
@@ -144,60 +158,44 @@ func (logger *Logger) Printf(format string, args ...interface{}) {
 }
 
 func (logger *Logger) Warnf(format string, args ...interface{}) {
-	if logger.IsLevelEnabled(WarnLevel) {
-		entry := logger.newEntry()
-		entry.Warnf(format, args...)
-		logger.releaseEntry(entry)
-	}
+	logger.Logf(WarnLevel, format, args...)
 }
 
 func (logger *Logger) Warningf(format string, args ...interface{}) {
-	if logger.IsLevelEnabled(WarnLevel) {
-		entry := logger.newEntry()
-		entry.Warnf(format, args...)
-		logger.releaseEntry(entry)
-	}
+	logger.Warnf(format, args...)
 }
 
 func (logger *Logger) Errorf(format string, args ...interface{}) {
-	if logger.IsLevelEnabled(ErrorLevel) {
-		entry := logger.newEntry()
-		entry.Errorf(format, args...)
-		logger.releaseEntry(entry)
-	}
+	logger.Logf(ErrorLevel, format, args...)
 }
 
 func (logger *Logger) Fatalf(format string, args ...interface{}) {
-	if logger.IsLevelEnabled(FatalLevel) {
-		entry := logger.newEntry()
-		entry.Fatalf(format, args...)
-		logger.releaseEntry(entry)
-	}
-	Exit(1)
+	logger.Logf(FatalLevel, format, args...)
+	logger.Exit(1)
 }
 
 func (logger *Logger) Panicf(format string, args ...interface{}) {
-	if logger.IsLevelEnabled(PanicLevel) {
+	logger.Logf(PanicLevel, format, args...)
+}
+
+func (logger *Logger) Log(level Level, args ...interface{}) {
+	if logger.IsLevelEnabled(level) {
 		entry := logger.newEntry()
-		entry.Panicf(format, args...)
+		entry.Log(level, args...)
 		logger.releaseEntry(entry)
 	}
 }
 
+func (logger *Logger) Trace(args ...interface{}) {
+	logger.Log(TraceLevel, args...)
+}
+
 func (logger *Logger) Debug(args ...interface{}) {
-	if logger.IsLevelEnabled(DebugLevel) {
-		entry := logger.newEntry()
-		entry.Debug(args...)
-		logger.releaseEntry(entry)
-	}
+	logger.Log(DebugLevel, args...)
 }
 
 func (logger *Logger) Info(args ...interface{}) {
-	if logger.IsLevelEnabled(InfoLevel) {
-		entry := logger.newEntry()
-		entry.Info(args...)
-		logger.releaseEntry(entry)
-	}
+	logger.Log(InfoLevel, args...)
 }
 
 func (logger *Logger) Print(args ...interface{}) {
@@ -207,60 +205,44 @@ func (logger *Logger) Print(args ...interface{}) {
 }
 
 func (logger *Logger) Warn(args ...interface{}) {
-	if logger.IsLevelEnabled(WarnLevel) {
-		entry := logger.newEntry()
-		entry.Warn(args...)
-		logger.releaseEntry(entry)
-	}
+	logger.Log(WarnLevel, args...)
 }
 
 func (logger *Logger) Warning(args ...interface{}) {
-	if logger.IsLevelEnabled(WarnLevel) {
-		entry := logger.newEntry()
-		entry.Warn(args...)
-		logger.releaseEntry(entry)
-	}
+	logger.Warn(args...)
 }
 
 func (logger *Logger) Error(args ...interface{}) {
-	if logger.IsLevelEnabled(ErrorLevel) {
-		entry := logger.newEntry()
-		entry.Error(args...)
-		logger.releaseEntry(entry)
-	}
+	logger.Log(ErrorLevel, args...)
 }
 
 func (logger *Logger) Fatal(args ...interface{}) {
-	if logger.IsLevelEnabled(FatalLevel) {
-		entry := logger.newEntry()
-		entry.Fatal(args...)
-		logger.releaseEntry(entry)
-	}
-	Exit(1)
+	logger.Log(FatalLevel, args...)
+	logger.Exit(1)
 }
 
 func (logger *Logger) Panic(args ...interface{}) {
-	if logger.IsLevelEnabled(PanicLevel) {
+	logger.Log(PanicLevel, args...)
+}
+
+func (logger *Logger) Logln(level Level, args ...interface{}) {
+	if logger.IsLevelEnabled(level) {
 		entry := logger.newEntry()
-		entry.Panic(args...)
+		entry.Logln(level, args...)
 		logger.releaseEntry(entry)
 	}
 }
 
+func (logger *Logger) Traceln(args ...interface{}) {
+	logger.Logln(TraceLevel, args...)
+}
+
 func (logger *Logger) Debugln(args ...interface{}) {
-	if logger.IsLevelEnabled(DebugLevel) {
-		entry := logger.newEntry()
-		entry.Debugln(args...)
-		logger.releaseEntry(entry)
-	}
+	logger.Logln(DebugLevel, args...)
 }
 
 func (logger *Logger) Infoln(args ...interface{}) {
-	if logger.IsLevelEnabled(InfoLevel) {
-		entry := logger.newEntry()
-		entry.Infoln(args...)
-		logger.releaseEntry(entry)
-	}
+	logger.Logln(InfoLevel, args...)
 }
 
 func (logger *Logger) Println(args ...interface{}) {
@@ -270,44 +252,32 @@ func (logger *Logger) Println(args ...interface{}) {
 }
 
 func (logger *Logger) Warnln(args ...interface{}) {
-	if logger.IsLevelEnabled(WarnLevel) {
-		entry := logger.newEntry()
-		entry.Warnln(args...)
-		logger.releaseEntry(entry)
-	}
+	logger.Logln(WarnLevel, args...)
 }
 
 func (logger *Logger) Warningln(args ...interface{}) {
-	if logger.IsLevelEnabled(WarnLevel) {
-		entry := logger.newEntry()
-		entry.Warnln(args...)
-		logger.releaseEntry(entry)
-	}
+	logger.Warn(args...)
 }
 
 func (logger *Logger) Errorln(args ...interface{}) {
-	if logger.IsLevelEnabled(ErrorLevel) {
-		entry := logger.newEntry()
-		entry.Errorln(args...)
-		logger.releaseEntry(entry)
-	}
+	logger.Logln(ErrorLevel, args...)
 }
 
 func (logger *Logger) Fatalln(args ...interface{}) {
-	if logger.IsLevelEnabled(FatalLevel) {
-		entry := logger.newEntry()
-		entry.Fatalln(args...)
-		logger.releaseEntry(entry)
-	}
-	Exit(1)
+	logger.Logln(FatalLevel, args...)
+	logger.Exit(1)
 }
 
 func (logger *Logger) Panicln(args ...interface{}) {
-	if logger.IsLevelEnabled(PanicLevel) {
-		entry := logger.newEntry()
-		entry.Panicln(args...)
-		logger.releaseEntry(entry)
+	logger.Logln(PanicLevel, args...)
+}
+
+func (logger *Logger) Exit(code int) {
+	runHandlers()
+	if logger.ExitFunc == nil {
+		logger.ExitFunc = os.Exit
 	}
+	logger.ExitFunc(code)
 }
 
 //When file is opened with appending mode, it's safe to
@@ -357,6 +327,12 @@ func (logger *Logger) SetOutput(output io.Writer) {
 	logger.Out = output
 }
 
+func (logger *Logger) SetReportCaller(reportCaller bool) {
+	logger.mu.Lock()
+	defer logger.mu.Unlock()
+	logger.ReportCaller = reportCaller
+}
+
 // ReplaceHooks replaces the logger hooks and returns the old ones
 func (logger *Logger) ReplaceHooks(hooks LevelHooks) LevelHooks {
 	logger.mu.Lock()
diff --git a/vendor/github.com/sirupsen/logrus/logger_test.go b/vendor/github.com/sirupsen/logrus/logger_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..73ba4506160951cc8372e19f02a63fcd22ccb754
--- /dev/null
+++ b/vendor/github.com/sirupsen/logrus/logger_test.go
@@ -0,0 +1,42 @@
+package logrus
+
+import (
+	"bytes"
+	"encoding/json"
+	"fmt"
+	"testing"
+
+	"github.com/stretchr/testify/require"
+)
+
+func TestFieldValueError(t *testing.T) {
+	buf := &bytes.Buffer{}
+	l := &Logger{
+		Out:       buf,
+		Formatter: new(JSONFormatter),
+		Hooks:     make(LevelHooks),
+		Level:     DebugLevel,
+	}
+	l.WithField("func", func() {}).Info("test")
+	fmt.Println(buf.String())
+	var data map[string]interface{}
+	json.Unmarshal(buf.Bytes(), &data)
+	_, ok := data[FieldKeyLogrusError]
+	require.True(t, ok)
+}
+
+func TestNoFieldValueError(t *testing.T) {
+	buf := &bytes.Buffer{}
+	l := &Logger{
+		Out:       buf,
+		Formatter: new(JSONFormatter),
+		Hooks:     make(LevelHooks),
+		Level:     DebugLevel,
+	}
+	l.WithField("str", "str").Info("test")
+	fmt.Println(buf.String())
+	var data map[string]interface{}
+	json.Unmarshal(buf.Bytes(), &data)
+	_, ok := data[FieldKeyLogrusError]
+	require.False(t, ok)
+}
diff --git a/vendor/github.com/sirupsen/logrus/logrus.go b/vendor/github.com/sirupsen/logrus/logrus.go
index fa0b9dea8adc994a8dcde1d16cd853aeba4380c5..c1ca889902bea91ff65d74b75fb518e41d815cf5 100644
--- a/vendor/github.com/sirupsen/logrus/logrus.go
+++ b/vendor/github.com/sirupsen/logrus/logrus.go
@@ -14,22 +14,11 @@ type Level uint32
 
 // Convert the Level to a string. E.g. PanicLevel becomes "panic".
 func (level Level) String() string {
-	switch level {
-	case DebugLevel:
-		return "debug"
-	case InfoLevel:
-		return "info"
-	case WarnLevel:
-		return "warning"
-	case ErrorLevel:
-		return "error"
-	case FatalLevel:
-		return "fatal"
-	case PanicLevel:
-		return "panic"
+	if b, err := level.MarshalText(); err == nil {
+		return string(b)
+	} else {
+		return "unknown"
 	}
-
-	return "unknown"
 }
 
 // ParseLevel takes a string level and returns the Logrus log level constant.
@@ -47,12 +36,47 @@ func ParseLevel(lvl string) (Level, error) {
 		return InfoLevel, nil
 	case "debug":
 		return DebugLevel, nil
+	case "trace":
+		return TraceLevel, nil
 	}
 
 	var l Level
 	return l, fmt.Errorf("not a valid logrus Level: %q", lvl)
 }
 
+// UnmarshalText implements encoding.TextUnmarshaler.
+func (level *Level) UnmarshalText(text []byte) error {
+	l, err := ParseLevel(string(text))
+	if err != nil {
+		return err
+	}
+
+	*level = Level(l)
+
+	return nil
+}
+
+func (level Level) MarshalText() ([]byte, error) {
+	switch level {
+	case TraceLevel:
+		return []byte("trace"), nil
+	case DebugLevel:
+		return []byte("debug"), nil
+	case InfoLevel:
+		return []byte("info"), nil
+	case WarnLevel:
+		return []byte("warning"), nil
+	case ErrorLevel:
+		return []byte("error"), nil
+	case FatalLevel:
+		return []byte("fatal"), nil
+	case PanicLevel:
+		return []byte("panic"), nil
+	}
+
+	return nil, fmt.Errorf("not a valid lorus level %q", level)
+}
+
 // A constant exposing all logging levels
 var AllLevels = []Level{
 	PanicLevel,
@@ -61,6 +85,7 @@ var AllLevels = []Level{
 	WarnLevel,
 	InfoLevel,
 	DebugLevel,
+	TraceLevel,
 }
 
 // These are the different logging levels. You can set the logging level to log
@@ -69,7 +94,7 @@ const (
 	// PanicLevel level, highest level of severity. Logs and then calls panic with the
 	// message passed to Debug, Info, ...
 	PanicLevel Level = iota
-	// FatalLevel level. Logs and then calls `os.Exit(1)`. It will exit even if the
+	// FatalLevel level. Logs and then calls `logger.Exit(1)`. It will exit even if the
 	// logging level is set to Panic.
 	FatalLevel
 	// ErrorLevel level. Logs. Used for errors that should definitely be noted.
@@ -82,6 +107,8 @@ const (
 	InfoLevel
 	// DebugLevel level. Usually only enabled when debugging. Very verbose logging.
 	DebugLevel
+	// TraceLevel level. Designates finer-grained informational events than the Debug.
+	TraceLevel
 )
 
 // Won't compile if StdLogger can't be realized by a log.Logger
@@ -148,3 +175,12 @@ type FieldLogger interface {
 	// IsFatalEnabled() bool
 	// IsPanicEnabled() bool
 }
+
+// Ext1FieldLogger (the first extension to FieldLogger) is superfluous, it is
+// here for consistancy. Do not use. Use Logger or Entry instead.
+type Ext1FieldLogger interface {
+	FieldLogger
+	Tracef(format string, args ...interface{})
+	Trace(args ...interface{})
+	Traceln(args ...interface{})
+}
diff --git a/vendor/github.com/sirupsen/logrus/logrus_test.go b/vendor/github.com/sirupsen/logrus/logrus_test.go
index 97d15d7fd46a6052c43576200c91aecb0f77e901..d857262a9ea7e1cc02eee6e11b2df476f3c7c024 100644
--- a/vendor/github.com/sirupsen/logrus/logrus_test.go
+++ b/vendor/github.com/sirupsen/logrus/logrus_test.go
@@ -1,69 +1,95 @@
-package logrus
+package logrus_test
 
 import (
 	"bytes"
 	"encoding/json"
+	"fmt"
 	"io/ioutil"
-	"strconv"
-	"strings"
+	"os"
+	"path/filepath"
+	"runtime"
 	"sync"
 	"testing"
 	"time"
 
 	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+
+	. "github.com/sirupsen/logrus"
+	. "github.com/sirupsen/logrus/internal/testutils"
 )
 
-func LogAndAssertJSON(t *testing.T, log func(*Logger), assertions func(fields Fields)) {
+// TestReportCaller verifies that when ReportCaller is set, the 'func' field
+// is added, and when it is unset it is not set or modified
+// Verify that functions within the Logrus package aren't considered when
+// discovering the caller.
+func TestReportCallerWhenConfigured(t *testing.T) {
+	LogAndAssertJSON(t, func(log *Logger) {
+		log.ReportCaller = false
+		log.Print("testNoCaller")
+	}, func(fields Fields) {
+		assert.Equal(t, "testNoCaller", fields["msg"])
+		assert.Equal(t, "info", fields["level"])
+		assert.Equal(t, nil, fields["func"])
+	})
+
+	LogAndAssertJSON(t, func(log *Logger) {
+		log.ReportCaller = true
+		log.Print("testWithCaller")
+	}, func(fields Fields) {
+		assert.Equal(t, "testWithCaller", fields["msg"])
+		assert.Equal(t, "info", fields["level"])
+		assert.Equal(t,
+			"github.com/sirupsen/logrus_test.TestReportCallerWhenConfigured.func3", fields["func"])
+	})
+}
+
+func logSomething(t *testing.T, message string) Fields {
 	var buffer bytes.Buffer
 	var fields Fields
 
 	logger := New()
 	logger.Out = &buffer
 	logger.Formatter = new(JSONFormatter)
+	logger.ReportCaller = true
 
-	log(logger)
+	entry := logger.WithFields(Fields{
+		"foo": "bar",
+	})
+
+	entry.Info(message)
 
 	err := json.Unmarshal(buffer.Bytes(), &fields)
 	assert.Nil(t, err)
 
-	assertions(fields)
+	return fields
 }
 
-func LogAndAssertText(t *testing.T, log func(*Logger), assertions func(fields map[string]string)) {
-	var buffer bytes.Buffer
+// TestReportCallerHelperDirect - verify reference when logging from a regular function
+func TestReportCallerHelperDirect(t *testing.T) {
+	fields := logSomething(t, "direct")
 
-	logger := New()
-	logger.Out = &buffer
-	logger.Formatter = &TextFormatter{
-		DisableColors: true,
-	}
+	assert.Equal(t, "direct", fields["msg"])
+	assert.Equal(t, "info", fields["level"])
+	assert.Regexp(t, "github.com/.*/logrus_test.logSomething", fields["func"])
+}
 
-	log(logger)
+// TestReportCallerHelperDirect - verify reference when logging from a function called via pointer
+func TestReportCallerHelperViaPointer(t *testing.T) {
+	fptr := logSomething
+	fields := fptr(t, "via pointer")
 
-	fields := make(map[string]string)
-	for _, kv := range strings.Split(buffer.String(), " ") {
-		if !strings.Contains(kv, "=") {
-			continue
-		}
-		kvArr := strings.Split(kv, "=")
-		key := strings.TrimSpace(kvArr[0])
-		val := kvArr[1]
-		if kvArr[1][0] == '"' {
-			var err error
-			val, err = strconv.Unquote(val)
-			assert.NoError(t, err)
-		}
-		fields[key] = val
-	}
-	assertions(fields)
+	assert.Equal(t, "via pointer", fields["msg"])
+	assert.Equal(t, "info", fields["level"])
+	assert.Regexp(t, "github.com/.*/logrus_test.logSomething", fields["func"])
 }
 
 func TestPrint(t *testing.T) {
 	LogAndAssertJSON(t, func(log *Logger) {
 		log.Print("test")
 	}, func(fields Fields) {
-		assert.Equal(t, fields["msg"], "test")
-		assert.Equal(t, fields["level"], "info")
+		assert.Equal(t, "test", fields["msg"])
+		assert.Equal(t, "info", fields["level"])
 	})
 }
 
@@ -71,8 +97,8 @@ func TestInfo(t *testing.T) {
 	LogAndAssertJSON(t, func(log *Logger) {
 		log.Info("test")
 	}, func(fields Fields) {
-		assert.Equal(t, fields["msg"], "test")
-		assert.Equal(t, fields["level"], "info")
+		assert.Equal(t, "test", fields["msg"])
+		assert.Equal(t, "info", fields["level"])
 	})
 }
 
@@ -80,8 +106,17 @@ func TestWarn(t *testing.T) {
 	LogAndAssertJSON(t, func(log *Logger) {
 		log.Warn("test")
 	}, func(fields Fields) {
-		assert.Equal(t, fields["msg"], "test")
-		assert.Equal(t, fields["level"], "warning")
+		assert.Equal(t, "test", fields["msg"])
+		assert.Equal(t, "warning", fields["level"])
+	})
+}
+
+func TestLog(t *testing.T) {
+	LogAndAssertJSON(t, func(log *Logger) {
+		log.Log(WarnLevel, "test")
+	}, func(fields Fields) {
+		assert.Equal(t, "test", fields["msg"])
+		assert.Equal(t, "warning", fields["level"])
 	})
 }
 
@@ -89,7 +124,7 @@ func TestInfolnShouldAddSpacesBetweenStrings(t *testing.T) {
 	LogAndAssertJSON(t, func(log *Logger) {
 		log.Infoln("test", "test")
 	}, func(fields Fields) {
-		assert.Equal(t, fields["msg"], "test test")
+		assert.Equal(t, "test test", fields["msg"])
 	})
 }
 
@@ -97,7 +132,7 @@ func TestInfolnShouldAddSpacesBetweenStringAndNonstring(t *testing.T) {
 	LogAndAssertJSON(t, func(log *Logger) {
 		log.Infoln("test", 10)
 	}, func(fields Fields) {
-		assert.Equal(t, fields["msg"], "test 10")
+		assert.Equal(t, "test 10", fields["msg"])
 	})
 }
 
@@ -105,7 +140,7 @@ func TestInfolnShouldAddSpacesBetweenTwoNonStrings(t *testing.T) {
 	LogAndAssertJSON(t, func(log *Logger) {
 		log.Infoln(10, 10)
 	}, func(fields Fields) {
-		assert.Equal(t, fields["msg"], "10 10")
+		assert.Equal(t, "10 10", fields["msg"])
 	})
 }
 
@@ -113,7 +148,7 @@ func TestInfoShouldAddSpacesBetweenTwoNonStrings(t *testing.T) {
 	LogAndAssertJSON(t, func(log *Logger) {
 		log.Infoln(10, 10)
 	}, func(fields Fields) {
-		assert.Equal(t, fields["msg"], "10 10")
+		assert.Equal(t, "10 10", fields["msg"])
 	})
 }
 
@@ -121,7 +156,7 @@ func TestInfoShouldNotAddSpacesBetweenStringAndNonstring(t *testing.T) {
 	LogAndAssertJSON(t, func(log *Logger) {
 		log.Info("test", 10)
 	}, func(fields Fields) {
-		assert.Equal(t, fields["msg"], "test10")
+		assert.Equal(t, "test10", fields["msg"])
 	})
 }
 
@@ -129,7 +164,7 @@ func TestInfoShouldNotAddSpacesBetweenStrings(t *testing.T) {
 	LogAndAssertJSON(t, func(log *Logger) {
 		log.Info("test", "test")
 	}, func(fields Fields) {
-		assert.Equal(t, fields["msg"], "testtest")
+		assert.Equal(t, "testtest", fields["msg"])
 	})
 }
 
@@ -167,7 +202,7 @@ func TestUserSuppliedFieldDoesNotOverwriteDefaults(t *testing.T) {
 	LogAndAssertJSON(t, func(log *Logger) {
 		log.WithField("msg", "hello").Info("test")
 	}, func(fields Fields) {
-		assert.Equal(t, fields["msg"], "test")
+		assert.Equal(t, "test", fields["msg"])
 	})
 }
 
@@ -175,8 +210,8 @@ func TestUserSuppliedMsgFieldHasPrefix(t *testing.T) {
 	LogAndAssertJSON(t, func(log *Logger) {
 		log.WithField("msg", "hello").Info("test")
 	}, func(fields Fields) {
-		assert.Equal(t, fields["msg"], "test")
-		assert.Equal(t, fields["fields.msg"], "hello")
+		assert.Equal(t, "test", fields["msg"])
+		assert.Equal(t, "hello", fields["fields.msg"])
 	})
 }
 
@@ -184,7 +219,7 @@ func TestUserSuppliedTimeFieldHasPrefix(t *testing.T) {
 	LogAndAssertJSON(t, func(log *Logger) {
 		log.WithField("time", "hello").Info("test")
 	}, func(fields Fields) {
-		assert.Equal(t, fields["fields.time"], "hello")
+		assert.Equal(t, "hello", fields["fields.time"])
 	})
 }
 
@@ -192,8 +227,8 @@ func TestUserSuppliedLevelFieldHasPrefix(t *testing.T) {
 	LogAndAssertJSON(t, func(log *Logger) {
 		log.WithField("level", 1).Info("test")
 	}, func(fields Fields) {
-		assert.Equal(t, fields["level"], "info")
-		assert.Equal(t, fields["fields.level"], 1.0) // JSON has floats only
+		assert.Equal(t, "info", fields["level"])
+		assert.Equal(t, 1.0, fields["fields.level"]) // JSON has floats only
 	})
 }
 
@@ -217,7 +252,7 @@ func TestWithTimeShouldOverrideTime(t *testing.T) {
 	LogAndAssertJSON(t, func(log *Logger) {
 		log.WithTime(now).Info("foobar")
 	}, func(fields Fields) {
-		assert.Equal(t, fields["time"], now.Format(defaultTimestampFormat))
+		assert.Equal(t, fields["time"], now.Format(time.RFC3339))
 	})
 }
 
@@ -227,7 +262,7 @@ func TestWithTimeShouldNotOverrideFields(t *testing.T) {
 	LogAndAssertJSON(t, func(log *Logger) {
 		log.WithField("herp", "derp").WithTime(now).Info("blah")
 	}, func(fields Fields) {
-		assert.Equal(t, fields["time"], now.Format(defaultTimestampFormat))
+		assert.Equal(t, fields["time"], now.Format(time.RFC3339))
 		assert.Equal(t, fields["herp"], "derp")
 	})
 }
@@ -238,7 +273,7 @@ func TestWithFieldShouldNotOverrideTime(t *testing.T) {
 	LogAndAssertJSON(t, func(log *Logger) {
 		log.WithTime(now).WithField("herp", "derp").Info("blah")
 	}, func(fields Fields) {
-		assert.Equal(t, fields["time"], now.Format(defaultTimestampFormat))
+		assert.Equal(t, fields["time"], now.Format(time.RFC3339))
 		assert.Equal(t, fields["herp"], "derp")
 	})
 }
@@ -296,13 +331,119 @@ func TestDoubleLoggingDoesntPrefixPreviousFields(t *testing.T) {
 	err = json.Unmarshal(buffer.Bytes(), &fields)
 	assert.NoError(t, err, "should have decoded second message")
 	assert.Equal(t, len(fields), 4, "should only have msg/time/level/context fields")
-	assert.Equal(t, fields["msg"], "omg it is!")
-	assert.Equal(t, fields["context"], "eating raw fish")
+	assert.Equal(t, "omg it is!", fields["msg"])
+	assert.Equal(t, "eating raw fish", fields["context"])
+	assert.Nil(t, fields["fields.msg"], "should not have prefixed previous `msg` entry")
+
+}
+
+func TestNestedLoggingReportsCorrectCaller(t *testing.T) {
+	var buffer bytes.Buffer
+	var fields Fields
+
+	logger := New()
+	logger.Out = &buffer
+	logger.Formatter = new(JSONFormatter)
+	logger.ReportCaller = true
+
+	llog := logger.WithField("context", "eating raw fish")
+
+	llog.Info("looks delicious")
+	_, _, line, _ := runtime.Caller(0)
+
+	err := json.Unmarshal(buffer.Bytes(), &fields)
+	require.NoError(t, err, "should have decoded first message")
+	assert.Equal(t, 6, len(fields), "should have msg/time/level/func/context fields")
+	assert.Equal(t, "looks delicious", fields["msg"])
+	assert.Equal(t, "eating raw fish", fields["context"])
+	assert.Equal(t,
+		"github.com/sirupsen/logrus_test.TestNestedLoggingReportsCorrectCaller", fields["func"])
+	cwd, err := os.Getwd()
+	require.NoError(t, err)
+	assert.Equal(t, filepath.ToSlash(fmt.Sprintf("%s/logrus_test.go:%d", cwd, line-1)), filepath.ToSlash(fields["file"].(string)))
+
+	buffer.Reset()
+
+	logger.WithFields(Fields{
+		"Clyde": "Stubblefield",
+	}).WithFields(Fields{
+		"Jab'o": "Starks",
+	}).WithFields(Fields{
+		"uri": "https://www.youtube.com/watch?v=V5DTznu-9v0",
+	}).WithFields(Fields{
+		"func": "y drummer",
+	}).WithFields(Fields{
+		"James": "Brown",
+	}).Print("The hardest workin' man in show business")
+	_, _, line, _ = runtime.Caller(0)
+
+	err = json.Unmarshal(buffer.Bytes(), &fields)
+	assert.NoError(t, err, "should have decoded second message")
+	assert.Equal(t, 11, len(fields), "should have all builtin fields plus foo,bar,baz,...")
+	assert.Equal(t, "Stubblefield", fields["Clyde"])
+	assert.Equal(t, "Starks", fields["Jab'o"])
+	assert.Equal(t, "https://www.youtube.com/watch?v=V5DTznu-9v0", fields["uri"])
+	assert.Equal(t, "y drummer", fields["fields.func"])
+	assert.Equal(t, "Brown", fields["James"])
+	assert.Equal(t, "The hardest workin' man in show business", fields["msg"])
 	assert.Nil(t, fields["fields.msg"], "should not have prefixed previous `msg` entry")
+	assert.Equal(t,
+		"github.com/sirupsen/logrus_test.TestNestedLoggingReportsCorrectCaller", fields["func"])
+	require.NoError(t, err)
+	assert.Equal(t, filepath.ToSlash(fmt.Sprintf("%s/logrus_test.go:%d", cwd, line-1)), filepath.ToSlash(fields["file"].(string)))
 
+	logger.ReportCaller = false // return to default value
+}
+
+func logLoop(iterations int, reportCaller bool) {
+	var buffer bytes.Buffer
+
+	logger := New()
+	logger.Out = &buffer
+	logger.Formatter = new(JSONFormatter)
+	logger.ReportCaller = reportCaller
+
+	for i := 0; i < iterations; i++ {
+		logger.Infof("round %d of %d", i, iterations)
+	}
+}
+
+// Assertions for upper bounds to reporting overhead
+func TestCallerReportingOverhead(t *testing.T) {
+	iterations := 5000
+	before := time.Now()
+	logLoop(iterations, false)
+	during := time.Now()
+	logLoop(iterations, true)
+	after := time.Now()
+
+	elapsedNotReporting := during.Sub(before).Nanoseconds()
+	elapsedReporting := after.Sub(during).Nanoseconds()
+
+	maxDelta := 1 * time.Second
+	assert.WithinDuration(t, during, before, maxDelta,
+		"%d log calls without caller name lookup takes less than %d second(s) (was %d nanoseconds)",
+		iterations, maxDelta.Seconds(), elapsedNotReporting)
+	assert.WithinDuration(t, after, during, maxDelta,
+		"%d log calls without caller name lookup takes less than %d second(s) (was %d nanoseconds)",
+		iterations, maxDelta.Seconds(), elapsedReporting)
+}
+
+// benchmarks for both with and without caller-function reporting
+func BenchmarkWithoutCallerTracing(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		logLoop(1000, false)
+	}
+}
+
+func BenchmarkWithCallerTracing(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		logLoop(1000, true)
+	}
 }
 
 func TestConvertLevelToString(t *testing.T) {
+	assert.Equal(t, "trace", TraceLevel.String())
 	assert.Equal(t, "debug", DebugLevel.String())
 	assert.Equal(t, "info", InfoLevel.String())
 	assert.Equal(t, "warning", WarnLevel.String())
@@ -368,6 +509,14 @@ func TestParseLevel(t *testing.T) {
 	assert.Nil(t, err)
 	assert.Equal(t, DebugLevel, l)
 
+	l, err = ParseLevel("trace")
+	assert.Nil(t, err)
+	assert.Equal(t, TraceLevel, l)
+
+	l, err = ParseLevel("TRACE")
+	assert.Nil(t, err)
+	assert.Equal(t, TraceLevel, l)
+
 	l, err = ParseLevel("invalid")
 	assert.Equal(t, "not a valid logrus Level: \"invalid\"", err.Error())
 }
@@ -444,9 +593,12 @@ func TestReplaceHooks(t *testing.T) {
 }
 
 // Compile test
-func TestLogrusInterface(t *testing.T) {
+func TestLogrusInterfaces(t *testing.T) {
 	var buffer bytes.Buffer
-	fn := func(l FieldLogger) {
+	// This verifies FieldLogger and Ext1FieldLogger work as designed.
+	// Please don't use them. Use Logger and Entry directly.
+	fn := func(xl Ext1FieldLogger) {
+		var l FieldLogger = xl
 		b := l.WithField("key", "value")
 		b.Debug("Test")
 	}
@@ -494,6 +646,7 @@ func TestLogLevelEnabled(t *testing.T) {
 	assert.Equal(t, false, log.IsLevelEnabled(WarnLevel))
 	assert.Equal(t, false, log.IsLevelEnabled(InfoLevel))
 	assert.Equal(t, false, log.IsLevelEnabled(DebugLevel))
+	assert.Equal(t, false, log.IsLevelEnabled(TraceLevel))
 
 	log.SetLevel(FatalLevel)
 	assert.Equal(t, true, log.IsLevelEnabled(PanicLevel))
@@ -502,6 +655,7 @@ func TestLogLevelEnabled(t *testing.T) {
 	assert.Equal(t, false, log.IsLevelEnabled(WarnLevel))
 	assert.Equal(t, false, log.IsLevelEnabled(InfoLevel))
 	assert.Equal(t, false, log.IsLevelEnabled(DebugLevel))
+	assert.Equal(t, false, log.IsLevelEnabled(TraceLevel))
 
 	log.SetLevel(ErrorLevel)
 	assert.Equal(t, true, log.IsLevelEnabled(PanicLevel))
@@ -510,6 +664,7 @@ func TestLogLevelEnabled(t *testing.T) {
 	assert.Equal(t, false, log.IsLevelEnabled(WarnLevel))
 	assert.Equal(t, false, log.IsLevelEnabled(InfoLevel))
 	assert.Equal(t, false, log.IsLevelEnabled(DebugLevel))
+	assert.Equal(t, false, log.IsLevelEnabled(TraceLevel))
 
 	log.SetLevel(WarnLevel)
 	assert.Equal(t, true, log.IsLevelEnabled(PanicLevel))
@@ -518,6 +673,7 @@ func TestLogLevelEnabled(t *testing.T) {
 	assert.Equal(t, true, log.IsLevelEnabled(WarnLevel))
 	assert.Equal(t, false, log.IsLevelEnabled(InfoLevel))
 	assert.Equal(t, false, log.IsLevelEnabled(DebugLevel))
+	assert.Equal(t, false, log.IsLevelEnabled(TraceLevel))
 
 	log.SetLevel(InfoLevel)
 	assert.Equal(t, true, log.IsLevelEnabled(PanicLevel))
@@ -526,6 +682,7 @@ func TestLogLevelEnabled(t *testing.T) {
 	assert.Equal(t, true, log.IsLevelEnabled(WarnLevel))
 	assert.Equal(t, true, log.IsLevelEnabled(InfoLevel))
 	assert.Equal(t, false, log.IsLevelEnabled(DebugLevel))
+	assert.Equal(t, false, log.IsLevelEnabled(TraceLevel))
 
 	log.SetLevel(DebugLevel)
 	assert.Equal(t, true, log.IsLevelEnabled(PanicLevel))
@@ -534,4 +691,26 @@ func TestLogLevelEnabled(t *testing.T) {
 	assert.Equal(t, true, log.IsLevelEnabled(WarnLevel))
 	assert.Equal(t, true, log.IsLevelEnabled(InfoLevel))
 	assert.Equal(t, true, log.IsLevelEnabled(DebugLevel))
+	assert.Equal(t, false, log.IsLevelEnabled(TraceLevel))
+
+	log.SetLevel(TraceLevel)
+	assert.Equal(t, true, log.IsLevelEnabled(PanicLevel))
+	assert.Equal(t, true, log.IsLevelEnabled(FatalLevel))
+	assert.Equal(t, true, log.IsLevelEnabled(ErrorLevel))
+	assert.Equal(t, true, log.IsLevelEnabled(WarnLevel))
+	assert.Equal(t, true, log.IsLevelEnabled(InfoLevel))
+	assert.Equal(t, true, log.IsLevelEnabled(DebugLevel))
+	assert.Equal(t, true, log.IsLevelEnabled(TraceLevel))
+}
+
+func TestReportCallerOnTextFormatter(t *testing.T) {
+	l := New()
+
+	l.Formatter.(*TextFormatter).ForceColors = true
+	l.Formatter.(*TextFormatter).DisableColors = false
+	l.WithFields(Fields{"func": "func", "file": "file"}).Info("test")
+
+	l.Formatter.(*TextFormatter).ForceColors = false
+	l.Formatter.(*TextFormatter).DisableColors = true
+	l.WithFields(Fields{"func": "func", "file": "file"}).Info("test")
 }
diff --git a/vendor/github.com/sirupsen/logrus/terminal_bsd.go b/vendor/github.com/sirupsen/logrus/terminal_bsd.go
deleted file mode 100644
index 5b6212d24c53ebbad4ffed4146cf17cd330e4235..0000000000000000000000000000000000000000
--- a/vendor/github.com/sirupsen/logrus/terminal_bsd.go
+++ /dev/null
@@ -1,10 +0,0 @@
-// +build darwin freebsd openbsd netbsd dragonfly
-// +build !appengine,!js
-
-package logrus
-
-import "golang.org/x/sys/unix"
-
-const ioctlReadTermios = unix.TIOCGETA
-
-type Termios unix.Termios
diff --git a/vendor/github.com/sirupsen/logrus/terminal_check_aix.go b/vendor/github.com/sirupsen/logrus/terminal_check_aix.go
new file mode 100644
index 0000000000000000000000000000000000000000..04fdb7ba37100722f09c3af825f0caa799ff2900
--- /dev/null
+++ b/vendor/github.com/sirupsen/logrus/terminal_check_aix.go
@@ -0,0 +1,9 @@
+// +build !appengine,!js,!windows,aix
+
+package logrus
+
+import "io"
+
+func checkIfTerminal(w io.Writer) bool {
+	return false
+}
diff --git a/vendor/github.com/sirupsen/logrus/terminal_check_notappengine.go b/vendor/github.com/sirupsen/logrus/terminal_check_notappengine.go
index 87f0b8097f50a9dea4017d339f8733594db0d032..d46556509e275d820fd7d3665171c2a849a7a9e9 100644
--- a/vendor/github.com/sirupsen/logrus/terminal_check_notappengine.go
+++ b/vendor/github.com/sirupsen/logrus/terminal_check_notappengine.go
@@ -1,4 +1,4 @@
-// +build !appengine,!js
+// +build !appengine,!js,!windows,!aix
 
 package logrus
 
diff --git a/vendor/github.com/sirupsen/logrus/terminal_check_windows.go b/vendor/github.com/sirupsen/logrus/terminal_check_windows.go
new file mode 100644
index 0000000000000000000000000000000000000000..3b9d2864ca34644151d5dbc04d35446c67006540
--- /dev/null
+++ b/vendor/github.com/sirupsen/logrus/terminal_check_windows.go
@@ -0,0 +1,20 @@
+// +build !appengine,!js,windows
+
+package logrus
+
+import (
+	"io"
+	"os"
+	"syscall"
+)
+
+func checkIfTerminal(w io.Writer) bool {
+	switch v := w.(type) {
+	case *os.File:
+		var mode uint32
+		err := syscall.GetConsoleMode(syscall.Handle(v.Fd()), &mode)
+		return err == nil
+	default:
+		return false
+	}
+}
diff --git a/vendor/github.com/sirupsen/logrus/terminal_linux.go b/vendor/github.com/sirupsen/logrus/terminal_linux.go
deleted file mode 100644
index 634e39b301fc0d7f31a350fa10787f8f35f06d9f..0000000000000000000000000000000000000000
--- a/vendor/github.com/sirupsen/logrus/terminal_linux.go
+++ /dev/null
@@ -1,14 +0,0 @@
-// Based on ssh/terminal:
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build !appengine,!js
-
-package logrus
-
-import "golang.org/x/sys/unix"
-
-const ioctlReadTermios = unix.TCGETS
-
-type Termios unix.Termios
diff --git a/vendor/github.com/sirupsen/logrus/terminal_notwindows.go b/vendor/github.com/sirupsen/logrus/terminal_notwindows.go
new file mode 100644
index 0000000000000000000000000000000000000000..3dbd237203097781cacee7a675ac9f8226f6c89c
--- /dev/null
+++ b/vendor/github.com/sirupsen/logrus/terminal_notwindows.go
@@ -0,0 +1,8 @@
+// +build !windows
+
+package logrus
+
+import "io"
+
+func initTerminal(w io.Writer) {
+}
diff --git a/vendor/github.com/sirupsen/logrus/terminal_windows.go b/vendor/github.com/sirupsen/logrus/terminal_windows.go
new file mode 100644
index 0000000000000000000000000000000000000000..b4ef5286cd472d46a7ee56fa80faa0f89f2ed52c
--- /dev/null
+++ b/vendor/github.com/sirupsen/logrus/terminal_windows.go
@@ -0,0 +1,18 @@
+// +build !appengine,!js,windows
+
+package logrus
+
+import (
+	"io"
+	"os"
+	"syscall"
+
+	sequences "github.com/konsorten/go-windows-terminal-sequences"
+)
+
+func initTerminal(w io.Writer) {
+	switch v := w.(type) {
+	case *os.File:
+		sequences.EnableVirtualTerminalProcessing(syscall.Handle(v.Fd()), true)
+	}
+}
diff --git a/vendor/github.com/sirupsen/logrus/text_formatter.go b/vendor/github.com/sirupsen/logrus/text_formatter.go
index 4b1f071f1a3046fabd0f4ca788aee9eb86e2b00e..fb21649c9ae3d1a34bc58d6a0af0709277d0f50f 100644
--- a/vendor/github.com/sirupsen/logrus/text_formatter.go
+++ b/vendor/github.com/sirupsen/logrus/text_formatter.go
@@ -4,6 +4,7 @@ import (
 	"bytes"
 	"fmt"
 	"os"
+	"runtime"
 	"sort"
 	"strings"
 	"sync"
@@ -55,6 +56,9 @@ type TextFormatter struct {
 	// be desired.
 	DisableSorting bool
 
+	// The keys sorting function, when uninitialized it uses sort.Strings.
+	SortingFunc func([]string)
+
 	// Disables the truncation of the level text to 4 characters.
 	DisableLevelTruncation bool
 
@@ -73,17 +77,21 @@ type TextFormatter struct {
 	//         FieldKeyMsg:   "@message"}}
 	FieldMap FieldMap
 
-	sync.Once
+	terminalInitOnce sync.Once
 }
 
 func (f *TextFormatter) init(entry *Entry) {
 	if entry.Logger != nil {
 		f.isTerminal = checkIfTerminal(entry.Logger.Out)
+
+		if f.isTerminal {
+			initTerminal(entry.Logger.Out)
+		}
 	}
 }
 
 func (f *TextFormatter) isColored() bool {
-	isColored := f.ForceColors || f.isTerminal
+	isColored := f.ForceColors || (f.isTerminal && (runtime.GOOS != "windows"))
 
 	if f.EnvironmentOverrideColors {
 		if force, ok := os.LookupEnv("CLICOLOR_FORCE"); ok && force != "0" {
@@ -100,15 +108,46 @@ func (f *TextFormatter) isColored() bool {
 
 // Format renders a single log entry
 func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
-	prefixFieldClashes(entry.Data, f.FieldMap)
-
-	keys := make([]string, 0, len(entry.Data))
-	for k := range entry.Data {
+	data := make(Fields)
+	for k, v := range entry.Data {
+		data[k] = v
+	}
+	prefixFieldClashes(data, f.FieldMap, entry.HasCaller())
+	keys := make([]string, 0, len(data))
+	for k := range data {
 		keys = append(keys, k)
 	}
 
+	fixedKeys := make([]string, 0, 4+len(data))
+	if !f.DisableTimestamp {
+		fixedKeys = append(fixedKeys, f.FieldMap.resolve(FieldKeyTime))
+	}
+	fixedKeys = append(fixedKeys, f.FieldMap.resolve(FieldKeyLevel))
+	if entry.Message != "" {
+		fixedKeys = append(fixedKeys, f.FieldMap.resolve(FieldKeyMsg))
+	}
+	if entry.err != "" {
+		fixedKeys = append(fixedKeys, f.FieldMap.resolve(FieldKeyLogrusError))
+	}
+	if entry.HasCaller() {
+		fixedKeys = append(fixedKeys,
+			f.FieldMap.resolve(FieldKeyFunc), f.FieldMap.resolve(FieldKeyFile))
+	}
+
 	if !f.DisableSorting {
-		sort.Strings(keys)
+		if f.SortingFunc == nil {
+			sort.Strings(keys)
+			fixedKeys = append(fixedKeys, keys...)
+		} else {
+			if !f.isColored() {
+				fixedKeys = append(fixedKeys, keys...)
+				f.SortingFunc(fixedKeys)
+			} else {
+				f.SortingFunc(keys)
+			}
+		}
+	} else {
+		fixedKeys = append(fixedKeys, keys...)
 	}
 
 	var b *bytes.Buffer
@@ -118,24 +157,34 @@ func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
 		b = &bytes.Buffer{}
 	}
 
-	f.Do(func() { f.init(entry) })
+	f.terminalInitOnce.Do(func() { f.init(entry) })
 
 	timestampFormat := f.TimestampFormat
 	if timestampFormat == "" {
 		timestampFormat = defaultTimestampFormat
 	}
 	if f.isColored() {
-		f.printColored(b, entry, keys, timestampFormat)
+		f.printColored(b, entry, keys, data, timestampFormat)
 	} else {
-		if !f.DisableTimestamp {
-			f.appendKeyValue(b, f.FieldMap.resolve(FieldKeyTime), entry.Time.Format(timestampFormat))
-		}
-		f.appendKeyValue(b, f.FieldMap.resolve(FieldKeyLevel), entry.Level.String())
-		if entry.Message != "" {
-			f.appendKeyValue(b, f.FieldMap.resolve(FieldKeyMsg), entry.Message)
-		}
-		for _, key := range keys {
-			f.appendKeyValue(b, key, entry.Data[key])
+		for _, key := range fixedKeys {
+			var value interface{}
+			switch {
+			case key == f.FieldMap.resolve(FieldKeyTime):
+				value = entry.Time.Format(timestampFormat)
+			case key == f.FieldMap.resolve(FieldKeyLevel):
+				value = entry.Level.String()
+			case key == f.FieldMap.resolve(FieldKeyMsg):
+				value = entry.Message
+			case key == f.FieldMap.resolve(FieldKeyLogrusError):
+				value = entry.err
+			case key == f.FieldMap.resolve(FieldKeyFunc) && entry.HasCaller():
+				value = entry.Caller.Function
+			case key == f.FieldMap.resolve(FieldKeyFile) && entry.HasCaller():
+				value = fmt.Sprintf("%s:%d", entry.Caller.File, entry.Caller.Line)
+			default:
+				value = data[key]
+			}
+			f.appendKeyValue(b, key, value)
 		}
 	}
 
@@ -143,10 +192,10 @@ func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
 	return b.Bytes(), nil
 }
 
-func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []string, timestampFormat string) {
+func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []string, data Fields, timestampFormat string) {
 	var levelColor int
 	switch entry.Level {
-	case DebugLevel:
+	case DebugLevel, TraceLevel:
 		levelColor = gray
 	case WarnLevel:
 		levelColor = yellow
@@ -165,15 +214,22 @@ func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []strin
 	// the behavior of logrus text_formatter the same as the stdlib log package
 	entry.Message = strings.TrimSuffix(entry.Message, "\n")
 
+	caller := ""
+
+	if entry.HasCaller() {
+		caller = fmt.Sprintf("%s:%d %s()",
+			entry.Caller.File, entry.Caller.Line, entry.Caller.Function)
+	}
+
 	if f.DisableTimestamp {
-		fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m %-44s ", levelColor, levelText, entry.Message)
+		fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m%s %-44s ", levelColor, levelText, caller, entry.Message)
 	} else if !f.FullTimestamp {
-		fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%04d] %-44s ", levelColor, levelText, int(entry.Time.Sub(baseTimestamp)/time.Second), entry.Message)
+		fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%04d]%s %-44s ", levelColor, levelText, int(entry.Time.Sub(baseTimestamp)/time.Second), caller, entry.Message)
 	} else {
-		fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%s] %-44s ", levelColor, levelText, entry.Time.Format(timestampFormat), entry.Message)
+		fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%s]%s %-44s ", levelColor, levelText, entry.Time.Format(timestampFormat), caller, entry.Message)
 	}
 	for _, k := range keys {
-		v := entry.Data[k]
+		v := data[k]
 		fmt.Fprintf(b, " \x1b[%dm%s\x1b[0m=", levelColor, k)
 		f.appendValue(b, v)
 	}
diff --git a/vendor/github.com/sirupsen/logrus/text_formatter_test.go b/vendor/github.com/sirupsen/logrus/text_formatter_test.go
index b57ef7ceef34d92d3992ed44877496fc5dc89523..9c5e6f0a1ed0efc0fc4785f73e7a82b1652c7c77 100644
--- a/vendor/github.com/sirupsen/logrus/text_formatter_test.go
+++ b/vendor/github.com/sirupsen/logrus/text_formatter_test.go
@@ -5,11 +5,14 @@ import (
 	"errors"
 	"fmt"
 	"os"
+	"runtime"
+	"sort"
 	"strings"
 	"testing"
 	"time"
 
 	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
 )
 
 func TestFormatting(t *testing.T) {
@@ -142,7 +145,7 @@ func TestDisableLevelTruncation(t *testing.T) {
 		tf := &TextFormatter{DisableLevelTruncation: disabled}
 		var b bytes.Buffer
 		entry.Level = level
-		tf.printColored(&b, entry, keys, timestampFormat)
+		tf.printColored(&b, entry, keys, nil, timestampFormat)
 		logLine := (&b).String()
 		if disabled {
 			expected := strings.ToUpper(level.String())
@@ -441,10 +444,42 @@ func TestTextFormatterIsColored(t *testing.T) {
 				os.Setenv("CLICOLOR_FORCE", val.clicolorForceVal)
 			}
 			res := tf.isColored()
-			assert.Equal(subT, val.expectedResult, res)
+			if runtime.GOOS == "windows" && !tf.ForceColors && !val.clicolorForceIsSet {
+				assert.Equal(subT, false, res)
+			} else {
+				assert.Equal(subT, val.expectedResult, res)
+			}
 		})
 	}
 }
 
-// TODO add tests for sorting etc., this requires a parser for the text
-// formatter output.
+func TestCustomSorting(t *testing.T) {
+	formatter := &TextFormatter{
+		DisableColors: true,
+		SortingFunc: func(keys []string) {
+			sort.Slice(keys, func(i, j int) bool {
+				if keys[j] == "prefix" {
+					return false
+				}
+				if keys[i] == "prefix" {
+					return true
+				}
+				return strings.Compare(keys[i], keys[j]) == -1
+			})
+		},
+	}
+
+	entry := &Entry{
+		Message: "Testing custom sort function",
+		Time:    time.Now(),
+		Level:   InfoLevel,
+		Data: Fields{
+			"test":      "testvalue",
+			"prefix":    "the application prefix",
+			"blablabla": "blablabla",
+		},
+	}
+	b, err := formatter.Format(entry)
+	require.NoError(t, err)
+	require.True(t, strings.HasPrefix(string(b), "prefix="), "format output is %q", string(b))
+}
diff --git a/vendor/github.com/sirupsen/logrus/writer.go b/vendor/github.com/sirupsen/logrus/writer.go
index 7bdebedc60bb91b7c24ec373cace3c6d3e9365a7..9e1f7513597d24c03ba25afd911b3d8a733c5c5f 100644
--- a/vendor/github.com/sirupsen/logrus/writer.go
+++ b/vendor/github.com/sirupsen/logrus/writer.go
@@ -24,6 +24,8 @@ func (entry *Entry) WriterLevel(level Level) *io.PipeWriter {
 	var printFunc func(args ...interface{})
 
 	switch level {
+	case TraceLevel:
+		printFunc = entry.Trace
 	case DebugLevel:
 		printFunc = entry.Debug
 	case InfoLevel:
diff --git a/vendor/github.com/stretchr/testify/LICENCE.txt b/vendor/github.com/stretchr/testify/LICENCE.txt
deleted file mode 100644
index 473b670a7c6195561168a94337416f32a4db8e73..0000000000000000000000000000000000000000
--- a/vendor/github.com/stretchr/testify/LICENCE.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell
-
-Please consider promoting this project if you find it useful.
-
-Permission is hereby granted, free of charge, to any person 
-obtaining a copy of this software and associated documentation 
-files (the "Software"), to deal in the Software without restriction, 
-including without limitation the rights to use, copy, modify, merge, 
-publish, distribute, sublicense, and/or sell copies of the Software, 
-and to permit persons to whom the Software is furnished to do so, 
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included
-in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 
-OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
-DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT 
-OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 
-OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/vendor/github.com/stretchr/testify/LICENSE b/vendor/github.com/stretchr/testify/LICENSE
index 473b670a7c6195561168a94337416f32a4db8e73..f38ec5956b6400841b45ca7c44940d9312e37e9e 100644
--- a/vendor/github.com/stretchr/testify/LICENSE
+++ b/vendor/github.com/stretchr/testify/LICENSE
@@ -1,22 +1,21 @@
-Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell
+MIT License
 
-Please consider promoting this project if you find it useful.
+Copyright (c) 2012-2018 Mat Ryer and Tyler Bunnell
 
-Permission is hereby granted, free of charge, to any person 
-obtaining a copy of this software and associated documentation 
-files (the "Software"), to deal in the Software without restriction, 
-including without limitation the rights to use, copy, modify, merge, 
-publish, distribute, sublicense, and/or sell copies of the Software, 
-and to permit persons to whom the Software is furnished to do so, 
-subject to the following conditions:
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
 
-The above copyright notice and this permission notice shall be included
-in all copies or substantial portions of the Software.
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
 
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 
-OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
-DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT 
-OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 
-OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/vendor/github.com/stretchr/testify/assert/assertion_format.go b/vendor/github.com/stretchr/testify/assert/assertion_format.go
index 23838c4ceea798900d74f4703cf87b62b1d33402..aa1c2b95cddb861f99392ba9e84f99dcb1c04699 100644
--- a/vendor/github.com/stretchr/testify/assert/assertion_format.go
+++ b/vendor/github.com/stretchr/testify/assert/assertion_format.go
@@ -13,6 +13,9 @@ import (
 
 // Conditionf uses a Comparison to assert a complex condition.
 func Conditionf(t TestingT, comp Comparison, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return Condition(t, comp, append([]interface{}{msg}, args...)...)
 }
 
@@ -22,19 +25,41 @@ func Conditionf(t TestingT, comp Comparison, msg string, args ...interface{}) bo
 //    assert.Containsf(t, "Hello World", "World", "error message %s", "formatted")
 //    assert.Containsf(t, ["Hello", "World"], "World", "error message %s", "formatted")
 //    assert.Containsf(t, {"Hello": "World"}, "Hello", "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func Containsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return Contains(t, s, contains, append([]interface{}{msg}, args...)...)
 }
 
+// DirExistsf checks whether a directory exists in the given path. It also fails if the path is a file rather a directory or there is an error checking whether it exists.
+func DirExistsf(t TestingT, path string, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	return DirExists(t, path, append([]interface{}{msg}, args...)...)
+}
+
+// ElementsMatchf asserts that the specified listA(array, slice...) is equal to specified
+// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements,
+// the number of appearances of each of them in both lists should match.
+//
+// assert.ElementsMatchf(t, [1, 3, 2, 3], [1, 3, 3, 2], "error message %s", "formatted")
+func ElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	return ElementsMatch(t, listA, listB, append([]interface{}{msg}, args...)...)
+}
+
 // Emptyf asserts that the specified object is empty.  I.e. nil, "", false, 0 or either
 // a slice or a channel with len == 0.
 //
 //  assert.Emptyf(t, obj, "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func Emptyf(t TestingT, object interface{}, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return Empty(t, object, append([]interface{}{msg}, args...)...)
 }
 
@@ -42,12 +67,13 @@ func Emptyf(t TestingT, object interface{}, msg string, args ...interface{}) boo
 //
 //    assert.Equalf(t, 123, 123, "error message %s", "formatted")
 //
-// Returns whether the assertion was successful (true) or not (false).
-//
 // Pointer variable equality is determined based on the equality of the
 // referenced values (as opposed to the memory addresses). Function equality
 // cannot be determined and will always fail.
 func Equalf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return Equal(t, expected, actual, append([]interface{}{msg}, args...)...)
 }
 
@@ -56,9 +82,10 @@ func Equalf(t TestingT, expected interface{}, actual interface{}, msg string, ar
 //
 //   actualObj, err := SomeFunction()
 //   assert.EqualErrorf(t, err,  expectedErrorString, "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func EqualErrorf(t TestingT, theError error, errString string, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return EqualError(t, theError, errString, append([]interface{}{msg}, args...)...)
 }
 
@@ -66,9 +93,10 @@ func EqualErrorf(t TestingT, theError error, errString string, msg string, args
 // and equal.
 //
 //    assert.EqualValuesf(t, uint32(123, "error message %s", "formatted"), int32(123))
-//
-// Returns whether the assertion was successful (true) or not (false).
 func EqualValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return EqualValues(t, expected, actual, append([]interface{}{msg}, args...)...)
 }
 
@@ -78,58 +106,81 @@ func EqualValuesf(t TestingT, expected interface{}, actual interface{}, msg stri
 //   if assert.Errorf(t, err, "error message %s", "formatted") {
 // 	   assert.Equal(t, expectedErrorf, err)
 //   }
-//
-// Returns whether the assertion was successful (true) or not (false).
 func Errorf(t TestingT, err error, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return Error(t, err, append([]interface{}{msg}, args...)...)
 }
 
-// Exactlyf asserts that two objects are equal is value and type.
+// Exactlyf asserts that two objects are equal in value and type.
 //
 //    assert.Exactlyf(t, int32(123, "error message %s", "formatted"), int64(123))
-//
-// Returns whether the assertion was successful (true) or not (false).
 func Exactlyf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return Exactly(t, expected, actual, append([]interface{}{msg}, args...)...)
 }
 
 // Failf reports a failure through
 func Failf(t TestingT, failureMessage string, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return Fail(t, failureMessage, append([]interface{}{msg}, args...)...)
 }
 
 // FailNowf fails test
 func FailNowf(t TestingT, failureMessage string, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return FailNow(t, failureMessage, append([]interface{}{msg}, args...)...)
 }
 
 // Falsef asserts that the specified value is false.
 //
 //    assert.Falsef(t, myBool, "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func Falsef(t TestingT, value bool, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return False(t, value, append([]interface{}{msg}, args...)...)
 }
 
+// FileExistsf checks whether a file exists in the given path. It also fails if the path points to a directory or there is an error when trying to check the file.
+func FileExistsf(t TestingT, path string, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	return FileExists(t, path, append([]interface{}{msg}, args...)...)
+}
+
 // HTTPBodyContainsf asserts that a specified handler returns a
 // body that contains a string.
 //
-//  assert.HTTPBodyContainsf(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted")
+//  assert.HTTPBodyContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted")
 //
 // Returns whether the assertion was successful (true) or not (false).
-func HTTPBodyContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}) bool {
-	return HTTPBodyContains(t, handler, method, url, values, str)
+func HTTPBodyContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	return HTTPBodyContains(t, handler, method, url, values, str, append([]interface{}{msg}, args...)...)
 }
 
 // HTTPBodyNotContainsf asserts that a specified handler returns a
 // body that does not contain a string.
 //
-//  assert.HTTPBodyNotContainsf(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted")
+//  assert.HTTPBodyNotContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted")
 //
 // Returns whether the assertion was successful (true) or not (false).
-func HTTPBodyNotContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}) bool {
-	return HTTPBodyNotContains(t, handler, method, url, values, str)
+func HTTPBodyNotContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	return HTTPBodyNotContains(t, handler, method, url, values, str, append([]interface{}{msg}, args...)...)
 }
 
 // HTTPErrorf asserts that a specified handler returns an error status code.
@@ -137,8 +188,11 @@ func HTTPBodyNotContainsf(t TestingT, handler http.HandlerFunc, method string, u
 //  assert.HTTPErrorf(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}}
 //
 // Returns whether the assertion was successful (true, "error message %s", "formatted") or not (false).
-func HTTPErrorf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values) bool {
-	return HTTPError(t, handler, method, url, values)
+func HTTPErrorf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	return HTTPError(t, handler, method, url, values, append([]interface{}{msg}, args...)...)
 }
 
 // HTTPRedirectf asserts that a specified handler returns a redirect status code.
@@ -146,8 +200,11 @@ func HTTPErrorf(t TestingT, handler http.HandlerFunc, method string, url string,
 //  assert.HTTPRedirectf(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}}
 //
 // Returns whether the assertion was successful (true, "error message %s", "formatted") or not (false).
-func HTTPRedirectf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values) bool {
-	return HTTPRedirect(t, handler, method, url, values)
+func HTTPRedirectf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	return HTTPRedirect(t, handler, method, url, values, append([]interface{}{msg}, args...)...)
 }
 
 // HTTPSuccessf asserts that a specified handler returns a success status code.
@@ -155,54 +212,80 @@ func HTTPRedirectf(t TestingT, handler http.HandlerFunc, method string, url stri
 //  assert.HTTPSuccessf(t, myHandler, "POST", "http://www.google.com", nil, "error message %s", "formatted")
 //
 // Returns whether the assertion was successful (true) or not (false).
-func HTTPSuccessf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values) bool {
-	return HTTPSuccess(t, handler, method, url, values)
+func HTTPSuccessf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	return HTTPSuccess(t, handler, method, url, values, append([]interface{}{msg}, args...)...)
 }
 
 // Implementsf asserts that an object is implemented by the specified interface.
 //
 //    assert.Implementsf(t, (*MyInterface, "error message %s", "formatted")(nil), new(MyObject))
 func Implementsf(t TestingT, interfaceObject interface{}, object interface{}, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return Implements(t, interfaceObject, object, append([]interface{}{msg}, args...)...)
 }
 
 // InDeltaf asserts that the two numerals are within delta of each other.
 //
 // 	 assert.InDeltaf(t, math.Pi, (22 / 7.0, "error message %s", "formatted"), 0.01)
-//
-// Returns whether the assertion was successful (true) or not (false).
 func InDeltaf(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return InDelta(t, expected, actual, delta, append([]interface{}{msg}, args...)...)
 }
 
+// InDeltaMapValuesf is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys.
+func InDeltaMapValuesf(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	return InDeltaMapValues(t, expected, actual, delta, append([]interface{}{msg}, args...)...)
+}
+
 // InDeltaSlicef is the same as InDelta, except it compares two slices.
 func InDeltaSlicef(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return InDeltaSlice(t, expected, actual, delta, append([]interface{}{msg}, args...)...)
 }
 
 // InEpsilonf asserts that expected and actual have a relative error less than epsilon
-//
-// Returns whether the assertion was successful (true) or not (false).
 func InEpsilonf(t TestingT, expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return InEpsilon(t, expected, actual, epsilon, append([]interface{}{msg}, args...)...)
 }
 
 // InEpsilonSlicef is the same as InEpsilon, except it compares each value from two slices.
 func InEpsilonSlicef(t TestingT, expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return InEpsilonSlice(t, expected, actual, epsilon, append([]interface{}{msg}, args...)...)
 }
 
 // IsTypef asserts that the specified objects are of the same type.
 func IsTypef(t TestingT, expectedType interface{}, object interface{}, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return IsType(t, expectedType, object, append([]interface{}{msg}, args...)...)
 }
 
 // JSONEqf asserts that two JSON strings are equivalent.
 //
 //  assert.JSONEqf(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`, "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func JSONEqf(t TestingT, expected string, actual string, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return JSONEq(t, expected, actual, append([]interface{}{msg}, args...)...)
 }
 
@@ -210,18 +293,20 @@ func JSONEqf(t TestingT, expected string, actual string, msg string, args ...int
 // Lenf also fails if the object has a type that len() not accept.
 //
 //    assert.Lenf(t, mySlice, 3, "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func Lenf(t TestingT, object interface{}, length int, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return Len(t, object, length, append([]interface{}{msg}, args...)...)
 }
 
 // Nilf asserts that the specified object is nil.
 //
 //    assert.Nilf(t, err, "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func Nilf(t TestingT, object interface{}, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return Nil(t, object, append([]interface{}{msg}, args...)...)
 }
 
@@ -231,9 +316,10 @@ func Nilf(t TestingT, object interface{}, msg string, args ...interface{}) bool
 //   if assert.NoErrorf(t, err, "error message %s", "formatted") {
 // 	   assert.Equal(t, expectedObj, actualObj)
 //   }
-//
-// Returns whether the assertion was successful (true) or not (false).
 func NoErrorf(t TestingT, err error, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return NoError(t, err, append([]interface{}{msg}, args...)...)
 }
 
@@ -243,9 +329,10 @@ func NoErrorf(t TestingT, err error, msg string, args ...interface{}) bool {
 //    assert.NotContainsf(t, "Hello World", "Earth", "error message %s", "formatted")
 //    assert.NotContainsf(t, ["Hello", "World"], "Earth", "error message %s", "formatted")
 //    assert.NotContainsf(t, {"Hello": "World"}, "Earth", "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func NotContainsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return NotContains(t, s, contains, append([]interface{}{msg}, args...)...)
 }
 
@@ -255,9 +342,10 @@ func NotContainsf(t TestingT, s interface{}, contains interface{}, msg string, a
 //  if assert.NotEmptyf(t, obj, "error message %s", "formatted") {
 //    assert.Equal(t, "two", obj[1])
 //  }
-//
-// Returns whether the assertion was successful (true) or not (false).
 func NotEmptyf(t TestingT, object interface{}, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return NotEmpty(t, object, append([]interface{}{msg}, args...)...)
 }
 
@@ -265,29 +353,32 @@ func NotEmptyf(t TestingT, object interface{}, msg string, args ...interface{})
 //
 //    assert.NotEqualf(t, obj1, obj2, "error message %s", "formatted")
 //
-// Returns whether the assertion was successful (true) or not (false).
-//
 // Pointer variable equality is determined based on the equality of the
 // referenced values (as opposed to the memory addresses).
 func NotEqualf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return NotEqual(t, expected, actual, append([]interface{}{msg}, args...)...)
 }
 
 // NotNilf asserts that the specified object is not nil.
 //
 //    assert.NotNilf(t, err, "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func NotNilf(t TestingT, object interface{}, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return NotNil(t, object, append([]interface{}{msg}, args...)...)
 }
 
 // NotPanicsf asserts that the code inside the specified PanicTestFunc does NOT panic.
 //
 //   assert.NotPanicsf(t, func(){ RemainCalm() }, "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func NotPanicsf(t TestingT, f PanicTestFunc, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return NotPanics(t, f, append([]interface{}{msg}, args...)...)
 }
 
@@ -295,9 +386,10 @@ func NotPanicsf(t TestingT, f PanicTestFunc, msg string, args ...interface{}) bo
 //
 //  assert.NotRegexpf(t, regexp.MustCompile("starts", "error message %s", "formatted"), "it's starting")
 //  assert.NotRegexpf(t, "^start", "it's not starting", "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func NotRegexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return NotRegexp(t, rx, str, append([]interface{}{msg}, args...)...)
 }
 
@@ -305,23 +397,28 @@ func NotRegexpf(t TestingT, rx interface{}, str interface{}, msg string, args ..
 // elements given in the specified subset(array, slice...).
 //
 //    assert.NotSubsetf(t, [1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]", "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func NotSubsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return NotSubset(t, list, subset, append([]interface{}{msg}, args...)...)
 }
 
-// NotZerof asserts that i is not the zero value for its type and returns the truth.
+// NotZerof asserts that i is not the zero value for its type.
 func NotZerof(t TestingT, i interface{}, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return NotZero(t, i, append([]interface{}{msg}, args...)...)
 }
 
 // Panicsf asserts that the code inside the specified PanicTestFunc panics.
 //
 //   assert.Panicsf(t, func(){ GoCrazy() }, "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func Panicsf(t TestingT, f PanicTestFunc, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return Panics(t, f, append([]interface{}{msg}, args...)...)
 }
 
@@ -329,9 +426,10 @@ func Panicsf(t TestingT, f PanicTestFunc, msg string, args ...interface{}) bool
 // the recovered panic value equals the expected panic value.
 //
 //   assert.PanicsWithValuef(t, "crazy error", func(){ GoCrazy() }, "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func PanicsWithValuef(t TestingT, expected interface{}, f PanicTestFunc, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return PanicsWithValue(t, expected, f, append([]interface{}{msg}, args...)...)
 }
 
@@ -339,9 +437,10 @@ func PanicsWithValuef(t TestingT, expected interface{}, f PanicTestFunc, msg str
 //
 //  assert.Regexpf(t, regexp.MustCompile("start", "error message %s", "formatted"), "it's starting")
 //  assert.Regexpf(t, "start...$", "it's not starting", "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func Regexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return Regexp(t, rx, str, append([]interface{}{msg}, args...)...)
 }
 
@@ -349,31 +448,37 @@ func Regexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...in
 // elements given in the specified subset(array, slice...).
 //
 //    assert.Subsetf(t, [1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]", "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func Subsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return Subset(t, list, subset, append([]interface{}{msg}, args...)...)
 }
 
 // Truef asserts that the specified value is true.
 //
 //    assert.Truef(t, myBool, "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func Truef(t TestingT, value bool, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return True(t, value, append([]interface{}{msg}, args...)...)
 }
 
 // WithinDurationf asserts that the two times are within duration delta of each other.
 //
 //   assert.WithinDurationf(t, time.Now(), time.Now(), 10*time.Second, "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func WithinDurationf(t TestingT, expected time.Time, actual time.Time, delta time.Duration, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return WithinDuration(t, expected, actual, delta, append([]interface{}{msg}, args...)...)
 }
 
-// Zerof asserts that i is the zero value for its type and returns the truth.
+// Zerof asserts that i is the zero value for its type.
 func Zerof(t TestingT, i interface{}, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return Zero(t, i, append([]interface{}{msg}, args...)...)
 }
diff --git a/vendor/github.com/stretchr/testify/assert/assertion_forward.go b/vendor/github.com/stretchr/testify/assert/assertion_forward.go
index fcccbd01c8da52e25c677acdb1f3a38fa73a17db..de39f794e72162679cc754b2864ecdacc8c21387 100644
--- a/vendor/github.com/stretchr/testify/assert/assertion_forward.go
+++ b/vendor/github.com/stretchr/testify/assert/assertion_forward.go
@@ -13,11 +13,17 @@ import (
 
 // Condition uses a Comparison to assert a complex condition.
 func (a *Assertions) Condition(comp Comparison, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return Condition(a.t, comp, msgAndArgs...)
 }
 
 // Conditionf uses a Comparison to assert a complex condition.
 func (a *Assertions) Conditionf(comp Comparison, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return Conditionf(a.t, comp, msg, args...)
 }
 
@@ -27,9 +33,10 @@ func (a *Assertions) Conditionf(comp Comparison, msg string, args ...interface{}
 //    a.Contains("Hello World", "World")
 //    a.Contains(["Hello", "World"], "World")
 //    a.Contains({"Hello": "World"}, "Hello")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) Contains(s interface{}, contains interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return Contains(a.t, s, contains, msgAndArgs...)
 }
 
@@ -39,19 +46,61 @@ func (a *Assertions) Contains(s interface{}, contains interface{}, msgAndArgs ..
 //    a.Containsf("Hello World", "World", "error message %s", "formatted")
 //    a.Containsf(["Hello", "World"], "World", "error message %s", "formatted")
 //    a.Containsf({"Hello": "World"}, "Hello", "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) Containsf(s interface{}, contains interface{}, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return Containsf(a.t, s, contains, msg, args...)
 }
 
+// DirExists checks whether a directory exists in the given path. It also fails if the path is a file rather a directory or there is an error checking whether it exists.
+func (a *Assertions) DirExists(path string, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	return DirExists(a.t, path, msgAndArgs...)
+}
+
+// DirExistsf checks whether a directory exists in the given path. It also fails if the path is a file rather a directory or there is an error checking whether it exists.
+func (a *Assertions) DirExistsf(path string, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	return DirExistsf(a.t, path, msg, args...)
+}
+
+// ElementsMatch asserts that the specified listA(array, slice...) is equal to specified
+// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements,
+// the number of appearances of each of them in both lists should match.
+//
+// a.ElementsMatch([1, 3, 2, 3], [1, 3, 3, 2])
+func (a *Assertions) ElementsMatch(listA interface{}, listB interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	return ElementsMatch(a.t, listA, listB, msgAndArgs...)
+}
+
+// ElementsMatchf asserts that the specified listA(array, slice...) is equal to specified
+// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements,
+// the number of appearances of each of them in both lists should match.
+//
+// a.ElementsMatchf([1, 3, 2, 3], [1, 3, 3, 2], "error message %s", "formatted")
+func (a *Assertions) ElementsMatchf(listA interface{}, listB interface{}, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	return ElementsMatchf(a.t, listA, listB, msg, args...)
+}
+
 // Empty asserts that the specified object is empty.  I.e. nil, "", false, 0 or either
 // a slice or a channel with len == 0.
 //
 //  a.Empty(obj)
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) Empty(object interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return Empty(a.t, object, msgAndArgs...)
 }
 
@@ -59,9 +108,10 @@ func (a *Assertions) Empty(object interface{}, msgAndArgs ...interface{}) bool {
 // a slice or a channel with len == 0.
 //
 //  a.Emptyf(obj, "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) Emptyf(object interface{}, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return Emptyf(a.t, object, msg, args...)
 }
 
@@ -69,12 +119,13 @@ func (a *Assertions) Emptyf(object interface{}, msg string, args ...interface{})
 //
 //    a.Equal(123, 123)
 //
-// Returns whether the assertion was successful (true) or not (false).
-//
 // Pointer variable equality is determined based on the equality of the
 // referenced values (as opposed to the memory addresses). Function equality
 // cannot be determined and will always fail.
 func (a *Assertions) Equal(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return Equal(a.t, expected, actual, msgAndArgs...)
 }
 
@@ -83,9 +134,10 @@ func (a *Assertions) Equal(expected interface{}, actual interface{}, msgAndArgs
 //
 //   actualObj, err := SomeFunction()
 //   a.EqualError(err,  expectedErrorString)
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) EqualError(theError error, errString string, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return EqualError(a.t, theError, errString, msgAndArgs...)
 }
 
@@ -94,9 +146,10 @@ func (a *Assertions) EqualError(theError error, errString string, msgAndArgs ...
 //
 //   actualObj, err := SomeFunction()
 //   a.EqualErrorf(err,  expectedErrorString, "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) EqualErrorf(theError error, errString string, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return EqualErrorf(a.t, theError, errString, msg, args...)
 }
 
@@ -104,9 +157,10 @@ func (a *Assertions) EqualErrorf(theError error, errString string, msg string, a
 // and equal.
 //
 //    a.EqualValues(uint32(123), int32(123))
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) EqualValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return EqualValues(a.t, expected, actual, msgAndArgs...)
 }
 
@@ -114,9 +168,10 @@ func (a *Assertions) EqualValues(expected interface{}, actual interface{}, msgAn
 // and equal.
 //
 //    a.EqualValuesf(uint32(123, "error message %s", "formatted"), int32(123))
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) EqualValuesf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return EqualValuesf(a.t, expected, actual, msg, args...)
 }
 
@@ -124,12 +179,13 @@ func (a *Assertions) EqualValuesf(expected interface{}, actual interface{}, msg
 //
 //    a.Equalf(123, 123, "error message %s", "formatted")
 //
-// Returns whether the assertion was successful (true) or not (false).
-//
 // Pointer variable equality is determined based on the equality of the
 // referenced values (as opposed to the memory addresses). Function equality
 // cannot be determined and will always fail.
 func (a *Assertions) Equalf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return Equalf(a.t, expected, actual, msg, args...)
 }
 
@@ -139,9 +195,10 @@ func (a *Assertions) Equalf(expected interface{}, actual interface{}, msg string
 //   if a.Error(err) {
 // 	   assert.Equal(t, expectedError, err)
 //   }
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) Error(err error, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return Error(a.t, err, msgAndArgs...)
 }
 
@@ -151,106 +208,151 @@ func (a *Assertions) Error(err error, msgAndArgs ...interface{}) bool {
 //   if a.Errorf(err, "error message %s", "formatted") {
 // 	   assert.Equal(t, expectedErrorf, err)
 //   }
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) Errorf(err error, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return Errorf(a.t, err, msg, args...)
 }
 
-// Exactly asserts that two objects are equal is value and type.
+// Exactly asserts that two objects are equal in value and type.
 //
 //    a.Exactly(int32(123), int64(123))
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) Exactly(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return Exactly(a.t, expected, actual, msgAndArgs...)
 }
 
-// Exactlyf asserts that two objects are equal is value and type.
+// Exactlyf asserts that two objects are equal in value and type.
 //
 //    a.Exactlyf(int32(123, "error message %s", "formatted"), int64(123))
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) Exactlyf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return Exactlyf(a.t, expected, actual, msg, args...)
 }
 
 // Fail reports a failure through
 func (a *Assertions) Fail(failureMessage string, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return Fail(a.t, failureMessage, msgAndArgs...)
 }
 
 // FailNow fails test
 func (a *Assertions) FailNow(failureMessage string, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return FailNow(a.t, failureMessage, msgAndArgs...)
 }
 
 // FailNowf fails test
 func (a *Assertions) FailNowf(failureMessage string, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return FailNowf(a.t, failureMessage, msg, args...)
 }
 
 // Failf reports a failure through
 func (a *Assertions) Failf(failureMessage string, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return Failf(a.t, failureMessage, msg, args...)
 }
 
 // False asserts that the specified value is false.
 //
 //    a.False(myBool)
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) False(value bool, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return False(a.t, value, msgAndArgs...)
 }
 
 // Falsef asserts that the specified value is false.
 //
 //    a.Falsef(myBool, "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) Falsef(value bool, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return Falsef(a.t, value, msg, args...)
 }
 
+// FileExists checks whether a file exists in the given path. It also fails if the path points to a directory or there is an error when trying to check the file.
+func (a *Assertions) FileExists(path string, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	return FileExists(a.t, path, msgAndArgs...)
+}
+
+// FileExistsf checks whether a file exists in the given path. It also fails if the path points to a directory or there is an error when trying to check the file.
+func (a *Assertions) FileExistsf(path string, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	return FileExistsf(a.t, path, msg, args...)
+}
+
 // HTTPBodyContains asserts that a specified handler returns a
 // body that contains a string.
 //
-//  a.HTTPBodyContains(myHandler, "www.google.com", nil, "I'm Feeling Lucky")
+//  a.HTTPBodyContains(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky")
 //
 // Returns whether the assertion was successful (true) or not (false).
-func (a *Assertions) HTTPBodyContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}) bool {
-	return HTTPBodyContains(a.t, handler, method, url, values, str)
+func (a *Assertions) HTTPBodyContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	return HTTPBodyContains(a.t, handler, method, url, values, str, msgAndArgs...)
 }
 
 // HTTPBodyContainsf asserts that a specified handler returns a
 // body that contains a string.
 //
-//  a.HTTPBodyContainsf(myHandler, "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted")
+//  a.HTTPBodyContainsf(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted")
 //
 // Returns whether the assertion was successful (true) or not (false).
-func (a *Assertions) HTTPBodyContainsf(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}) bool {
-	return HTTPBodyContainsf(a.t, handler, method, url, values, str)
+func (a *Assertions) HTTPBodyContainsf(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	return HTTPBodyContainsf(a.t, handler, method, url, values, str, msg, args...)
 }
 
 // HTTPBodyNotContains asserts that a specified handler returns a
 // body that does not contain a string.
 //
-//  a.HTTPBodyNotContains(myHandler, "www.google.com", nil, "I'm Feeling Lucky")
+//  a.HTTPBodyNotContains(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky")
 //
 // Returns whether the assertion was successful (true) or not (false).
-func (a *Assertions) HTTPBodyNotContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}) bool {
-	return HTTPBodyNotContains(a.t, handler, method, url, values, str)
+func (a *Assertions) HTTPBodyNotContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	return HTTPBodyNotContains(a.t, handler, method, url, values, str, msgAndArgs...)
 }
 
 // HTTPBodyNotContainsf asserts that a specified handler returns a
 // body that does not contain a string.
 //
-//  a.HTTPBodyNotContainsf(myHandler, "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted")
+//  a.HTTPBodyNotContainsf(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted")
 //
 // Returns whether the assertion was successful (true) or not (false).
-func (a *Assertions) HTTPBodyNotContainsf(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}) bool {
-	return HTTPBodyNotContainsf(a.t, handler, method, url, values, str)
+func (a *Assertions) HTTPBodyNotContainsf(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	return HTTPBodyNotContainsf(a.t, handler, method, url, values, str, msg, args...)
 }
 
 // HTTPError asserts that a specified handler returns an error status code.
@@ -258,8 +360,11 @@ func (a *Assertions) HTTPBodyNotContainsf(handler http.HandlerFunc, method strin
 //  a.HTTPError(myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}}
 //
 // Returns whether the assertion was successful (true) or not (false).
-func (a *Assertions) HTTPError(handler http.HandlerFunc, method string, url string, values url.Values) bool {
-	return HTTPError(a.t, handler, method, url, values)
+func (a *Assertions) HTTPError(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	return HTTPError(a.t, handler, method, url, values, msgAndArgs...)
 }
 
 // HTTPErrorf asserts that a specified handler returns an error status code.
@@ -267,8 +372,11 @@ func (a *Assertions) HTTPError(handler http.HandlerFunc, method string, url stri
 //  a.HTTPErrorf(myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}}
 //
 // Returns whether the assertion was successful (true, "error message %s", "formatted") or not (false).
-func (a *Assertions) HTTPErrorf(handler http.HandlerFunc, method string, url string, values url.Values) bool {
-	return HTTPErrorf(a.t, handler, method, url, values)
+func (a *Assertions) HTTPErrorf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	return HTTPErrorf(a.t, handler, method, url, values, msg, args...)
 }
 
 // HTTPRedirect asserts that a specified handler returns a redirect status code.
@@ -276,8 +384,11 @@ func (a *Assertions) HTTPErrorf(handler http.HandlerFunc, method string, url str
 //  a.HTTPRedirect(myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}}
 //
 // Returns whether the assertion was successful (true) or not (false).
-func (a *Assertions) HTTPRedirect(handler http.HandlerFunc, method string, url string, values url.Values) bool {
-	return HTTPRedirect(a.t, handler, method, url, values)
+func (a *Assertions) HTTPRedirect(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	return HTTPRedirect(a.t, handler, method, url, values, msgAndArgs...)
 }
 
 // HTTPRedirectf asserts that a specified handler returns a redirect status code.
@@ -285,8 +396,11 @@ func (a *Assertions) HTTPRedirect(handler http.HandlerFunc, method string, url s
 //  a.HTTPRedirectf(myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}}
 //
 // Returns whether the assertion was successful (true, "error message %s", "formatted") or not (false).
-func (a *Assertions) HTTPRedirectf(handler http.HandlerFunc, method string, url string, values url.Values) bool {
-	return HTTPRedirectf(a.t, handler, method, url, values)
+func (a *Assertions) HTTPRedirectf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	return HTTPRedirectf(a.t, handler, method, url, values, msg, args...)
 }
 
 // HTTPSuccess asserts that a specified handler returns a success status code.
@@ -294,8 +408,11 @@ func (a *Assertions) HTTPRedirectf(handler http.HandlerFunc, method string, url
 //  a.HTTPSuccess(myHandler, "POST", "http://www.google.com", nil)
 //
 // Returns whether the assertion was successful (true) or not (false).
-func (a *Assertions) HTTPSuccess(handler http.HandlerFunc, method string, url string, values url.Values) bool {
-	return HTTPSuccess(a.t, handler, method, url, values)
+func (a *Assertions) HTTPSuccess(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	return HTTPSuccess(a.t, handler, method, url, values, msgAndArgs...)
 }
 
 // HTTPSuccessf asserts that a specified handler returns a success status code.
@@ -303,14 +420,20 @@ func (a *Assertions) HTTPSuccess(handler http.HandlerFunc, method string, url st
 //  a.HTTPSuccessf(myHandler, "POST", "http://www.google.com", nil, "error message %s", "formatted")
 //
 // Returns whether the assertion was successful (true) or not (false).
-func (a *Assertions) HTTPSuccessf(handler http.HandlerFunc, method string, url string, values url.Values) bool {
-	return HTTPSuccessf(a.t, handler, method, url, values)
+func (a *Assertions) HTTPSuccessf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	return HTTPSuccessf(a.t, handler, method, url, values, msg, args...)
 }
 
 // Implements asserts that an object is implemented by the specified interface.
 //
 //    a.Implements((*MyInterface)(nil), new(MyObject))
 func (a *Assertions) Implements(interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return Implements(a.t, interfaceObject, object, msgAndArgs...)
 }
 
@@ -318,86 +441,129 @@ func (a *Assertions) Implements(interfaceObject interface{}, object interface{},
 //
 //    a.Implementsf((*MyInterface, "error message %s", "formatted")(nil), new(MyObject))
 func (a *Assertions) Implementsf(interfaceObject interface{}, object interface{}, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return Implementsf(a.t, interfaceObject, object, msg, args...)
 }
 
 // InDelta asserts that the two numerals are within delta of each other.
 //
 // 	 a.InDelta(math.Pi, (22 / 7.0), 0.01)
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) InDelta(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return InDelta(a.t, expected, actual, delta, msgAndArgs...)
 }
 
+// InDeltaMapValues is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys.
+func (a *Assertions) InDeltaMapValues(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	return InDeltaMapValues(a.t, expected, actual, delta, msgAndArgs...)
+}
+
+// InDeltaMapValuesf is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys.
+func (a *Assertions) InDeltaMapValuesf(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	return InDeltaMapValuesf(a.t, expected, actual, delta, msg, args...)
+}
+
 // InDeltaSlice is the same as InDelta, except it compares two slices.
 func (a *Assertions) InDeltaSlice(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return InDeltaSlice(a.t, expected, actual, delta, msgAndArgs...)
 }
 
 // InDeltaSlicef is the same as InDelta, except it compares two slices.
 func (a *Assertions) InDeltaSlicef(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return InDeltaSlicef(a.t, expected, actual, delta, msg, args...)
 }
 
 // InDeltaf asserts that the two numerals are within delta of each other.
 //
 // 	 a.InDeltaf(math.Pi, (22 / 7.0, "error message %s", "formatted"), 0.01)
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) InDeltaf(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return InDeltaf(a.t, expected, actual, delta, msg, args...)
 }
 
 // InEpsilon asserts that expected and actual have a relative error less than epsilon
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) InEpsilon(expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return InEpsilon(a.t, expected, actual, epsilon, msgAndArgs...)
 }
 
 // InEpsilonSlice is the same as InEpsilon, except it compares each value from two slices.
 func (a *Assertions) InEpsilonSlice(expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return InEpsilonSlice(a.t, expected, actual, epsilon, msgAndArgs...)
 }
 
 // InEpsilonSlicef is the same as InEpsilon, except it compares each value from two slices.
 func (a *Assertions) InEpsilonSlicef(expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return InEpsilonSlicef(a.t, expected, actual, epsilon, msg, args...)
 }
 
 // InEpsilonf asserts that expected and actual have a relative error less than epsilon
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) InEpsilonf(expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return InEpsilonf(a.t, expected, actual, epsilon, msg, args...)
 }
 
 // IsType asserts that the specified objects are of the same type.
 func (a *Assertions) IsType(expectedType interface{}, object interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return IsType(a.t, expectedType, object, msgAndArgs...)
 }
 
 // IsTypef asserts that the specified objects are of the same type.
 func (a *Assertions) IsTypef(expectedType interface{}, object interface{}, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return IsTypef(a.t, expectedType, object, msg, args...)
 }
 
 // JSONEq asserts that two JSON strings are equivalent.
 //
 //  a.JSONEq(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`)
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) JSONEq(expected string, actual string, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return JSONEq(a.t, expected, actual, msgAndArgs...)
 }
 
 // JSONEqf asserts that two JSON strings are equivalent.
 //
 //  a.JSONEqf(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`, "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) JSONEqf(expected string, actual string, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return JSONEqf(a.t, expected, actual, msg, args...)
 }
 
@@ -405,9 +571,10 @@ func (a *Assertions) JSONEqf(expected string, actual string, msg string, args ..
 // Len also fails if the object has a type that len() not accept.
 //
 //    a.Len(mySlice, 3)
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) Len(object interface{}, length int, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return Len(a.t, object, length, msgAndArgs...)
 }
 
@@ -415,27 +582,30 @@ func (a *Assertions) Len(object interface{}, length int, msgAndArgs ...interface
 // Lenf also fails if the object has a type that len() not accept.
 //
 //    a.Lenf(mySlice, 3, "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) Lenf(object interface{}, length int, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return Lenf(a.t, object, length, msg, args...)
 }
 
 // Nil asserts that the specified object is nil.
 //
 //    a.Nil(err)
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) Nil(object interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return Nil(a.t, object, msgAndArgs...)
 }
 
 // Nilf asserts that the specified object is nil.
 //
 //    a.Nilf(err, "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) Nilf(object interface{}, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return Nilf(a.t, object, msg, args...)
 }
 
@@ -445,9 +615,10 @@ func (a *Assertions) Nilf(object interface{}, msg string, args ...interface{}) b
 //   if a.NoError(err) {
 // 	   assert.Equal(t, expectedObj, actualObj)
 //   }
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) NoError(err error, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return NoError(a.t, err, msgAndArgs...)
 }
 
@@ -457,9 +628,10 @@ func (a *Assertions) NoError(err error, msgAndArgs ...interface{}) bool {
 //   if a.NoErrorf(err, "error message %s", "formatted") {
 // 	   assert.Equal(t, expectedObj, actualObj)
 //   }
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) NoErrorf(err error, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return NoErrorf(a.t, err, msg, args...)
 }
 
@@ -469,9 +641,10 @@ func (a *Assertions) NoErrorf(err error, msg string, args ...interface{}) bool {
 //    a.NotContains("Hello World", "Earth")
 //    a.NotContains(["Hello", "World"], "Earth")
 //    a.NotContains({"Hello": "World"}, "Earth")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) NotContains(s interface{}, contains interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return NotContains(a.t, s, contains, msgAndArgs...)
 }
 
@@ -481,9 +654,10 @@ func (a *Assertions) NotContains(s interface{}, contains interface{}, msgAndArgs
 //    a.NotContainsf("Hello World", "Earth", "error message %s", "formatted")
 //    a.NotContainsf(["Hello", "World"], "Earth", "error message %s", "formatted")
 //    a.NotContainsf({"Hello": "World"}, "Earth", "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) NotContainsf(s interface{}, contains interface{}, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return NotContainsf(a.t, s, contains, msg, args...)
 }
 
@@ -493,9 +667,10 @@ func (a *Assertions) NotContainsf(s interface{}, contains interface{}, msg strin
 //  if a.NotEmpty(obj) {
 //    assert.Equal(t, "two", obj[1])
 //  }
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) NotEmpty(object interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return NotEmpty(a.t, object, msgAndArgs...)
 }
 
@@ -505,9 +680,10 @@ func (a *Assertions) NotEmpty(object interface{}, msgAndArgs ...interface{}) boo
 //  if a.NotEmptyf(obj, "error message %s", "formatted") {
 //    assert.Equal(t, "two", obj[1])
 //  }
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) NotEmptyf(object interface{}, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return NotEmptyf(a.t, object, msg, args...)
 }
 
@@ -515,11 +691,12 @@ func (a *Assertions) NotEmptyf(object interface{}, msg string, args ...interface
 //
 //    a.NotEqual(obj1, obj2)
 //
-// Returns whether the assertion was successful (true) or not (false).
-//
 // Pointer variable equality is determined based on the equality of the
 // referenced values (as opposed to the memory addresses).
 func (a *Assertions) NotEqual(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return NotEqual(a.t, expected, actual, msgAndArgs...)
 }
 
@@ -527,47 +704,52 @@ func (a *Assertions) NotEqual(expected interface{}, actual interface{}, msgAndAr
 //
 //    a.NotEqualf(obj1, obj2, "error message %s", "formatted")
 //
-// Returns whether the assertion was successful (true) or not (false).
-//
 // Pointer variable equality is determined based on the equality of the
 // referenced values (as opposed to the memory addresses).
 func (a *Assertions) NotEqualf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return NotEqualf(a.t, expected, actual, msg, args...)
 }
 
 // NotNil asserts that the specified object is not nil.
 //
 //    a.NotNil(err)
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) NotNil(object interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return NotNil(a.t, object, msgAndArgs...)
 }
 
 // NotNilf asserts that the specified object is not nil.
 //
 //    a.NotNilf(err, "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) NotNilf(object interface{}, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return NotNilf(a.t, object, msg, args...)
 }
 
 // NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic.
 //
 //   a.NotPanics(func(){ RemainCalm() })
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) NotPanics(f PanicTestFunc, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return NotPanics(a.t, f, msgAndArgs...)
 }
 
 // NotPanicsf asserts that the code inside the specified PanicTestFunc does NOT panic.
 //
 //   a.NotPanicsf(func(){ RemainCalm() }, "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) NotPanicsf(f PanicTestFunc, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return NotPanicsf(a.t, f, msg, args...)
 }
 
@@ -575,9 +757,10 @@ func (a *Assertions) NotPanicsf(f PanicTestFunc, msg string, args ...interface{}
 //
 //  a.NotRegexp(regexp.MustCompile("starts"), "it's starting")
 //  a.NotRegexp("^start", "it's not starting")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) NotRegexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return NotRegexp(a.t, rx, str, msgAndArgs...)
 }
 
@@ -585,9 +768,10 @@ func (a *Assertions) NotRegexp(rx interface{}, str interface{}, msgAndArgs ...in
 //
 //  a.NotRegexpf(regexp.MustCompile("starts", "error message %s", "formatted"), "it's starting")
 //  a.NotRegexpf("^start", "it's not starting", "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) NotRegexpf(rx interface{}, str interface{}, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return NotRegexpf(a.t, rx, str, msg, args...)
 }
 
@@ -595,9 +779,10 @@ func (a *Assertions) NotRegexpf(rx interface{}, str interface{}, msg string, arg
 // elements given in the specified subset(array, slice...).
 //
 //    a.NotSubset([1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) NotSubset(list interface{}, subset interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return NotSubset(a.t, list, subset, msgAndArgs...)
 }
 
@@ -605,28 +790,36 @@ func (a *Assertions) NotSubset(list interface{}, subset interface{}, msgAndArgs
 // elements given in the specified subset(array, slice...).
 //
 //    a.NotSubsetf([1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]", "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) NotSubsetf(list interface{}, subset interface{}, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return NotSubsetf(a.t, list, subset, msg, args...)
 }
 
-// NotZero asserts that i is not the zero value for its type and returns the truth.
+// NotZero asserts that i is not the zero value for its type.
 func (a *Assertions) NotZero(i interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return NotZero(a.t, i, msgAndArgs...)
 }
 
-// NotZerof asserts that i is not the zero value for its type and returns the truth.
+// NotZerof asserts that i is not the zero value for its type.
 func (a *Assertions) NotZerof(i interface{}, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return NotZerof(a.t, i, msg, args...)
 }
 
 // Panics asserts that the code inside the specified PanicTestFunc panics.
 //
 //   a.Panics(func(){ GoCrazy() })
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) Panics(f PanicTestFunc, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return Panics(a.t, f, msgAndArgs...)
 }
 
@@ -634,9 +827,10 @@ func (a *Assertions) Panics(f PanicTestFunc, msgAndArgs ...interface{}) bool {
 // the recovered panic value equals the expected panic value.
 //
 //   a.PanicsWithValue("crazy error", func(){ GoCrazy() })
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) PanicsWithValue(expected interface{}, f PanicTestFunc, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return PanicsWithValue(a.t, expected, f, msgAndArgs...)
 }
 
@@ -644,18 +838,20 @@ func (a *Assertions) PanicsWithValue(expected interface{}, f PanicTestFunc, msgA
 // the recovered panic value equals the expected panic value.
 //
 //   a.PanicsWithValuef("crazy error", func(){ GoCrazy() }, "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) PanicsWithValuef(expected interface{}, f PanicTestFunc, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return PanicsWithValuef(a.t, expected, f, msg, args...)
 }
 
 // Panicsf asserts that the code inside the specified PanicTestFunc panics.
 //
 //   a.Panicsf(func(){ GoCrazy() }, "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) Panicsf(f PanicTestFunc, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return Panicsf(a.t, f, msg, args...)
 }
 
@@ -663,9 +859,10 @@ func (a *Assertions) Panicsf(f PanicTestFunc, msg string, args ...interface{}) b
 //
 //  a.Regexp(regexp.MustCompile("start"), "it's starting")
 //  a.Regexp("start...$", "it's not starting")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) Regexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return Regexp(a.t, rx, str, msgAndArgs...)
 }
 
@@ -673,9 +870,10 @@ func (a *Assertions) Regexp(rx interface{}, str interface{}, msgAndArgs ...inter
 //
 //  a.Regexpf(regexp.MustCompile("start", "error message %s", "formatted"), "it's starting")
 //  a.Regexpf("start...$", "it's not starting", "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) Regexpf(rx interface{}, str interface{}, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return Regexpf(a.t, rx, str, msg, args...)
 }
 
@@ -683,9 +881,10 @@ func (a *Assertions) Regexpf(rx interface{}, str interface{}, msg string, args .
 // elements given in the specified subset(array, slice...).
 //
 //    a.Subset([1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) Subset(list interface{}, subset interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return Subset(a.t, list, subset, msgAndArgs...)
 }
 
@@ -693,54 +892,65 @@ func (a *Assertions) Subset(list interface{}, subset interface{}, msgAndArgs ...
 // elements given in the specified subset(array, slice...).
 //
 //    a.Subsetf([1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]", "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) Subsetf(list interface{}, subset interface{}, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return Subsetf(a.t, list, subset, msg, args...)
 }
 
 // True asserts that the specified value is true.
 //
 //    a.True(myBool)
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) True(value bool, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return True(a.t, value, msgAndArgs...)
 }
 
 // Truef asserts that the specified value is true.
 //
 //    a.Truef(myBool, "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) Truef(value bool, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return Truef(a.t, value, msg, args...)
 }
 
 // WithinDuration asserts that the two times are within duration delta of each other.
 //
 //   a.WithinDuration(time.Now(), time.Now(), 10*time.Second)
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) WithinDuration(expected time.Time, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return WithinDuration(a.t, expected, actual, delta, msgAndArgs...)
 }
 
 // WithinDurationf asserts that the two times are within duration delta of each other.
 //
 //   a.WithinDurationf(time.Now(), time.Now(), 10*time.Second, "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) WithinDurationf(expected time.Time, actual time.Time, delta time.Duration, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return WithinDurationf(a.t, expected, actual, delta, msg, args...)
 }
 
-// Zero asserts that i is the zero value for its type and returns the truth.
+// Zero asserts that i is the zero value for its type.
 func (a *Assertions) Zero(i interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return Zero(a.t, i, msgAndArgs...)
 }
 
-// Zerof asserts that i is the zero value for its type and returns the truth.
+// Zerof asserts that i is the zero value for its type.
 func (a *Assertions) Zerof(i interface{}, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return Zerof(a.t, i, msg, args...)
 }
diff --git a/vendor/github.com/stretchr/testify/assert/assertions.go b/vendor/github.com/stretchr/testify/assert/assertions.go
index 4c0383477d787d4fde7fad0e223eebbbf2ed066f..9bd4a80e4847c014478d6e36e15c3c9bdf93a194 100644
--- a/vendor/github.com/stretchr/testify/assert/assertions.go
+++ b/vendor/github.com/stretchr/testify/assert/assertions.go
@@ -7,6 +7,7 @@ import (
 	"errors"
 	"fmt"
 	"math"
+	"os"
 	"reflect"
 	"regexp"
 	"runtime"
@@ -26,6 +27,22 @@ type TestingT interface {
 	Errorf(format string, args ...interface{})
 }
 
+// ComparisonAssertionFunc is a common function prototype when comparing two values.  Can be useful
+// for table driven tests.
+type ComparisonAssertionFunc func(TestingT, interface{}, interface{}, ...interface{}) bool
+
+// ValueAssertionFunc is a common function prototype when validating a single value.  Can be useful
+// for table driven tests.
+type ValueAssertionFunc func(TestingT, interface{}, ...interface{}) bool
+
+// BoolAssertionFunc is a common function prototype when validating a bool value.  Can be useful
+// for table driven tests.
+type BoolAssertionFunc func(TestingT, bool, ...interface{}) bool
+
+// ErrorAssertionFunc is a common function prototype when validating an error value.  Can be useful
+// for table driven tests.
+type ErrorAssertionFunc func(TestingT, error, ...interface{}) bool
+
 // Comparison a custom function that returns true on success and false on failure
 type Comparison func() (success bool)
 
@@ -37,21 +54,23 @@ type Comparison func() (success bool)
 //
 // This function does no assertion of any kind.
 func ObjectsAreEqual(expected, actual interface{}) bool {
-
 	if expected == nil || actual == nil {
 		return expected == actual
 	}
-	if exp, ok := expected.([]byte); ok {
-		act, ok := actual.([]byte)
-		if !ok {
-			return false
-		} else if exp == nil || act == nil {
-			return exp == nil && act == nil
-		}
-		return bytes.Equal(exp, act)
+
+	exp, ok := expected.([]byte)
+	if !ok {
+		return reflect.DeepEqual(expected, actual)
 	}
-	return reflect.DeepEqual(expected, actual)
 
+	act, ok := actual.([]byte)
+	if !ok {
+		return false
+	}
+	if exp == nil || act == nil {
+		return exp == nil && act == nil
+	}
+	return bytes.Equal(exp, act)
 }
 
 // ObjectsAreEqualValues gets whether two objects are equal, or if their
@@ -155,27 +174,16 @@ func isTest(name, prefix string) bool {
 	return !unicode.IsLower(rune)
 }
 
-// getWhitespaceString returns a string that is long enough to overwrite the default
-// output from the go testing framework.
-func getWhitespaceString() string {
-
-	_, file, line, ok := runtime.Caller(1)
-	if !ok {
-		return ""
-	}
-	parts := strings.Split(file, "/")
-	file = parts[len(parts)-1]
-
-	return strings.Repeat(" ", len(fmt.Sprintf("%s:%d:        ", file, line)))
-
-}
-
 func messageFromMsgAndArgs(msgAndArgs ...interface{}) string {
 	if len(msgAndArgs) == 0 || msgAndArgs == nil {
 		return ""
 	}
 	if len(msgAndArgs) == 1 {
-		return msgAndArgs[0].(string)
+		msg := msgAndArgs[0]
+		if msgAsStr, ok := msg.(string); ok {
+			return msgAsStr
+		}
+		return fmt.Sprintf("%+v", msg)
 	}
 	if len(msgAndArgs) > 1 {
 		return fmt.Sprintf(msgAndArgs[0].(string), msgAndArgs[1:]...)
@@ -194,7 +202,7 @@ func indentMessageLines(message string, longestLabelLen int) string {
 		// no need to align first line because it starts at the correct location (after the label)
 		if i != 0 {
 			// append alignLen+1 spaces to align with "{{longestLabel}}:" before adding tab
-			outBuf.WriteString("\n\r\t" + strings.Repeat(" ", longestLabelLen+1) + "\t")
+			outBuf.WriteString("\n\t" + strings.Repeat(" ", longestLabelLen+1) + "\t")
 		}
 		outBuf.WriteString(scanner.Text())
 	}
@@ -208,6 +216,9 @@ type failNower interface {
 
 // FailNow fails test
 func FailNow(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	Fail(t, failureMessage, msgAndArgs...)
 
 	// We cannot extend TestingT with FailNow() and
@@ -226,17 +237,27 @@ func FailNow(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool
 
 // Fail reports a failure through
 func Fail(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	content := []labeledContent{
-		{"Error Trace", strings.Join(CallerInfo(), "\n\r\t\t\t")},
+		{"Error Trace", strings.Join(CallerInfo(), "\n\t\t\t")},
 		{"Error", failureMessage},
 	}
 
+	// Add test name if the Go version supports it
+	if n, ok := t.(interface {
+		Name() string
+	}); ok {
+		content = append(content, labeledContent{"Test", n.Name()})
+	}
+
 	message := messageFromMsgAndArgs(msgAndArgs...)
 	if len(message) > 0 {
 		content = append(content, labeledContent{"Messages", message})
 	}
 
-	t.Errorf("%s", "\r"+getWhitespaceString()+labeledOutput(content...))
+	t.Errorf("\n%s", ""+labeledOutput(content...))
 
 	return false
 }
@@ -248,7 +269,7 @@ type labeledContent struct {
 
 // labeledOutput returns a string consisting of the provided labeledContent. Each labeled output is appended in the following manner:
 //
-//   \r\t{{label}}:{{align_spaces}}\t{{content}}\n
+//   \t{{label}}:{{align_spaces}}\t{{content}}\n
 //
 // The initial carriage return is required to undo/erase any padding added by testing.T.Errorf. The "\t{{label}}:" is for the label.
 // If a label is shorter than the longest label provided, padding spaces are added to make all the labels match in length. Once this
@@ -264,7 +285,7 @@ func labeledOutput(content ...labeledContent) string {
 	}
 	var output string
 	for _, v := range content {
-		output += "\r\t" + v.label + ":" + strings.Repeat(" ", longestLabel-len(v.label)) + "\t" + indentMessageLines(v.content, longestLabel) + "\n"
+		output += "\t" + v.label + ":" + strings.Repeat(" ", longestLabel-len(v.label)) + "\t" + indentMessageLines(v.content, longestLabel) + "\n"
 	}
 	return output
 }
@@ -273,19 +294,26 @@ func labeledOutput(content ...labeledContent) string {
 //
 //    assert.Implements(t, (*MyInterface)(nil), new(MyObject))
 func Implements(t TestingT, interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool {
-
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	interfaceType := reflect.TypeOf(interfaceObject).Elem()
 
+	if object == nil {
+		return Fail(t, fmt.Sprintf("Cannot check if nil implements %v", interfaceType), msgAndArgs...)
+	}
 	if !reflect.TypeOf(object).Implements(interfaceType) {
 		return Fail(t, fmt.Sprintf("%T must implement %v", object, interfaceType), msgAndArgs...)
 	}
 
 	return true
-
 }
 
 // IsType asserts that the specified objects are of the same type.
 func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 
 	if !ObjectsAreEqual(reflect.TypeOf(object), reflect.TypeOf(expectedType)) {
 		return Fail(t, fmt.Sprintf("Object expected to be of type %v, but was %v", reflect.TypeOf(expectedType), reflect.TypeOf(object)), msgAndArgs...)
@@ -298,12 +326,13 @@ func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs
 //
 //    assert.Equal(t, 123, 123)
 //
-// Returns whether the assertion was successful (true) or not (false).
-//
 // Pointer variable equality is determined based on the equality of the
 // referenced values (as opposed to the memory addresses). Function equality
 // cannot be determined and will always fail.
 func Equal(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	if err := validateEqualArgs(expected, actual); err != nil {
 		return Fail(t, fmt.Sprintf("Invalid operation: %#v == %#v (%s)",
 			expected, actual, err), msgAndArgs...)
@@ -314,7 +343,7 @@ func Equal(t TestingT, expected, actual interface{}, msgAndArgs ...interface{})
 		expected, actual = formatUnequalValues(expected, actual)
 		return Fail(t, fmt.Sprintf("Not equal: \n"+
 			"expected: %s\n"+
-			"actual: %s%s", expected, actual, diff), msgAndArgs...)
+			"actual  : %s%s", expected, actual, diff), msgAndArgs...)
 	}
 
 	return true
@@ -341,34 +370,36 @@ func formatUnequalValues(expected, actual interface{}) (e string, a string) {
 // and equal.
 //
 //    assert.EqualValues(t, uint32(123), int32(123))
-//
-// Returns whether the assertion was successful (true) or not (false).
 func EqualValues(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 
 	if !ObjectsAreEqualValues(expected, actual) {
 		diff := diff(expected, actual)
 		expected, actual = formatUnequalValues(expected, actual)
 		return Fail(t, fmt.Sprintf("Not equal: \n"+
 			"expected: %s\n"+
-			"actual: %s%s", expected, actual, diff), msgAndArgs...)
+			"actual  : %s%s", expected, actual, diff), msgAndArgs...)
 	}
 
 	return true
 
 }
 
-// Exactly asserts that two objects are equal is value and type.
+// Exactly asserts that two objects are equal in value and type.
 //
 //    assert.Exactly(t, int32(123), int64(123))
-//
-// Returns whether the assertion was successful (true) or not (false).
 func Exactly(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 
 	aType := reflect.TypeOf(expected)
 	bType := reflect.TypeOf(actual)
 
 	if aType != bType {
-		return Fail(t, fmt.Sprintf("Types expected to match exactly\n\r\t%v != %v", aType, bType), msgAndArgs...)
+		return Fail(t, fmt.Sprintf("Types expected to match exactly\n\t%v != %v", aType, bType), msgAndArgs...)
 	}
 
 	return Equal(t, expected, actual, msgAndArgs...)
@@ -378,15 +409,27 @@ func Exactly(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}
 // NotNil asserts that the specified object is not nil.
 //
 //    assert.NotNil(t, err)
-//
-// Returns whether the assertion was successful (true) or not (false).
 func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	if !isNil(object) {
 		return true
 	}
 	return Fail(t, "Expected value not to be nil.", msgAndArgs...)
 }
 
+// containsKind checks if a specified kind in the slice of kinds.
+func containsKind(kinds []reflect.Kind, kind reflect.Kind) bool {
+	for i := 0; i < len(kinds); i++ {
+		if kind == kinds[i] {
+			return true
+		}
+	}
+
+	return false
+}
+
 // isNil checks if a specified object is nil or not, without Failing.
 func isNil(object interface{}) bool {
 	if object == nil {
@@ -395,7 +438,14 @@ func isNil(object interface{}) bool {
 
 	value := reflect.ValueOf(object)
 	kind := value.Kind()
-	if kind >= reflect.Chan && kind <= reflect.Slice && value.IsNil() {
+	isNilableKind := containsKind(
+		[]reflect.Kind{
+			reflect.Chan, reflect.Func,
+			reflect.Interface, reflect.Map,
+			reflect.Ptr, reflect.Slice},
+		kind)
+
+	if isNilableKind && value.IsNil() {
 		return true
 	}
 
@@ -405,84 +455,52 @@ func isNil(object interface{}) bool {
 // Nil asserts that the specified object is nil.
 //
 //    assert.Nil(t, err)
-//
-// Returns whether the assertion was successful (true) or not (false).
 func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	if isNil(object) {
 		return true
 	}
 	return Fail(t, fmt.Sprintf("Expected nil, but got: %#v", object), msgAndArgs...)
 }
 
-var numericZeros = []interface{}{
-	int(0),
-	int8(0),
-	int16(0),
-	int32(0),
-	int64(0),
-	uint(0),
-	uint8(0),
-	uint16(0),
-	uint32(0),
-	uint64(0),
-	float32(0),
-	float64(0),
-}
-
 // isEmpty gets whether the specified object is considered empty or not.
 func isEmpty(object interface{}) bool {
 
+	// get nil case out of the way
 	if object == nil {
 		return true
-	} else if object == "" {
-		return true
-	} else if object == false {
-		return true
-	}
-
-	for _, v := range numericZeros {
-		if object == v {
-			return true
-		}
 	}
 
 	objValue := reflect.ValueOf(object)
 
 	switch objValue.Kind() {
-	case reflect.Map:
-		fallthrough
-	case reflect.Slice, reflect.Chan:
-		{
-			return (objValue.Len() == 0)
-		}
-	case reflect.Struct:
-		switch object.(type) {
-		case time.Time:
-			return object.(time.Time).IsZero()
-		}
+	// collection types are empty when they have no element
+	case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice:
+		return objValue.Len() == 0
+	// pointers are empty if nil or if the value they point to is empty
 	case reflect.Ptr:
-		{
-			if objValue.IsNil() {
-				return true
-			}
-			switch object.(type) {
-			case *time.Time:
-				return object.(*time.Time).IsZero()
-			default:
-				return false
-			}
+		if objValue.IsNil() {
+			return true
 		}
+		deref := objValue.Elem().Interface()
+		return isEmpty(deref)
+	// for all other types, compare against the zero value
+	default:
+		zero := reflect.Zero(objValue.Type())
+		return reflect.DeepEqual(object, zero.Interface())
 	}
-	return false
 }
 
 // Empty asserts that the specified object is empty.  I.e. nil, "", false, 0 or either
 // a slice or a channel with len == 0.
 //
 //  assert.Empty(t, obj)
-//
-// Returns whether the assertion was successful (true) or not (false).
 func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 
 	pass := isEmpty(object)
 	if !pass {
@@ -499,9 +517,10 @@ func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
 //  if assert.NotEmpty(t, obj) {
 //    assert.Equal(t, "two", obj[1])
 //  }
-//
-// Returns whether the assertion was successful (true) or not (false).
 func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 
 	pass := !isEmpty(object)
 	if !pass {
@@ -528,9 +547,10 @@ func getLen(x interface{}) (ok bool, length int) {
 // Len also fails if the object has a type that len() not accept.
 //
 //    assert.Len(t, mySlice, 3)
-//
-// Returns whether the assertion was successful (true) or not (false).
 func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	ok, l := getLen(object)
 	if !ok {
 		return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", object), msgAndArgs...)
@@ -545,9 +565,15 @@ func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{})
 // True asserts that the specified value is true.
 //
 //    assert.True(t, myBool)
-//
-// Returns whether the assertion was successful (true) or not (false).
 func True(t TestingT, value bool, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	if h, ok := t.(interface {
+		Helper()
+	}); ok {
+		h.Helper()
+	}
 
 	if value != true {
 		return Fail(t, "Should be true", msgAndArgs...)
@@ -560,9 +586,10 @@ func True(t TestingT, value bool, msgAndArgs ...interface{}) bool {
 // False asserts that the specified value is false.
 //
 //    assert.False(t, myBool)
-//
-// Returns whether the assertion was successful (true) or not (false).
 func False(t TestingT, value bool, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 
 	if value != false {
 		return Fail(t, "Should be false", msgAndArgs...)
@@ -576,11 +603,12 @@ func False(t TestingT, value bool, msgAndArgs ...interface{}) bool {
 //
 //    assert.NotEqual(t, obj1, obj2)
 //
-// Returns whether the assertion was successful (true) or not (false).
-//
 // Pointer variable equality is determined based on the equality of the
 // referenced values (as opposed to the memory addresses).
 func NotEqual(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	if err := validateEqualArgs(expected, actual); err != nil {
 		return Fail(t, fmt.Sprintf("Invalid operation: %#v != %#v (%s)",
 			expected, actual, err), msgAndArgs...)
@@ -638,9 +666,10 @@ func includeElement(list interface{}, element interface{}) (ok, found bool) {
 //    assert.Contains(t, "Hello World", "World")
 //    assert.Contains(t, ["Hello", "World"], "World")
 //    assert.Contains(t, {"Hello": "World"}, "Hello")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func Contains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 
 	ok, found := includeElement(s, contains)
 	if !ok {
@@ -660,9 +689,10 @@ func Contains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bo
 //    assert.NotContains(t, "Hello World", "Earth")
 //    assert.NotContains(t, ["Hello", "World"], "Earth")
 //    assert.NotContains(t, {"Hello": "World"}, "Earth")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func NotContains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 
 	ok, found := includeElement(s, contains)
 	if !ok {
@@ -680,9 +710,10 @@ func NotContains(t TestingT, s, contains interface{}, msgAndArgs ...interface{})
 // elements given in the specified subset(array, slice...).
 //
 //    assert.Subset(t, [1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok bool) {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	if subset == nil {
 		return true // we consider nil to be equal to the nil set
 	}
@@ -723,11 +754,12 @@ func Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok
 // elements given in the specified subset(array, slice...).
 //
 //    assert.NotSubset(t, [1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok bool) {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	if subset == nil {
-		return false // we consider nil to be equal to the nil set
+		return Fail(t, fmt.Sprintf("nil is the empty set which is a subset of every set"), msgAndArgs...)
 	}
 
 	subsetValue := reflect.ValueOf(subset)
@@ -762,8 +794,68 @@ func NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{})
 	return Fail(t, fmt.Sprintf("%q is a subset of %q", subset, list), msgAndArgs...)
 }
 
+// ElementsMatch asserts that the specified listA(array, slice...) is equal to specified
+// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements,
+// the number of appearances of each of them in both lists should match.
+//
+// assert.ElementsMatch(t, [1, 3, 2, 3], [1, 3, 3, 2])
+func ElementsMatch(t TestingT, listA, listB interface{}, msgAndArgs ...interface{}) (ok bool) {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	if isEmpty(listA) && isEmpty(listB) {
+		return true
+	}
+
+	aKind := reflect.TypeOf(listA).Kind()
+	bKind := reflect.TypeOf(listB).Kind()
+
+	if aKind != reflect.Array && aKind != reflect.Slice {
+		return Fail(t, fmt.Sprintf("%q has an unsupported type %s", listA, aKind), msgAndArgs...)
+	}
+
+	if bKind != reflect.Array && bKind != reflect.Slice {
+		return Fail(t, fmt.Sprintf("%q has an unsupported type %s", listB, bKind), msgAndArgs...)
+	}
+
+	aValue := reflect.ValueOf(listA)
+	bValue := reflect.ValueOf(listB)
+
+	aLen := aValue.Len()
+	bLen := bValue.Len()
+
+	if aLen != bLen {
+		return Fail(t, fmt.Sprintf("lengths don't match: %d != %d", aLen, bLen), msgAndArgs...)
+	}
+
+	// Mark indexes in bValue that we already used
+	visited := make([]bool, bLen)
+	for i := 0; i < aLen; i++ {
+		element := aValue.Index(i).Interface()
+		found := false
+		for j := 0; j < bLen; j++ {
+			if visited[j] {
+				continue
+			}
+			if ObjectsAreEqual(bValue.Index(j).Interface(), element) {
+				visited[j] = true
+				found = true
+				break
+			}
+		}
+		if !found {
+			return Fail(t, fmt.Sprintf("element %s appears more times in %s than in %s", element, aValue, bValue), msgAndArgs...)
+		}
+	}
+
+	return true
+}
+
 // Condition uses a Comparison to assert a complex condition.
 func Condition(t TestingT, comp Comparison, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	result := comp()
 	if !result {
 		Fail(t, "Condition failed!", msgAndArgs...)
@@ -800,12 +892,13 @@ func didPanic(f PanicTestFunc) (bool, interface{}) {
 // Panics asserts that the code inside the specified PanicTestFunc panics.
 //
 //   assert.Panics(t, func(){ GoCrazy() })
-//
-// Returns whether the assertion was successful (true) or not (false).
 func Panics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 
 	if funcDidPanic, panicValue := didPanic(f); !funcDidPanic {
-		return Fail(t, fmt.Sprintf("func %#v should panic\n\r\tPanic value:\t%v", f, panicValue), msgAndArgs...)
+		return Fail(t, fmt.Sprintf("func %#v should panic\n\tPanic value:\t%#v", f, panicValue), msgAndArgs...)
 	}
 
 	return true
@@ -815,16 +908,17 @@ func Panics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool {
 // the recovered panic value equals the expected panic value.
 //
 //   assert.PanicsWithValue(t, "crazy error", func(){ GoCrazy() })
-//
-// Returns whether the assertion was successful (true) or not (false).
 func PanicsWithValue(t TestingT, expected interface{}, f PanicTestFunc, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 
 	funcDidPanic, panicValue := didPanic(f)
 	if !funcDidPanic {
-		return Fail(t, fmt.Sprintf("func %#v should panic\n\r\tPanic value:\t%v", f, panicValue), msgAndArgs...)
+		return Fail(t, fmt.Sprintf("func %#v should panic\n\tPanic value:\t%#v", f, panicValue), msgAndArgs...)
 	}
 	if panicValue != expected {
-		return Fail(t, fmt.Sprintf("func %#v should panic with value:\t%v\n\r\tPanic value:\t%v", f, expected, panicValue), msgAndArgs...)
+		return Fail(t, fmt.Sprintf("func %#v should panic with value:\t%#v\n\tPanic value:\t%#v", f, expected, panicValue), msgAndArgs...)
 	}
 
 	return true
@@ -833,12 +927,13 @@ func PanicsWithValue(t TestingT, expected interface{}, f PanicTestFunc, msgAndAr
 // NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic.
 //
 //   assert.NotPanics(t, func(){ RemainCalm() })
-//
-// Returns whether the assertion was successful (true) or not (false).
 func NotPanics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 
 	if funcDidPanic, panicValue := didPanic(f); funcDidPanic {
-		return Fail(t, fmt.Sprintf("func %#v should not panic\n\r\tPanic value:\t%v", f, panicValue), msgAndArgs...)
+		return Fail(t, fmt.Sprintf("func %#v should not panic\n\tPanic value:\t%v", f, panicValue), msgAndArgs...)
 	}
 
 	return true
@@ -847,9 +942,10 @@ func NotPanics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool {
 // WithinDuration asserts that the two times are within duration delta of each other.
 //
 //   assert.WithinDuration(t, time.Now(), time.Now(), 10*time.Second)
-//
-// Returns whether the assertion was successful (true) or not (false).
 func WithinDuration(t TestingT, expected, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 
 	dt := expected.Sub(actual)
 	if dt < -delta || dt > delta {
@@ -886,6 +982,8 @@ func toFloat(x interface{}) (float64, bool) {
 		xf = float64(xn)
 	case float64:
 		xf = float64(xn)
+	case time.Duration:
+		xf = float64(xn)
 	default:
 		xok = false
 	}
@@ -896,9 +994,10 @@ func toFloat(x interface{}) (float64, bool) {
 // InDelta asserts that the two numerals are within delta of each other.
 //
 // 	 assert.InDelta(t, math.Pi, (22 / 7.0), 0.01)
-//
-// Returns whether the assertion was successful (true) or not (false).
 func InDelta(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 
 	af, aok := toFloat(expected)
 	bf, bok := toFloat(actual)
@@ -925,6 +1024,9 @@ func InDelta(t TestingT, expected, actual interface{}, delta float64, msgAndArgs
 
 // InDeltaSlice is the same as InDelta, except it compares two slices.
 func InDeltaSlice(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	if expected == nil || actual == nil ||
 		reflect.TypeOf(actual).Kind() != reflect.Slice ||
 		reflect.TypeOf(expected).Kind() != reflect.Slice {
@@ -944,6 +1046,50 @@ func InDeltaSlice(t TestingT, expected, actual interface{}, delta float64, msgAn
 	return true
 }
 
+// InDeltaMapValues is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys.
+func InDeltaMapValues(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	if expected == nil || actual == nil ||
+		reflect.TypeOf(actual).Kind() != reflect.Map ||
+		reflect.TypeOf(expected).Kind() != reflect.Map {
+		return Fail(t, "Arguments must be maps", msgAndArgs...)
+	}
+
+	expectedMap := reflect.ValueOf(expected)
+	actualMap := reflect.ValueOf(actual)
+
+	if expectedMap.Len() != actualMap.Len() {
+		return Fail(t, "Arguments must have the same number of keys", msgAndArgs...)
+	}
+
+	for _, k := range expectedMap.MapKeys() {
+		ev := expectedMap.MapIndex(k)
+		av := actualMap.MapIndex(k)
+
+		if !ev.IsValid() {
+			return Fail(t, fmt.Sprintf("missing key %q in expected map", k), msgAndArgs...)
+		}
+
+		if !av.IsValid() {
+			return Fail(t, fmt.Sprintf("missing key %q in actual map", k), msgAndArgs...)
+		}
+
+		if !InDelta(
+			t,
+			ev.Interface(),
+			av.Interface(),
+			delta,
+			msgAndArgs...,
+		) {
+			return false
+		}
+	}
+
+	return true
+}
+
 func calcRelativeError(expected, actual interface{}) (float64, error) {
 	af, aok := toFloat(expected)
 	if !aok {
@@ -961,16 +1107,17 @@ func calcRelativeError(expected, actual interface{}) (float64, error) {
 }
 
 // InEpsilon asserts that expected and actual have a relative error less than epsilon
-//
-// Returns whether the assertion was successful (true) or not (false).
 func InEpsilon(t TestingT, expected, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	actualEpsilon, err := calcRelativeError(expected, actual)
 	if err != nil {
 		return Fail(t, err.Error(), msgAndArgs...)
 	}
 	if actualEpsilon > epsilon {
 		return Fail(t, fmt.Sprintf("Relative error is too high: %#v (expected)\n"+
-			"        < %#v (actual)", actualEpsilon, epsilon), msgAndArgs...)
+			"        < %#v (actual)", epsilon, actualEpsilon), msgAndArgs...)
 	}
 
 	return true
@@ -978,6 +1125,9 @@ func InEpsilon(t TestingT, expected, actual interface{}, epsilon float64, msgAnd
 
 // InEpsilonSlice is the same as InEpsilon, except it compares each value from two slices.
 func InEpsilonSlice(t TestingT, expected, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	if expected == nil || actual == nil ||
 		reflect.TypeOf(actual).Kind() != reflect.Slice ||
 		reflect.TypeOf(expected).Kind() != reflect.Slice {
@@ -1007,9 +1157,10 @@ func InEpsilonSlice(t TestingT, expected, actual interface{}, epsilon float64, m
 //   if assert.NoError(t, err) {
 //	   assert.Equal(t, expectedObj, actualObj)
 //   }
-//
-// Returns whether the assertion was successful (true) or not (false).
 func NoError(t TestingT, err error, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	if err != nil {
 		return Fail(t, fmt.Sprintf("Received unexpected error:\n%+v", err), msgAndArgs...)
 	}
@@ -1023,9 +1174,10 @@ func NoError(t TestingT, err error, msgAndArgs ...interface{}) bool {
 //   if assert.Error(t, err) {
 //	   assert.Equal(t, expectedError, err)
 //   }
-//
-// Returns whether the assertion was successful (true) or not (false).
 func Error(t TestingT, err error, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 
 	if err == nil {
 		return Fail(t, "An error is expected but got nil.", msgAndArgs...)
@@ -1039,9 +1191,10 @@ func Error(t TestingT, err error, msgAndArgs ...interface{}) bool {
 //
 //   actualObj, err := SomeFunction()
 //   assert.EqualError(t, err,  expectedErrorString)
-//
-// Returns whether the assertion was successful (true) or not (false).
 func EqualError(t TestingT, theError error, errString string, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	if !Error(t, theError, msgAndArgs...) {
 		return false
 	}
@@ -1051,7 +1204,7 @@ func EqualError(t TestingT, theError error, errString string, msgAndArgs ...inte
 	if expected != actual {
 		return Fail(t, fmt.Sprintf("Error message not equal:\n"+
 			"expected: %q\n"+
-			"actual: %q", expected, actual), msgAndArgs...)
+			"actual  : %q", expected, actual), msgAndArgs...)
 	}
 	return true
 }
@@ -1074,9 +1227,10 @@ func matchRegexp(rx interface{}, str interface{}) bool {
 //
 //  assert.Regexp(t, regexp.MustCompile("start"), "it's starting")
 //  assert.Regexp(t, "start...$", "it's not starting")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 
 	match := matchRegexp(rx, str)
 
@@ -1091,9 +1245,10 @@ func Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface
 //
 //  assert.NotRegexp(t, regexp.MustCompile("starts"), "it's starting")
 //  assert.NotRegexp(t, "^start", "it's not starting")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	match := matchRegexp(rx, str)
 
 	if match {
@@ -1104,28 +1259,71 @@ func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interf
 
 }
 
-// Zero asserts that i is the zero value for its type and returns the truth.
+// Zero asserts that i is the zero value for its type.
 func Zero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	if i != nil && !reflect.DeepEqual(i, reflect.Zero(reflect.TypeOf(i)).Interface()) {
 		return Fail(t, fmt.Sprintf("Should be zero, but was %v", i), msgAndArgs...)
 	}
 	return true
 }
 
-// NotZero asserts that i is not the zero value for its type and returns the truth.
+// NotZero asserts that i is not the zero value for its type.
 func NotZero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	if i == nil || reflect.DeepEqual(i, reflect.Zero(reflect.TypeOf(i)).Interface()) {
 		return Fail(t, fmt.Sprintf("Should not be zero, but was %v", i), msgAndArgs...)
 	}
 	return true
 }
 
+// FileExists checks whether a file exists in the given path. It also fails if the path points to a directory or there is an error when trying to check the file.
+func FileExists(t TestingT, path string, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	info, err := os.Lstat(path)
+	if err != nil {
+		if os.IsNotExist(err) {
+			return Fail(t, fmt.Sprintf("unable to find file %q", path), msgAndArgs...)
+		}
+		return Fail(t, fmt.Sprintf("error when running os.Lstat(%q): %s", path, err), msgAndArgs...)
+	}
+	if info.IsDir() {
+		return Fail(t, fmt.Sprintf("%q is a directory", path), msgAndArgs...)
+	}
+	return true
+}
+
+// DirExists checks whether a directory exists in the given path. It also fails if the path is a file rather a directory or there is an error checking whether it exists.
+func DirExists(t TestingT, path string, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	info, err := os.Lstat(path)
+	if err != nil {
+		if os.IsNotExist(err) {
+			return Fail(t, fmt.Sprintf("unable to find file %q", path), msgAndArgs...)
+		}
+		return Fail(t, fmt.Sprintf("error when running os.Lstat(%q): %s", path, err), msgAndArgs...)
+	}
+	if !info.IsDir() {
+		return Fail(t, fmt.Sprintf("%q is a file", path), msgAndArgs...)
+	}
+	return true
+}
+
 // JSONEq asserts that two JSON strings are equivalent.
 //
 //  assert.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`)
-//
-// Returns whether the assertion was successful (true) or not (false).
 func JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	var expectedJSONAsInterface, actualJSONAsInterface interface{}
 
 	if err := json.Unmarshal([]byte(expected), &expectedJSONAsInterface); err != nil {
@@ -1151,7 +1349,7 @@ func typeAndKind(v interface{}) (reflect.Type, reflect.Kind) {
 }
 
 // diff returns a diff of both values as long as both are of the same type and
-// are a struct, map, slice or array. Otherwise it returns an empty string.
+// are a struct, map, slice, array or string. Otherwise it returns an empty string.
 func diff(expected interface{}, actual interface{}) string {
 	if expected == nil || actual == nil {
 		return ""
@@ -1164,12 +1362,18 @@ func diff(expected interface{}, actual interface{}) string {
 		return ""
 	}
 
-	if ek != reflect.Struct && ek != reflect.Map && ek != reflect.Slice && ek != reflect.Array {
+	if ek != reflect.Struct && ek != reflect.Map && ek != reflect.Slice && ek != reflect.Array && ek != reflect.String {
 		return ""
 	}
 
-	e := spewConfig.Sdump(expected)
-	a := spewConfig.Sdump(actual)
+	var e, a string
+	if et != reflect.TypeOf("") {
+		e = spewConfig.Sdump(expected)
+		a = spewConfig.Sdump(actual)
+	} else {
+		e = expected.(string)
+		a = actual.(string)
+	}
 
 	diff, _ := difflib.GetUnifiedDiffString(difflib.UnifiedDiff{
 		A:        difflib.SplitLines(e),
@@ -1206,3 +1410,7 @@ var spewConfig = spew.ConfigState{
 	DisableCapacities:       true,
 	SortKeys:                true,
 }
+
+type tHelper interface {
+	Helper()
+}
diff --git a/vendor/github.com/stretchr/testify/assert/assertions_test.go b/vendor/github.com/stretchr/testify/assert/assertions_test.go
index cd67ee6eca767b35f003ea8f5f3a0da297ba072d..00e2d21fc858b4e0e64fbed05fea6348daf15179 100644
--- a/vendor/github.com/stretchr/testify/assert/assertions_test.go
+++ b/vendor/github.com/stretchr/testify/assert/assertions_test.go
@@ -2,6 +2,7 @@ package assert
 
 import (
 	"bytes"
+	"encoding/json"
 	"errors"
 	"fmt"
 	"io"
@@ -155,6 +156,9 @@ func TestImplements(t *testing.T) {
 	if Implements(mockT, (*AssertionTesterInterface)(nil), new(AssertionTesterNonConformingObject)) {
 		t.Error("Implements method should return false: AssertionTesterNonConformingObject does not implements AssertionTesterInterface")
 	}
+	if Implements(mockT, (*AssertionTesterInterface)(nil), nil) {
+		t.Error("Implements method should return false: nil does not implement AssertionTesterInterface")
+	}
 
 }
 
@@ -171,6 +175,8 @@ func TestIsType(t *testing.T) {
 
 }
 
+type myType string
+
 func TestEqual(t *testing.T) {
 
 	mockT := new(testing.T)
@@ -196,6 +202,9 @@ func TestEqual(t *testing.T) {
 	if !Equal(mockT, uint64(123), uint64(123)) {
 		t.Error("Equal should return true")
 	}
+	if !Equal(mockT, myType("1"), myType("1")) {
+		t.Error("Equal should return true")
+	}
 	if !Equal(mockT, &struct{}{}, &struct{}{}) {
 		t.Error("Equal should return true (pointer equality is based on equality of underlying value)")
 	}
@@ -203,6 +212,9 @@ func TestEqual(t *testing.T) {
 	if Equal(mockT, m["bar"], "something") {
 		t.Error("Equal should return false")
 	}
+	if Equal(mockT, myType("1"), myType("2")) {
+		t.Error("Equal should return false")
+	}
 }
 
 // bufferT implements TestingT. Its implementation of Errorf writes the output that would be produced by
@@ -247,6 +259,21 @@ func (t *bufferT) Errorf(format string, args ...interface{}) {
 	t.buf.WriteString(decorate(fmt.Sprintf(format, args...)))
 }
 
+func TestStringEqual(t *testing.T) {
+	for i, currCase := range []struct {
+		equalWant  string
+		equalGot   string
+		msgAndArgs []interface{}
+		want       string
+	}{
+		{equalWant: "hi, \nmy name is", equalGot: "what,\nmy name is", want: "\tassertions.go:\\d+: \n\t+Error Trace:\t\n\t+Error:\\s+Not equal:\\s+\n\\s+expected: \"hi, \\\\nmy name is\"\n\\s+actual\\s+: \"what,\\\\nmy name is\"\n\\s+Diff:\n\\s+-+ Expected\n\\s+\\++ Actual\n\\s+@@ -1,2 \\+1,2 @@\n\\s+-hi, \n\\s+\\+what,\n\\s+my name is"},
+	} {
+		mockT := &bufferT{}
+		Equal(mockT, currCase.equalWant, currCase.equalGot, currCase.msgAndArgs...)
+		Regexp(t, regexp.MustCompile(currCase.want), mockT.buf.String(), "Case %d", i)
+	}
+}
+
 func TestEqualFormatting(t *testing.T) {
 	for i, currCase := range []struct {
 		equalWant  string
@@ -254,8 +281,10 @@ func TestEqualFormatting(t *testing.T) {
 		msgAndArgs []interface{}
 		want       string
 	}{
-		{equalWant: "want", equalGot: "got", want: "\tassertions.go:[0-9]+: \r                          \r\tError Trace:\t\n\t\t\r\tError:      \tNot equal: \n\t\t\r\t            \texpected: \"want\"\n\t\t\r\t            \tactual: \"got\"\n"},
-		{equalWant: "want", equalGot: "got", msgAndArgs: []interface{}{"hello, %v!", "world"}, want: "\tassertions.go:[0-9]+: \r                          \r\tError Trace:\t\n\t\t\r\tError:      \tNot equal: \n\t\t\r\t            \texpected: \"want\"\n\t\t\r\t            \tactual: \"got\"\n\t\t\r\tMessages:   \thello, world!\n"},
+		{equalWant: "want", equalGot: "got", want: "\tassertions.go:\\d+: \n\t+Error Trace:\t\n\t+Error:\\s+Not equal:\\s+\n\\s+expected: \"want\"\n\\s+actual\\s+: \"got\"\n\\s+Diff:\n\\s+-+ Expected\n\\s+\\++ Actual\n\\s+@@ -1 \\+1 @@\n\\s+-want\n\\s+\\+got\n"},
+		{equalWant: "want", equalGot: "got", msgAndArgs: []interface{}{"hello, %v!", "world"}, want: "\tassertions.go:[0-9]+: \n\t+Error Trace:\t\n\t+Error:\\s+Not equal:\\s+\n\\s+expected: \"want\"\n\\s+actual\\s+: \"got\"\n\\s+Diff:\n\\s+-+ Expected\n\\s+\\++ Actual\n\\s+@@ -1 \\+1 @@\n\\s+-want\n\\s+\\+got\n\\s+Messages:\\s+hello, world!\n"},
+		{equalWant: "want", equalGot: "got", msgAndArgs: []interface{}{123}, want: "\tassertions.go:[0-9]+: \n\t+Error Trace:\t\n\t+Error:\\s+Not equal:\\s+\n\\s+expected: \"want\"\n\\s+actual\\s+: \"got\"\n\\s+Diff:\n\\s+-+ Expected\n\\s+\\++ Actual\n\\s+@@ -1 \\+1 @@\n\\s+-want\n\\s+\\+got\n\\s+Messages:\\s+123\n"},
+		{equalWant: "want", equalGot: "got", msgAndArgs: []interface{}{struct{ a string }{"hello"}}, want: "\tassertions.go:[0-9]+: \n\t+Error Trace:\t\n\t+Error:\\s+Not equal:\\s+\n\\s+expected: \"want\"\n\\s+actual\\s+: \"got\"\n\\s+Diff:\n\\s+-+ Expected\n\\s+\\++ Actual\n\\s+@@ -1 \\+1 @@\n\\s+-want\n\\s+\\+got\n\\s+Messages:\\s+{a:hello}\n"},
 	} {
 		mockT := &bufferT{}
 		Equal(mockT, currCase.equalWant, currCase.equalGot, currCase.msgAndArgs...)
@@ -553,6 +582,14 @@ func TestNotSubset(t *testing.T) {
 	}
 }
 
+func TestNotSubsetNil(t *testing.T) {
+	mockT := new(testing.T)
+	NotSubset(mockT, []string{"foo"}, nil)
+	if !mockT.Failed() {
+		t.Error("NotSubset on nil set should have failed the test")
+	}
+}
+
 func Test_includeElement(t *testing.T) {
 
 	list1 := []string{"Foo", "Bar"}
@@ -604,6 +641,57 @@ func Test_includeElement(t *testing.T) {
 	False(t, found)
 }
 
+func TestElementsMatch(t *testing.T) {
+	mockT := new(testing.T)
+
+	if !ElementsMatch(mockT, nil, nil) {
+		t.Error("ElementsMatch should return true")
+	}
+	if !ElementsMatch(mockT, []int{}, []int{}) {
+		t.Error("ElementsMatch should return true")
+	}
+	if !ElementsMatch(mockT, []int{1}, []int{1}) {
+		t.Error("ElementsMatch should return true")
+	}
+	if !ElementsMatch(mockT, []int{1, 1}, []int{1, 1}) {
+		t.Error("ElementsMatch should return true")
+	}
+	if !ElementsMatch(mockT, []int{1, 2}, []int{1, 2}) {
+		t.Error("ElementsMatch should return true")
+	}
+	if !ElementsMatch(mockT, []int{1, 2}, []int{2, 1}) {
+		t.Error("ElementsMatch should return true")
+	}
+	if !ElementsMatch(mockT, [2]int{1, 2}, [2]int{2, 1}) {
+		t.Error("ElementsMatch should return true")
+	}
+	if !ElementsMatch(mockT, []string{"hello", "world"}, []string{"world", "hello"}) {
+		t.Error("ElementsMatch should return true")
+	}
+	if !ElementsMatch(mockT, []string{"hello", "hello"}, []string{"hello", "hello"}) {
+		t.Error("ElementsMatch should return true")
+	}
+	if !ElementsMatch(mockT, []string{"hello", "hello", "world"}, []string{"hello", "world", "hello"}) {
+		t.Error("ElementsMatch should return true")
+	}
+	if !ElementsMatch(mockT, [3]string{"hello", "hello", "world"}, [3]string{"hello", "world", "hello"}) {
+		t.Error("ElementsMatch should return true")
+	}
+	if !ElementsMatch(mockT, []int{}, nil) {
+		t.Error("ElementsMatch should return true")
+	}
+
+	if ElementsMatch(mockT, []int{1}, []int{1, 1}) {
+		t.Error("ElementsMatch should return false")
+	}
+	if ElementsMatch(mockT, []int{1, 2}, []int{2, 2}) {
+		t.Error("ElementsMatch should return false")
+	}
+	if ElementsMatch(mockT, []string{"hello", "hello"}, []string{"hello"}) {
+		t.Error("ElementsMatch should return false")
+	}
+}
+
 func TestCondition(t *testing.T) {
 	mockT := new(testing.T)
 
@@ -806,6 +894,15 @@ func TestEmpty(t *testing.T) {
 	var tiNP time.Time
 	var s *string
 	var f *os.File
+	sP := &s
+	x := 1
+	xP := &x
+
+	type TString string
+	type TStruct struct {
+		x int
+		s []int
+	}
 
 	True(t, Empty(mockT, ""), "Empty string is empty")
 	True(t, Empty(mockT, nil), "Nil is empty")
@@ -817,6 +914,9 @@ func TestEmpty(t *testing.T) {
 	True(t, Empty(mockT, f), "Nil os.File pointer is empty")
 	True(t, Empty(mockT, tiP), "Nil time.Time pointer is empty")
 	True(t, Empty(mockT, tiNP), "time.Time is empty")
+	True(t, Empty(mockT, TStruct{}), "struct with zero values is empty")
+	True(t, Empty(mockT, TString("")), "empty aliased string is empty")
+	True(t, Empty(mockT, sP), "ptr to nil value is empty")
 
 	False(t, Empty(mockT, "something"), "Non Empty string is not empty")
 	False(t, Empty(mockT, errors.New("something")), "Non nil object is not empty")
@@ -824,6 +924,9 @@ func TestEmpty(t *testing.T) {
 	False(t, Empty(mockT, 1), "Non-zero int value is not empty")
 	False(t, Empty(mockT, true), "True value is not empty")
 	False(t, Empty(mockT, chWithValue), "Channel with values is not empty")
+	False(t, Empty(mockT, TStruct{x: 1}), "struct with initialized values is empty")
+	False(t, Empty(mockT, TString("abc")), "non-empty aliased string is empty")
+	False(t, Empty(mockT, xP), "ptr to non-nil value is not empty")
 }
 
 func TestNotEmpty(t *testing.T) {
@@ -1030,6 +1133,82 @@ func TestInDeltaSlice(t *testing.T) {
 	False(t, InDeltaSlice(mockT, "", nil, 1), "Expected non numeral slices to fail")
 }
 
+func TestInDeltaMapValues(t *testing.T) {
+	mockT := new(testing.T)
+
+	for _, tc := range []struct {
+		title  string
+		expect interface{}
+		actual interface{}
+		f      func(TestingT, bool, ...interface{}) bool
+		delta  float64
+	}{
+		{
+			title: "Within delta",
+			expect: map[string]float64{
+				"foo": 1.0,
+				"bar": 2.0,
+			},
+			actual: map[string]float64{
+				"foo": 1.01,
+				"bar": 1.99,
+			},
+			delta: 0.1,
+			f:     True,
+		},
+		{
+			title: "Within delta",
+			expect: map[int]float64{
+				1: 1.0,
+				2: 2.0,
+			},
+			actual: map[int]float64{
+				1: 1.0,
+				2: 1.99,
+			},
+			delta: 0.1,
+			f:     True,
+		},
+		{
+			title: "Different number of keys",
+			expect: map[int]float64{
+				1: 1.0,
+				2: 2.0,
+			},
+			actual: map[int]float64{
+				1: 1.0,
+			},
+			delta: 0.1,
+			f:     False,
+		},
+		{
+			title: "Within delta with zero value",
+			expect: map[string]float64{
+				"zero": 0.0,
+			},
+			actual: map[string]float64{
+				"zero": 0.0,
+			},
+			delta: 0.1,
+			f:     True,
+		},
+		{
+			title: "With missing key with zero value",
+			expect: map[string]float64{
+				"zero": 0.0,
+				"foo":  0.0,
+			},
+			actual: map[string]float64{
+				"zero": 0.0,
+				"bar":  0.0,
+			},
+			f: False,
+		},
+	} {
+		tc.f(t, InDeltaMapValues(mockT, tc.expect, tc.actual, tc.delta), tc.title+"\n"+diff(tc.expect, tc.actual))
+	}
+}
+
 func TestInEpsilon(t *testing.T) {
 	mockT := new(testing.T)
 
@@ -1045,6 +1224,7 @@ func TestInEpsilon(t *testing.T) {
 		{uint64(100), uint8(101), 0.01},
 		{0.1, -0.1, 2},
 		{0.1, 0, 2},
+		{time.Second, time.Second + time.Millisecond, 0.002},
 	}
 
 	for _, tc := range cases {
@@ -1063,6 +1243,7 @@ func TestInEpsilon(t *testing.T) {
 		{2.1, "bla-bla", 0},
 		{0.1, -0.1, 1.99},
 		{0, 0.1, 2}, // expected must be different to zero
+		{time.Second, time.Second + 10*time.Millisecond, 0.002},
 	}
 
 	for _, tc := range cases {
@@ -1166,6 +1347,28 @@ func TestNotZero(t *testing.T) {
 	}
 }
 
+func TestFileExists(t *testing.T) {
+	mockT := new(testing.T)
+	True(t, FileExists(mockT, "assertions.go"))
+
+	mockT = new(testing.T)
+	False(t, FileExists(mockT, "random_file"))
+
+	mockT = new(testing.T)
+	False(t, FileExists(mockT, "../_codegen"))
+}
+
+func TestDirExists(t *testing.T) {
+	mockT := new(testing.T)
+	False(t, DirExists(mockT, "assertions.go"))
+
+	mockT = new(testing.T)
+	False(t, DirExists(mockT, "random_dir"))
+
+	mockT = new(testing.T)
+	True(t, DirExists(mockT, "../_codegen"))
+}
+
 func TestJSONEq_EqualSONString(t *testing.T) {
 	mockT := new(testing.T)
 	True(t, JSONEq(mockT, `{"hello": "world", "foo": "bar"}`, `{"hello": "world", "foo": "bar"}`))
@@ -1402,3 +1605,199 @@ func TestEqualArgsValidation(t *testing.T) {
 	err := validateEqualArgs(time.Now, time.Now)
 	EqualError(t, err, "cannot take func type as argument")
 }
+
+func ExampleComparisonAssertionFunc() {
+	t := &testing.T{} // provided by test
+
+	adder := func(x, y int) int {
+		return x + y
+	}
+
+	type args struct {
+		x int
+		y int
+	}
+
+	tests := []struct {
+		name      string
+		args      args
+		expect    int
+		assertion ComparisonAssertionFunc
+	}{
+		{"2+2=4", args{2, 2}, 4, Equal},
+		{"2+2!=5", args{2, 2}, 5, NotEqual},
+		{"2+3==5", args{2, 3}, 5, Exactly},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			tt.assertion(t, tt.expect, adder(tt.args.x, tt.args.y))
+		})
+	}
+}
+
+func TestComparisonAssertionFunc(t *testing.T) {
+	type iface interface {
+		Name() string
+	}
+
+	tests := []struct {
+		name      string
+		expect    interface{}
+		got       interface{}
+		assertion ComparisonAssertionFunc
+	}{
+		{"implements", (*iface)(nil), t, Implements},
+		{"isType", (*testing.T)(nil), t, IsType},
+		{"equal", t, t, Equal},
+		{"equalValues", t, t, EqualValues},
+		{"exactly", t, t, Exactly},
+		{"notEqual", t, nil, NotEqual},
+		{"notContains", []int{1, 2, 3}, 4, NotContains},
+		{"subset", []int{1, 2, 3, 4}, []int{2, 3}, Subset},
+		{"notSubset", []int{1, 2, 3, 4}, []int{0, 3}, NotSubset},
+		{"elementsMatch", []byte("abc"), []byte("bac"), ElementsMatch},
+		{"regexp", "^t.*y$", "testify", Regexp},
+		{"notRegexp", "^t.*y$", "Testify", NotRegexp},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			tt.assertion(t, tt.expect, tt.got)
+		})
+	}
+}
+
+func ExampleValueAssertionFunc() {
+	t := &testing.T{} // provided by test
+
+	dumbParse := func(input string) interface{} {
+		var x interface{}
+		json.Unmarshal([]byte(input), &x)
+		return x
+	}
+
+	tests := []struct {
+		name      string
+		arg       string
+		assertion ValueAssertionFunc
+	}{
+		{"true is not nil", "true", NotNil},
+		{"empty string is nil", "", Nil},
+		{"zero is not nil", "0", NotNil},
+		{"zero is zero", "0", Zero},
+		{"false is zero", "false", Zero},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			tt.assertion(t, dumbParse(tt.arg))
+		})
+	}
+}
+
+func TestValueAssertionFunc(t *testing.T) {
+	tests := []struct {
+		name      string
+		value     interface{}
+		assertion ValueAssertionFunc
+	}{
+		{"notNil", true, NotNil},
+		{"nil", nil, Nil},
+		{"empty", []int{}, Empty},
+		{"notEmpty", []int{1}, NotEmpty},
+		{"zero", false, Zero},
+		{"notZero", 42, NotZero},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			tt.assertion(t, tt.value)
+		})
+	}
+}
+
+func ExampleBoolAssertionFunc() {
+	t := &testing.T{} // provided by test
+
+	isOkay := func(x int) bool {
+		return x >= 42
+	}
+
+	tests := []struct {
+		name      string
+		arg       int
+		assertion BoolAssertionFunc
+	}{
+		{"-1 is bad", -1, False},
+		{"42 is good", 42, True},
+		{"41 is bad", 41, False},
+		{"45 is cool", 45, True},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			tt.assertion(t, isOkay(tt.arg))
+		})
+	}
+}
+
+func TestBoolAssertionFunc(t *testing.T) {
+	tests := []struct {
+		name      string
+		value     bool
+		assertion BoolAssertionFunc
+	}{
+		{"true", true, True},
+		{"false", false, False},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			tt.assertion(t, tt.value)
+		})
+	}
+}
+
+func ExampleErrorAssertionFunc() {
+	t := &testing.T{} // provided by test
+
+	dumbParseNum := func(input string, v interface{}) error {
+		return json.Unmarshal([]byte(input), v)
+	}
+
+	tests := []struct {
+		name      string
+		arg       string
+		assertion ErrorAssertionFunc
+	}{
+		{"1.2 is number", "1.2", NoError},
+		{"1.2.3 not number", "1.2.3", Error},
+		{"true is not number", "true", Error},
+		{"3 is number", "3", NoError},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			var x float64
+			tt.assertion(t, dumbParseNum(tt.arg, &x))
+		})
+	}
+}
+
+func TestErrorAssertionFunc(t *testing.T) {
+	tests := []struct {
+		name      string
+		err       error
+		assertion ErrorAssertionFunc
+	}{
+		{"noError", nil, NoError},
+		{"error", errors.New("whoops"), Error},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			tt.assertion(t, tt.err)
+		})
+	}
+}
diff --git a/vendor/github.com/stretchr/testify/assert/http_assertions.go b/vendor/github.com/stretchr/testify/assert/http_assertions.go
index ba811c04dd5f344cd551dd6591bb5020f13c2f0d..df46fa777acb3b8bc6c58371d8c48375a6a623de 100644
--- a/vendor/github.com/stretchr/testify/assert/http_assertions.go
+++ b/vendor/github.com/stretchr/testify/assert/http_assertions.go
@@ -12,10 +12,11 @@ import (
 // an error if building a new request fails.
 func httpCode(handler http.HandlerFunc, method, url string, values url.Values) (int, error) {
 	w := httptest.NewRecorder()
-	req, err := http.NewRequest(method, url+"?"+values.Encode(), nil)
+	req, err := http.NewRequest(method, url, nil)
 	if err != nil {
 		return -1, err
 	}
+	req.URL.RawQuery = values.Encode()
 	handler(w, req)
 	return w.Code, nil
 }
@@ -25,7 +26,10 @@ func httpCode(handler http.HandlerFunc, method, url string, values url.Values) (
 //  assert.HTTPSuccess(t, myHandler, "POST", "http://www.google.com", nil)
 //
 // Returns whether the assertion was successful (true) or not (false).
-func HTTPSuccess(t TestingT, handler http.HandlerFunc, method, url string, values url.Values) bool {
+func HTTPSuccess(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	code, err := httpCode(handler, method, url, values)
 	if err != nil {
 		Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err))
@@ -45,7 +49,10 @@ func HTTPSuccess(t TestingT, handler http.HandlerFunc, method, url string, value
 //  assert.HTTPRedirect(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}}
 //
 // Returns whether the assertion was successful (true) or not (false).
-func HTTPRedirect(t TestingT, handler http.HandlerFunc, method, url string, values url.Values) bool {
+func HTTPRedirect(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	code, err := httpCode(handler, method, url, values)
 	if err != nil {
 		Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err))
@@ -65,7 +72,10 @@ func HTTPRedirect(t TestingT, handler http.HandlerFunc, method, url string, valu
 //  assert.HTTPError(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}}
 //
 // Returns whether the assertion was successful (true) or not (false).
-func HTTPError(t TestingT, handler http.HandlerFunc, method, url string, values url.Values) bool {
+func HTTPError(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	code, err := httpCode(handler, method, url, values)
 	if err != nil {
 		Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err))
@@ -95,10 +105,13 @@ func HTTPBody(handler http.HandlerFunc, method, url string, values url.Values) s
 // HTTPBodyContains asserts that a specified handler returns a
 // body that contains a string.
 //
-//  assert.HTTPBodyContains(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky")
+//  assert.HTTPBodyContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky")
 //
 // Returns whether the assertion was successful (true) or not (false).
-func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}) bool {
+func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	body := HTTPBody(handler, method, url, values)
 
 	contains := strings.Contains(body, fmt.Sprint(str))
@@ -112,10 +125,13 @@ func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method, url string,
 // HTTPBodyNotContains asserts that a specified handler returns a
 // body that does not contain a string.
 //
-//  assert.HTTPBodyNotContains(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky")
+//  assert.HTTPBodyNotContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky")
 //
 // Returns whether the assertion was successful (true) or not (false).
-func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}) bool {
+func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	body := HTTPBody(handler, method, url, values)
 
 	contains := strings.Contains(body, fmt.Sprint(str))
diff --git a/vendor/github.com/stretchr/testify/assert/http_assertions_test.go b/vendor/github.com/stretchr/testify/assert/http_assertions_test.go
index 3ab76830f6bf0d8a36c4f8c3b772327106caa354..112beaf6429b3d8f435f744f240e1bc0ca6c5486 100644
--- a/vendor/github.com/stretchr/testify/assert/http_assertions_test.go
+++ b/vendor/github.com/stretchr/testify/assert/http_assertions_test.go
@@ -89,6 +89,35 @@ func httpHelloName(w http.ResponseWriter, r *http.Request) {
 	w.Write([]byte(fmt.Sprintf("Hello, %s!", name)))
 }
 
+func TestHTTPRequestWithNoParams(t *testing.T) {
+	var got *http.Request
+	handler := func(w http.ResponseWriter, r *http.Request) {
+		got = r
+		w.WriteHeader(http.StatusOK)
+	}
+
+	True(t, HTTPSuccess(t, handler, "GET", "/url", nil))
+
+	Empty(t, got.URL.Query())
+	Equal(t, "/url", got.URL.RequestURI())
+}
+
+func TestHTTPRequestWithParams(t *testing.T) {
+	var got *http.Request
+	handler := func(w http.ResponseWriter, r *http.Request) {
+		got = r
+		w.WriteHeader(http.StatusOK)
+	}
+	params := url.Values{}
+	params.Add("id", "12345")
+
+	True(t, HTTPSuccess(t, handler, "GET", "/url", params))
+
+	Equal(t, url.Values{"id": []string{"12345"}}, got.URL.Query())
+	Equal(t, "/url?id=12345", got.URL.String())
+	Equal(t, "/url?id=12345", got.URL.RequestURI())
+}
+
 func TestHttpBody(t *testing.T) {
 	assert := New(t)
 	mockT := new(testing.T)
diff --git a/vendor/github.com/stretchr/testify/mock/mock.go b/vendor/github.com/stretchr/testify/mock/mock.go
index fc63571d4e8b3a4d49fda3270f6af0de6c473b70..d6694ed78a1010668ddeb58c51f61a2c7edbc065 100644
--- a/vendor/github.com/stretchr/testify/mock/mock.go
+++ b/vendor/github.com/stretchr/testify/mock/mock.go
@@ -1,6 +1,7 @@
 package mock
 
 import (
+	"errors"
 	"fmt"
 	"reflect"
 	"regexp"
@@ -41,6 +42,9 @@ type Call struct {
 	// this method is called.
 	ReturnArguments Arguments
 
+	// Holds the caller info for the On() call
+	callerInfo []string
+
 	// The number of times to return the return arguments when setting
 	// expectations. 0 means to always return the value.
 	Repeatability int
@@ -48,22 +52,28 @@ type Call struct {
 	// Amount of times this call has been called
 	totalCalls int
 
+	// Call to this method can be optional
+	optional bool
+
 	// Holds a channel that will be used to block the Return until it either
 	// receives a message or is closed. nil means it returns immediately.
 	WaitFor <-chan time.Time
 
+	waitTime time.Duration
+
 	// Holds a handler used to manipulate arguments content that are passed by
 	// reference. It's useful when mocking methods such as unmarshalers or
 	// decoders.
 	RunFn func(Arguments)
 }
 
-func newCall(parent *Mock, methodName string, methodArguments ...interface{}) *Call {
+func newCall(parent *Mock, methodName string, callerInfo []string, methodArguments ...interface{}) *Call {
 	return &Call{
 		Parent:          parent,
 		Method:          methodName,
 		Arguments:       methodArguments,
 		ReturnArguments: make([]interface{}, 0),
+		callerInfo:      callerInfo,
 		Repeatability:   0,
 		WaitFor:         nil,
 		RunFn:           nil,
@@ -130,7 +140,10 @@ func (c *Call) WaitUntil(w <-chan time.Time) *Call {
 //
 //    Mock.On("MyMethod", arg1, arg2).After(time.Second)
 func (c *Call) After(d time.Duration) *Call {
-	return c.WaitUntil(time.After(d))
+	c.lock()
+	defer c.unlock()
+	c.waitTime = d
+	return c
 }
 
 // Run sets a handler to be called before returning. It can be used when
@@ -148,12 +161,22 @@ func (c *Call) Run(fn func(args Arguments)) *Call {
 	return c
 }
 
+// Maybe allows the method call to be optional. Not calling an optional method
+// will not cause an error while asserting expectations
+func (c *Call) Maybe() *Call {
+	c.lock()
+	defer c.unlock()
+	c.optional = true
+	return c
+}
+
 // On chains a new expectation description onto the mocked interface. This
 // allows syntax like.
 //
 //    Mock.
 //       On("MyMethod", 1).Return(nil).
 //       On("MyOtherMethod", 'a', 'b', 'c').Return(errors.New("Some Error"))
+//go:noinline
 func (c *Call) On(methodName string, arguments ...interface{}) *Call {
 	return c.Parent.On(methodName, arguments...)
 }
@@ -169,6 +192,10 @@ type Mock struct {
 	// Holds the calls that were made to this mocked object.
 	Calls []Call
 
+	// test is An optional variable that holds the test struct, to be used when an
+	// invalid mock call was made.
+	test TestingT
+
 	// TestData holds any data that might be useful for testing.  Testify ignores
 	// this data completely allowing you to do whatever you like with it.
 	testData objx.Map
@@ -191,6 +218,27 @@ func (m *Mock) TestData() objx.Map {
 	Setting expectations
 */
 
+// Test sets the test struct variable of the mock object
+func (m *Mock) Test(t TestingT) {
+	m.mutex.Lock()
+	defer m.mutex.Unlock()
+	m.test = t
+}
+
+// fail fails the current test with the given formatted format and args.
+// In case that a test was defined, it uses the test APIs for failing a test,
+// otherwise it uses panic.
+func (m *Mock) fail(format string, args ...interface{}) {
+	m.mutex.Lock()
+	defer m.mutex.Unlock()
+
+	if m.test == nil {
+		panic(fmt.Sprintf(format, args...))
+	}
+	m.test.Errorf(format, args...)
+	m.test.FailNow()
+}
+
 // On starts a description of an expectation of the specified method
 // being called.
 //
@@ -204,7 +252,7 @@ func (m *Mock) On(methodName string, arguments ...interface{}) *Call {
 
 	m.mutex.Lock()
 	defer m.mutex.Unlock()
-	c := newCall(m, methodName, arguments...)
+	c := newCall(m, methodName, assert.CallerInfo(), arguments...)
 	m.ExpectedCalls = append(m.ExpectedCalls, c)
 	return c
 }
@@ -227,27 +275,25 @@ func (m *Mock) findExpectedCall(method string, arguments ...interface{}) (int, *
 	return -1, nil
 }
 
-func (m *Mock) findClosestCall(method string, arguments ...interface{}) (bool, *Call) {
-	diffCount := 0
+func (m *Mock) findClosestCall(method string, arguments ...interface{}) (*Call, string) {
+	var diffCount int
 	var closestCall *Call
+	var err string
 
 	for _, call := range m.expectedCalls() {
 		if call.Method == method {
 
-			_, tempDiffCount := call.Arguments.Diff(arguments)
+			errInfo, tempDiffCount := call.Arguments.Diff(arguments)
 			if tempDiffCount < diffCount || diffCount == 0 {
 				diffCount = tempDiffCount
 				closestCall = call
+				err = errInfo
 			}
 
 		}
 	}
 
-	if closestCall == nil {
-		return false, nil
-	}
-
-	return true, closestCall
+	return closestCall, err
 }
 
 func callString(method string, arguments Arguments, includeArgumentValues bool) string {
@@ -294,6 +340,7 @@ func (m *Mock) Called(arguments ...interface{}) Arguments {
 // If Call.WaitFor is set, blocks until the channel is closed or receives a message.
 func (m *Mock) MethodCalled(methodName string, arguments ...interface{}) Arguments {
 	m.mutex.Lock()
+	//TODO: could combine expected and closes in single loop
 	found, call := m.findExpectedCall(methodName, arguments...)
 
 	if found < 0 {
@@ -304,43 +351,52 @@ func (m *Mock) MethodCalled(methodName string, arguments ...interface{}) Argumen
 		//   b) the arguments are not what was expected, or
 		//   c) the developer has forgotten to add an accompanying On...Return pair.
 
-		closestFound, closestCall := m.findClosestCall(methodName, arguments...)
+		closestCall, mismatch := m.findClosestCall(methodName, arguments...)
 		m.mutex.Unlock()
 
-		if closestFound {
-			panic(fmt.Sprintf("\n\nmock: Unexpected Method Call\n-----------------------------\n\n%s\n\nThe closest call I have is: \n\n%s\n\n%s\n", callString(methodName, arguments, true), callString(methodName, closestCall.Arguments, true), diffArguments(arguments, closestCall.Arguments)))
+		if closestCall != nil {
+			m.fail("\n\nmock: Unexpected Method Call\n-----------------------------\n\n%s\n\nThe closest call I have is: \n\n%s\n\n%s\nDiff: %s",
+				callString(methodName, arguments, true),
+				callString(methodName, closestCall.Arguments, true),
+				diffArguments(closestCall.Arguments, arguments),
+				strings.TrimSpace(mismatch),
+			)
 		} else {
-			panic(fmt.Sprintf("\nassert: mock: I don't know what to return because the method call was unexpected.\n\tEither do Mock.On(\"%s\").Return(...) first, or remove the %s() call.\n\tThis method was unexpected:\n\t\t%s\n\tat: %s", methodName, methodName, callString(methodName, arguments, true), assert.CallerInfo()))
+			m.fail("\nassert: mock: I don't know what to return because the method call was unexpected.\n\tEither do Mock.On(\"%s\").Return(...) first, or remove the %s() call.\n\tThis method was unexpected:\n\t\t%s\n\tat: %s", methodName, methodName, callString(methodName, arguments, true), assert.CallerInfo())
 		}
 	}
 
-	switch {
-	case call.Repeatability == 1:
+	if call.Repeatability == 1 {
 		call.Repeatability = -1
-		call.totalCalls++
-
-	case call.Repeatability > 1:
+	} else if call.Repeatability > 1 {
 		call.Repeatability--
-		call.totalCalls++
-
-	case call.Repeatability == 0:
-		call.totalCalls++
 	}
+	call.totalCalls++
 
 	// add the call
-	m.Calls = append(m.Calls, *newCall(m, methodName, arguments...))
+	m.Calls = append(m.Calls, *newCall(m, methodName, assert.CallerInfo(), arguments...))
 	m.mutex.Unlock()
 
 	// block if specified
 	if call.WaitFor != nil {
 		<-call.WaitFor
+	} else {
+		time.Sleep(call.waitTime)
 	}
 
-	if call.RunFn != nil {
-		call.RunFn(arguments)
+	m.mutex.Lock()
+	runFn := call.RunFn
+	m.mutex.Unlock()
+
+	if runFn != nil {
+		runFn(arguments)
 	}
 
-	return call.ReturnArguments
+	m.mutex.Lock()
+	returnArgs := call.ReturnArguments
+	m.mutex.Unlock()
+
+	return returnArgs
 }
 
 /*
@@ -356,6 +412,9 @@ type assertExpectationser interface {
 //
 // Calls may have occurred in any order.
 func AssertExpectationsForObjects(t TestingT, testObjects ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	for _, obj := range testObjects {
 		if m, ok := obj.(Mock); ok {
 			t.Logf("Deprecated mock.AssertExpectationsForObjects(myMock.Mock) use mock.AssertExpectationsForObjects(myMock)")
@@ -363,6 +422,7 @@ func AssertExpectationsForObjects(t TestingT, testObjects ...interface{}) bool {
 		}
 		m := obj.(assertExpectationser)
 		if !m.AssertExpectations(t) {
+			t.Logf("Expectations didn't match for Mock: %+v", reflect.TypeOf(m))
 			return false
 		}
 	}
@@ -372,6 +432,9 @@ func AssertExpectationsForObjects(t TestingT, testObjects ...interface{}) bool {
 // AssertExpectations asserts that everything specified with On and Return was
 // in fact called as expected.  Calls may have occurred in any order.
 func (m *Mock) AssertExpectations(t TestingT) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	m.mutex.Lock()
 	defer m.mutex.Unlock()
 	var somethingMissing bool
@@ -380,16 +443,17 @@ func (m *Mock) AssertExpectations(t TestingT) bool {
 	// iterate through each expectation
 	expectedCalls := m.expectedCalls()
 	for _, expectedCall := range expectedCalls {
-		if !m.methodWasCalled(expectedCall.Method, expectedCall.Arguments) && expectedCall.totalCalls == 0 {
+		if !expectedCall.optional && !m.methodWasCalled(expectedCall.Method, expectedCall.Arguments) && expectedCall.totalCalls == 0 {
 			somethingMissing = true
 			failedExpectations++
-			t.Logf("\u274C\t%s(%s)", expectedCall.Method, expectedCall.Arguments.String())
+			t.Logf("FAIL:\t%s(%s)\n\t\tat: %s", expectedCall.Method, expectedCall.Arguments.String(), expectedCall.callerInfo)
 		} else {
 			if expectedCall.Repeatability > 0 {
 				somethingMissing = true
 				failedExpectations++
+				t.Logf("FAIL:\t%s(%s)\n\t\tat: %s", expectedCall.Method, expectedCall.Arguments.String(), expectedCall.callerInfo)
 			} else {
-				t.Logf("\u2705\t%s(%s)", expectedCall.Method, expectedCall.Arguments.String())
+				t.Logf("PASS:\t%s(%s)", expectedCall.Method, expectedCall.Arguments.String())
 			}
 		}
 	}
@@ -403,6 +467,9 @@ func (m *Mock) AssertExpectations(t TestingT) bool {
 
 // AssertNumberOfCalls asserts that the method was called expectedCalls times.
 func (m *Mock) AssertNumberOfCalls(t TestingT, methodName string, expectedCalls int) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	m.mutex.Lock()
 	defer m.mutex.Unlock()
 	var actualCalls int
@@ -417,11 +484,22 @@ func (m *Mock) AssertNumberOfCalls(t TestingT, methodName string, expectedCalls
 // AssertCalled asserts that the method was called.
 // It can produce a false result when an argument is a pointer type and the underlying value changed after calling the mocked method.
 func (m *Mock) AssertCalled(t TestingT, methodName string, arguments ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	m.mutex.Lock()
 	defer m.mutex.Unlock()
-	if !assert.True(t, m.methodWasCalled(methodName, arguments), fmt.Sprintf("The \"%s\" method should have been called with %d argument(s), but was not.", methodName, len(arguments))) {
-		t.Logf("%v", m.expectedCalls())
-		return false
+	if !m.methodWasCalled(methodName, arguments) {
+		var calledWithArgs []string
+		for _, call := range m.calls() {
+			calledWithArgs = append(calledWithArgs, fmt.Sprintf("%v", call.Arguments))
+		}
+		if len(calledWithArgs) == 0 {
+			return assert.Fail(t, "Should have called with given arguments",
+				fmt.Sprintf("Expected %q to have been called with:\n%v\nbut no actual calls happened", methodName, arguments))
+		}
+		return assert.Fail(t, "Should have called with given arguments",
+			fmt.Sprintf("Expected %q to have been called with:\n%v\nbut actual calls were:\n        %v", methodName, arguments, strings.Join(calledWithArgs, "\n")))
 	}
 	return true
 }
@@ -429,11 +507,14 @@ func (m *Mock) AssertCalled(t TestingT, methodName string, arguments ...interfac
 // AssertNotCalled asserts that the method was not called.
 // It can produce a false result when an argument is a pointer type and the underlying value changed after calling the mocked method.
 func (m *Mock) AssertNotCalled(t TestingT, methodName string, arguments ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	m.mutex.Lock()
 	defer m.mutex.Unlock()
-	if !assert.False(t, m.methodWasCalled(methodName, arguments), fmt.Sprintf("The \"%s\" method was called with %d argument(s), but should NOT have been.", methodName, len(arguments))) {
-		t.Logf("%v", m.expectedCalls())
-		return false
+	if m.methodWasCalled(methodName, arguments) {
+		return assert.Fail(t, "Should not have called with given arguments",
+			fmt.Sprintf("Expected %q to not have been called with:\n%v\nbut actually it was.", methodName, arguments))
 	}
 	return true
 }
@@ -473,7 +554,7 @@ type Arguments []interface{}
 const (
 	// Anything is used in Diff and Assert when the argument being tested
 	// shouldn't be taken into consideration.
-	Anything string = "mock.Anything"
+	Anything = "mock.Anything"
 )
 
 // AnythingOfTypeArgument is a string that contains the type of an argument
@@ -498,9 +579,25 @@ type argumentMatcher struct {
 
 func (f argumentMatcher) Matches(argument interface{}) bool {
 	expectType := f.fn.Type().In(0)
+	expectTypeNilSupported := false
+	switch expectType.Kind() {
+	case reflect.Interface, reflect.Chan, reflect.Func, reflect.Map, reflect.Slice, reflect.Ptr:
+		expectTypeNilSupported = true
+	}
 
-	if reflect.TypeOf(argument).AssignableTo(expectType) {
-		result := f.fn.Call([]reflect.Value{reflect.ValueOf(argument)})
+	argType := reflect.TypeOf(argument)
+	var arg reflect.Value
+	if argType == nil {
+		arg = reflect.New(expectType).Elem()
+	} else {
+		arg = reflect.ValueOf(argument)
+	}
+
+	if argType == nil && !expectTypeNilSupported {
+		panic(errors.New("attempting to call matcher with nil for non-nil expected type"))
+	}
+	if argType == nil || argType.AssignableTo(expectType) {
+		result := f.fn.Call([]reflect.Value{arg})
 		return result[0].Bool()
 	}
 	return false
@@ -560,6 +657,7 @@ func (args Arguments) Is(objects ...interface{}) bool {
 //
 // Returns the diff string and number of differences found.
 func (args Arguments) Diff(objects []interface{}) (string, int) {
+	//TODO: could return string as error and nil for No difference
 
 	var output = "\n"
 	var differences int
@@ -571,25 +669,30 @@ func (args Arguments) Diff(objects []interface{}) (string, int) {
 
 	for i := 0; i < maxArgCount; i++ {
 		var actual, expected interface{}
+		var actualFmt, expectedFmt string
 
 		if len(objects) <= i {
 			actual = "(Missing)"
+			actualFmt = "(Missing)"
 		} else {
 			actual = objects[i]
+			actualFmt = fmt.Sprintf("(%[1]T=%[1]v)", actual)
 		}
 
 		if len(args) <= i {
 			expected = "(Missing)"
+			expectedFmt = "(Missing)"
 		} else {
 			expected = args[i]
+			expectedFmt = fmt.Sprintf("(%[1]T=%[1]v)", expected)
 		}
 
 		if matcher, ok := expected.(argumentMatcher); ok {
 			if matcher.Matches(actual) {
-				output = fmt.Sprintf("%s\t%d: \u2705  %s matched by %s\n", output, i, actual, matcher)
+				output = fmt.Sprintf("%s\t%d: PASS:  %s matched by %s\n", output, i, actualFmt, matcher)
 			} else {
 				differences++
-				output = fmt.Sprintf("%s\t%d: \u2705  %s not matched by %s\n", output, i, actual, matcher)
+				output = fmt.Sprintf("%s\t%d: FAIL:  %s not matched by %s\n", output, i, actualFmt, matcher)
 			}
 		} else if reflect.TypeOf(expected) == reflect.TypeOf((*AnythingOfTypeArgument)(nil)).Elem() {
 
@@ -597,7 +700,7 @@ func (args Arguments) Diff(objects []interface{}) (string, int) {
 			if reflect.TypeOf(actual).Name() != string(expected.(AnythingOfTypeArgument)) && reflect.TypeOf(actual).String() != string(expected.(AnythingOfTypeArgument)) {
 				// not match
 				differences++
-				output = fmt.Sprintf("%s\t%d: \u274C  type %s != type %s - %s\n", output, i, expected, reflect.TypeOf(actual).Name(), actual)
+				output = fmt.Sprintf("%s\t%d: FAIL:  type %s != type %s - %s\n", output, i, expected, reflect.TypeOf(actual).Name(), actualFmt)
 			}
 
 		} else {
@@ -606,11 +709,11 @@ func (args Arguments) Diff(objects []interface{}) (string, int) {
 
 			if assert.ObjectsAreEqual(expected, Anything) || assert.ObjectsAreEqual(actual, Anything) || assert.ObjectsAreEqual(actual, expected) {
 				// match
-				output = fmt.Sprintf("%s\t%d: \u2705  %s == %s\n", output, i, actual, expected)
+				output = fmt.Sprintf("%s\t%d: PASS:  %s == %s\n", output, i, actualFmt, expectedFmt)
 			} else {
 				// not match
 				differences++
-				output = fmt.Sprintf("%s\t%d: \u274C  %s != %s\n", output, i, actual, expected)
+				output = fmt.Sprintf("%s\t%d: FAIL:  %s != %s\n", output, i, actualFmt, expectedFmt)
 			}
 		}
 
@@ -627,6 +730,9 @@ func (args Arguments) Diff(objects []interface{}) (string, int) {
 // Assert compares the arguments with the specified objects and fails if
 // they do not exactly match.
 func (args Arguments) Assert(t TestingT, objects ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 
 	// get the differences
 	diff, diffCount := args.Diff(objects)
@@ -774,3 +880,7 @@ var spewConfig = spew.ConfigState{
 	DisableCapacities:       true,
 	SortKeys:                true,
 }
+
+type tHelper interface {
+	Helper()
+}
diff --git a/vendor/github.com/stretchr/testify/mock/mock_test.go b/vendor/github.com/stretchr/testify/mock/mock_test.go
index c0502364b0eedf6ce189af3e390a56adeed54578..2608f5a36e1a5a32aa7b6988c30e7ccf43a08796 100644
--- a/vendor/github.com/stretchr/testify/mock/mock_test.go
+++ b/vendor/github.com/stretchr/testify/mock/mock_test.go
@@ -2,6 +2,10 @@ package mock
 
 import (
 	"errors"
+	"fmt"
+	"regexp"
+	"runtime"
+	"sync"
 	"testing"
 	"time"
 
@@ -28,6 +32,7 @@ func (i *TestExampleImplementation) TheExampleMethod(a, b, c int) (int, error) {
 	return args.Int(0), errors.New("Whoops")
 }
 
+//go:noinline
 func (i *TestExampleImplementation) TheExampleMethod2(yesorno bool) {
 	i.Called(yesorno)
 }
@@ -41,6 +46,26 @@ func (i *TestExampleImplementation) TheExampleMethod3(et *ExampleType) error {
 	return args.Error(0)
 }
 
+func (i *TestExampleImplementation) TheExampleMethod4(v ExampleInterface) error {
+	args := i.Called(v)
+	return args.Error(0)
+}
+
+func (i *TestExampleImplementation) TheExampleMethod5(ch chan struct{}) error {
+	args := i.Called(ch)
+	return args.Error(0)
+}
+
+func (i *TestExampleImplementation) TheExampleMethod6(m map[string]bool) error {
+	args := i.Called(m)
+	return args.Error(0)
+}
+
+func (i *TestExampleImplementation) TheExampleMethod7(slice []bool) error {
+	args := i.Called(slice)
+	return args.Error(0)
+}
+
 func (i *TestExampleImplementation) TheExampleMethodFunc(fn func(string) error) error {
 	args := i.Called(fn)
 	return args.Error(0)
@@ -68,6 +93,34 @@ func (i *TestExampleImplementation) TheExampleMethodFuncType(fn ExampleFuncType)
 	return args.Error(0)
 }
 
+// MockTestingT mocks a test struct
+type MockTestingT struct {
+	logfCount, errorfCount, failNowCount int
+}
+
+const mockTestingTFailNowCalled = "FailNow was called"
+
+func (m *MockTestingT) Logf(string, ...interface{}) {
+	m.logfCount++
+}
+
+func (m *MockTestingT) Errorf(string, ...interface{}) {
+	m.errorfCount++
+}
+
+// FailNow mocks the FailNow call.
+// It panics in order to mimic the FailNow behavior in the sense that
+// the execution stops.
+// When expecting this method, the call that invokes it should use the following code:
+//
+//     assert.PanicsWithValue(t, mockTestingTFailNowCalled, func() {...})
+func (m *MockTestingT) FailNow() {
+	m.failNowCount++
+
+	// this function should panic now to stop the execution as expected
+	panic(mockTestingTFailNowCalled)
+}
+
 /*
 	Mock
 */
@@ -97,6 +150,8 @@ func Test_Mock_Chained_On(t *testing.T) {
 	// make a test impl object
 	var mockedService = new(TestExampleImplementation)
 
+	// determine our current line number so we can assert the expected calls callerInfo properly
+	_, _, line, _ := runtime.Caller(0)
 	mockedService.
 		On("TheExampleMethod", 1, 2, 3).
 		Return(0).
@@ -104,17 +159,19 @@ func Test_Mock_Chained_On(t *testing.T) {
 		Return(nil)
 
 	expectedCalls := []*Call{
-		&Call{
+		{
 			Parent:          &mockedService.Mock,
 			Method:          "TheExampleMethod",
 			Arguments:       []interface{}{1, 2, 3},
 			ReturnArguments: []interface{}{0},
+			callerInfo:      []string{fmt.Sprintf("mock_test.go:%d", line+2)},
 		},
-		&Call{
+		{
 			Parent:          &mockedService.Mock,
 			Method:          "TheExampleMethod3",
 			Arguments:       []interface{}{AnythingOfType("*mock.ExampleType")},
 			ReturnArguments: []interface{}{nil},
+			callerInfo:      []string{fmt.Sprintf("mock_test.go:%d", line+4)},
 		},
 	}
 	assert.Equal(t, expectedCalls, mockedService.ExpectedCalls)
@@ -176,19 +233,52 @@ func Test_Mock_On_WithIntArgMatcher(t *testing.T) {
 	})
 }
 
+func TestMock_WithTest(t *testing.T) {
+	var (
+		mockedService TestExampleImplementation
+		mockedTest    MockTestingT
+	)
+
+	mockedService.Test(&mockedTest)
+	mockedService.On("TheExampleMethod", 1, 2, 3).Return(0, nil)
+
+	// Test that on an expected call, the test was not failed
+
+	mockedService.TheExampleMethod(1, 2, 3)
+
+	// Assert that Errorf and FailNow were not called
+	assert.Equal(t, 0, mockedTest.errorfCount)
+	assert.Equal(t, 0, mockedTest.failNowCount)
+
+	// Test that on unexpected call, the mocked test was called to fail the test
+
+	assert.PanicsWithValue(t, mockTestingTFailNowCalled, func() {
+		mockedService.TheExampleMethod(1, 1, 1)
+	})
+
+	// Assert that Errorf and FailNow were called once
+	assert.Equal(t, 1, mockedTest.errorfCount)
+	assert.Equal(t, 1, mockedTest.failNowCount)
+}
+
 func Test_Mock_On_WithPtrArgMatcher(t *testing.T) {
 	var mockedService TestExampleImplementation
 
 	mockedService.On("TheExampleMethod3",
-		MatchedBy(func(a *ExampleType) bool { return a.ran == true }),
+		MatchedBy(func(a *ExampleType) bool { return a != nil && a.ran == true }),
 	).Return(nil)
 
 	mockedService.On("TheExampleMethod3",
-		MatchedBy(func(a *ExampleType) bool { return a.ran == false }),
+		MatchedBy(func(a *ExampleType) bool { return a != nil && a.ran == false }),
 	).Return(errors.New("error"))
 
+	mockedService.On("TheExampleMethod3",
+		MatchedBy(func(a *ExampleType) bool { return a == nil }),
+	).Return(errors.New("error2"))
+
 	assert.Equal(t, mockedService.TheExampleMethod3(&ExampleType{true}), nil)
 	assert.EqualError(t, mockedService.TheExampleMethod3(&ExampleType{false}), "error")
+	assert.EqualError(t, mockedService.TheExampleMethod3(nil), "error2")
 }
 
 func Test_Mock_On_WithFuncArgMatcher(t *testing.T) {
@@ -197,17 +287,62 @@ func Test_Mock_On_WithFuncArgMatcher(t *testing.T) {
 	fixture1, fixture2 := errors.New("fixture1"), errors.New("fixture2")
 
 	mockedService.On("TheExampleMethodFunc",
-		MatchedBy(func(a func(string) error) bool { return a("string") == fixture1 }),
+		MatchedBy(func(a func(string) error) bool { return a != nil && a("string") == fixture1 }),
 	).Return(errors.New("fixture1"))
 
 	mockedService.On("TheExampleMethodFunc",
-		MatchedBy(func(a func(string) error) bool { return a("string") == fixture2 }),
+		MatchedBy(func(a func(string) error) bool { return a != nil && a("string") == fixture2 }),
 	).Return(errors.New("fixture2"))
 
+	mockedService.On("TheExampleMethodFunc",
+		MatchedBy(func(a func(string) error) bool { return a == nil }),
+	).Return(errors.New("fixture3"))
+
 	assert.EqualError(t, mockedService.TheExampleMethodFunc(
 		func(string) error { return fixture1 }), "fixture1")
 	assert.EqualError(t, mockedService.TheExampleMethodFunc(
 		func(string) error { return fixture2 }), "fixture2")
+	assert.EqualError(t, mockedService.TheExampleMethodFunc(nil), "fixture3")
+}
+
+func Test_Mock_On_WithInterfaceArgMatcher(t *testing.T) {
+	var mockedService TestExampleImplementation
+
+	mockedService.On("TheExampleMethod4",
+		MatchedBy(func(a ExampleInterface) bool { return a == nil }),
+	).Return(errors.New("fixture1"))
+
+	assert.EqualError(t, mockedService.TheExampleMethod4(nil), "fixture1")
+}
+
+func Test_Mock_On_WithChannelArgMatcher(t *testing.T) {
+	var mockedService TestExampleImplementation
+
+	mockedService.On("TheExampleMethod5",
+		MatchedBy(func(ch chan struct{}) bool { return ch == nil }),
+	).Return(errors.New("fixture1"))
+
+	assert.EqualError(t, mockedService.TheExampleMethod5(nil), "fixture1")
+}
+
+func Test_Mock_On_WithMapArgMatcher(t *testing.T) {
+	var mockedService TestExampleImplementation
+
+	mockedService.On("TheExampleMethod6",
+		MatchedBy(func(m map[string]bool) bool { return m == nil }),
+	).Return(errors.New("fixture1"))
+
+	assert.EqualError(t, mockedService.TheExampleMethod6(nil), "fixture1")
+}
+
+func Test_Mock_On_WithSliceArgMatcher(t *testing.T) {
+	var mockedService TestExampleImplementation
+
+	mockedService.On("TheExampleMethod7",
+		MatchedBy(func(slice []bool) bool { return slice == nil }),
+	).Return(errors.New("fixture1"))
+
+	assert.EqualError(t, mockedService.TheExampleMethod7(nil), "fixture1")
 }
 
 func Test_Mock_On_WithVariadicFunc(t *testing.T) {
@@ -998,6 +1133,31 @@ func Test_Mock_AssertNotCalled(t *testing.T) {
 
 }
 
+func Test_Mock_AssertOptional(t *testing.T) {
+	// Optional called
+	var ms1 = new(TestExampleImplementation)
+	ms1.On("TheExampleMethod", 1, 2, 3).Maybe().Return(4, nil)
+	ms1.TheExampleMethod(1, 2, 3)
+
+	tt1 := new(testing.T)
+	assert.Equal(t, true, ms1.AssertExpectations(tt1))
+
+	// Optional not called
+	var ms2 = new(TestExampleImplementation)
+	ms2.On("TheExampleMethod", 1, 2, 3).Maybe().Return(4, nil)
+
+	tt2 := new(testing.T)
+	assert.Equal(t, true, ms2.AssertExpectations(tt2))
+
+	// Non-optional called
+	var ms3 = new(TestExampleImplementation)
+	ms3.On("TheExampleMethod", 1, 2, 3).Return(4, nil)
+	ms3.TheExampleMethod(1, 2, 3)
+
+	tt3 := new(testing.T)
+	assert.Equal(t, true, ms3.AssertExpectations(tt3))
+}
+
 /*
 	Arguments helper methods
 */
@@ -1028,8 +1188,8 @@ func Test_Arguments_Diff(t *testing.T) {
 	diff, count = args.Diff([]interface{}{"Hello World", 456, "false"})
 
 	assert.Equal(t, 2, count)
-	assert.Contains(t, diff, `%!s(int=456) != %!s(int=123)`)
-	assert.Contains(t, diff, `false != %!s(bool=true)`)
+	assert.Contains(t, diff, `(int=456) != (int=123)`)
+	assert.Contains(t, diff, `(string=false) != (bool=true)`)
 
 }
 
@@ -1041,7 +1201,7 @@ func Test_Arguments_Diff_DifferentNumberOfArgs(t *testing.T) {
 	diff, count = args.Diff([]interface{}{"string", 456, "false", "extra"})
 
 	assert.Equal(t, 3, count)
-	assert.Contains(t, diff, `extra != (Missing)`)
+	assert.Contains(t, diff, `(string=extra) != (Missing)`)
 
 }
 
@@ -1083,7 +1243,7 @@ func Test_Arguments_Diff_WithAnythingOfTypeArgument_Failing(t *testing.T) {
 	diff, count = args.Diff([]interface{}{"string", 123, true})
 
 	assert.Equal(t, 1, count)
-	assert.Contains(t, diff, `string != type int - %!s(int=123)`)
+	assert.Contains(t, diff, `string != type int - (int=123)`)
 
 }
 
@@ -1095,14 +1255,14 @@ func Test_Arguments_Diff_WithArgMatcher(t *testing.T) {
 
 	diff, count := args.Diff([]interface{}{"string", 124, true})
 	assert.Equal(t, 1, count)
-	assert.Contains(t, diff, `%!s(int=124) not matched by func(int) bool`)
+	assert.Contains(t, diff, `(int=124) not matched by func(int) bool`)
 
 	diff, count = args.Diff([]interface{}{"string", false, true})
 	assert.Equal(t, 1, count)
-	assert.Contains(t, diff, `%!s(bool=false) not matched by func(int) bool`)
+	assert.Contains(t, diff, `(bool=false) not matched by func(int) bool`)
 
 	diff, count = args.Diff([]interface{}{"string", 123, false})
-	assert.Contains(t, diff, `%!s(int=123) matched by func(int) bool`)
+	assert.Contains(t, diff, `(int=123) matched by func(int) bool`)
 
 	diff, count = args.Diff([]interface{}{"string", 123, true})
 	assert.Equal(t, 0, count)
@@ -1163,7 +1323,7 @@ func Test_Arguments_Bool(t *testing.T) {
 func Test_WaitUntil_Parallel(t *testing.T) {
 
 	// make a test impl object
-	var mockedService *TestExampleImplementation = new(TestExampleImplementation)
+	var mockedService = new(TestExampleImplementation)
 
 	ch1 := make(chan time.Time)
 	ch2 := make(chan time.Time)
@@ -1195,3 +1355,145 @@ func Test_MockMethodCalled(t *testing.T) {
 	require.Equal(t, "world", retArgs[0])
 	m.AssertExpectations(t)
 }
+
+// Test to validate fix for racy concurrent call access in MethodCalled()
+func Test_MockReturnAndCalledConcurrent(t *testing.T) {
+	iterations := 1000
+	m := &Mock{}
+	call := m.On("ConcurrencyTestMethod")
+
+	wg := sync.WaitGroup{}
+	wg.Add(2)
+
+	go func() {
+		for i := 0; i < iterations; i++ {
+			call.Return(10)
+		}
+		wg.Done()
+	}()
+	go func() {
+		for i := 0; i < iterations; i++ {
+			ConcurrencyTestMethod(m)
+		}
+		wg.Done()
+	}()
+	wg.Wait()
+}
+
+type timer struct{ Mock }
+
+func (s *timer) GetTime(i int) string {
+	return s.Called(i).Get(0).(string)
+}
+
+type tCustomLogger struct {
+	*testing.T
+	logs []string
+	errs []string
+}
+
+func (tc *tCustomLogger) Logf(format string, args ...interface{}) {
+	tc.T.Logf(format, args...)
+	tc.logs = append(tc.logs, fmt.Sprintf(format, args...))
+}
+
+func (tc *tCustomLogger) Errorf(format string, args ...interface{}) {
+	tc.errs = append(tc.errs, fmt.Sprintf(format, args...))
+}
+
+func (tc *tCustomLogger) FailNow() {}
+
+func TestLoggingAssertExpectations(t *testing.T) {
+	m := new(timer)
+	m.On("GetTime", 0).Return("")
+	tcl := &tCustomLogger{t, []string{}, []string{}}
+
+	AssertExpectationsForObjects(tcl, m, new(TestExampleImplementation))
+
+	require.Equal(t, 1, len(tcl.errs))
+	assert.Regexp(t, regexp.MustCompile("(?s)FAIL: 0 out of 1 expectation\\(s\\) were met.*The code you are testing needs to make 1 more call\\(s\\).*"), tcl.errs[0])
+	require.Equal(t, 2, len(tcl.logs))
+	assert.Regexp(t, regexp.MustCompile("(?s)FAIL:\tGetTime\\(int\\).*"), tcl.logs[0])
+	require.Equal(t, "Expectations didn't match for Mock: *mock.timer", tcl.logs[1])
+}
+
+func TestAfterTotalWaitTimeWhileExecution(t *testing.T) {
+	waitDuration := 1
+	total, waitMs := 5, time.Millisecond*time.Duration(waitDuration)
+	aTimer := new(timer)
+	for i := 0; i < total; i++ {
+		aTimer.On("GetTime", i).After(waitMs).Return(fmt.Sprintf("Time%d", i)).Once()
+	}
+	time.Sleep(waitMs)
+	start := time.Now()
+	var results []string
+
+	for i := 0; i < total; i++ {
+		results = append(results, aTimer.GetTime(i))
+	}
+
+	end := time.Now()
+	elapsedTime := end.Sub(start)
+	assert.True(t, elapsedTime > waitMs, fmt.Sprintf("Total elapsed time:%v should be atleast greater than %v", elapsedTime, waitMs))
+	assert.Equal(t, total, len(results))
+	for i := range results {
+		assert.Equal(t, fmt.Sprintf("Time%d", i), results[i], "Return value of method should be same")
+	}
+}
+
+func TestArgumentMatcherToPrintMismatch(t *testing.T) {
+	defer func() {
+		if r := recover(); r != nil {
+			matchingExp := regexp.MustCompile(
+				`\s+mock: Unexpected Method Call\s+-*\s+GetTime\(int\)\s+0: 1\s+The closest call I have is:\s+GetTime\(mock.argumentMatcher\)\s+0: mock.argumentMatcher\{.*?\}\s+Diff:.*\(int=1\) not matched by func\(int\) bool`)
+			assert.Regexp(t, matchingExp, r)
+		}
+	}()
+
+	m := new(timer)
+	m.On("GetTime", MatchedBy(func(i int) bool { return false })).Return("SomeTime").Once()
+
+	res := m.GetTime(1)
+	require.Equal(t, "SomeTime", res)
+	m.AssertExpectations(t)
+}
+
+func TestClosestCallMismatchedArgumentInformationShowsTheClosest(t *testing.T) {
+	defer func() {
+		if r := recover(); r != nil {
+			matchingExp := regexp.MustCompile(unexpectedCallRegex(`TheExampleMethod(int,int,int)`, `0: 1\s+1: 1\s+2: 2`, `0: 1\s+1: 1\s+2: 1`, `0: PASS:  \(int=1\) == \(int=1\)\s+1: PASS:  \(int=1\) == \(int=1\)\s+2: FAIL:  \(int=2\) != \(int=1\)`))
+			assert.Regexp(t, matchingExp, r)
+		}
+	}()
+
+	m := new(TestExampleImplementation)
+	m.On("TheExampleMethod", 1, 1, 1).Return(1, nil).Once()
+	m.On("TheExampleMethod", 2, 2, 2).Return(2, nil).Once()
+
+	m.TheExampleMethod(1, 1, 2)
+}
+
+func TestClosestCallMismatchedArgumentValueInformation(t *testing.T) {
+	defer func() {
+		if r := recover(); r != nil {
+			matchingExp := regexp.MustCompile(unexpectedCallRegex(`GetTime(int)`, "0: 1", "0: 999", `0: FAIL:  \(int=1\) != \(int=999\)`))
+			assert.Regexp(t, matchingExp, r)
+		}
+	}()
+
+	m := new(timer)
+	m.On("GetTime", 999).Return("SomeTime").Once()
+
+	_ = m.GetTime(1)
+}
+
+func unexpectedCallRegex(method, calledArg, expectedArg, diff string) string {
+	rMethod := regexp.QuoteMeta(method)
+	return fmt.Sprintf(`\s+mock: Unexpected Method Call\s+-*\s+%s\s+%s\s+The closest call I have is:\s+%s\s+%s\s+Diff: %s`,
+		rMethod, calledArg, rMethod, expectedArg, diff)
+}
+
+//go:noinline
+func ConcurrencyTestMethod(m *Mock) {
+	m.Called()
+}
diff --git a/vendor/github.com/stretchr/testify/require/require.go b/vendor/github.com/stretchr/testify/require/require.go
index 2fe05578464494ce43044892ea866902144824f9..535f293490ce97e9ee271793c00ff56935e07e24 100644
--- a/vendor/github.com/stretchr/testify/require/require.go
+++ b/vendor/github.com/stretchr/testify/require/require.go
@@ -14,16 +14,24 @@ import (
 
 // Condition uses a Comparison to assert a complex condition.
 func Condition(t TestingT, comp assert.Comparison, msgAndArgs ...interface{}) {
-	if !assert.Condition(t, comp, msgAndArgs...) {
-		t.FailNow()
+	if assert.Condition(t, comp, msgAndArgs...) {
+		return
 	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	t.FailNow()
 }
 
 // Conditionf uses a Comparison to assert a complex condition.
 func Conditionf(t TestingT, comp assert.Comparison, msg string, args ...interface{}) {
-	if !assert.Conditionf(t, comp, msg, args...) {
-		t.FailNow()
+	if assert.Conditionf(t, comp, msg, args...) {
+		return
+	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
 	}
+	t.FailNow()
 }
 
 // Contains asserts that the specified string, list(array, slice...) or map contains the
@@ -32,12 +40,14 @@ func Conditionf(t TestingT, comp assert.Comparison, msg string, args ...interfac
 //    assert.Contains(t, "Hello World", "World")
 //    assert.Contains(t, ["Hello", "World"], "World")
 //    assert.Contains(t, {"Hello": "World"}, "Hello")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func Contains(t TestingT, s interface{}, contains interface{}, msgAndArgs ...interface{}) {
-	if !assert.Contains(t, s, contains, msgAndArgs...) {
-		t.FailNow()
+	if assert.Contains(t, s, contains, msgAndArgs...) {
+		return
 	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	t.FailNow()
 }
 
 // Containsf asserts that the specified string, list(array, slice...) or map contains the
@@ -46,51 +56,111 @@ func Contains(t TestingT, s interface{}, contains interface{}, msgAndArgs ...int
 //    assert.Containsf(t, "Hello World", "World", "error message %s", "formatted")
 //    assert.Containsf(t, ["Hello", "World"], "World", "error message %s", "formatted")
 //    assert.Containsf(t, {"Hello": "World"}, "Hello", "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func Containsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) {
-	if !assert.Containsf(t, s, contains, msg, args...) {
-		t.FailNow()
+	if assert.Containsf(t, s, contains, msg, args...) {
+		return
+	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	t.FailNow()
+}
+
+// DirExists checks whether a directory exists in the given path. It also fails if the path is a file rather a directory or there is an error checking whether it exists.
+func DirExists(t TestingT, path string, msgAndArgs ...interface{}) {
+	if assert.DirExists(t, path, msgAndArgs...) {
+		return
+	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	t.FailNow()
+}
+
+// DirExistsf checks whether a directory exists in the given path. It also fails if the path is a file rather a directory or there is an error checking whether it exists.
+func DirExistsf(t TestingT, path string, msg string, args ...interface{}) {
+	if assert.DirExistsf(t, path, msg, args...) {
+		return
+	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	t.FailNow()
+}
+
+// ElementsMatch asserts that the specified listA(array, slice...) is equal to specified
+// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements,
+// the number of appearances of each of them in both lists should match.
+//
+// assert.ElementsMatch(t, [1, 3, 2, 3], [1, 3, 3, 2])
+func ElementsMatch(t TestingT, listA interface{}, listB interface{}, msgAndArgs ...interface{}) {
+	if assert.ElementsMatch(t, listA, listB, msgAndArgs...) {
+		return
+	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
 	}
+	t.FailNow()
+}
+
+// ElementsMatchf asserts that the specified listA(array, slice...) is equal to specified
+// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements,
+// the number of appearances of each of them in both lists should match.
+//
+// assert.ElementsMatchf(t, [1, 3, 2, 3], [1, 3, 3, 2], "error message %s", "formatted")
+func ElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg string, args ...interface{}) {
+	if assert.ElementsMatchf(t, listA, listB, msg, args...) {
+		return
+	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	t.FailNow()
 }
 
 // Empty asserts that the specified object is empty.  I.e. nil, "", false, 0 or either
 // a slice or a channel with len == 0.
 //
 //  assert.Empty(t, obj)
-//
-// Returns whether the assertion was successful (true) or not (false).
 func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) {
-	if !assert.Empty(t, object, msgAndArgs...) {
-		t.FailNow()
+	if assert.Empty(t, object, msgAndArgs...) {
+		return
 	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	t.FailNow()
 }
 
 // Emptyf asserts that the specified object is empty.  I.e. nil, "", false, 0 or either
 // a slice or a channel with len == 0.
 //
 //  assert.Emptyf(t, obj, "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func Emptyf(t TestingT, object interface{}, msg string, args ...interface{}) {
-	if !assert.Emptyf(t, object, msg, args...) {
-		t.FailNow()
+	if assert.Emptyf(t, object, msg, args...) {
+		return
+	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
 	}
+	t.FailNow()
 }
 
 // Equal asserts that two objects are equal.
 //
 //    assert.Equal(t, 123, 123)
 //
-// Returns whether the assertion was successful (true) or not (false).
-//
 // Pointer variable equality is determined based on the equality of the
 // referenced values (as opposed to the memory addresses). Function equality
 // cannot be determined and will always fail.
 func Equal(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) {
-	if !assert.Equal(t, expected, actual, msgAndArgs...) {
-		t.FailNow()
+	if assert.Equal(t, expected, actual, msgAndArgs...) {
+		return
+	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
 	}
+	t.FailNow()
 }
 
 // EqualError asserts that a function returned an error (i.e. not `nil`)
@@ -98,12 +168,14 @@ func Equal(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...i
 //
 //   actualObj, err := SomeFunction()
 //   assert.EqualError(t, err,  expectedErrorString)
-//
-// Returns whether the assertion was successful (true) or not (false).
 func EqualError(t TestingT, theError error, errString string, msgAndArgs ...interface{}) {
-	if !assert.EqualError(t, theError, errString, msgAndArgs...) {
-		t.FailNow()
+	if assert.EqualError(t, theError, errString, msgAndArgs...) {
+		return
 	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	t.FailNow()
 }
 
 // EqualErrorf asserts that a function returned an error (i.e. not `nil`)
@@ -111,51 +183,59 @@ func EqualError(t TestingT, theError error, errString string, msgAndArgs ...inte
 //
 //   actualObj, err := SomeFunction()
 //   assert.EqualErrorf(t, err,  expectedErrorString, "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func EqualErrorf(t TestingT, theError error, errString string, msg string, args ...interface{}) {
-	if !assert.EqualErrorf(t, theError, errString, msg, args...) {
-		t.FailNow()
+	if assert.EqualErrorf(t, theError, errString, msg, args...) {
+		return
+	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
 	}
+	t.FailNow()
 }
 
 // EqualValues asserts that two objects are equal or convertable to the same types
 // and equal.
 //
 //    assert.EqualValues(t, uint32(123), int32(123))
-//
-// Returns whether the assertion was successful (true) or not (false).
 func EqualValues(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) {
-	if !assert.EqualValues(t, expected, actual, msgAndArgs...) {
-		t.FailNow()
+	if assert.EqualValues(t, expected, actual, msgAndArgs...) {
+		return
+	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
 	}
+	t.FailNow()
 }
 
 // EqualValuesf asserts that two objects are equal or convertable to the same types
 // and equal.
 //
 //    assert.EqualValuesf(t, uint32(123, "error message %s", "formatted"), int32(123))
-//
-// Returns whether the assertion was successful (true) or not (false).
 func EqualValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) {
-	if !assert.EqualValuesf(t, expected, actual, msg, args...) {
-		t.FailNow()
+	if assert.EqualValuesf(t, expected, actual, msg, args...) {
+		return
 	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	t.FailNow()
 }
 
 // Equalf asserts that two objects are equal.
 //
 //    assert.Equalf(t, 123, 123, "error message %s", "formatted")
 //
-// Returns whether the assertion was successful (true) or not (false).
-//
 // Pointer variable equality is determined based on the equality of the
 // referenced values (as opposed to the memory addresses). Function equality
 // cannot be determined and will always fail.
 func Equalf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) {
-	if !assert.Equalf(t, expected, actual, msg, args...) {
-		t.FailNow()
+	if assert.Equalf(t, expected, actual, msg, args...) {
+		return
 	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	t.FailNow()
 }
 
 // Error asserts that a function returned an error (i.e. not `nil`).
@@ -164,12 +244,14 @@ func Equalf(t TestingT, expected interface{}, actual interface{}, msg string, ar
 //   if assert.Error(t, err) {
 // 	   assert.Equal(t, expectedError, err)
 //   }
-//
-// Returns whether the assertion was successful (true) or not (false).
 func Error(t TestingT, err error, msgAndArgs ...interface{}) {
-	if !assert.Error(t, err, msgAndArgs...) {
-		t.FailNow()
+	if assert.Error(t, err, msgAndArgs...) {
+		return
+	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
 	}
+	t.FailNow()
 }
 
 // Errorf asserts that a function returned an error (i.e. not `nil`).
@@ -178,132 +260,196 @@ func Error(t TestingT, err error, msgAndArgs ...interface{}) {
 //   if assert.Errorf(t, err, "error message %s", "formatted") {
 // 	   assert.Equal(t, expectedErrorf, err)
 //   }
-//
-// Returns whether the assertion was successful (true) or not (false).
 func Errorf(t TestingT, err error, msg string, args ...interface{}) {
-	if !assert.Errorf(t, err, msg, args...) {
-		t.FailNow()
+	if assert.Errorf(t, err, msg, args...) {
+		return
+	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
 	}
+	t.FailNow()
 }
 
-// Exactly asserts that two objects are equal is value and type.
+// Exactly asserts that two objects are equal in value and type.
 //
 //    assert.Exactly(t, int32(123), int64(123))
-//
-// Returns whether the assertion was successful (true) or not (false).
 func Exactly(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) {
-	if !assert.Exactly(t, expected, actual, msgAndArgs...) {
-		t.FailNow()
+	if assert.Exactly(t, expected, actual, msgAndArgs...) {
+		return
 	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	t.FailNow()
 }
 
-// Exactlyf asserts that two objects are equal is value and type.
+// Exactlyf asserts that two objects are equal in value and type.
 //
 //    assert.Exactlyf(t, int32(123, "error message %s", "formatted"), int64(123))
-//
-// Returns whether the assertion was successful (true) or not (false).
 func Exactlyf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) {
-	if !assert.Exactlyf(t, expected, actual, msg, args...) {
-		t.FailNow()
+	if assert.Exactlyf(t, expected, actual, msg, args...) {
+		return
+	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
 	}
+	t.FailNow()
 }
 
 // Fail reports a failure through
 func Fail(t TestingT, failureMessage string, msgAndArgs ...interface{}) {
-	if !assert.Fail(t, failureMessage, msgAndArgs...) {
-		t.FailNow()
+	if assert.Fail(t, failureMessage, msgAndArgs...) {
+		return
+	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
 	}
+	t.FailNow()
 }
 
 // FailNow fails test
 func FailNow(t TestingT, failureMessage string, msgAndArgs ...interface{}) {
-	if !assert.FailNow(t, failureMessage, msgAndArgs...) {
-		t.FailNow()
+	if assert.FailNow(t, failureMessage, msgAndArgs...) {
+		return
 	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	t.FailNow()
 }
 
 // FailNowf fails test
 func FailNowf(t TestingT, failureMessage string, msg string, args ...interface{}) {
-	if !assert.FailNowf(t, failureMessage, msg, args...) {
-		t.FailNow()
+	if assert.FailNowf(t, failureMessage, msg, args...) {
+		return
+	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
 	}
+	t.FailNow()
 }
 
 // Failf reports a failure through
 func Failf(t TestingT, failureMessage string, msg string, args ...interface{}) {
-	if !assert.Failf(t, failureMessage, msg, args...) {
-		t.FailNow()
+	if assert.Failf(t, failureMessage, msg, args...) {
+		return
 	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	t.FailNow()
 }
 
 // False asserts that the specified value is false.
 //
 //    assert.False(t, myBool)
-//
-// Returns whether the assertion was successful (true) or not (false).
 func False(t TestingT, value bool, msgAndArgs ...interface{}) {
-	if !assert.False(t, value, msgAndArgs...) {
-		t.FailNow()
+	if assert.False(t, value, msgAndArgs...) {
+		return
+	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
 	}
+	t.FailNow()
 }
 
 // Falsef asserts that the specified value is false.
 //
 //    assert.Falsef(t, myBool, "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func Falsef(t TestingT, value bool, msg string, args ...interface{}) {
-	if !assert.Falsef(t, value, msg, args...) {
-		t.FailNow()
+	if assert.Falsef(t, value, msg, args...) {
+		return
+	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	t.FailNow()
+}
+
+// FileExists checks whether a file exists in the given path. It also fails if the path points to a directory or there is an error when trying to check the file.
+func FileExists(t TestingT, path string, msgAndArgs ...interface{}) {
+	if assert.FileExists(t, path, msgAndArgs...) {
+		return
+	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	t.FailNow()
+}
+
+// FileExistsf checks whether a file exists in the given path. It also fails if the path points to a directory or there is an error when trying to check the file.
+func FileExistsf(t TestingT, path string, msg string, args ...interface{}) {
+	if assert.FileExistsf(t, path, msg, args...) {
+		return
 	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	t.FailNow()
 }
 
 // HTTPBodyContains asserts that a specified handler returns a
 // body that contains a string.
 //
-//  assert.HTTPBodyContains(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky")
+//  assert.HTTPBodyContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky")
 //
 // Returns whether the assertion was successful (true) or not (false).
-func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}) {
-	if !assert.HTTPBodyContains(t, handler, method, url, values, str) {
-		t.FailNow()
+func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) {
+	if assert.HTTPBodyContains(t, handler, method, url, values, str, msgAndArgs...) {
+		return
+	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
 	}
+	t.FailNow()
 }
 
 // HTTPBodyContainsf asserts that a specified handler returns a
 // body that contains a string.
 //
-//  assert.HTTPBodyContainsf(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted")
+//  assert.HTTPBodyContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted")
 //
 // Returns whether the assertion was successful (true) or not (false).
-func HTTPBodyContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}) {
-	if !assert.HTTPBodyContainsf(t, handler, method, url, values, str) {
-		t.FailNow()
+func HTTPBodyContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) {
+	if assert.HTTPBodyContainsf(t, handler, method, url, values, str, msg, args...) {
+		return
 	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	t.FailNow()
 }
 
 // HTTPBodyNotContains asserts that a specified handler returns a
 // body that does not contain a string.
 //
-//  assert.HTTPBodyNotContains(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky")
+//  assert.HTTPBodyNotContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky")
 //
 // Returns whether the assertion was successful (true) or not (false).
-func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}) {
-	if !assert.HTTPBodyNotContains(t, handler, method, url, values, str) {
-		t.FailNow()
+func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) {
+	if assert.HTTPBodyNotContains(t, handler, method, url, values, str, msgAndArgs...) {
+		return
+	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
 	}
+	t.FailNow()
 }
 
 // HTTPBodyNotContainsf asserts that a specified handler returns a
 // body that does not contain a string.
 //
-//  assert.HTTPBodyNotContainsf(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted")
+//  assert.HTTPBodyNotContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted")
 //
 // Returns whether the assertion was successful (true) or not (false).
-func HTTPBodyNotContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}) {
-	if !assert.HTTPBodyNotContainsf(t, handler, method, url, values, str) {
-		t.FailNow()
+func HTTPBodyNotContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) {
+	if assert.HTTPBodyNotContainsf(t, handler, method, url, values, str, msg, args...) {
+		return
+	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
 	}
+	t.FailNow()
 }
 
 // HTTPError asserts that a specified handler returns an error status code.
@@ -311,10 +457,14 @@ func HTTPBodyNotContainsf(t TestingT, handler http.HandlerFunc, method string, u
 //  assert.HTTPError(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}}
 //
 // Returns whether the assertion was successful (true) or not (false).
-func HTTPError(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values) {
-	if !assert.HTTPError(t, handler, method, url, values) {
-		t.FailNow()
+func HTTPError(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) {
+	if assert.HTTPError(t, handler, method, url, values, msgAndArgs...) {
+		return
 	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	t.FailNow()
 }
 
 // HTTPErrorf asserts that a specified handler returns an error status code.
@@ -322,10 +472,14 @@ func HTTPError(t TestingT, handler http.HandlerFunc, method string, url string,
 //  assert.HTTPErrorf(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}}
 //
 // Returns whether the assertion was successful (true, "error message %s", "formatted") or not (false).
-func HTTPErrorf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values) {
-	if !assert.HTTPErrorf(t, handler, method, url, values) {
-		t.FailNow()
+func HTTPErrorf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) {
+	if assert.HTTPErrorf(t, handler, method, url, values, msg, args...) {
+		return
+	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
 	}
+	t.FailNow()
 }
 
 // HTTPRedirect asserts that a specified handler returns a redirect status code.
@@ -333,10 +487,14 @@ func HTTPErrorf(t TestingT, handler http.HandlerFunc, method string, url string,
 //  assert.HTTPRedirect(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}}
 //
 // Returns whether the assertion was successful (true) or not (false).
-func HTTPRedirect(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values) {
-	if !assert.HTTPRedirect(t, handler, method, url, values) {
-		t.FailNow()
+func HTTPRedirect(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) {
+	if assert.HTTPRedirect(t, handler, method, url, values, msgAndArgs...) {
+		return
 	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	t.FailNow()
 }
 
 // HTTPRedirectf asserts that a specified handler returns a redirect status code.
@@ -344,10 +502,14 @@ func HTTPRedirect(t TestingT, handler http.HandlerFunc, method string, url strin
 //  assert.HTTPRedirectf(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}}
 //
 // Returns whether the assertion was successful (true, "error message %s", "formatted") or not (false).
-func HTTPRedirectf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values) {
-	if !assert.HTTPRedirectf(t, handler, method, url, values) {
-		t.FailNow()
+func HTTPRedirectf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) {
+	if assert.HTTPRedirectf(t, handler, method, url, values, msg, args...) {
+		return
+	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
 	}
+	t.FailNow()
 }
 
 // HTTPSuccess asserts that a specified handler returns a success status code.
@@ -355,10 +517,14 @@ func HTTPRedirectf(t TestingT, handler http.HandlerFunc, method string, url stri
 //  assert.HTTPSuccess(t, myHandler, "POST", "http://www.google.com", nil)
 //
 // Returns whether the assertion was successful (true) or not (false).
-func HTTPSuccess(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values) {
-	if !assert.HTTPSuccess(t, handler, method, url, values) {
-		t.FailNow()
+func HTTPSuccess(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) {
+	if assert.HTTPSuccess(t, handler, method, url, values, msgAndArgs...) {
+		return
 	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	t.FailNow()
 }
 
 // HTTPSuccessf asserts that a specified handler returns a success status code.
@@ -366,178 +532,256 @@ func HTTPSuccess(t TestingT, handler http.HandlerFunc, method string, url string
 //  assert.HTTPSuccessf(t, myHandler, "POST", "http://www.google.com", nil, "error message %s", "formatted")
 //
 // Returns whether the assertion was successful (true) or not (false).
-func HTTPSuccessf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values) {
-	if !assert.HTTPSuccessf(t, handler, method, url, values) {
-		t.FailNow()
+func HTTPSuccessf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) {
+	if assert.HTTPSuccessf(t, handler, method, url, values, msg, args...) {
+		return
+	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
 	}
+	t.FailNow()
 }
 
 // Implements asserts that an object is implemented by the specified interface.
 //
 //    assert.Implements(t, (*MyInterface)(nil), new(MyObject))
 func Implements(t TestingT, interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) {
-	if !assert.Implements(t, interfaceObject, object, msgAndArgs...) {
-		t.FailNow()
+	if assert.Implements(t, interfaceObject, object, msgAndArgs...) {
+		return
+	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
 	}
+	t.FailNow()
 }
 
 // Implementsf asserts that an object is implemented by the specified interface.
 //
 //    assert.Implementsf(t, (*MyInterface, "error message %s", "formatted")(nil), new(MyObject))
 func Implementsf(t TestingT, interfaceObject interface{}, object interface{}, msg string, args ...interface{}) {
-	if !assert.Implementsf(t, interfaceObject, object, msg, args...) {
-		t.FailNow()
+	if assert.Implementsf(t, interfaceObject, object, msg, args...) {
+		return
 	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	t.FailNow()
 }
 
 // InDelta asserts that the two numerals are within delta of each other.
 //
 // 	 assert.InDelta(t, math.Pi, (22 / 7.0), 0.01)
-//
-// Returns whether the assertion was successful (true) or not (false).
 func InDelta(t TestingT, expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) {
-	if !assert.InDelta(t, expected, actual, delta, msgAndArgs...) {
-		t.FailNow()
+	if assert.InDelta(t, expected, actual, delta, msgAndArgs...) {
+		return
+	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	t.FailNow()
+}
+
+// InDeltaMapValues is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys.
+func InDeltaMapValues(t TestingT, expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) {
+	if assert.InDeltaMapValues(t, expected, actual, delta, msgAndArgs...) {
+		return
 	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	t.FailNow()
+}
+
+// InDeltaMapValuesf is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys.
+func InDeltaMapValuesf(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) {
+	if assert.InDeltaMapValuesf(t, expected, actual, delta, msg, args...) {
+		return
+	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	t.FailNow()
 }
 
 // InDeltaSlice is the same as InDelta, except it compares two slices.
 func InDeltaSlice(t TestingT, expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) {
-	if !assert.InDeltaSlice(t, expected, actual, delta, msgAndArgs...) {
-		t.FailNow()
+	if assert.InDeltaSlice(t, expected, actual, delta, msgAndArgs...) {
+		return
+	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
 	}
+	t.FailNow()
 }
 
 // InDeltaSlicef is the same as InDelta, except it compares two slices.
 func InDeltaSlicef(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) {
-	if !assert.InDeltaSlicef(t, expected, actual, delta, msg, args...) {
-		t.FailNow()
+	if assert.InDeltaSlicef(t, expected, actual, delta, msg, args...) {
+		return
+	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
 	}
+	t.FailNow()
 }
 
 // InDeltaf asserts that the two numerals are within delta of each other.
 //
 // 	 assert.InDeltaf(t, math.Pi, (22 / 7.0, "error message %s", "formatted"), 0.01)
-//
-// Returns whether the assertion was successful (true) or not (false).
 func InDeltaf(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) {
-	if !assert.InDeltaf(t, expected, actual, delta, msg, args...) {
-		t.FailNow()
+	if assert.InDeltaf(t, expected, actual, delta, msg, args...) {
+		return
 	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	t.FailNow()
 }
 
 // InEpsilon asserts that expected and actual have a relative error less than epsilon
-//
-// Returns whether the assertion was successful (true) or not (false).
 func InEpsilon(t TestingT, expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) {
-	if !assert.InEpsilon(t, expected, actual, epsilon, msgAndArgs...) {
-		t.FailNow()
+	if assert.InEpsilon(t, expected, actual, epsilon, msgAndArgs...) {
+		return
+	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
 	}
+	t.FailNow()
 }
 
 // InEpsilonSlice is the same as InEpsilon, except it compares each value from two slices.
 func InEpsilonSlice(t TestingT, expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) {
-	if !assert.InEpsilonSlice(t, expected, actual, epsilon, msgAndArgs...) {
-		t.FailNow()
+	if assert.InEpsilonSlice(t, expected, actual, epsilon, msgAndArgs...) {
+		return
+	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
 	}
+	t.FailNow()
 }
 
 // InEpsilonSlicef is the same as InEpsilon, except it compares each value from two slices.
 func InEpsilonSlicef(t TestingT, expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) {
-	if !assert.InEpsilonSlicef(t, expected, actual, epsilon, msg, args...) {
-		t.FailNow()
+	if assert.InEpsilonSlicef(t, expected, actual, epsilon, msg, args...) {
+		return
 	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	t.FailNow()
 }
 
 // InEpsilonf asserts that expected and actual have a relative error less than epsilon
-//
-// Returns whether the assertion was successful (true) or not (false).
 func InEpsilonf(t TestingT, expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) {
-	if !assert.InEpsilonf(t, expected, actual, epsilon, msg, args...) {
-		t.FailNow()
+	if assert.InEpsilonf(t, expected, actual, epsilon, msg, args...) {
+		return
+	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
 	}
+	t.FailNow()
 }
 
 // IsType asserts that the specified objects are of the same type.
 func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs ...interface{}) {
-	if !assert.IsType(t, expectedType, object, msgAndArgs...) {
-		t.FailNow()
+	if assert.IsType(t, expectedType, object, msgAndArgs...) {
+		return
 	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	t.FailNow()
 }
 
 // IsTypef asserts that the specified objects are of the same type.
 func IsTypef(t TestingT, expectedType interface{}, object interface{}, msg string, args ...interface{}) {
-	if !assert.IsTypef(t, expectedType, object, msg, args...) {
-		t.FailNow()
+	if assert.IsTypef(t, expectedType, object, msg, args...) {
+		return
+	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
 	}
+	t.FailNow()
 }
 
 // JSONEq asserts that two JSON strings are equivalent.
 //
 //  assert.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`)
-//
-// Returns whether the assertion was successful (true) or not (false).
 func JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) {
-	if !assert.JSONEq(t, expected, actual, msgAndArgs...) {
-		t.FailNow()
+	if assert.JSONEq(t, expected, actual, msgAndArgs...) {
+		return
+	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
 	}
+	t.FailNow()
 }
 
 // JSONEqf asserts that two JSON strings are equivalent.
 //
 //  assert.JSONEqf(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`, "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func JSONEqf(t TestingT, expected string, actual string, msg string, args ...interface{}) {
-	if !assert.JSONEqf(t, expected, actual, msg, args...) {
-		t.FailNow()
+	if assert.JSONEqf(t, expected, actual, msg, args...) {
+		return
 	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	t.FailNow()
 }
 
 // Len asserts that the specified object has specific length.
 // Len also fails if the object has a type that len() not accept.
 //
 //    assert.Len(t, mySlice, 3)
-//
-// Returns whether the assertion was successful (true) or not (false).
 func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) {
-	if !assert.Len(t, object, length, msgAndArgs...) {
-		t.FailNow()
+	if assert.Len(t, object, length, msgAndArgs...) {
+		return
 	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	t.FailNow()
 }
 
 // Lenf asserts that the specified object has specific length.
 // Lenf also fails if the object has a type that len() not accept.
 //
 //    assert.Lenf(t, mySlice, 3, "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func Lenf(t TestingT, object interface{}, length int, msg string, args ...interface{}) {
-	if !assert.Lenf(t, object, length, msg, args...) {
-		t.FailNow()
+	if assert.Lenf(t, object, length, msg, args...) {
+		return
+	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
 	}
+	t.FailNow()
 }
 
 // Nil asserts that the specified object is nil.
 //
 //    assert.Nil(t, err)
-//
-// Returns whether the assertion was successful (true) or not (false).
 func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) {
-	if !assert.Nil(t, object, msgAndArgs...) {
-		t.FailNow()
+	if assert.Nil(t, object, msgAndArgs...) {
+		return
+	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
 	}
+	t.FailNow()
 }
 
 // Nilf asserts that the specified object is nil.
 //
 //    assert.Nilf(t, err, "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func Nilf(t TestingT, object interface{}, msg string, args ...interface{}) {
-	if !assert.Nilf(t, object, msg, args...) {
-		t.FailNow()
+	if assert.Nilf(t, object, msg, args...) {
+		return
 	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	t.FailNow()
 }
 
 // NoError asserts that a function returned no error (i.e. `nil`).
@@ -546,12 +790,14 @@ func Nilf(t TestingT, object interface{}, msg string, args ...interface{}) {
 //   if assert.NoError(t, err) {
 // 	   assert.Equal(t, expectedObj, actualObj)
 //   }
-//
-// Returns whether the assertion was successful (true) or not (false).
 func NoError(t TestingT, err error, msgAndArgs ...interface{}) {
-	if !assert.NoError(t, err, msgAndArgs...) {
-		t.FailNow()
+	if assert.NoError(t, err, msgAndArgs...) {
+		return
+	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
 	}
+	t.FailNow()
 }
 
 // NoErrorf asserts that a function returned no error (i.e. `nil`).
@@ -560,12 +806,14 @@ func NoError(t TestingT, err error, msgAndArgs ...interface{}) {
 //   if assert.NoErrorf(t, err, "error message %s", "formatted") {
 // 	   assert.Equal(t, expectedObj, actualObj)
 //   }
-//
-// Returns whether the assertion was successful (true) or not (false).
 func NoErrorf(t TestingT, err error, msg string, args ...interface{}) {
-	if !assert.NoErrorf(t, err, msg, args...) {
-		t.FailNow()
+	if assert.NoErrorf(t, err, msg, args...) {
+		return
+	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
 	}
+	t.FailNow()
 }
 
 // NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the
@@ -574,12 +822,14 @@ func NoErrorf(t TestingT, err error, msg string, args ...interface{}) {
 //    assert.NotContains(t, "Hello World", "Earth")
 //    assert.NotContains(t, ["Hello", "World"], "Earth")
 //    assert.NotContains(t, {"Hello": "World"}, "Earth")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func NotContains(t TestingT, s interface{}, contains interface{}, msgAndArgs ...interface{}) {
-	if !assert.NotContains(t, s, contains, msgAndArgs...) {
-		t.FailNow()
+	if assert.NotContains(t, s, contains, msgAndArgs...) {
+		return
 	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	t.FailNow()
 }
 
 // NotContainsf asserts that the specified string, list(array, slice...) or map does NOT contain the
@@ -588,12 +838,14 @@ func NotContains(t TestingT, s interface{}, contains interface{}, msgAndArgs ...
 //    assert.NotContainsf(t, "Hello World", "Earth", "error message %s", "formatted")
 //    assert.NotContainsf(t, ["Hello", "World"], "Earth", "error message %s", "formatted")
 //    assert.NotContainsf(t, {"Hello": "World"}, "Earth", "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func NotContainsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) {
-	if !assert.NotContainsf(t, s, contains, msg, args...) {
-		t.FailNow()
+	if assert.NotContainsf(t, s, contains, msg, args...) {
+		return
 	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	t.FailNow()
 }
 
 // NotEmpty asserts that the specified object is NOT empty.  I.e. not nil, "", false, 0 or either
@@ -602,12 +854,14 @@ func NotContainsf(t TestingT, s interface{}, contains interface{}, msg string, a
 //  if assert.NotEmpty(t, obj) {
 //    assert.Equal(t, "two", obj[1])
 //  }
-//
-// Returns whether the assertion was successful (true) or not (false).
 func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) {
-	if !assert.NotEmpty(t, object, msgAndArgs...) {
-		t.FailNow()
+	if assert.NotEmpty(t, object, msgAndArgs...) {
+		return
+	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
 	}
+	t.FailNow()
 }
 
 // NotEmptyf asserts that the specified object is NOT empty.  I.e. not nil, "", false, 0 or either
@@ -616,296 +870,358 @@ func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) {
 //  if assert.NotEmptyf(t, obj, "error message %s", "formatted") {
 //    assert.Equal(t, "two", obj[1])
 //  }
-//
-// Returns whether the assertion was successful (true) or not (false).
 func NotEmptyf(t TestingT, object interface{}, msg string, args ...interface{}) {
-	if !assert.NotEmptyf(t, object, msg, args...) {
-		t.FailNow()
+	if assert.NotEmptyf(t, object, msg, args...) {
+		return
+	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
 	}
+	t.FailNow()
 }
 
 // NotEqual asserts that the specified values are NOT equal.
 //
 //    assert.NotEqual(t, obj1, obj2)
 //
-// Returns whether the assertion was successful (true) or not (false).
-//
 // Pointer variable equality is determined based on the equality of the
 // referenced values (as opposed to the memory addresses).
 func NotEqual(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) {
-	if !assert.NotEqual(t, expected, actual, msgAndArgs...) {
-		t.FailNow()
+	if assert.NotEqual(t, expected, actual, msgAndArgs...) {
+		return
 	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	t.FailNow()
 }
 
 // NotEqualf asserts that the specified values are NOT equal.
 //
 //    assert.NotEqualf(t, obj1, obj2, "error message %s", "formatted")
 //
-// Returns whether the assertion was successful (true) or not (false).
-//
 // Pointer variable equality is determined based on the equality of the
 // referenced values (as opposed to the memory addresses).
 func NotEqualf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) {
-	if !assert.NotEqualf(t, expected, actual, msg, args...) {
-		t.FailNow()
+	if assert.NotEqualf(t, expected, actual, msg, args...) {
+		return
+	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
 	}
+	t.FailNow()
 }
 
 // NotNil asserts that the specified object is not nil.
 //
 //    assert.NotNil(t, err)
-//
-// Returns whether the assertion was successful (true) or not (false).
 func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) {
-	if !assert.NotNil(t, object, msgAndArgs...) {
-		t.FailNow()
+	if assert.NotNil(t, object, msgAndArgs...) {
+		return
+	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
 	}
+	t.FailNow()
 }
 
 // NotNilf asserts that the specified object is not nil.
 //
 //    assert.NotNilf(t, err, "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func NotNilf(t TestingT, object interface{}, msg string, args ...interface{}) {
-	if !assert.NotNilf(t, object, msg, args...) {
-		t.FailNow()
+	if assert.NotNilf(t, object, msg, args...) {
+		return
 	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	t.FailNow()
 }
 
 // NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic.
 //
 //   assert.NotPanics(t, func(){ RemainCalm() })
-//
-// Returns whether the assertion was successful (true) or not (false).
 func NotPanics(t TestingT, f assert.PanicTestFunc, msgAndArgs ...interface{}) {
-	if !assert.NotPanics(t, f, msgAndArgs...) {
-		t.FailNow()
+	if assert.NotPanics(t, f, msgAndArgs...) {
+		return
 	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	t.FailNow()
 }
 
 // NotPanicsf asserts that the code inside the specified PanicTestFunc does NOT panic.
 //
 //   assert.NotPanicsf(t, func(){ RemainCalm() }, "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func NotPanicsf(t TestingT, f assert.PanicTestFunc, msg string, args ...interface{}) {
-	if !assert.NotPanicsf(t, f, msg, args...) {
-		t.FailNow()
+	if assert.NotPanicsf(t, f, msg, args...) {
+		return
+	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
 	}
+	t.FailNow()
 }
 
 // NotRegexp asserts that a specified regexp does not match a string.
 //
 //  assert.NotRegexp(t, regexp.MustCompile("starts"), "it's starting")
 //  assert.NotRegexp(t, "^start", "it's not starting")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) {
-	if !assert.NotRegexp(t, rx, str, msgAndArgs...) {
-		t.FailNow()
+	if assert.NotRegexp(t, rx, str, msgAndArgs...) {
+		return
+	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
 	}
+	t.FailNow()
 }
 
 // NotRegexpf asserts that a specified regexp does not match a string.
 //
 //  assert.NotRegexpf(t, regexp.MustCompile("starts", "error message %s", "formatted"), "it's starting")
 //  assert.NotRegexpf(t, "^start", "it's not starting", "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func NotRegexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...interface{}) {
-	if !assert.NotRegexpf(t, rx, str, msg, args...) {
-		t.FailNow()
+	if assert.NotRegexpf(t, rx, str, msg, args...) {
+		return
 	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	t.FailNow()
 }
 
 // NotSubset asserts that the specified list(array, slice...) contains not all
 // elements given in the specified subset(array, slice...).
 //
 //    assert.NotSubset(t, [1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func NotSubset(t TestingT, list interface{}, subset interface{}, msgAndArgs ...interface{}) {
-	if !assert.NotSubset(t, list, subset, msgAndArgs...) {
-		t.FailNow()
+	if assert.NotSubset(t, list, subset, msgAndArgs...) {
+		return
+	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
 	}
+	t.FailNow()
 }
 
 // NotSubsetf asserts that the specified list(array, slice...) contains not all
 // elements given in the specified subset(array, slice...).
 //
 //    assert.NotSubsetf(t, [1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]", "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func NotSubsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) {
-	if !assert.NotSubsetf(t, list, subset, msg, args...) {
-		t.FailNow()
+	if assert.NotSubsetf(t, list, subset, msg, args...) {
+		return
+	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
 	}
+	t.FailNow()
 }
 
-// NotZero asserts that i is not the zero value for its type and returns the truth.
+// NotZero asserts that i is not the zero value for its type.
 func NotZero(t TestingT, i interface{}, msgAndArgs ...interface{}) {
-	if !assert.NotZero(t, i, msgAndArgs...) {
-		t.FailNow()
+	if assert.NotZero(t, i, msgAndArgs...) {
+		return
 	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	t.FailNow()
 }
 
-// NotZerof asserts that i is not the zero value for its type and returns the truth.
+// NotZerof asserts that i is not the zero value for its type.
 func NotZerof(t TestingT, i interface{}, msg string, args ...interface{}) {
-	if !assert.NotZerof(t, i, msg, args...) {
-		t.FailNow()
+	if assert.NotZerof(t, i, msg, args...) {
+		return
+	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
 	}
+	t.FailNow()
 }
 
 // Panics asserts that the code inside the specified PanicTestFunc panics.
 //
 //   assert.Panics(t, func(){ GoCrazy() })
-//
-// Returns whether the assertion was successful (true) or not (false).
 func Panics(t TestingT, f assert.PanicTestFunc, msgAndArgs ...interface{}) {
-	if !assert.Panics(t, f, msgAndArgs...) {
-		t.FailNow()
+	if assert.Panics(t, f, msgAndArgs...) {
+		return
+	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
 	}
+	t.FailNow()
 }
 
 // PanicsWithValue asserts that the code inside the specified PanicTestFunc panics, and that
 // the recovered panic value equals the expected panic value.
 //
 //   assert.PanicsWithValue(t, "crazy error", func(){ GoCrazy() })
-//
-// Returns whether the assertion was successful (true) or not (false).
 func PanicsWithValue(t TestingT, expected interface{}, f assert.PanicTestFunc, msgAndArgs ...interface{}) {
-	if !assert.PanicsWithValue(t, expected, f, msgAndArgs...) {
-		t.FailNow()
+	if assert.PanicsWithValue(t, expected, f, msgAndArgs...) {
+		return
 	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	t.FailNow()
 }
 
 // PanicsWithValuef asserts that the code inside the specified PanicTestFunc panics, and that
 // the recovered panic value equals the expected panic value.
 //
 //   assert.PanicsWithValuef(t, "crazy error", func(){ GoCrazy() }, "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func PanicsWithValuef(t TestingT, expected interface{}, f assert.PanicTestFunc, msg string, args ...interface{}) {
-	if !assert.PanicsWithValuef(t, expected, f, msg, args...) {
-		t.FailNow()
+	if assert.PanicsWithValuef(t, expected, f, msg, args...) {
+		return
+	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
 	}
+	t.FailNow()
 }
 
 // Panicsf asserts that the code inside the specified PanicTestFunc panics.
 //
 //   assert.Panicsf(t, func(){ GoCrazy() }, "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func Panicsf(t TestingT, f assert.PanicTestFunc, msg string, args ...interface{}) {
-	if !assert.Panicsf(t, f, msg, args...) {
-		t.FailNow()
+	if assert.Panicsf(t, f, msg, args...) {
+		return
+	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
 	}
+	t.FailNow()
 }
 
 // Regexp asserts that a specified regexp matches a string.
 //
 //  assert.Regexp(t, regexp.MustCompile("start"), "it's starting")
 //  assert.Regexp(t, "start...$", "it's not starting")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) {
-	if !assert.Regexp(t, rx, str, msgAndArgs...) {
-		t.FailNow()
+	if assert.Regexp(t, rx, str, msgAndArgs...) {
+		return
 	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	t.FailNow()
 }
 
 // Regexpf asserts that a specified regexp matches a string.
 //
 //  assert.Regexpf(t, regexp.MustCompile("start", "error message %s", "formatted"), "it's starting")
 //  assert.Regexpf(t, "start...$", "it's not starting", "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func Regexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...interface{}) {
-	if !assert.Regexpf(t, rx, str, msg, args...) {
-		t.FailNow()
+	if assert.Regexpf(t, rx, str, msg, args...) {
+		return
 	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	t.FailNow()
 }
 
 // Subset asserts that the specified list(array, slice...) contains all
 // elements given in the specified subset(array, slice...).
 //
 //    assert.Subset(t, [1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func Subset(t TestingT, list interface{}, subset interface{}, msgAndArgs ...interface{}) {
-	if !assert.Subset(t, list, subset, msgAndArgs...) {
-		t.FailNow()
+	if assert.Subset(t, list, subset, msgAndArgs...) {
+		return
+	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
 	}
+	t.FailNow()
 }
 
 // Subsetf asserts that the specified list(array, slice...) contains all
 // elements given in the specified subset(array, slice...).
 //
 //    assert.Subsetf(t, [1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]", "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func Subsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) {
-	if !assert.Subsetf(t, list, subset, msg, args...) {
-		t.FailNow()
+	if assert.Subsetf(t, list, subset, msg, args...) {
+		return
+	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
 	}
+	t.FailNow()
 }
 
 // True asserts that the specified value is true.
 //
 //    assert.True(t, myBool)
-//
-// Returns whether the assertion was successful (true) or not (false).
 func True(t TestingT, value bool, msgAndArgs ...interface{}) {
-	if !assert.True(t, value, msgAndArgs...) {
-		t.FailNow()
+	if assert.True(t, value, msgAndArgs...) {
+		return
 	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	t.FailNow()
 }
 
 // Truef asserts that the specified value is true.
 //
 //    assert.Truef(t, myBool, "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func Truef(t TestingT, value bool, msg string, args ...interface{}) {
-	if !assert.Truef(t, value, msg, args...) {
-		t.FailNow()
+	if assert.Truef(t, value, msg, args...) {
+		return
+	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
 	}
+	t.FailNow()
 }
 
 // WithinDuration asserts that the two times are within duration delta of each other.
 //
 //   assert.WithinDuration(t, time.Now(), time.Now(), 10*time.Second)
-//
-// Returns whether the assertion was successful (true) or not (false).
 func WithinDuration(t TestingT, expected time.Time, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) {
-	if !assert.WithinDuration(t, expected, actual, delta, msgAndArgs...) {
-		t.FailNow()
+	if assert.WithinDuration(t, expected, actual, delta, msgAndArgs...) {
+		return
+	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
 	}
+	t.FailNow()
 }
 
 // WithinDurationf asserts that the two times are within duration delta of each other.
 //
 //   assert.WithinDurationf(t, time.Now(), time.Now(), 10*time.Second, "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func WithinDurationf(t TestingT, expected time.Time, actual time.Time, delta time.Duration, msg string, args ...interface{}) {
-	if !assert.WithinDurationf(t, expected, actual, delta, msg, args...) {
-		t.FailNow()
+	if assert.WithinDurationf(t, expected, actual, delta, msg, args...) {
+		return
 	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	t.FailNow()
 }
 
-// Zero asserts that i is the zero value for its type and returns the truth.
+// Zero asserts that i is the zero value for its type.
 func Zero(t TestingT, i interface{}, msgAndArgs ...interface{}) {
-	if !assert.Zero(t, i, msgAndArgs...) {
-		t.FailNow()
+	if assert.Zero(t, i, msgAndArgs...) {
+		return
+	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
 	}
+	t.FailNow()
 }
 
-// Zerof asserts that i is the zero value for its type and returns the truth.
+// Zerof asserts that i is the zero value for its type.
 func Zerof(t TestingT, i interface{}, msg string, args ...interface{}) {
-	if !assert.Zerof(t, i, msg, args...) {
-		t.FailNow()
+	if assert.Zerof(t, i, msg, args...) {
+		return
+	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
 	}
+	t.FailNow()
 }
diff --git a/vendor/github.com/stretchr/testify/require/require_forward.go b/vendor/github.com/stretchr/testify/require/require_forward.go
index c59c3c7b475e88b7198de7193905d53276762160..9fe41dbdc0cb15506d682bea563da92e5cc08f60 100644
--- a/vendor/github.com/stretchr/testify/require/require_forward.go
+++ b/vendor/github.com/stretchr/testify/require/require_forward.go
@@ -14,11 +14,17 @@ import (
 
 // Condition uses a Comparison to assert a complex condition.
 func (a *Assertions) Condition(comp assert.Comparison, msgAndArgs ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	Condition(a.t, comp, msgAndArgs...)
 }
 
 // Conditionf uses a Comparison to assert a complex condition.
 func (a *Assertions) Conditionf(comp assert.Comparison, msg string, args ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	Conditionf(a.t, comp, msg, args...)
 }
 
@@ -28,9 +34,10 @@ func (a *Assertions) Conditionf(comp assert.Comparison, msg string, args ...inte
 //    a.Contains("Hello World", "World")
 //    a.Contains(["Hello", "World"], "World")
 //    a.Contains({"Hello": "World"}, "Hello")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) Contains(s interface{}, contains interface{}, msgAndArgs ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	Contains(a.t, s, contains, msgAndArgs...)
 }
 
@@ -40,19 +47,61 @@ func (a *Assertions) Contains(s interface{}, contains interface{}, msgAndArgs ..
 //    a.Containsf("Hello World", "World", "error message %s", "formatted")
 //    a.Containsf(["Hello", "World"], "World", "error message %s", "formatted")
 //    a.Containsf({"Hello": "World"}, "Hello", "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) Containsf(s interface{}, contains interface{}, msg string, args ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	Containsf(a.t, s, contains, msg, args...)
 }
 
+// DirExists checks whether a directory exists in the given path. It also fails if the path is a file rather a directory or there is an error checking whether it exists.
+func (a *Assertions) DirExists(path string, msgAndArgs ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	DirExists(a.t, path, msgAndArgs...)
+}
+
+// DirExistsf checks whether a directory exists in the given path. It also fails if the path is a file rather a directory or there is an error checking whether it exists.
+func (a *Assertions) DirExistsf(path string, msg string, args ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	DirExistsf(a.t, path, msg, args...)
+}
+
+// ElementsMatch asserts that the specified listA(array, slice...) is equal to specified
+// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements,
+// the number of appearances of each of them in both lists should match.
+//
+// a.ElementsMatch([1, 3, 2, 3], [1, 3, 3, 2])
+func (a *Assertions) ElementsMatch(listA interface{}, listB interface{}, msgAndArgs ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	ElementsMatch(a.t, listA, listB, msgAndArgs...)
+}
+
+// ElementsMatchf asserts that the specified listA(array, slice...) is equal to specified
+// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements,
+// the number of appearances of each of them in both lists should match.
+//
+// a.ElementsMatchf([1, 3, 2, 3], [1, 3, 3, 2], "error message %s", "formatted")
+func (a *Assertions) ElementsMatchf(listA interface{}, listB interface{}, msg string, args ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	ElementsMatchf(a.t, listA, listB, msg, args...)
+}
+
 // Empty asserts that the specified object is empty.  I.e. nil, "", false, 0 or either
 // a slice or a channel with len == 0.
 //
 //  a.Empty(obj)
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) Empty(object interface{}, msgAndArgs ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	Empty(a.t, object, msgAndArgs...)
 }
 
@@ -60,9 +109,10 @@ func (a *Assertions) Empty(object interface{}, msgAndArgs ...interface{}) {
 // a slice or a channel with len == 0.
 //
 //  a.Emptyf(obj, "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) Emptyf(object interface{}, msg string, args ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	Emptyf(a.t, object, msg, args...)
 }
 
@@ -70,12 +120,13 @@ func (a *Assertions) Emptyf(object interface{}, msg string, args ...interface{})
 //
 //    a.Equal(123, 123)
 //
-// Returns whether the assertion was successful (true) or not (false).
-//
 // Pointer variable equality is determined based on the equality of the
 // referenced values (as opposed to the memory addresses). Function equality
 // cannot be determined and will always fail.
 func (a *Assertions) Equal(expected interface{}, actual interface{}, msgAndArgs ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	Equal(a.t, expected, actual, msgAndArgs...)
 }
 
@@ -84,9 +135,10 @@ func (a *Assertions) Equal(expected interface{}, actual interface{}, msgAndArgs
 //
 //   actualObj, err := SomeFunction()
 //   a.EqualError(err,  expectedErrorString)
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) EqualError(theError error, errString string, msgAndArgs ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	EqualError(a.t, theError, errString, msgAndArgs...)
 }
 
@@ -95,9 +147,10 @@ func (a *Assertions) EqualError(theError error, errString string, msgAndArgs ...
 //
 //   actualObj, err := SomeFunction()
 //   a.EqualErrorf(err,  expectedErrorString, "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) EqualErrorf(theError error, errString string, msg string, args ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	EqualErrorf(a.t, theError, errString, msg, args...)
 }
 
@@ -105,9 +158,10 @@ func (a *Assertions) EqualErrorf(theError error, errString string, msg string, a
 // and equal.
 //
 //    a.EqualValues(uint32(123), int32(123))
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) EqualValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	EqualValues(a.t, expected, actual, msgAndArgs...)
 }
 
@@ -115,9 +169,10 @@ func (a *Assertions) EqualValues(expected interface{}, actual interface{}, msgAn
 // and equal.
 //
 //    a.EqualValuesf(uint32(123, "error message %s", "formatted"), int32(123))
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) EqualValuesf(expected interface{}, actual interface{}, msg string, args ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	EqualValuesf(a.t, expected, actual, msg, args...)
 }
 
@@ -125,12 +180,13 @@ func (a *Assertions) EqualValuesf(expected interface{}, actual interface{}, msg
 //
 //    a.Equalf(123, 123, "error message %s", "formatted")
 //
-// Returns whether the assertion was successful (true) or not (false).
-//
 // Pointer variable equality is determined based on the equality of the
 // referenced values (as opposed to the memory addresses). Function equality
 // cannot be determined and will always fail.
 func (a *Assertions) Equalf(expected interface{}, actual interface{}, msg string, args ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	Equalf(a.t, expected, actual, msg, args...)
 }
 
@@ -140,9 +196,10 @@ func (a *Assertions) Equalf(expected interface{}, actual interface{}, msg string
 //   if a.Error(err) {
 // 	   assert.Equal(t, expectedError, err)
 //   }
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) Error(err error, msgAndArgs ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	Error(a.t, err, msgAndArgs...)
 }
 
@@ -152,106 +209,151 @@ func (a *Assertions) Error(err error, msgAndArgs ...interface{}) {
 //   if a.Errorf(err, "error message %s", "formatted") {
 // 	   assert.Equal(t, expectedErrorf, err)
 //   }
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) Errorf(err error, msg string, args ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	Errorf(a.t, err, msg, args...)
 }
 
-// Exactly asserts that two objects are equal is value and type.
+// Exactly asserts that two objects are equal in value and type.
 //
 //    a.Exactly(int32(123), int64(123))
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) Exactly(expected interface{}, actual interface{}, msgAndArgs ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	Exactly(a.t, expected, actual, msgAndArgs...)
 }
 
-// Exactlyf asserts that two objects are equal is value and type.
+// Exactlyf asserts that two objects are equal in value and type.
 //
 //    a.Exactlyf(int32(123, "error message %s", "formatted"), int64(123))
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) Exactlyf(expected interface{}, actual interface{}, msg string, args ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	Exactlyf(a.t, expected, actual, msg, args...)
 }
 
 // Fail reports a failure through
 func (a *Assertions) Fail(failureMessage string, msgAndArgs ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	Fail(a.t, failureMessage, msgAndArgs...)
 }
 
 // FailNow fails test
 func (a *Assertions) FailNow(failureMessage string, msgAndArgs ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	FailNow(a.t, failureMessage, msgAndArgs...)
 }
 
 // FailNowf fails test
 func (a *Assertions) FailNowf(failureMessage string, msg string, args ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	FailNowf(a.t, failureMessage, msg, args...)
 }
 
 // Failf reports a failure through
 func (a *Assertions) Failf(failureMessage string, msg string, args ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	Failf(a.t, failureMessage, msg, args...)
 }
 
 // False asserts that the specified value is false.
 //
 //    a.False(myBool)
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) False(value bool, msgAndArgs ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	False(a.t, value, msgAndArgs...)
 }
 
 // Falsef asserts that the specified value is false.
 //
 //    a.Falsef(myBool, "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) Falsef(value bool, msg string, args ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	Falsef(a.t, value, msg, args...)
 }
 
+// FileExists checks whether a file exists in the given path. It also fails if the path points to a directory or there is an error when trying to check the file.
+func (a *Assertions) FileExists(path string, msgAndArgs ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	FileExists(a.t, path, msgAndArgs...)
+}
+
+// FileExistsf checks whether a file exists in the given path. It also fails if the path points to a directory or there is an error when trying to check the file.
+func (a *Assertions) FileExistsf(path string, msg string, args ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	FileExistsf(a.t, path, msg, args...)
+}
+
 // HTTPBodyContains asserts that a specified handler returns a
 // body that contains a string.
 //
-//  a.HTTPBodyContains(myHandler, "www.google.com", nil, "I'm Feeling Lucky")
+//  a.HTTPBodyContains(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky")
 //
 // Returns whether the assertion was successful (true) or not (false).
-func (a *Assertions) HTTPBodyContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}) {
-	HTTPBodyContains(a.t, handler, method, url, values, str)
+func (a *Assertions) HTTPBodyContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	HTTPBodyContains(a.t, handler, method, url, values, str, msgAndArgs...)
 }
 
 // HTTPBodyContainsf asserts that a specified handler returns a
 // body that contains a string.
 //
-//  a.HTTPBodyContainsf(myHandler, "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted")
+//  a.HTTPBodyContainsf(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted")
 //
 // Returns whether the assertion was successful (true) or not (false).
-func (a *Assertions) HTTPBodyContainsf(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}) {
-	HTTPBodyContainsf(a.t, handler, method, url, values, str)
+func (a *Assertions) HTTPBodyContainsf(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	HTTPBodyContainsf(a.t, handler, method, url, values, str, msg, args...)
 }
 
 // HTTPBodyNotContains asserts that a specified handler returns a
 // body that does not contain a string.
 //
-//  a.HTTPBodyNotContains(myHandler, "www.google.com", nil, "I'm Feeling Lucky")
+//  a.HTTPBodyNotContains(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky")
 //
 // Returns whether the assertion was successful (true) or not (false).
-func (a *Assertions) HTTPBodyNotContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}) {
-	HTTPBodyNotContains(a.t, handler, method, url, values, str)
+func (a *Assertions) HTTPBodyNotContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	HTTPBodyNotContains(a.t, handler, method, url, values, str, msgAndArgs...)
 }
 
 // HTTPBodyNotContainsf asserts that a specified handler returns a
 // body that does not contain a string.
 //
-//  a.HTTPBodyNotContainsf(myHandler, "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted")
+//  a.HTTPBodyNotContainsf(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted")
 //
 // Returns whether the assertion was successful (true) or not (false).
-func (a *Assertions) HTTPBodyNotContainsf(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}) {
-	HTTPBodyNotContainsf(a.t, handler, method, url, values, str)
+func (a *Assertions) HTTPBodyNotContainsf(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	HTTPBodyNotContainsf(a.t, handler, method, url, values, str, msg, args...)
 }
 
 // HTTPError asserts that a specified handler returns an error status code.
@@ -259,8 +361,11 @@ func (a *Assertions) HTTPBodyNotContainsf(handler http.HandlerFunc, method strin
 //  a.HTTPError(myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}}
 //
 // Returns whether the assertion was successful (true) or not (false).
-func (a *Assertions) HTTPError(handler http.HandlerFunc, method string, url string, values url.Values) {
-	HTTPError(a.t, handler, method, url, values)
+func (a *Assertions) HTTPError(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	HTTPError(a.t, handler, method, url, values, msgAndArgs...)
 }
 
 // HTTPErrorf asserts that a specified handler returns an error status code.
@@ -268,8 +373,11 @@ func (a *Assertions) HTTPError(handler http.HandlerFunc, method string, url stri
 //  a.HTTPErrorf(myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}}
 //
 // Returns whether the assertion was successful (true, "error message %s", "formatted") or not (false).
-func (a *Assertions) HTTPErrorf(handler http.HandlerFunc, method string, url string, values url.Values) {
-	HTTPErrorf(a.t, handler, method, url, values)
+func (a *Assertions) HTTPErrorf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	HTTPErrorf(a.t, handler, method, url, values, msg, args...)
 }
 
 // HTTPRedirect asserts that a specified handler returns a redirect status code.
@@ -277,8 +385,11 @@ func (a *Assertions) HTTPErrorf(handler http.HandlerFunc, method string, url str
 //  a.HTTPRedirect(myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}}
 //
 // Returns whether the assertion was successful (true) or not (false).
-func (a *Assertions) HTTPRedirect(handler http.HandlerFunc, method string, url string, values url.Values) {
-	HTTPRedirect(a.t, handler, method, url, values)
+func (a *Assertions) HTTPRedirect(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	HTTPRedirect(a.t, handler, method, url, values, msgAndArgs...)
 }
 
 // HTTPRedirectf asserts that a specified handler returns a redirect status code.
@@ -286,8 +397,11 @@ func (a *Assertions) HTTPRedirect(handler http.HandlerFunc, method string, url s
 //  a.HTTPRedirectf(myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}}
 //
 // Returns whether the assertion was successful (true, "error message %s", "formatted") or not (false).
-func (a *Assertions) HTTPRedirectf(handler http.HandlerFunc, method string, url string, values url.Values) {
-	HTTPRedirectf(a.t, handler, method, url, values)
+func (a *Assertions) HTTPRedirectf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	HTTPRedirectf(a.t, handler, method, url, values, msg, args...)
 }
 
 // HTTPSuccess asserts that a specified handler returns a success status code.
@@ -295,8 +409,11 @@ func (a *Assertions) HTTPRedirectf(handler http.HandlerFunc, method string, url
 //  a.HTTPSuccess(myHandler, "POST", "http://www.google.com", nil)
 //
 // Returns whether the assertion was successful (true) or not (false).
-func (a *Assertions) HTTPSuccess(handler http.HandlerFunc, method string, url string, values url.Values) {
-	HTTPSuccess(a.t, handler, method, url, values)
+func (a *Assertions) HTTPSuccess(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	HTTPSuccess(a.t, handler, method, url, values, msgAndArgs...)
 }
 
 // HTTPSuccessf asserts that a specified handler returns a success status code.
@@ -304,14 +421,20 @@ func (a *Assertions) HTTPSuccess(handler http.HandlerFunc, method string, url st
 //  a.HTTPSuccessf(myHandler, "POST", "http://www.google.com", nil, "error message %s", "formatted")
 //
 // Returns whether the assertion was successful (true) or not (false).
-func (a *Assertions) HTTPSuccessf(handler http.HandlerFunc, method string, url string, values url.Values) {
-	HTTPSuccessf(a.t, handler, method, url, values)
+func (a *Assertions) HTTPSuccessf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	HTTPSuccessf(a.t, handler, method, url, values, msg, args...)
 }
 
 // Implements asserts that an object is implemented by the specified interface.
 //
 //    a.Implements((*MyInterface)(nil), new(MyObject))
 func (a *Assertions) Implements(interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	Implements(a.t, interfaceObject, object, msgAndArgs...)
 }
 
@@ -319,86 +442,129 @@ func (a *Assertions) Implements(interfaceObject interface{}, object interface{},
 //
 //    a.Implementsf((*MyInterface, "error message %s", "formatted")(nil), new(MyObject))
 func (a *Assertions) Implementsf(interfaceObject interface{}, object interface{}, msg string, args ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	Implementsf(a.t, interfaceObject, object, msg, args...)
 }
 
 // InDelta asserts that the two numerals are within delta of each other.
 //
 // 	 a.InDelta(math.Pi, (22 / 7.0), 0.01)
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) InDelta(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	InDelta(a.t, expected, actual, delta, msgAndArgs...)
 }
 
+// InDeltaMapValues is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys.
+func (a *Assertions) InDeltaMapValues(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	InDeltaMapValues(a.t, expected, actual, delta, msgAndArgs...)
+}
+
+// InDeltaMapValuesf is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys.
+func (a *Assertions) InDeltaMapValuesf(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	InDeltaMapValuesf(a.t, expected, actual, delta, msg, args...)
+}
+
 // InDeltaSlice is the same as InDelta, except it compares two slices.
 func (a *Assertions) InDeltaSlice(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	InDeltaSlice(a.t, expected, actual, delta, msgAndArgs...)
 }
 
 // InDeltaSlicef is the same as InDelta, except it compares two slices.
 func (a *Assertions) InDeltaSlicef(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	InDeltaSlicef(a.t, expected, actual, delta, msg, args...)
 }
 
 // InDeltaf asserts that the two numerals are within delta of each other.
 //
 // 	 a.InDeltaf(math.Pi, (22 / 7.0, "error message %s", "formatted"), 0.01)
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) InDeltaf(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	InDeltaf(a.t, expected, actual, delta, msg, args...)
 }
 
 // InEpsilon asserts that expected and actual have a relative error less than epsilon
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) InEpsilon(expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	InEpsilon(a.t, expected, actual, epsilon, msgAndArgs...)
 }
 
 // InEpsilonSlice is the same as InEpsilon, except it compares each value from two slices.
 func (a *Assertions) InEpsilonSlice(expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	InEpsilonSlice(a.t, expected, actual, epsilon, msgAndArgs...)
 }
 
 // InEpsilonSlicef is the same as InEpsilon, except it compares each value from two slices.
 func (a *Assertions) InEpsilonSlicef(expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	InEpsilonSlicef(a.t, expected, actual, epsilon, msg, args...)
 }
 
 // InEpsilonf asserts that expected and actual have a relative error less than epsilon
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) InEpsilonf(expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	InEpsilonf(a.t, expected, actual, epsilon, msg, args...)
 }
 
 // IsType asserts that the specified objects are of the same type.
 func (a *Assertions) IsType(expectedType interface{}, object interface{}, msgAndArgs ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	IsType(a.t, expectedType, object, msgAndArgs...)
 }
 
 // IsTypef asserts that the specified objects are of the same type.
 func (a *Assertions) IsTypef(expectedType interface{}, object interface{}, msg string, args ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	IsTypef(a.t, expectedType, object, msg, args...)
 }
 
 // JSONEq asserts that two JSON strings are equivalent.
 //
 //  a.JSONEq(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`)
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) JSONEq(expected string, actual string, msgAndArgs ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	JSONEq(a.t, expected, actual, msgAndArgs...)
 }
 
 // JSONEqf asserts that two JSON strings are equivalent.
 //
 //  a.JSONEqf(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`, "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) JSONEqf(expected string, actual string, msg string, args ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	JSONEqf(a.t, expected, actual, msg, args...)
 }
 
@@ -406,9 +572,10 @@ func (a *Assertions) JSONEqf(expected string, actual string, msg string, args ..
 // Len also fails if the object has a type that len() not accept.
 //
 //    a.Len(mySlice, 3)
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) Len(object interface{}, length int, msgAndArgs ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	Len(a.t, object, length, msgAndArgs...)
 }
 
@@ -416,27 +583,30 @@ func (a *Assertions) Len(object interface{}, length int, msgAndArgs ...interface
 // Lenf also fails if the object has a type that len() not accept.
 //
 //    a.Lenf(mySlice, 3, "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) Lenf(object interface{}, length int, msg string, args ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	Lenf(a.t, object, length, msg, args...)
 }
 
 // Nil asserts that the specified object is nil.
 //
 //    a.Nil(err)
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) Nil(object interface{}, msgAndArgs ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	Nil(a.t, object, msgAndArgs...)
 }
 
 // Nilf asserts that the specified object is nil.
 //
 //    a.Nilf(err, "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) Nilf(object interface{}, msg string, args ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	Nilf(a.t, object, msg, args...)
 }
 
@@ -446,9 +616,10 @@ func (a *Assertions) Nilf(object interface{}, msg string, args ...interface{}) {
 //   if a.NoError(err) {
 // 	   assert.Equal(t, expectedObj, actualObj)
 //   }
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) NoError(err error, msgAndArgs ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	NoError(a.t, err, msgAndArgs...)
 }
 
@@ -458,9 +629,10 @@ func (a *Assertions) NoError(err error, msgAndArgs ...interface{}) {
 //   if a.NoErrorf(err, "error message %s", "formatted") {
 // 	   assert.Equal(t, expectedObj, actualObj)
 //   }
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) NoErrorf(err error, msg string, args ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	NoErrorf(a.t, err, msg, args...)
 }
 
@@ -470,9 +642,10 @@ func (a *Assertions) NoErrorf(err error, msg string, args ...interface{}) {
 //    a.NotContains("Hello World", "Earth")
 //    a.NotContains(["Hello", "World"], "Earth")
 //    a.NotContains({"Hello": "World"}, "Earth")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) NotContains(s interface{}, contains interface{}, msgAndArgs ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	NotContains(a.t, s, contains, msgAndArgs...)
 }
 
@@ -482,9 +655,10 @@ func (a *Assertions) NotContains(s interface{}, contains interface{}, msgAndArgs
 //    a.NotContainsf("Hello World", "Earth", "error message %s", "formatted")
 //    a.NotContainsf(["Hello", "World"], "Earth", "error message %s", "formatted")
 //    a.NotContainsf({"Hello": "World"}, "Earth", "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) NotContainsf(s interface{}, contains interface{}, msg string, args ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	NotContainsf(a.t, s, contains, msg, args...)
 }
 
@@ -494,9 +668,10 @@ func (a *Assertions) NotContainsf(s interface{}, contains interface{}, msg strin
 //  if a.NotEmpty(obj) {
 //    assert.Equal(t, "two", obj[1])
 //  }
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) NotEmpty(object interface{}, msgAndArgs ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	NotEmpty(a.t, object, msgAndArgs...)
 }
 
@@ -506,9 +681,10 @@ func (a *Assertions) NotEmpty(object interface{}, msgAndArgs ...interface{}) {
 //  if a.NotEmptyf(obj, "error message %s", "formatted") {
 //    assert.Equal(t, "two", obj[1])
 //  }
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) NotEmptyf(object interface{}, msg string, args ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	NotEmptyf(a.t, object, msg, args...)
 }
 
@@ -516,11 +692,12 @@ func (a *Assertions) NotEmptyf(object interface{}, msg string, args ...interface
 //
 //    a.NotEqual(obj1, obj2)
 //
-// Returns whether the assertion was successful (true) or not (false).
-//
 // Pointer variable equality is determined based on the equality of the
 // referenced values (as opposed to the memory addresses).
 func (a *Assertions) NotEqual(expected interface{}, actual interface{}, msgAndArgs ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	NotEqual(a.t, expected, actual, msgAndArgs...)
 }
 
@@ -528,47 +705,52 @@ func (a *Assertions) NotEqual(expected interface{}, actual interface{}, msgAndAr
 //
 //    a.NotEqualf(obj1, obj2, "error message %s", "formatted")
 //
-// Returns whether the assertion was successful (true) or not (false).
-//
 // Pointer variable equality is determined based on the equality of the
 // referenced values (as opposed to the memory addresses).
 func (a *Assertions) NotEqualf(expected interface{}, actual interface{}, msg string, args ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	NotEqualf(a.t, expected, actual, msg, args...)
 }
 
 // NotNil asserts that the specified object is not nil.
 //
 //    a.NotNil(err)
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) NotNil(object interface{}, msgAndArgs ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	NotNil(a.t, object, msgAndArgs...)
 }
 
 // NotNilf asserts that the specified object is not nil.
 //
 //    a.NotNilf(err, "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) NotNilf(object interface{}, msg string, args ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	NotNilf(a.t, object, msg, args...)
 }
 
 // NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic.
 //
 //   a.NotPanics(func(){ RemainCalm() })
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) NotPanics(f assert.PanicTestFunc, msgAndArgs ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	NotPanics(a.t, f, msgAndArgs...)
 }
 
 // NotPanicsf asserts that the code inside the specified PanicTestFunc does NOT panic.
 //
 //   a.NotPanicsf(func(){ RemainCalm() }, "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) NotPanicsf(f assert.PanicTestFunc, msg string, args ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	NotPanicsf(a.t, f, msg, args...)
 }
 
@@ -576,9 +758,10 @@ func (a *Assertions) NotPanicsf(f assert.PanicTestFunc, msg string, args ...inte
 //
 //  a.NotRegexp(regexp.MustCompile("starts"), "it's starting")
 //  a.NotRegexp("^start", "it's not starting")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) NotRegexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	NotRegexp(a.t, rx, str, msgAndArgs...)
 }
 
@@ -586,9 +769,10 @@ func (a *Assertions) NotRegexp(rx interface{}, str interface{}, msgAndArgs ...in
 //
 //  a.NotRegexpf(regexp.MustCompile("starts", "error message %s", "formatted"), "it's starting")
 //  a.NotRegexpf("^start", "it's not starting", "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) NotRegexpf(rx interface{}, str interface{}, msg string, args ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	NotRegexpf(a.t, rx, str, msg, args...)
 }
 
@@ -596,9 +780,10 @@ func (a *Assertions) NotRegexpf(rx interface{}, str interface{}, msg string, arg
 // elements given in the specified subset(array, slice...).
 //
 //    a.NotSubset([1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) NotSubset(list interface{}, subset interface{}, msgAndArgs ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	NotSubset(a.t, list, subset, msgAndArgs...)
 }
 
@@ -606,28 +791,36 @@ func (a *Assertions) NotSubset(list interface{}, subset interface{}, msgAndArgs
 // elements given in the specified subset(array, slice...).
 //
 //    a.NotSubsetf([1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]", "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) NotSubsetf(list interface{}, subset interface{}, msg string, args ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	NotSubsetf(a.t, list, subset, msg, args...)
 }
 
-// NotZero asserts that i is not the zero value for its type and returns the truth.
+// NotZero asserts that i is not the zero value for its type.
 func (a *Assertions) NotZero(i interface{}, msgAndArgs ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	NotZero(a.t, i, msgAndArgs...)
 }
 
-// NotZerof asserts that i is not the zero value for its type and returns the truth.
+// NotZerof asserts that i is not the zero value for its type.
 func (a *Assertions) NotZerof(i interface{}, msg string, args ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	NotZerof(a.t, i, msg, args...)
 }
 
 // Panics asserts that the code inside the specified PanicTestFunc panics.
 //
 //   a.Panics(func(){ GoCrazy() })
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) Panics(f assert.PanicTestFunc, msgAndArgs ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	Panics(a.t, f, msgAndArgs...)
 }
 
@@ -635,9 +828,10 @@ func (a *Assertions) Panics(f assert.PanicTestFunc, msgAndArgs ...interface{}) {
 // the recovered panic value equals the expected panic value.
 //
 //   a.PanicsWithValue("crazy error", func(){ GoCrazy() })
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) PanicsWithValue(expected interface{}, f assert.PanicTestFunc, msgAndArgs ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	PanicsWithValue(a.t, expected, f, msgAndArgs...)
 }
 
@@ -645,18 +839,20 @@ func (a *Assertions) PanicsWithValue(expected interface{}, f assert.PanicTestFun
 // the recovered panic value equals the expected panic value.
 //
 //   a.PanicsWithValuef("crazy error", func(){ GoCrazy() }, "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) PanicsWithValuef(expected interface{}, f assert.PanicTestFunc, msg string, args ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	PanicsWithValuef(a.t, expected, f, msg, args...)
 }
 
 // Panicsf asserts that the code inside the specified PanicTestFunc panics.
 //
 //   a.Panicsf(func(){ GoCrazy() }, "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) Panicsf(f assert.PanicTestFunc, msg string, args ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	Panicsf(a.t, f, msg, args...)
 }
 
@@ -664,9 +860,10 @@ func (a *Assertions) Panicsf(f assert.PanicTestFunc, msg string, args ...interfa
 //
 //  a.Regexp(regexp.MustCompile("start"), "it's starting")
 //  a.Regexp("start...$", "it's not starting")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) Regexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	Regexp(a.t, rx, str, msgAndArgs...)
 }
 
@@ -674,9 +871,10 @@ func (a *Assertions) Regexp(rx interface{}, str interface{}, msgAndArgs ...inter
 //
 //  a.Regexpf(regexp.MustCompile("start", "error message %s", "formatted"), "it's starting")
 //  a.Regexpf("start...$", "it's not starting", "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) Regexpf(rx interface{}, str interface{}, msg string, args ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	Regexpf(a.t, rx, str, msg, args...)
 }
 
@@ -684,9 +882,10 @@ func (a *Assertions) Regexpf(rx interface{}, str interface{}, msg string, args .
 // elements given in the specified subset(array, slice...).
 //
 //    a.Subset([1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) Subset(list interface{}, subset interface{}, msgAndArgs ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	Subset(a.t, list, subset, msgAndArgs...)
 }
 
@@ -694,54 +893,65 @@ func (a *Assertions) Subset(list interface{}, subset interface{}, msgAndArgs ...
 // elements given in the specified subset(array, slice...).
 //
 //    a.Subsetf([1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]", "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) Subsetf(list interface{}, subset interface{}, msg string, args ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	Subsetf(a.t, list, subset, msg, args...)
 }
 
 // True asserts that the specified value is true.
 //
 //    a.True(myBool)
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) True(value bool, msgAndArgs ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	True(a.t, value, msgAndArgs...)
 }
 
 // Truef asserts that the specified value is true.
 //
 //    a.Truef(myBool, "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) Truef(value bool, msg string, args ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	Truef(a.t, value, msg, args...)
 }
 
 // WithinDuration asserts that the two times are within duration delta of each other.
 //
 //   a.WithinDuration(time.Now(), time.Now(), 10*time.Second)
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) WithinDuration(expected time.Time, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	WithinDuration(a.t, expected, actual, delta, msgAndArgs...)
 }
 
 // WithinDurationf asserts that the two times are within duration delta of each other.
 //
 //   a.WithinDurationf(time.Now(), time.Now(), 10*time.Second, "error message %s", "formatted")
-//
-// Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) WithinDurationf(expected time.Time, actual time.Time, delta time.Duration, msg string, args ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	WithinDurationf(a.t, expected, actual, delta, msg, args...)
 }
 
-// Zero asserts that i is the zero value for its type and returns the truth.
+// Zero asserts that i is the zero value for its type.
 func (a *Assertions) Zero(i interface{}, msgAndArgs ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	Zero(a.t, i, msgAndArgs...)
 }
 
-// Zerof asserts that i is the zero value for its type and returns the truth.
+// Zerof asserts that i is the zero value for its type.
 func (a *Assertions) Zerof(i interface{}, msg string, args ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	Zerof(a.t, i, msg, args...)
 }
diff --git a/vendor/github.com/stretchr/testify/require/requirements.go b/vendor/github.com/stretchr/testify/require/requirements.go
index e404f016d182c319d6893829ada5e03bc82f3d8c..6b85c5ecef251782251b12e74772d0825c56acc0 100644
--- a/vendor/github.com/stretchr/testify/require/requirements.go
+++ b/vendor/github.com/stretchr/testify/require/requirements.go
@@ -6,4 +6,24 @@ type TestingT interface {
 	FailNow()
 }
 
+type tHelper interface {
+	Helper()
+}
+
+// ComparisonAssertionFunc is a common function prototype when comparing two values.  Can be useful
+// for table driven tests.
+type ComparisonAssertionFunc func(TestingT, interface{}, interface{}, ...interface{})
+
+// ValueAssertionFunc is a common function prototype when validating a single value.  Can be useful
+// for table driven tests.
+type ValueAssertionFunc func(TestingT, interface{}, ...interface{})
+
+// BoolAssertionFunc is a common function prototype when validating a bool value.  Can be useful
+// for table driven tests.
+type BoolAssertionFunc func(TestingT, bool, ...interface{})
+
+// ErrorAssertionFunc is a common function prototype when validating an error value.  Can be useful
+// for table driven tests.
+type ErrorAssertionFunc func(TestingT, error, ...interface{})
+
 //go:generate go run ../_codegen/main.go -output-package=require -template=require.go.tmpl -include-format-funcs
diff --git a/vendor/github.com/stretchr/testify/require/requirements_test.go b/vendor/github.com/stretchr/testify/require/requirements_test.go
index d2ccc99c9acc719713446a0e774d2b409d20401e..39467d9a51f2b20319855662982d8d0e601cf2e3 100644
--- a/vendor/github.com/stretchr/testify/require/requirements_test.go
+++ b/vendor/github.com/stretchr/testify/require/requirements_test.go
@@ -1,6 +1,7 @@
 package require
 
 import (
+	"encoding/json"
 	"errors"
 	"testing"
 	"time"
@@ -367,3 +368,199 @@ func TestJSONEq_ArraysOfDifferentOrder(t *testing.T) {
 		t.Error("Check should fail")
 	}
 }
+
+func ExampleComparisonAssertionFunc() {
+	t := &testing.T{} // provided by test
+
+	adder := func(x, y int) int {
+		return x + y
+	}
+
+	type args struct {
+		x int
+		y int
+	}
+
+	tests := []struct {
+		name      string
+		args      args
+		expect    int
+		assertion ComparisonAssertionFunc
+	}{
+		{"2+2=4", args{2, 2}, 4, Equal},
+		{"2+2!=5", args{2, 2}, 5, NotEqual},
+		{"2+3==5", args{2, 3}, 5, Exactly},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			tt.assertion(t, tt.expect, adder(tt.args.x, tt.args.y))
+		})
+	}
+}
+
+func TestComparisonAssertionFunc(t *testing.T) {
+	type iface interface {
+		Name() string
+	}
+
+	tests := []struct {
+		name      string
+		expect    interface{}
+		got       interface{}
+		assertion ComparisonAssertionFunc
+	}{
+		{"implements", (*iface)(nil), t, Implements},
+		{"isType", (*testing.T)(nil), t, IsType},
+		{"equal", t, t, Equal},
+		{"equalValues", t, t, EqualValues},
+		{"exactly", t, t, Exactly},
+		{"notEqual", t, nil, NotEqual},
+		{"notContains", []int{1, 2, 3}, 4, NotContains},
+		{"subset", []int{1, 2, 3, 4}, []int{2, 3}, Subset},
+		{"notSubset", []int{1, 2, 3, 4}, []int{0, 3}, NotSubset},
+		{"elementsMatch", []byte("abc"), []byte("bac"), ElementsMatch},
+		{"regexp", "^t.*y$", "testify", Regexp},
+		{"notRegexp", "^t.*y$", "Testify", NotRegexp},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			tt.assertion(t, tt.expect, tt.got)
+		})
+	}
+}
+
+func ExampleValueAssertionFunc() {
+	t := &testing.T{} // provided by test
+
+	dumbParse := func(input string) interface{} {
+		var x interface{}
+		json.Unmarshal([]byte(input), &x)
+		return x
+	}
+
+	tests := []struct {
+		name      string
+		arg       string
+		assertion ValueAssertionFunc
+	}{
+		{"true is not nil", "true", NotNil},
+		{"empty string is nil", "", Nil},
+		{"zero is not nil", "0", NotNil},
+		{"zero is zero", "0", Zero},
+		{"false is zero", "false", Zero},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			tt.assertion(t, dumbParse(tt.arg))
+		})
+	}
+}
+
+func TestValueAssertionFunc(t *testing.T) {
+	tests := []struct {
+		name      string
+		value     interface{}
+		assertion ValueAssertionFunc
+	}{
+		{"notNil", true, NotNil},
+		{"nil", nil, Nil},
+		{"empty", []int{}, Empty},
+		{"notEmpty", []int{1}, NotEmpty},
+		{"zero", false, Zero},
+		{"notZero", 42, NotZero},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			tt.assertion(t, tt.value)
+		})
+	}
+}
+
+func ExampleBoolAssertionFunc() {
+	t := &testing.T{} // provided by test
+
+	isOkay := func(x int) bool {
+		return x >= 42
+	}
+
+	tests := []struct {
+		name      string
+		arg       int
+		assertion BoolAssertionFunc
+	}{
+		{"-1 is bad", -1, False},
+		{"42 is good", 42, True},
+		{"41 is bad", 41, False},
+		{"45 is cool", 45, True},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			tt.assertion(t, isOkay(tt.arg))
+		})
+	}
+}
+
+func TestBoolAssertionFunc(t *testing.T) {
+	tests := []struct {
+		name      string
+		value     bool
+		assertion BoolAssertionFunc
+	}{
+		{"true", true, True},
+		{"false", false, False},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			tt.assertion(t, tt.value)
+		})
+	}
+}
+
+func ExampleErrorAssertionFunc() {
+	t := &testing.T{} // provided by test
+
+	dumbParseNum := func(input string, v interface{}) error {
+		return json.Unmarshal([]byte(input), v)
+	}
+
+	tests := []struct {
+		name      string
+		arg       string
+		assertion ErrorAssertionFunc
+	}{
+		{"1.2 is number", "1.2", NoError},
+		{"1.2.3 not number", "1.2.3", Error},
+		{"true is not number", "true", Error},
+		{"3 is number", "3", NoError},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			var x float64
+			tt.assertion(t, dumbParseNum(tt.arg, &x))
+		})
+	}
+}
+
+func TestErrorAssertionFunc(t *testing.T) {
+	tests := []struct {
+		name      string
+		err       error
+		assertion ErrorAssertionFunc
+	}{
+		{"noError", nil, NoError},
+		{"error", errors.New("whoops"), Error},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			tt.assertion(t, tt.err)
+		})
+	}
+}
diff --git a/vendor/github.com/stretchr/testify/suite/suite.go b/vendor/github.com/stretchr/testify/suite/suite.go
index e20afbc21ff60bba909174815bef06110ad0f193..5cea8f8c757f95ff9e3cd863a5d43996f8ae4e18 100644
--- a/vendor/github.com/stretchr/testify/suite/suite.go
+++ b/vendor/github.com/stretchr/testify/suite/suite.go
@@ -55,10 +55,32 @@ func (suite *Suite) Assert() *assert.Assertions {
 	return suite.Assertions
 }
 
+func failOnPanic(t *testing.T) {
+	r := recover()
+	if r != nil {
+		t.Errorf("test panicked: %v", r)
+		t.FailNow()
+	}
+}
+
+// Run provides suite functionality around golang subtests.  It should be
+// called in place of t.Run(name, func(t *testing.T)) in test suite code.
+// The passed-in func will be executed as a subtest with a fresh instance of t.
+// Provides compatibility with go test pkg -run TestSuite/TestName/SubTestName.
+func (suite *Suite) Run(name string, subtest func()) bool {
+	oldT := suite.T()
+	defer suite.SetT(oldT)
+	return oldT.Run(name, func(t *testing.T) {
+		suite.SetT(t)
+		subtest()
+	})
+}
+
 // Run takes a testing suite and runs all of the tests attached
 // to it.
 func Run(t *testing.T, suite TestingSuite) {
 	suite.SetT(t)
+	defer failOnPanic(t)
 
 	if setupAllSuite, ok := suite.(SetupAllSuite); ok {
 		setupAllSuite.SetupSuite()
@@ -84,6 +106,8 @@ func Run(t *testing.T, suite TestingSuite) {
 				F: func(t *testing.T) {
 					parentT := suite.T()
 					suite.SetT(t)
+					defer failOnPanic(t)
+
 					if setupTestSuite, ok := suite.(SetupTestSuite); ok {
 						setupTestSuite.SetupTest()
 					}
diff --git a/vendor/github.com/stretchr/testify/suite/suite_test.go b/vendor/github.com/stretchr/testify/suite/suite_test.go
index b75fa4ac1e35d6e6f3cffdbb9646d08ca5802f65..6dfba08cd17f3e97743e60913545c92cf5e377ea 100644
--- a/vendor/github.com/stretchr/testify/suite/suite_test.go
+++ b/vendor/github.com/stretchr/testify/suite/suite_test.go
@@ -42,6 +42,99 @@ func (s *SuiteRequireTwice) TestRequireTwo() {
 	r.Equal(1, 2)
 }
 
+type panickingSuite struct {
+	Suite
+	panicInSetupSuite    bool
+	panicInSetupTest     bool
+	panicInBeforeTest    bool
+	panicInTest          bool
+	panicInAfterTest     bool
+	panicInTearDownTest  bool
+	panicInTearDownSuite bool
+}
+
+func (s *panickingSuite) SetupSuite() {
+	if s.panicInSetupSuite {
+		panic("oops in setup suite")
+	}
+}
+
+func (s *panickingSuite) SetupTest() {
+	if s.panicInSetupTest {
+		panic("oops in setup test")
+	}
+}
+
+func (s *panickingSuite) BeforeTest(_, _ string) {
+	if s.panicInBeforeTest {
+		panic("oops in before test")
+	}
+}
+
+func (s *panickingSuite) Test() {
+	if s.panicInTest {
+		panic("oops in test")
+	}
+}
+
+func (s *panickingSuite) AfterTest(_, _ string) {
+	if s.panicInAfterTest {
+		panic("oops in after test")
+	}
+}
+
+func (s *panickingSuite) TearDownTest() {
+	if s.panicInTearDownTest {
+		panic("oops in tear down test")
+	}
+}
+
+func (s *panickingSuite) TearDownSuite() {
+	if s.panicInTearDownSuite {
+		panic("oops in tear down suite")
+	}
+}
+
+func TestSuiteRecoverPanic(t *testing.T) {
+	ok := true
+	panickingTests := []testing.InternalTest{
+		{
+			Name: "TestPanicInSetupSuite",
+			F:    func(t *testing.T) { Run(t, &panickingSuite{panicInSetupSuite: true}) },
+		},
+		{
+			Name: "TestPanicInSetupTest",
+			F:    func(t *testing.T) { Run(t, &panickingSuite{panicInSetupTest: true}) },
+		},
+		{
+			Name: "TestPanicInBeforeTest",
+			F:    func(t *testing.T) { Run(t, &panickingSuite{panicInBeforeTest: true}) },
+		},
+		{
+			Name: "TestPanicInTest",
+			F:    func(t *testing.T) { Run(t, &panickingSuite{panicInTest: true}) },
+		},
+		{
+			Name: "TestPanicInAfterTest",
+			F:    func(t *testing.T) { Run(t, &panickingSuite{panicInAfterTest: true}) },
+		},
+		{
+			Name: "TestPanicInTearDownTest",
+			F:    func(t *testing.T) { Run(t, &panickingSuite{panicInTearDownTest: true}) },
+		},
+		{
+			Name: "TestPanicInTearDownSuite",
+			F:    func(t *testing.T) { Run(t, &panickingSuite{panicInTearDownSuite: true}) },
+		},
+	}
+
+	require.NotPanics(t, func() {
+		ok = testing.RunTests(allTestsFilter, panickingTests)
+	})
+
+	assert.False(t, ok)
+}
+
 // This suite is intended to store values to make sure that only
 // testing-suite-related methods are run.  It's also a fully
 // functional example of a testing suite, using setup/teardown methods
@@ -59,6 +152,7 @@ type SuiteTester struct {
 	TearDownTestRunCount  int
 	TestOneRunCount       int
 	TestTwoRunCount       int
+	TestSubtestRunCount   int
 	NonTestMethodRunCount int
 
 	SuiteNameBefore []string
@@ -153,6 +247,27 @@ func (suite *SuiteTester) NonTestMethod() {
 	suite.NonTestMethodRunCount++
 }
 
+func (suite *SuiteTester) TestSubtest() {
+	suite.TestSubtestRunCount++
+
+	for _, t := range []struct {
+		testName string
+	}{
+		{"first"},
+		{"second"},
+	} {
+		suiteT := suite.T()
+		suite.Run(t.testName, func() {
+			// We should get a different *testing.T for subtests, so that
+			// go test recognizes them as proper subtests for output formatting
+			// and running individual subtests
+			subTestT := suite.T()
+			suite.NotEqual(subTestT, suiteT)
+		})
+		suite.Equal(suiteT, suite.T())
+	}
+}
+
 // TestRunSuite will be run by the 'go test' command, so within it, we
 // can run our suite using the Run(*testing.T, TestingSuite) function.
 func TestRunSuite(t *testing.T) {
@@ -168,18 +283,20 @@ func TestRunSuite(t *testing.T) {
 	assert.Equal(t, suiteTester.SetupSuiteRunCount, 1)
 	assert.Equal(t, suiteTester.TearDownSuiteRunCount, 1)
 
-	assert.Equal(t, len(suiteTester.SuiteNameAfter), 3)
-	assert.Equal(t, len(suiteTester.SuiteNameBefore), 3)
-	assert.Equal(t, len(suiteTester.TestNameAfter), 3)
-	assert.Equal(t, len(suiteTester.TestNameBefore), 3)
+	assert.Equal(t, len(suiteTester.SuiteNameAfter), 4)
+	assert.Equal(t, len(suiteTester.SuiteNameBefore), 4)
+	assert.Equal(t, len(suiteTester.TestNameAfter), 4)
+	assert.Equal(t, len(suiteTester.TestNameBefore), 4)
 
 	assert.Contains(t, suiteTester.TestNameAfter, "TestOne")
 	assert.Contains(t, suiteTester.TestNameAfter, "TestTwo")
 	assert.Contains(t, suiteTester.TestNameAfter, "TestSkip")
+	assert.Contains(t, suiteTester.TestNameAfter, "TestSubtest")
 
 	assert.Contains(t, suiteTester.TestNameBefore, "TestOne")
 	assert.Contains(t, suiteTester.TestNameBefore, "TestTwo")
 	assert.Contains(t, suiteTester.TestNameBefore, "TestSkip")
+	assert.Contains(t, suiteTester.TestNameBefore, "TestSubtest")
 
 	for _, suiteName := range suiteTester.SuiteNameAfter {
 		assert.Equal(t, "SuiteTester", suiteName)
@@ -197,15 +314,16 @@ func TestRunSuite(t *testing.T) {
 		assert.False(t, when.IsZero())
 	}
 
-	// There are three test methods (TestOne, TestTwo, and TestSkip), so
+	// There are four test methods (TestOne, TestTwo, TestSkip, and TestSubtest), so
 	// the SetupTest and TearDownTest methods (which should be run once for
-	// each test) should have been run three times.
-	assert.Equal(t, suiteTester.SetupTestRunCount, 3)
-	assert.Equal(t, suiteTester.TearDownTestRunCount, 3)
+	// each test) should have been run four times.
+	assert.Equal(t, suiteTester.SetupTestRunCount, 4)
+	assert.Equal(t, suiteTester.TearDownTestRunCount, 4)
 
 	// Each test should have been run once.
 	assert.Equal(t, suiteTester.TestOneRunCount, 1)
 	assert.Equal(t, suiteTester.TestTwoRunCount, 1)
+	assert.Equal(t, suiteTester.TestSubtestRunCount, 1)
 
 	// Methods that don't match the test method identifier shouldn't
 	// have been run at all.