Repository: knative-sandbox/eventing-kafka
Pull request #291 (2021-01-05 08:35:28)

Updates and fixes for slinky's loadastic
Signed-off-by: Matthias Wessendorf <mwessend@redhat.com>

Fixes #

<!-- Please include the 'why' behind your changes if no issue exists -->

## Proposed Changes

-
-
-

<!--
If this change has user-visible impact, follow the instructions below.
Examples include:

- 🎁 Add new feature
- 🐛 Fix bug
- 🧽 Update or clean up current behavior
- 🗑️ Remove feature or internal logic

Otherwise delete the rest of this template.
-->

**Release Note**

<!--
🗒️ If this change has user-visible impact, write a release note in the block
below. Include the string "action required" if additional action is required of
users switching to the new release, for example in case of a breaking change.

Write as if you are speaking to users, not other Knative contributors. If this
change has no user-visible impact, no release-note is needed.
-->

```release-note

```

**Docs**

<!--
📖 If this change has user-visible impact, link to an issue or PR in
https://github.com/knative/docs.
-->


knative-prow-robot: [APPROVALNOTIFIER] This PR is **APPROVED**

This pull-request has been approved by: *<a href="https://github.com/knative-sandbox/eventing-kafka/pull/291#" title="Author self-approved">matzew</a>*

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=knative-sandbox%2Feventing-kafka).

The pull request process is described [here](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process)

<details >
Needs approval from an approver in each of these files:

- ~~[OWNERS](https://github.com/knative-sandbox/eventing-kafka/blob/master/OWNERS)~~ [matzew]

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":[]} -->
knative-prow-robot: @matzew: The following test **failed**, say `/retest` to rerun all failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pull-knative-sandbox-eventing-kafka-build-tests | 69511630ffcc109844f50e8ad25e95ff5d4fac9e | [link](https://prow.knative.dev/view/gs/knative-prow/pr-logs/pull/knative-sandbox_eventing-kafka/291/pull-knative-sandbox-eventing-kafka-build-tests/1346374756634464256) | `/test pull-knative-sandbox-eventing-kafka-build-tests`

[Full PR test history](https://gubernator.knative.dev/pr/knative-sandbox_eventing-kafka/291). [Your PR dashboard](https://gubernator.knative.dev/pr/matzew).

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
codecov[bot]: # [Codecov](https://codecov.io/gh/knative-sandbox/eventing-kafka/pull/291?src=pr&el=h1) Report
> Merging [#291](https://codecov.io/gh/knative-sandbox/eventing-kafka/pull/291?src=pr&el=desc) (6951163) into [master](https://codecov.io/gh/knative-sandbox/eventing-kafka/commit/53a663d84a3ef04620ddbdc5ca9337087407b41b?el=desc) (53a663d) will **increase** coverage by `0.85%`.
> The diff coverage is `n/a`.

[![Impacted file tree graph](https://codecov.io/gh/knative-sandbox/eventing-kafka/pull/291/graphs/tree.svg?width=650&height=150&src=pr&token=W765CT93QC)](https://codecov.io/gh/knative-sandbox/eventing-kafka/pull/291?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master     #291      +/-   ##
==========================================
+ Coverage   75.30%   76.15%   +0.85%     
==========================================
  Files         116      114       -2     
  Lines        4486     4424      -62     
==========================================
- Hits         3378     3369       -9     
+ Misses        902      849      -53     
  Partials      206      206              
```


| [Impacted Files](https://codecov.io/gh/knative-sandbox/eventing-kafka/pull/291?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [...el/distributed/dispatcher/dispatcher/dispatcher.go](https://codecov.io/gh/knative-sandbox/eventing-kafka/pull/291/diff?src=pr&el=tree#diff-cGtnL2NoYW5uZWwvZGlzdHJpYnV0ZWQvZGlzcGF0Y2hlci9kaXNwYXRjaGVyL2Rpc3BhdGNoZXIuZ28=) | `73.46% <0.00%> (+7.14%)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/knative-sandbox/eventing-kafka/pull/291?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/knative-sandbox/eventing-kafka/pull/291?src=pr&el=footer). Last update [53a663d...6951163](https://codecov.io/gh/knative-sandbox/eventing-kafka/pull/291?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

knative-prow-robot: @matzew: The following test **failed**, say `/retest` to rerun all failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pull-knative-sandbox-eventing-kafka-build-tests | ba37a03876ecc9fb00a9880dc8d14ac824926936 | [link](https://prow.knative.dev/view/gs/knative-prow/pr-logs/pull/knative-sandbox_eventing-kafka/291/pull-knative-sandbox-eventing-kafka-build-tests/1346377997761908736) | `/test pull-knative-sandbox-eventing-kafka-build-tests`

[Full PR test history](https://gubernator.knative.dev/pr/knative-sandbox_eventing-kafka/291). [Your PR dashboard](https://gubernator.knative.dev/pr/matzew).

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
knative-prow-robot: @matzew: The following tests **failed**, say `/retest` to rerun all failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pull-knative-sandbox-eventing-kafka-build-tests | ba37a03876ecc9fb00a9880dc8d14ac824926936 | [link](https://prow.knative.dev/view/gs/knative-prow/pr-logs/pull/knative-sandbox_eventing-kafka/291/pull-knative-sandbox-eventing-kafka-build-tests/1346377997761908736) | `/test pull-knative-sandbox-eventing-kafka-build-tests`
pull-knative-sandbox-eventing-kafka-integration-test-channel-consolidated | ba37a03876ecc9fb00a9880dc8d14ac824926936 | [link](https://prow.knative.dev/view/gs/knative-prow/pr-logs/pull/knative-sandbox_eventing-kafka/291/pull-knative-sandbox-eventing-kafka-integration-test-channel-consolidated/1346377997686411264) | `/test pull-knative-sandbox-eventing-kafka-integration-test-channel-consolidated`

[Full PR test history](https://gubernator.knative.dev/pr/knative-sandbox_eventing-kafka/291). [Your PR dashboard](https://gubernator.knative.dev/pr/matzew).

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
knative-prow-robot: @matzew: The following tests **failed**, say `/retest` to rerun all failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pull-knative-sandbox-eventing-kafka-build-tests | ba37a03876ecc9fb00a9880dc8d14ac824926936 | [link](https://prow.knative.dev/view/gs/knative-prow/pr-logs/pull/knative-sandbox_eventing-kafka/291/pull-knative-sandbox-eventing-kafka-build-tests/1346377997761908736) | `/test pull-knative-sandbox-eventing-kafka-build-tests`
pull-knative-sandbox-eventing-kafka-integration-test-channel-consolidated | ba37a03876ecc9fb00a9880dc8d14ac824926936 | [link](https://prow.knative.dev/view/gs/knative-prow/pr-logs/pull/knative-sandbox_eventing-kafka/291/pull-knative-sandbox-eventing-kafka-integration-test-channel-consolidated/1346377997686411264) | `/test pull-knative-sandbox-eventing-kafka-integration-test-channel-consolidated`
pull-knative-sandbox-eventing-kafka-integration-test-channel-distributed | ba37a03876ecc9fb00a9880dc8d14ac824926936 | [link](https://prow.knative.dev/view/gs/knative-prow/pr-logs/pull/knative-sandbox_eventing-kafka/291/pull-knative-sandbox-eventing-kafka-integration-test-channel-distributed/1346377997740937216) | `/test pull-knative-sandbox-eventing-kafka-integration-test-channel-distributed`

[Full PR test history](https://gubernator.knative.dev/pr/knative-sandbox_eventing-kafka/291). [Your PR dashboard](https://gubernator.knative.dev/pr/matzew).

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
knative-prow-robot: @matzew: The following tests **failed**, say `/retest` to rerun all failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pull-knative-sandbox-eventing-kafka-build-tests | ba37a03876ecc9fb00a9880dc8d14ac824926936 | [link](https://prow.knative.dev/view/gs/knative-prow/pr-logs/pull/knative-sandbox_eventing-kafka/291/pull-knative-sandbox-eventing-kafka-build-tests/1346377997761908736) | `/test pull-knative-sandbox-eventing-kafka-build-tests`
pull-knative-sandbox-eventing-kafka-integration-test-channel-consolidated | ba37a03876ecc9fb00a9880dc8d14ac824926936 | [link](https://prow.knative.dev/view/gs/knative-prow/pr-logs/pull/knative-sandbox_eventing-kafka/291/pull-knative-sandbox-eventing-kafka-integration-test-channel-consolidated/1346377997686411264) | `/test pull-knative-sandbox-eventing-kafka-integration-test-channel-consolidated`
pull-knative-sandbox-eventing-kafka-integration-test-channel-distributed | ba37a03876ecc9fb00a9880dc8d14ac824926936 | [link](https://prow.knative.dev/view/gs/knative-prow/pr-logs/pull/knative-sandbox_eventing-kafka/291/pull-knative-sandbox-eventing-kafka-integration-test-channel-distributed/1346377997740937216) | `/test pull-knative-sandbox-eventing-kafka-integration-test-channel-distributed`
pull-knative-sandbox-eventing-kafka-integration-test-channel-consolidated-tls | ba37a03876ecc9fb00a9880dc8d14ac824926936 | [link](https://prow.knative.dev/view/gs/knative-prow/pr-logs/pull/knative-sandbox_eventing-kafka/291/pull-knative-sandbox-eventing-kafka-integration-test-channel-consolidated-tls/1346377997707382784) | `/test pull-knative-sandbox-eventing-kafka-integration-test-channel-consolidated-tls`

[Full PR test history](https://gubernator.knative.dev/pr/knative-sandbox_eventing-kafka/291). [Your PR dashboard](https://gubernator.knative.dev/pr/matzew).

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
knative-prow-robot: @matzew: The following tests **failed**, say `/retest` to rerun all failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pull-knative-sandbox-eventing-kafka-build-tests | ba37a03876ecc9fb00a9880dc8d14ac824926936 | [link](https://prow.knative.dev/view/gs/knative-prow/pr-logs/pull/knative-sandbox_eventing-kafka/291/pull-knative-sandbox-eventing-kafka-build-tests/1346377997761908736) | `/test pull-knative-sandbox-eventing-kafka-build-tests`
pull-knative-sandbox-eventing-kafka-integration-test-channel-consolidated | ba37a03876ecc9fb00a9880dc8d14ac824926936 | [link](https://prow.knative.dev/view/gs/knative-prow/pr-logs/pull/knative-sandbox_eventing-kafka/291/pull-knative-sandbox-eventing-kafka-integration-test-channel-consolidated/1346377997686411264) | `/test pull-knative-sandbox-eventing-kafka-integration-test-channel-consolidated`
pull-knative-sandbox-eventing-kafka-integration-test-channel-distributed | ba37a03876ecc9fb00a9880dc8d14ac824926936 | [link](https://prow.knative.dev/view/gs/knative-prow/pr-logs/pull/knative-sandbox_eventing-kafka/291/pull-knative-sandbox-eventing-kafka-integration-test-channel-distributed/1346377997740937216) | `/test pull-knative-sandbox-eventing-kafka-integration-test-channel-distributed`
pull-knative-sandbox-eventing-kafka-integration-test-channel-consolidated-tls | ba37a03876ecc9fb00a9880dc8d14ac824926936 | [link](https://prow.knative.dev/view/gs/knative-prow/pr-logs/pull/knative-sandbox_eventing-kafka/291/pull-knative-sandbox-eventing-kafka-integration-test-channel-consolidated-tls/1346377997707382784) | `/test pull-knative-sandbox-eventing-kafka-integration-test-channel-consolidated-tls`
pull-knative-sandbox-eventing-kafka-integration-test-channel-consolidated-sasl | ba37a03876ecc9fb00a9880dc8d14ac824926936 | [link](https://prow.knative.dev/view/gs/knative-prow/pr-logs/pull/knative-sandbox_eventing-kafka/291/pull-knative-sandbox-eventing-kafka-integration-test-channel-consolidated-sasl/1346377997724160000) | `/test pull-knative-sandbox-eventing-kafka-integration-test-channel-consolidated-sasl`

[Full PR test history](https://gubernator.knative.dev/pr/knative-sandbox_eventing-kafka/291). [Your PR dashboard](https://gubernator.knative.dev/pr/matzew).

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
knative-prow-robot: @matzew: The following tests **failed**, say `/retest` to rerun all failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pull-knative-sandbox-eventing-kafka-integration-test-channel-consolidated | ba37a03876ecc9fb00a9880dc8d14ac824926936 | [link](https://prow.knative.dev/view/gs/knative-prow/pr-logs/pull/knative-sandbox_eventing-kafka/291/pull-knative-sandbox-eventing-kafka-integration-test-channel-consolidated/1346377997686411264) | `/test pull-knative-sandbox-eventing-kafka-integration-test-channel-consolidated`
pull-knative-sandbox-eventing-kafka-integration-test-channel-distributed | ba37a03876ecc9fb00a9880dc8d14ac824926936 | [link](https://prow.knative.dev/view/gs/knative-prow/pr-logs/pull/knative-sandbox_eventing-kafka/291/pull-knative-sandbox-eventing-kafka-integration-test-channel-distributed/1346377997740937216) | `/test pull-knative-sandbox-eventing-kafka-integration-test-channel-distributed`
pull-knative-sandbox-eventing-kafka-integration-test-channel-consolidated-tls | ba37a03876ecc9fb00a9880dc8d14ac824926936 | [link](https://prow.knative.dev/view/gs/knative-prow/pr-logs/pull/knative-sandbox_eventing-kafka/291/pull-knative-sandbox-eventing-kafka-integration-test-channel-consolidated-tls/1346377997707382784) | `/test pull-knative-sandbox-eventing-kafka-integration-test-channel-consolidated-tls`
pull-knative-sandbox-eventing-kafka-integration-test-channel-consolidated-sasl | ba37a03876ecc9fb00a9880dc8d14ac824926936 | [link](https://prow.knative.dev/view/gs/knative-prow/pr-logs/pull/knative-sandbox_eventing-kafka/291/pull-knative-sandbox-eventing-kafka-integration-test-channel-consolidated-sasl/1346377997724160000) | `/test pull-knative-sandbox-eventing-kafka-integration-test-channel-consolidated-sasl`
pull-knative-sandbox-eventing-kafka-build-tests | 125640ea8859054dca5a356a8b1f210c310ac5ec | [link](https://prow.knative.dev/view/gs/knative-prow/pr-logs/pull/knative-sandbox_eventing-kafka/291/pull-knative-sandbox-eventing-kafka-build-tests/1346384484894773248) | `/test pull-knative-sandbox-eventing-kafka-build-tests`

[Full PR test history](https://gubernator.knative.dev/pr/knative-sandbox_eventing-kafka/291). [Your PR dashboard](https://gubernator.knative.dev/pr/matzew).

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
knative-prow-robot: @matzew: The following tests **failed**, say `/retest` to rerun all failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pull-knative-sandbox-eventing-kafka-integration-test-channel-consolidated | ba37a03876ecc9fb00a9880dc8d14ac824926936 | [link](https://prow.knative.dev/view/gs/knative-prow/pr-logs/pull/knative-sandbox_eventing-kafka/291/pull-knative-sandbox-eventing-kafka-integration-test-channel-consolidated/1346377997686411264) | `/test pull-knative-sandbox-eventing-kafka-integration-test-channel-consolidated`
pull-knative-sandbox-eventing-kafka-build-tests | 33c674dd8fec61488174851f046511dea5f72138 | [link](https://prow.knative.dev/view/gs/knative-prow/pr-logs/pull/knative-sandbox_eventing-kafka/291/pull-knative-sandbox-eventing-kafka-build-tests/1346390736857206784) | `/test pull-knative-sandbox-eventing-kafka-build-tests`

[Full PR test history](https://gubernator.knative.dev/pr/knative-sandbox_eventing-kafka/291). [Your PR dashboard](https://gubernator.knative.dev/pr/matzew).

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
knative-prow-robot: @matzew: The following tests **failed**, say `/retest` to rerun all failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pull-knative-sandbox-eventing-kafka-integration-test-channel-consolidated | ba37a03876ecc9fb00a9880dc8d14ac824926936 | [link](https://prow.knative.dev/view/gs/knative-prow/pr-logs/pull/knative-sandbox_eventing-kafka/291/pull-knative-sandbox-eventing-kafka-integration-test-channel-consolidated/1346377997686411264) | `/test pull-knative-sandbox-eventing-kafka-integration-test-channel-consolidated`
pull-knative-sandbox-eventing-kafka-build-tests | a38c59dea619771b47adf550a3bfbc0d7aba14f3 | [link](https://prow.knative.dev/view/gs/knative-prow/pr-logs/pull/knative-sandbox_eventing-kafka/291/pull-knative-sandbox-eventing-kafka-build-tests/1346394042534989824) | `/test pull-knative-sandbox-eventing-kafka-build-tests`

[Full PR test history](https://gubernator.knative.dev/pr/knative-sandbox_eventing-kafka/291). [Your PR dashboard](https://gubernator.knative.dev/pr/matzew).

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
matzew: @slinkydeveloper  I think this is it now... :see_no_evil: 
slinkydeveloper: Seems like you need to run update-codegen
matzew: > Seems like you need to run update-codegen

well, I did - if really an issue, I think the "build tests" etc would have complained too 
matzew: @slinkydeveloper did it _again_... and... (as expected) -> no diff

so... I think this is OK....
slinkydeveloper: Sounds like there's a change in the file modes?!
matzew: yet another round of updates, and a rebase ... lets see ... :sleepy:  
matzew: @slinkydeveloper for some reason, those modes were wrong here .. not sure why.
I changed them, they are now same like on `eventing` core...

also, I did do another round of "updates", to catch the latests (e.g. from today).

I now see that particular one failing check is now :green_heart: 
slinkydeveloper: /lgtm
/approve
knative-prow-robot: [APPROVALNOTIFIER] This PR is **APPROVED**

This pull-request has been approved by: *<a href="https://github.com/knative-sandbox/eventing-kafka/pull/291#" title="Author self-approved">matzew</a>*, *<a href="https://github.com/knative-sandbox/eventing-kafka/pull/291#issuecomment-755233774" title="Approved">slinkydeveloper</a>*

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=knative-sandbox%2Feventing-kafka).

The pull request process is described [here](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process)

<details >
Needs approval from an approver in each of these files:

- ~~[OWNERS](https://github.com/knative-sandbox/eventing-kafka/blob/master/OWNERS)~~ [matzew,slinkydeveloper]

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":[]} -->
slinkydeveloper: Thanks!

Patch:
diff --git a/go.mod b/go.mod
index fa6e00fe0..e0894c157 100644
--- a/go.mod
+++ b/go.mod
@@ -21,7 +21,7 @@ require (
 	github.com/kelseyhightower/envconfig v1.4.0
 	github.com/mitchellh/mapstructure v1.3.3 // indirect
 	github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0
-	github.com/slinkydeveloper/loadastic v0.0.0-20191203132749-9afe5a010a57
+	github.com/slinkydeveloper/loadastic v0.0.0-20201218203601-5c69eea3b7d8
 	github.com/stretchr/testify v1.6.1
 	github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c
 	go.opencensus.io v0.22.5
@@ -32,9 +32,9 @@ require (
 	k8s.io/apimachinery v0.18.12
 	k8s.io/client-go v11.0.1-0.20190805182717-6502b5e7b1b5+incompatible
 	k8s.io/utils v0.0.0-20200603063816-c1c6865ac451
-	knative.dev/eventing v0.19.1-0.20201216183558-f3468d1c9954
+	knative.dev/eventing v0.19.1-0.20210106094043-f4b5fd47542c
 	knative.dev/hack v0.0.0-20201214230143-4ed1ecb8db24
-	knative.dev/pkg v0.0.0-20201222215804-e2d6b4f84573
+	knative.dev/pkg v0.0.0-20201231084629-fb3dc711206a
 )
 
 replace (
diff --git a/go.sum b/go.sum
index 390cd43a0..352d87af9 100644
--- a/go.sum
+++ b/go.sum
@@ -695,8 +695,8 @@ github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPx
 github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
 github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I=
 github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
-github.com/slinkydeveloper/loadastic v0.0.0-20191203132749-9afe5a010a57 h1:ey3F1SgRqpMDAPkESctIBu2NGvj0Zn/ycRgrq/OTf9o=
-github.com/slinkydeveloper/loadastic v0.0.0-20191203132749-9afe5a010a57/go.mod h1:ZVGR+mBhAvZjxtY1dTpM8TQL/mVx7M1h4G8lG2rQH1c=
+github.com/slinkydeveloper/loadastic v0.0.0-20201218203601-5c69eea3b7d8 h1:W2F1+6SL7+Ofr+Yuruqv1rTgmpzdsNaiS3QV8BeyXpQ=
+github.com/slinkydeveloper/loadastic v0.0.0-20201218203601-5c69eea3b7d8/go.mod h1:vNSJ7ak+2OeAb5bhSHRmMKKcbadbxlokx/Wh1lC50e4=
 github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
 github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
 github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
@@ -732,9 +732,7 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
 github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
 github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
 github.com/tsenart/go-tsz v0.0.0-20180814232043-cdeb9e1e981e/go.mod h1:SWZznP1z5Ki7hDT2ioqiFKEse8K9tU2OUvaRI0NeGQo=
-github.com/tsenart/vegeta v12.7.0+incompatible/go.mod h1:Smz/ZWfhKRcyDDChZkG3CyTHdj87lHzio/HOCkbndXM=
-github.com/tsenart/vegeta v12.7.1-0.20190725001342-b5f4fca92137+incompatible h1:ErZrHhRveAoznVW80gbrxz+qxJNydpA2fcQxTPHkZbU=
-github.com/tsenart/vegeta v12.7.1-0.20190725001342-b5f4fca92137+incompatible/go.mod h1:Smz/ZWfhKRcyDDChZkG3CyTHdj87lHzio/HOCkbndXM=
+github.com/tsenart/vegeta/v12 v12.8.4 h1:UQ7tG7WkDorKj0wjx78Z4/vsMBP8RJQMGJqRVrkvngg=
 github.com/tsenart/vegeta/v12 v12.8.4/go.mod h1:ZiJtwLn/9M4fTPdMY7bdbIeyNeFVE8/AHbWFqCsUuho=
 github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
 github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
@@ -1250,17 +1248,17 @@ k8s.io/kube-openapi v0.0.0-20200410145947-bcb3869e6f29/go.mod h1:F+5wygcW0wmRTnM
 k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
 k8s.io/utils v0.0.0-20200603063816-c1c6865ac451 h1:v8ud2Up6QK1lNOKFgiIVrZdMg7MpmSnvtrOieolJKoE=
 k8s.io/utils v0.0.0-20200603063816-c1c6865ac451/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
-knative.dev/eventing v0.19.1-0.20201216183558-f3468d1c9954 h1:6aNIdsIusWwC2esDUuvzSqyf7hUPohwsX2avcR/q0Kc=
-knative.dev/eventing v0.19.1-0.20201216183558-f3468d1c9954/go.mod h1:Zs0qfFfbKDhEM5JHjQtmCXBu9k+GERSfeDwitMtgjQM=
+knative.dev/eventing v0.19.1-0.20210106094043-f4b5fd47542c h1:sPOn+U2IPLNP64TEd6dK7Bz2a5XrySBqhajbMYak5Fg=
+knative.dev/eventing v0.19.1-0.20210106094043-f4b5fd47542c/go.mod h1:1F2YE3RDRqu7urMAC8mZDqkRnzS7exaQeAGtEvsD+Ss=
 knative.dev/hack v0.0.0-20201112185459-01a34c573bd8/go.mod h1:PHt8x8yX5Z9pPquBEfIj0X66f8iWkWfR0S/sarACJrI=
 knative.dev/hack v0.0.0-20201118155651-b31d3bb6bff9/go.mod h1:PHt8x8yX5Z9pPquBEfIj0X66f8iWkWfR0S/sarACJrI=
 knative.dev/hack v0.0.0-20201214230143-4ed1ecb8db24 h1:kIztWfvnIFV8Lhlea02K3YO2mIzcDyQNzrBLn0Oq9sA=
 knative.dev/hack v0.0.0-20201214230143-4ed1ecb8db24/go.mod h1:PHt8x8yX5Z9pPquBEfIj0X66f8iWkWfR0S/sarACJrI=
 knative.dev/pkg v0.0.0-20201117221452-0fccc54273ed/go.mod h1:nxlh3CUvx6WBPr1WKD96AHxFZPD2UKRDo9RUp8ILTyQ=
-knative.dev/pkg v0.0.0-20201215202458-ef8048c0ba77/go.mod h1:VjrwVhfEZUnn6FruncHcBm854FldnRpekpyBbYtBvZM=
-knative.dev/pkg v0.0.0-20201222215804-e2d6b4f84573 h1:AOvVeFfZDd7j2S6oyfO0Qiv2Vj5eFqKUyU0TEf/qz7M=
-knative.dev/pkg v0.0.0-20201222215804-e2d6b4f84573/go.mod h1:hckgW978SdzPA2H5EDvRPY8xsnPuDZLJLbPf8Jte7Q0=
+knative.dev/pkg v0.0.0-20201231084629-fb3dc711206a h1:LjZzFXE9VuhuPJFMn7KdjmsukoLOwQasfBuEJPc53ys=
+knative.dev/pkg v0.0.0-20201231084629-fb3dc711206a/go.mod h1:hckgW978SdzPA2H5EDvRPY8xsnPuDZLJLbPf8Jte7Q0=
 knative.dev/reconciler-test v0.0.0-20201124190335-83a44efcdfef/go.mod h1:YSs1y1rgnjs8w39/drLIOQbWvZUQwqApvd+EizO8UsA=
+pgregory.net/rapid v0.3.3 h1:jCjBsY4ln4Atz78QoBWxUEvAHaFyNDQg9+WU62aCn1U=
 pgregory.net/rapid v0.3.3/go.mod h1:UYpPVyjFHzYBGHIxLFoupi8vwk6rXNzRY9OMvVxFIOU=
 rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
 rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
diff --git a/third_party/VENDOR-LICENSE/github.com/tsenart/vegeta/lib/LICENSE b/third_party/VENDOR-LICENSE/github.com/tsenart/vegeta/v12/lib/LICENSE
similarity index 96%
rename from third_party/VENDOR-LICENSE/github.com/tsenart/vegeta/lib/LICENSE
rename to third_party/VENDOR-LICENSE/github.com/tsenart/vegeta/v12/lib/LICENSE
index 441df0ab4..03ec4f5a8 100644
--- a/third_party/VENDOR-LICENSE/github.com/tsenart/vegeta/lib/LICENSE
+++ b/third_party/VENDOR-LICENSE/github.com/tsenart/vegeta/v12/lib/LICENSE
@@ -1,6 +1,6 @@
 The MIT License (MIT)
 
-Copyright (c) 2013-2016 Tomás Senart
+Copyright (c) 2013-2020 Tomás Senart
 
 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
diff --git a/vendor/github.com/mailru/easyjson/.gitignore b/vendor/github.com/mailru/easyjson/.gitignore
new file mode 100644
index 000000000..26156fb4b
--- /dev/null
+++ b/vendor/github.com/mailru/easyjson/.gitignore
@@ -0,0 +1,5 @@
+.root
+*_easyjson.go
+*.iml
+.idea
+*.swp
diff --git a/vendor/github.com/mailru/easyjson/.travis.yml b/vendor/github.com/mailru/easyjson/.travis.yml
new file mode 100644
index 000000000..0ececa071
--- /dev/null
+++ b/vendor/github.com/mailru/easyjson/.travis.yml
@@ -0,0 +1,12 @@
+language: go
+
+go:
+  - tip
+  - stable
+
+matrix:
+  allow_failures:
+    - go: tip
+
+install:
+  - go get golang.org/x/lint/golint
diff --git a/vendor/github.com/mailru/easyjson/Makefile b/vendor/github.com/mailru/easyjson/Makefile
new file mode 100644
index 000000000..66cc40243
--- /dev/null
+++ b/vendor/github.com/mailru/easyjson/Makefile
@@ -0,0 +1,54 @@
+all: test
+
+clean:
+	rm -rf bin
+	rm -rf tests/*_easyjson.go
+	rm -rf benchmark/*_easyjson.go
+
+build:
+	go build -i -o ./bin/easyjson ./easyjson
+
+generate: build
+	bin/easyjson -stubs \
+		./tests/snake.go \
+		./tests/data.go \
+		./tests/omitempty.go \
+		./tests/nothing.go \
+		./tests/named_type.go \
+		./tests/custom_map_key_type.go \
+		./tests/embedded_type.go \
+		./tests/reference_to_pointer.go \
+		./tests/html.go \
+
+	bin/easyjson -all ./tests/data.go
+	bin/easyjson -all ./tests/nothing.go
+	bin/easyjson -all ./tests/errors.go
+	bin/easyjson -all ./tests/html.go
+	bin/easyjson -snake_case ./tests/snake.go
+	bin/easyjson -omit_empty ./tests/omitempty.go
+	bin/easyjson -build_tags=use_easyjson ./benchmark/data.go
+	bin/easyjson ./tests/nested_easy.go
+	bin/easyjson ./tests/named_type.go
+	bin/easyjson ./tests/custom_map_key_type.go
+	bin/easyjson ./tests/embedded_type.go
+	bin/easyjson ./tests/reference_to_pointer.go
+	bin/easyjson ./tests/key_marshaler_map.go
+	bin/easyjson -disallow_unknown_fields ./tests/disallow_unknown.go
+
+test: generate
+	go test \
+		./tests \
+		./jlexer \
+		./gen \
+		./buffer
+	cd benchmark && go test -benchmem -tags use_easyjson -bench .
+	golint -set_exit_status ./tests/*_easyjson.go
+
+bench-other: generate
+	cd benchmark && make
+
+bench-python:
+	benchmark/ujson.sh
+
+
+.PHONY: clean generate test build
diff --git a/vendor/github.com/mailru/easyjson/README.md b/vendor/github.com/mailru/easyjson/README.md
new file mode 100644
index 000000000..3bdcf2d06
--- /dev/null
+++ b/vendor/github.com/mailru/easyjson/README.md
@@ -0,0 +1,336 @@
+# easyjson [![Build Status](https://travis-ci.org/mailru/easyjson.svg?branch=master)](https://travis-ci.org/mailru/easyjson) [![Go Report Card](https://goreportcard.com/badge/github.com/mailru/easyjson)](https://goreportcard.com/report/github.com/mailru/easyjson)
+
+Package easyjson provides a fast and easy way to marshal/unmarshal Go structs
+to/from JSON without the use of reflection. In performance tests, easyjson
+outperforms the standard `encoding/json` package by a factor of 4-5x, and other
+JSON encoding packages by a factor of 2-3x.
+
+easyjson aims to keep generated Go code simple enough so that it can be easily
+optimized or fixed. Another goal is to provide users with the ability to
+customize the generated code by providing options not available with the
+standard `encoding/json` package, such as generating "snake_case" names or
+enabling `omitempty` behavior by default.
+
+## Usage
+```sh
+# install
+go get -u github.com/mailru/easyjson/...
+
+# run
+easyjson -all <file>.go
+```
+
+The above will generate `<file>_easyjson.go` containing the appropriate marshaler and
+unmarshaler funcs for all structs contained in `<file>.go`.
+
+Please note that easyjson requires a full Go build environment and the `GOPATH`
+environment variable to be set. This is because easyjson code generation
+invokes `go run` on a temporary file (an approach to code generation borrowed
+from [ffjson](https://github.com/pquerna/ffjson)).
+
+## Options
+```txt
+Usage of easyjson:
+  -all
+    	generate marshaler/unmarshalers for all structs in a file
+  -build_tags string
+    	build tags to add to generated file
+  -leave_temps
+    	do not delete temporary files
+  -no_std_marshalers
+    	don't generate MarshalJSON/UnmarshalJSON funcs
+  -noformat
+    	do not run 'gofmt -w' on output file
+  -omit_empty
+    	omit empty fields by default
+  -output_filename string
+    	specify the filename of the output
+  -pkg
+    	process the whole package instead of just the given file
+  -snake_case
+    	use snake_case names instead of CamelCase by default
+  -lower_camel_case
+        use lowerCamelCase instead of CamelCase by default
+  -stubs
+    	only generate stubs for marshaler/unmarshaler funcs
+  -disallow_unknown_fields
+        return error if some unknown field in json appeared
+```
+
+Using `-all` will generate marshalers/unmarshalers for all Go structs in the
+file. If `-all` is not provided, then only those structs whose preceding
+comment starts with `easyjson:json` will have marshalers/unmarshalers
+generated. For example:
+
+```go
+//easyjson:json
+type A struct {}
+```
+
+Additional option notes:
+
+* `-snake_case` tells easyjson to generate snake\_case field names by default
+  (unless overridden by a field tag). The CamelCase to snake\_case conversion
+  algorithm should work in most cases (ie, HTTPVersion will be converted to
+  "http_version").
+
+* `-build_tags` will add the specified build tags to generated Go sources.
+
+## Generated Marshaler/Unmarshaler Funcs
+
+For Go struct types, easyjson generates the funcs `MarshalEasyJSON` /
+`UnmarshalEasyJSON` for marshaling/unmarshaling JSON. In turn, these satisify
+the `easyjson.Marshaler` and `easyjson.Unmarshaler` interfaces and when used in
+conjunction with `easyjson.Marshal` / `easyjson.Unmarshal` avoid unnecessary
+reflection / type assertions during marshaling/unmarshaling to/from JSON for Go
+structs.
+
+easyjson also generates `MarshalJSON` and `UnmarshalJSON` funcs for Go struct
+types compatible with the standard `json.Marshaler` and `json.Unmarshaler`
+interfaces. Please be aware that using the standard `json.Marshal` /
+`json.Unmarshal` for marshaling/unmarshaling will incur a significant
+performance penalty when compared to using `easyjson.Marshal` /
+`easyjson.Unmarshal`.
+
+Additionally, easyjson exposes utility funcs that use the `MarshalEasyJSON` and
+`UnmarshalEasyJSON` for marshaling/unmarshaling to and from standard readers
+and writers. For example, easyjson provides `easyjson.MarshalToHTTPResponseWriter`
+which marshals to the standard `http.ResponseWriter`. Please see the [GoDoc
+listing](https://godoc.org/github.com/mailru/easyjson) for the full listing of
+utility funcs that are available.
+
+## Controlling easyjson Marshaling and Unmarshaling Behavior
+
+Go types can provide their own `MarshalEasyJSON` and `UnmarshalEasyJSON` funcs
+that satisify the `easyjson.Marshaler` / `easyjson.Unmarshaler` interfaces.
+These will be used by `easyjson.Marshal` and `easyjson.Unmarshal` when defined
+for a Go type.
+
+Go types can also satisify the `easyjson.Optional` interface, which allows the
+type to define its own `omitempty` logic.
+
+## Type Wrappers
+
+easyjson provides additional type wrappers defined in the `easyjson/opt`
+package. These wrap the standard Go primitives and in turn satisify the
+easyjson interfaces.
+
+The `easyjson/opt` type wrappers are useful when needing to distinguish between
+a missing value and/or when needing to specifying a default value. Type
+wrappers allow easyjson to avoid additional pointers and heap allocations and
+can significantly increase performance when used properly.
+
+## Memory Pooling
+
+easyjson uses a buffer pool that allocates data in increasing chunks from 128
+to 32768 bytes. Chunks of 512 bytes and larger will be reused with the help of
+`sync.Pool`. The maximum size of a chunk is bounded to reduce redundant memory
+allocation and to allow larger reusable buffers.
+
+easyjson's custom allocation buffer pool is defined in the `easyjson/buffer`
+package, and the default behavior pool behavior can be modified (if necessary)
+through a call to `buffer.Init()` prior to any marshaling or unmarshaling.
+Please see the [GoDoc listing](https://godoc.org/github.com/mailru/easyjson/buffer)
+for more information.
+
+## Issues, Notes, and Limitations
+
+* easyjson is still early in its development. As such, there are likely to be
+  bugs and missing features when compared to `encoding/json`. In the case of a
+  missing feature or bug, please create a GitHub issue. Pull requests are
+  welcome!
+
+* Unlike `encoding/json`, object keys are case-sensitive. Case-insensitive
+  matching is not currently provided due to the significant performance hit
+  when doing case-insensitive key matching. In the future, case-insensitive
+  object key matching may be provided via an option to the generator.
+
+* easyjson makes use of `unsafe`, which simplifies the code and
+  provides significant performance benefits by allowing no-copy
+  conversion from `[]byte` to `string`. That said, `unsafe` is used
+  only when unmarshaling and parsing JSON, and any `unsafe` operations
+  / memory allocations done will be safely deallocated by
+  easyjson. Set the build tag `easyjson_nounsafe` to compile it
+  without `unsafe`.
+
+* easyjson is compatible with Google App Engine. The `appengine` build
+  tag (set by App Engine's environment) will automatically disable the
+  use of `unsafe`, which is not allowed in App Engine's Standard
+  Environment. Note that the use with App Engine is still experimental.
+
+* Floats are formatted using the default precision from Go's `strconv` package.
+  As such, easyjson will not correctly handle high precision floats when
+  marshaling/unmarshaling JSON. Note, however, that there are very few/limited
+  uses where this behavior is not sufficient for general use. That said, a
+  different package may be needed if precise marshaling/unmarshaling of high
+  precision floats to/from JSON is required.
+
+* While unmarshaling, the JSON parser does the minimal amount of work needed to
+  skip over unmatching parens, and as such full validation is not done for the
+  entire JSON value being unmarshaled/parsed.
+
+* Currently there is no true streaming support for encoding/decoding as
+  typically for many uses/protocols the final, marshaled length of the JSON
+  needs to be known prior to sending the data. Currently this is not possible
+  with easyjson's architecture.
+  
+* easyjson parser and codegen based on reflection, so it wont works on `package main` 
+  files, because they cant be imported by parser.
+
+## Benchmarks
+
+Most benchmarks were done using the example
+[13kB example JSON](https://dev.twitter.com/rest/reference/get/search/tweets)
+(9k after eliminating whitespace). This example is similar to real-world data,
+is well-structured, and contains a healthy variety of different types, making
+it ideal for JSON serialization benchmarks.
+
+Note:
+
+* For small request benchmarks, an 80 byte portion of the above example was
+  used.
+
+* For large request marshaling benchmarks, a struct containing 50 regular
+  samples was used, making a ~500kB output JSON.
+
+* Benchmarks are showing the results of easyjson's default behaviour,
+  which makes use of `unsafe`.
+
+Benchmarks are available in the repository and can be run by invoking `make`.
+
+### easyjson vs. encoding/json
+
+easyjson is roughly 5-6 times faster than the standard `encoding/json` for
+unmarshaling, and 3-4 times faster for non-concurrent marshaling. Concurrent
+marshaling is 6-7x faster if marshaling to a writer.
+
+### easyjson vs. ffjson
+
+easyjson uses the same approach for JSON marshaling as
+[ffjson](https://github.com/pquerna/ffjson), but takes a significantly
+different approach to lexing and parsing JSON during unmarshaling. This means
+easyjson is roughly 2-3x faster for unmarshaling and 1.5-2x faster for
+non-concurrent unmarshaling.
+
+As of this writing, `ffjson` seems to have issues when used concurrently:
+specifically, large request pooling hurts `ffjson`'s performance and causes
+scalability issues. These issues with `ffjson` can likely be fixed, but as of
+writing remain outstanding/known issues with `ffjson`.
+
+easyjson and `ffjson` have similar performance for small requests, however
+easyjson outperforms `ffjson` by roughly 2-5x times for large requests when
+used with a writer.
+
+### easyjson vs. go/codec
+
+[go/codec](https://github.com/ugorji/go) provides
+compile-time helpers for JSON generation. In this case, helpers do not work
+like marshalers as they are encoding-independent.
+
+easyjson is generally 2x faster than `go/codec` for non-concurrent benchmarks
+and about 3x faster for concurrent encoding (without marshaling to a writer).
+
+In an attempt to measure marshaling performance of `go/codec` (as opposed to
+allocations/memcpy/writer interface invocations), a benchmark was done with
+resetting length of a byte slice rather than resetting the whole slice to nil.
+However, the optimization in this exact form may not be applicable in practice,
+since the memory is not freed between marshaling operations.
+
+### easyjson vs 'ujson' python module
+
+[ujson](https://github.com/esnme/ultrajson) is using C code for parsing, so it
+is interesting to see how plain golang compares to that. It is imporant to note
+that the resulting object for python is slower to access, since the library
+parses JSON object into dictionaries.
+
+easyjson is slightly faster for unmarshaling and 2-3x faster than `ujson` for
+marshaling.
+
+### Benchmark Results
+
+`ffjson` results are from February 4th, 2016, using the latest `ffjson` and go1.6.
+`go/codec` results are from March 4th, 2016, using the latest `go/codec` and go1.6.
+
+#### Unmarshaling
+
+| lib      | json size | MB/s | allocs/op | B/op  |
+|:---------|:----------|-----:|----------:|------:|
+| standard | regular   | 22   | 218       | 10229 |
+| standard | small     | 9.7  | 14        | 720   |
+|          |           |      |           |       |
+| easyjson | regular   | 125  | 128       | 9794  |
+| easyjson | small     | 67   | 3         | 128   |
+|          |           |      |           |       |
+| ffjson   | regular   | 66   | 141       | 9985  |
+| ffjson   | small     | 17.6 | 10        | 488   |
+|          |           |      |           |       |
+| codec    | regular   | 55   | 434       | 19299 |
+| codec    | small     | 29   | 7         | 336   |
+|          |           |      |           |       |
+| ujson    | regular   | 103  | N/A       | N/A   |
+
+#### Marshaling, one goroutine.
+
+| lib       | json size | MB/s | allocs/op | B/op  |
+|:----------|:----------|-----:|----------:|------:|
+| standard  | regular   | 75   | 9         | 23256 |
+| standard  | small     | 32   | 3         | 328   |
+| standard  | large     | 80   | 17        | 1.2M  |
+|           |           |      |           |       |
+| easyjson  | regular   | 213  | 9         | 10260 |
+| easyjson* | regular   | 263  | 8         | 742   |
+| easyjson  | small     | 125  | 1         | 128   |
+| easyjson  | large     | 212  | 33        | 490k  |
+| easyjson* | large     | 262  | 25        | 2879  |
+|           |           |      |           |       |
+| ffjson    | regular   | 122  | 153       | 21340 |
+| ffjson**  | regular   | 146  | 152       | 4897  |
+| ffjson    | small     | 36   | 5         | 384   |
+| ffjson**  | small     | 64   | 4         | 128   |
+| ffjson    | large     | 134  | 7317      | 818k  |
+| ffjson**  | large     | 125  | 7320      | 827k  |
+|           |           |      |           |       |
+| codec     | regular   | 80   | 17        | 33601 |
+| codec***  | regular   | 108  | 9         | 1153  |
+| codec     | small     | 42   | 3         | 304   |
+| codec***  | small     | 56   | 1         | 48    |
+| codec     | large     | 73   | 483       | 2.5M  |
+| codec***  | large     | 103  | 451       | 66007 |
+|           |           |      |           |       |
+| ujson     | regular   | 92   | N/A       | N/A   |
+
+\* marshaling to a writer,
+\*\* using `ffjson.Pool()`,
+\*\*\* reusing output slice instead of resetting it to nil
+
+#### Marshaling, concurrent.
+
+| lib       | json size | MB/s | allocs/op | B/op  |
+|:----------|:----------|-----:|----------:|------:|
+| standard  | regular   | 252  | 9         | 23257 |
+| standard  | small     | 124  | 3         | 328   |
+| standard  | large     | 289  | 17        | 1.2M  |
+|           |           |      |           |       |
+| easyjson  | regular   | 792  | 9         | 10597 |
+| easyjson* | regular   | 1748 | 8         | 779   |
+| easyjson  | small     | 333  | 1         | 128   |
+| easyjson  | large     | 718  | 36        | 548k  |
+| easyjson* | large     | 2134 | 25        | 4957  |
+|           |           |      |           |       |
+| ffjson    | regular   | 301  | 153       | 21629 |
+| ffjson**  | regular   | 707  | 152       | 5148  |
+| ffjson    | small     | 62   | 5         | 384   |
+| ffjson**  | small     | 282  | 4         | 128   |
+| ffjson    | large     | 438  | 7330      | 1.0M  |
+| ffjson**  | large     | 131  | 7319      | 820k  |
+|           |           |      |           |       |
+| codec     | regular   | 183  | 17        | 33603 |
+| codec***  | regular   | 671  | 9         | 1157  |
+| codec     | small     | 147  | 3         | 304   |
+| codec***  | small     | 299  | 1         | 48    |
+| codec     | large     | 190  | 483       | 2.5M  |
+| codec***  | large     | 752  | 451       | 77574 |
+
+\* marshaling to a writer,
+\*\* using `ffjson.Pool()`,
+\*\*\* reusing output slice instead of resetting it to nil
diff --git a/vendor/github.com/mailru/easyjson/go.mod b/vendor/github.com/mailru/easyjson/go.mod
new file mode 100644
index 000000000..7bc4a6584
--- /dev/null
+++ b/vendor/github.com/mailru/easyjson/go.mod
@@ -0,0 +1,3 @@
+module github.com/mailru/easyjson
+
+go 1.12
diff --git a/vendor/github.com/mailru/easyjson/helpers.go b/vendor/github.com/mailru/easyjson/helpers.go
new file mode 100644
index 000000000..b86b87d22
--- /dev/null
+++ b/vendor/github.com/mailru/easyjson/helpers.go
@@ -0,0 +1,78 @@
+// Package easyjson contains marshaler/unmarshaler interfaces and helper functions.
+package easyjson
+
+import (
+	"io"
+	"io/ioutil"
+	"net/http"
+	"strconv"
+
+	"github.com/mailru/easyjson/jlexer"
+	"github.com/mailru/easyjson/jwriter"
+)
+
+// Marshaler is an easyjson-compatible marshaler interface.
+type Marshaler interface {
+	MarshalEasyJSON(w *jwriter.Writer)
+}
+
+// Marshaler is an easyjson-compatible unmarshaler interface.
+type Unmarshaler interface {
+	UnmarshalEasyJSON(w *jlexer.Lexer)
+}
+
+// Optional defines an undefined-test method for a type to integrate with 'omitempty' logic.
+type Optional interface {
+	IsDefined() bool
+}
+
+// Marshal returns data as a single byte slice. Method is suboptimal as the data is likely to be copied
+// from a chain of smaller chunks.
+func Marshal(v Marshaler) ([]byte, error) {
+	w := jwriter.Writer{}
+	v.MarshalEasyJSON(&w)
+	return w.BuildBytes()
+}
+
+// MarshalToWriter marshals the data to an io.Writer.
+func MarshalToWriter(v Marshaler, w io.Writer) (written int, err error) {
+	jw := jwriter.Writer{}
+	v.MarshalEasyJSON(&jw)
+	return jw.DumpTo(w)
+}
+
+// MarshalToHTTPResponseWriter sets Content-Length and Content-Type headers for the
+// http.ResponseWriter, and send the data to the writer. started will be equal to
+// false if an error occurred before any http.ResponseWriter methods were actually
+// invoked (in this case a 500 reply is possible).
+func MarshalToHTTPResponseWriter(v Marshaler, w http.ResponseWriter) (started bool, written int, err error) {
+	jw := jwriter.Writer{}
+	v.MarshalEasyJSON(&jw)
+	if jw.Error != nil {
+		return false, 0, jw.Error
+	}
+	w.Header().Set("Content-Type", "application/json")
+	w.Header().Set("Content-Length", strconv.Itoa(jw.Size()))
+
+	started = true
+	written, err = jw.DumpTo(w)
+	return
+}
+
+// Unmarshal decodes the JSON in data into the object.
+func Unmarshal(data []byte, v Unmarshaler) error {
+	l := jlexer.Lexer{Data: data}
+	v.UnmarshalEasyJSON(&l)
+	return l.Error()
+}
+
+// UnmarshalFromReader reads all the data in the reader and decodes as JSON into the object.
+func UnmarshalFromReader(r io.Reader, v Unmarshaler) error {
+	data, err := ioutil.ReadAll(r)
+	if err != nil {
+		return err
+	}
+	l := jlexer.Lexer{Data: data}
+	v.UnmarshalEasyJSON(&l)
+	return l.Error()
+}
diff --git a/vendor/github.com/mailru/easyjson/raw.go b/vendor/github.com/mailru/easyjson/raw.go
new file mode 100644
index 000000000..81bd002e1
--- /dev/null
+++ b/vendor/github.com/mailru/easyjson/raw.go
@@ -0,0 +1,45 @@
+package easyjson
+
+import (
+	"github.com/mailru/easyjson/jlexer"
+	"github.com/mailru/easyjson/jwriter"
+)
+
+// RawMessage is a raw piece of JSON (number, string, bool, object, array or
+// null) that is extracted without parsing and output as is during marshaling.
+type RawMessage []byte
+
+// MarshalEasyJSON does JSON marshaling using easyjson interface.
+func (v *RawMessage) MarshalEasyJSON(w *jwriter.Writer) {
+	if len(*v) == 0 {
+		w.RawString("null")
+	} else {
+		w.Raw(*v, nil)
+	}
+}
+
+// UnmarshalEasyJSON does JSON unmarshaling using easyjson interface.
+func (v *RawMessage) UnmarshalEasyJSON(l *jlexer.Lexer) {
+	*v = RawMessage(l.Raw())
+}
+
+// UnmarshalJSON implements encoding/json.Unmarshaler interface.
+func (v *RawMessage) UnmarshalJSON(data []byte) error {
+	*v = data
+	return nil
+}
+
+var nullBytes = []byte("null")
+
+// MarshalJSON implements encoding/json.Marshaler interface.
+func (v RawMessage) MarshalJSON() ([]byte, error) {
+	if len(v) == 0 {
+		return nullBytes, nil
+	}
+	return v, nil
+}
+
+// IsDefined is required for integration with omitempty easyjson logic.
+func (v *RawMessage) IsDefined() bool {
+	return len(*v) > 0
+}
diff --git a/vendor/github.com/slinkydeveloper/loadastic/kafka/gen-loadastic.go b/vendor/github.com/slinkydeveloper/loadastic/kafka/gen-loadastic.go
index 7c47183bf..c570b43ee 100644
--- a/vendor/github.com/slinkydeveloper/loadastic/kafka/gen-loadastic.go
+++ b/vendor/github.com/slinkydeveloper/loadastic/kafka/gen-loadastic.go
@@ -11,7 +11,7 @@ import (
 
 	"github.com/google/uuid"
 	"github.com/slinkydeveloper/loadastic/common"
-	vegeta "github.com/tsenart/vegeta/lib"
+	vegeta "github.com/tsenart/vegeta/v12/lib"
 )
 
 type BeforeSend func(request RecordPayload, tickerTimestamp time.Time, id uint64, uuid string)
diff --git a/vendor/github.com/tsenart/vegeta/lib/results_easyjson.go b/vendor/github.com/tsenart/vegeta/lib/results_easyjson.go
deleted file mode 100644
index b1594bdc3..000000000
--- a/vendor/github.com/tsenart/vegeta/lib/results_easyjson.go
+++ /dev/null
@@ -1,165 +0,0 @@
-// This file has been modified from the original generated code to make it work with
-// type alias jsonResult so that the methods aren't exposed in Result.
-
-package vegeta
-
-import (
-	"time"
-
-	"github.com/mailru/easyjson/jlexer"
-	"github.com/mailru/easyjson/jwriter"
-)
-
-type jsonResult Result
-
-func (r *jsonResult) decode(in *jlexer.Lexer) {
-	isTopLevel := in.IsStart()
-	if in.IsNull() {
-		if isTopLevel {
-			in.Consumed()
-		}
-		in.Skip()
-		return
-	}
-	in.Delim('{')
-	for !in.IsDelim('}') {
-		key := in.UnsafeString()
-		in.WantColon()
-		if in.IsNull() {
-			in.Skip()
-			in.WantComma()
-			continue
-		}
-		switch key {
-		case "attack":
-			r.Attack = string(in.String())
-		case "seq":
-			r.Seq = uint64(in.Uint64())
-		case "code":
-			r.Code = uint16(in.Uint16())
-		case "timestamp":
-			if data := in.Raw(); in.Ok() {
-				in.AddError((r.Timestamp).UnmarshalJSON(data))
-			}
-		case "latency":
-			r.Latency = time.Duration(in.Int64())
-		case "bytes_out":
-			r.BytesOut = uint64(in.Uint64())
-		case "bytes_in":
-			r.BytesIn = uint64(in.Uint64())
-		case "error":
-			r.Error = string(in.String())
-		case "body":
-			if in.IsNull() {
-				in.Skip()
-				r.Body = nil
-			} else {
-				r.Body = in.Bytes()
-			}
-		default:
-			in.SkipRecursive()
-		}
-		in.WantComma()
-	}
-	in.Delim('}')
-	if isTopLevel {
-		in.Consumed()
-	}
-}
-
-func (r jsonResult) encode(out *jwriter.Writer) {
-	out.RawByte('{')
-	first := true
-	_ = first
-	{
-		const prefix string = ",\"attack\":"
-		if first {
-			first = false
-			out.RawString(prefix[1:])
-		} else {
-			out.RawString(prefix)
-		}
-		out.String(string(r.Attack))
-	}
-	{
-		const prefix string = ",\"seq\":"
-		if first {
-			first = false
-			out.RawString(prefix[1:])
-		} else {
-			out.RawString(prefix)
-		}
-		out.Uint64(uint64(r.Seq))
-	}
-	{
-		const prefix string = ",\"code\":"
-		if first {
-			first = false
-			out.RawString(prefix[1:])
-		} else {
-			out.RawString(prefix)
-		}
-		out.Uint16(uint16(r.Code))
-	}
-	{
-		const prefix string = ",\"timestamp\":"
-		if first {
-			first = false
-			out.RawString(prefix[1:])
-		} else {
-			out.RawString(prefix)
-		}
-		out.Raw((r.Timestamp).MarshalJSON())
-	}
-	{
-		const prefix string = ",\"latency\":"
-		if first {
-			first = false
-			out.RawString(prefix[1:])
-		} else {
-			out.RawString(prefix)
-		}
-		out.Int64(int64(r.Latency))
-	}
-	{
-		const prefix string = ",\"bytes_out\":"
-		if first {
-			first = false
-			out.RawString(prefix[1:])
-		} else {
-			out.RawString(prefix)
-		}
-		out.Uint64(uint64(r.BytesOut))
-	}
-	{
-		const prefix string = ",\"bytes_in\":"
-		if first {
-			first = false
-			out.RawString(prefix[1:])
-		} else {
-			out.RawString(prefix)
-		}
-		out.Uint64(uint64(r.BytesIn))
-	}
-	{
-		const prefix string = ",\"error\":"
-		if first {
-			first = false
-			out.RawString(prefix[1:])
-		} else {
-			out.RawString(prefix)
-		}
-		out.String(string(r.Error))
-	}
-	{
-		const prefix string = ",\"body\":"
-		if first {
-			first = false
-			out.RawString(prefix[1:])
-		} else {
-			out.RawString(prefix)
-		}
-		out.Base64Bytes(r.Body)
-	}
-	out.RawByte('}')
-}
diff --git a/vendor/github.com/tsenart/vegeta/LICENSE b/vendor/github.com/tsenart/vegeta/v12/LICENSE
similarity index 96%
rename from vendor/github.com/tsenart/vegeta/LICENSE
rename to vendor/github.com/tsenart/vegeta/v12/LICENSE
index 441df0ab4..03ec4f5a8 100644
--- a/vendor/github.com/tsenart/vegeta/LICENSE
+++ b/vendor/github.com/tsenart/vegeta/v12/LICENSE
@@ -1,6 +1,6 @@
 The MIT License (MIT)
 
-Copyright (c) 2013-2016 Tomás Senart
+Copyright (c) 2013-2020 Tomás Senart
 
 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
diff --git a/vendor/github.com/tsenart/vegeta/lib/attack.go b/vendor/github.com/tsenart/vegeta/v12/lib/attack.go
similarity index 88%
rename from vendor/github.com/tsenart/vegeta/lib/attack.go
rename to vendor/github.com/tsenart/vegeta/v12/lib/attack.go
index 51c4957db..0294c628b 100644
--- a/vendor/github.com/tsenart/vegeta/lib/attack.go
+++ b/vendor/github.com/tsenart/vegeta/v12/lib/attack.go
@@ -10,6 +10,7 @@ import (
 	"net"
 	"net/http"
 	"net/url"
+	"strconv"
 	"sync"
 	"time"
 
@@ -28,6 +29,7 @@ type Attacker struct {
 	seqmu      sync.Mutex
 	seq        uint64
 	began      time.Time
+	chunked    bool
 }
 
 const (
@@ -40,6 +42,9 @@ const (
 	// DefaultConnections is the default amount of max open idle connections per
 	// target host.
 	DefaultConnections = 10000
+	// DefaultMaxConnections is the default amount of connections per target
+	// host.
+	DefaultMaxConnections = 0
 	// DefaultWorkers is the default initial number of workers used to carry an attack.
 	DefaultWorkers = 10
 	// DefaultMaxWorkers is the default maximum number of workers used to carry an attack.
@@ -81,6 +86,7 @@ func NewAttacker(opts ...func(*Attacker)) *Attacker {
 			Dial:                a.dialer.Dial,
 			TLSClientConfig:     DefaultTLSConfig,
 			MaxIdleConnsPerHost: DefaultConnections,
+			MaxConnsPerHost:     DefaultMaxConnections,
 		},
 	}
 
@@ -113,6 +119,21 @@ func Connections(n int) func(*Attacker) {
 	}
 }
 
+// MaxConnections returns a functional option which sets the number of maximum
+// connections per target host.
+func MaxConnections(n int) func(*Attacker) {
+	return func(a *Attacker) {
+		tr := a.client.Transport.(*http.Transport)
+		tr.MaxConnsPerHost = n
+	}
+}
+
+// ChunkedBody returns a functional option which makes the attacker send the
+// body of each request with the chunked transfer encoding.
+func ChunkedBody(b bool) func(*Attacker) {
+	return func(a *Attacker) { a.chunked = b }
+}
+
 // Redirects returns a functional option which sets the maximum
 // number of redirects an Attacker will follow.
 func Redirects(n int) func(*Attacker) {
@@ -229,6 +250,16 @@ func Client(c *http.Client) func(*Attacker) {
 	return func(a *Attacker) { a.client = *c }
 }
 
+// ProxyHeader returns a functional option that allows you to add your own
+// Proxy CONNECT headers
+func ProxyHeader(h http.Header) func(*Attacker) {
+	return func(a *Attacker) {
+		if tr, ok := a.client.Transport.(*http.Transport); ok {
+			tr.ProxyConnectHeader = h
+		}
+	}
+}
+
 // Attack reads its Targets from the passed Targeter and attacks them at
 // the rate specified by the Pacer. When the duration is zero the attack
 // runs until Stop is called. Results are sent to the returned channel as soon
@@ -336,11 +367,24 @@ func (a *Attacker) hit(tr Targeter, name string) *Result {
 		return &res
 	}
 
+	res.Method = tgt.Method
+	res.URL = tgt.URL
+
 	req, err := tgt.Request()
 	if err != nil {
 		return &res
 	}
 
+	if name != "" {
+		req.Header.Set("X-Vegeta-Attack", name)
+	}
+
+	req.Header.Set("X-Vegeta-Seq", strconv.FormatUint(res.Seq, 10))
+
+	if a.chunked {
+		req.TransferEncoding = append(req.TransferEncoding, "chunked")
+	}
+
 	r, err := a.client.Do(req)
 	if err != nil {
 		return &res
@@ -368,5 +412,7 @@ func (a *Attacker) hit(tr Targeter, name string) *Result {
 		res.Error = r.Status
 	}
 
+	res.Headers = r.Header
+
 	return &res
 }
diff --git a/vendor/github.com/tsenart/vegeta/v12/lib/attack_fuzz.go b/vendor/github.com/tsenart/vegeta/v12/lib/attack_fuzz.go
new file mode 100644
index 000000000..e14eef61f
--- /dev/null
+++ b/vendor/github.com/tsenart/vegeta/v12/lib/attack_fuzz.go
@@ -0,0 +1,154 @@
+// +build gofuzz
+
+package vegeta
+
+import (
+	"encoding/binary"
+	"fmt"
+	"io/ioutil"
+	"net"
+	"net/http"
+	"os"
+	"time"
+)
+
+// FuzzAttackerTCP fuzzes binary responses to attacker.
+func FuzzAttackerTCP(fuzz []byte) int {
+	// Ignore empty fuzz
+	if len(fuzz) == 0 {
+		return -1
+	}
+
+	// Start server
+	directory, err := ioutil.TempDir("/tmp", "fuzz")
+	if err != nil {
+		panic(err.Error())
+	}
+	socket := fmt.Sprintf("%s/attacker.sock", directory)
+	listener, err := net.Listen("unix", socket)
+	if err != nil {
+		panic(err.Error())
+	}
+	go func() {
+		connection, err := listener.Accept()
+		if err != nil {
+			panic(err.Error())
+		}
+		_, err = connection.Write(fuzz)
+		if err != nil {
+			panic(err.Error())
+		}
+		err = connection.Close()
+		if err != nil {
+			panic(err.Error())
+		}
+	}()
+	defer listener.Close()
+	defer os.RemoveAll(directory)
+
+	// Setup targeter
+	targeter := Targeter(func(target *Target) error {
+		target.Method = "GET"
+		target.URL = "http://vegeta.test"
+		return nil
+	})
+
+	// Deliver a single hit
+	attacker := NewAttacker(
+		UnixSocket(socket),
+		Workers(1),
+		MaxWorkers(1),
+		Timeout(time.Second),
+		KeepAlive(false),
+	)
+	result := attacker.hit(targeter, "fuzz")
+	if result.Error != "" {
+		return 0
+	}
+	return 1
+}
+
+// FuzzAttackerHTTP fuzzes valid HTTP responses to attacker.
+func FuzzAttackerHTTP(fuzz []byte) int {
+	// Decode response
+	code, headers, body, ok := decodeFuzzResponse(fuzz)
+	if !ok {
+		return -1
+	}
+
+	// Start server
+	directory, err := ioutil.TempDir("/tmp", "fuzz")
+	if err != nil {
+		panic(err.Error())
+	}
+	socket := fmt.Sprintf("%s/attacker.sock", directory)
+	listener, err := net.Listen("unix", socket)
+	if err != nil {
+		panic(err.Error())
+	}
+	handler := func(response http.ResponseWriter, request *http.Request) {
+		for name, values := range headers {
+			for _, value := range values {
+				response.Header().Add(name, value)
+			}
+		}
+		response.WriteHeader(int(code))
+		_, err := response.Write(body)
+		if err != nil {
+			panic(err.Error())
+		}
+	}
+	server := http.Server{
+		Handler: http.HandlerFunc(handler),
+	}
+	defer server.Close()
+	defer listener.Close()
+	defer os.RemoveAll(directory)
+	go server.Serve(listener)
+
+	// Setup targeter
+	targeter := Targeter(func(target *Target) error {
+		target.Method = "GET"
+		target.URL = "http://vegeta.test"
+		return nil
+	})
+
+	// Deliver a single hit
+	attacker := NewAttacker(
+		UnixSocket(socket),
+		Workers(1),
+		MaxWorkers(1),
+		Timeout(time.Second),
+		KeepAlive(false),
+	)
+	result := attacker.hit(targeter, "fuzz")
+	if result.Error != "" {
+		return 0
+	}
+	return 1
+}
+
+func decodeFuzzResponse(fuzz []byte) (
+	code int,
+	headers map[string][]string,
+	body []byte,
+	ok bool,
+) {
+	if len(fuzz) < 2 {
+		return
+	}
+	headers = make(map[string][]string)
+	body = []byte{}
+	code = int(binary.LittleEndian.Uint16(fuzz[0:2]))
+	if len(fuzz) == 2 {
+		ok = true
+		return
+	}
+	fuzz, ok = decodeFuzzHeaders(fuzz[2:], headers)
+	if !ok {
+		return
+	}
+	body = fuzz
+	ok = true
+	return
+}
diff --git a/vendor/github.com/tsenart/vegeta/lib/histogram.go b/vendor/github.com/tsenart/vegeta/v12/lib/histogram.go
similarity index 91%
rename from vendor/github.com/tsenart/vegeta/lib/histogram.go
rename to vendor/github.com/tsenart/vegeta/v12/lib/histogram.go
index f8fd84462..acb546f19 100644
--- a/vendor/github.com/tsenart/vegeta/lib/histogram.go
+++ b/vendor/github.com/tsenart/vegeta/v12/lib/histogram.go
@@ -68,11 +68,15 @@ func (bs *Buckets) UnmarshalText(value []byte) error {
 	if len(value) < 2 || value[0] != '[' || value[len(value)-1] != ']' {
 		return fmt.Errorf("bad buckets: %s", value)
 	}
-	for _, v := range strings.Split(string(value[1:len(value)-1]), ",") {
+	for i, v := range strings.Split(string(value[1:len(value)-1]), ",") {
 		d, err := time.ParseDuration(strings.TrimSpace(v))
 		if err != nil {
 			return err
 		}
+		// add a default range of [0-Buckets[0]) if needed
+		if i == 0 && d > 0 {
+			*bs = append(*bs, 0)
+		}
 		*bs = append(*bs, d)
 	}
 	if len(*bs) == 0 {
diff --git a/vendor/github.com/tsenart/vegeta/lib/metrics.go b/vendor/github.com/tsenart/vegeta/v12/lib/metrics.go
similarity index 94%
rename from vendor/github.com/tsenart/vegeta/lib/metrics.go
rename to vendor/github.com/tsenart/vegeta/v12/lib/metrics.go
index 5b3cd626a..5d7dbf9b2 100644
--- a/vendor/github.com/tsenart/vegeta/lib/metrics.go
+++ b/vendor/github.com/tsenart/vegeta/v12/lib/metrics.go
@@ -89,6 +89,11 @@ func (m *Metrics) Add(r *Result) {
 // derived summary metrics which don't need to be run on every Add call.
 func (m *Metrics) Close() {
 	m.init()
+
+	if m.Requests == 0 {
+		return
+	}
+
 	m.Rate = float64(m.Requests)
 	m.Throughput = float64(m.success)
 	m.Duration = m.Latest.Sub(m.Earliest)
@@ -104,6 +109,7 @@ func (m *Metrics) Close() {
 	m.Success = float64(m.success) / float64(m.Requests)
 	m.Latencies.Mean = time.Duration(float64(m.Latencies.Total) / float64(m.Requests))
 	m.Latencies.P50 = m.Latencies.Quantile(0.50)
+	m.Latencies.P90 = m.Latencies.Quantile(0.90)
 	m.Latencies.P95 = m.Latencies.Quantile(0.95)
 	m.Latencies.P99 = m.Latencies.Quantile(0.99)
 }
@@ -130,12 +136,16 @@ type LatencyMetrics struct {
 	Mean time.Duration `json:"mean"`
 	// P50 is the 50th percentile request latency.
 	P50 time.Duration `json:"50th"`
+	// P90 is the 90th percentile request latency.
+	P90 time.Duration `json:"90th"`
 	// P95 is the 95th percentile request latency.
 	P95 time.Duration `json:"95th"`
 	// P99 is the 99th percentile request latency.
 	P99 time.Duration `json:"99th"`
 	// Max is the maximum observed request latency.
 	Max time.Duration `json:"max"`
+	// Min is the minimum observed request latency.
+	Min time.Duration `json:"min"`
 
 	estimator estimator
 }
@@ -146,6 +156,9 @@ func (l *LatencyMetrics) Add(latency time.Duration) {
 	if l.Total += latency; latency > l.Max {
 		l.Max = latency
 	}
+	if latency < l.Min || l.Min == 0 {
+		l.Min = latency
+	}
 	l.estimator.Add(float64(latency))
 }
 
diff --git a/vendor/github.com/tsenart/vegeta/lib/pacer.go b/vendor/github.com/tsenart/vegeta/v12/lib/pacer.go
similarity index 88%
rename from vendor/github.com/tsenart/vegeta/lib/pacer.go
rename to vendor/github.com/tsenart/vegeta/v12/lib/pacer.go
index 97c8310be..4c04d637f 100644
--- a/vendor/github.com/tsenart/vegeta/lib/pacer.go
+++ b/vendor/github.com/tsenart/vegeta/v12/lib/pacer.go
@@ -6,12 +6,17 @@ import (
 	"time"
 )
 
-// A Pacer defines the rate of hits during an Attack by
-// returning the duration an Attacker should wait until
-// hitting the next Target. If the second return value
-// is true, the attack will terminate.
+// A Pacer defines the rate of hits during an Attack.
 type Pacer interface {
+	// Pace returns the duration an Attacker should wait until
+	// hitting the next Target, given an already elapsed duration and
+	// completed hits. If the second return value is true, an attacker
+	// should stop sending hits.
 	Pace(elapsed time.Duration, hits uint64) (wait time.Duration, stop bool)
+
+	// Rate returns a Pacer's instantaneous hit rate (per seconds)
+	// at the given elapsed duration of an attack.
+	Rate(elapsed time.Duration) float64
 }
 
 // A PacerFunc is a function adapter type that implements
@@ -65,6 +70,13 @@ func (cp ConstantPacer) Pace(elapsed time.Duration, hits uint64) (time.Duration,
 	return delta - elapsed, false
 }
 
+// Rate returns a ConstantPacer's instantaneous hit rate (i.e. requests per second)
+// at the given elapsed duration of an attack. Since it's constant, the return
+// value is independent of the given elapsed duration.
+func (cp ConstantPacer) Rate(elapsed time.Duration) float64 {
+	return cp.hitsPerNs() * 1e9
+}
+
 // hitsPerNs returns the attack rate this ConstantPacer represents, in
 // fractional hits per nanosecond.
 func (cp ConstantPacer) hitsPerNs() float64 {
@@ -184,6 +196,12 @@ func (sp SinePacer) Pace(elapsedTime time.Duration, elapsedHits uint64) (time.Du
 	return nextHitIn, false
 }
 
+// Rate returns a SinePacer's instantaneous hit rate (i.e. requests per second)
+// at the given elapsed duration of an attack.
+func (sp SinePacer) Rate(elapsed time.Duration) float64 {
+	return sp.hitsPerNs(elapsed) * 1e9
+}
+
 // ampHits returns AP/2𝛑, which is the number of hits added or subtracted
 // from the Mean due to the Amplitude over a quarter of the Period,
 // i.e. from 0 → 𝛑/2 radians
@@ -240,7 +258,7 @@ func (p LinearPacer) Pace(elapsed time.Duration, hits uint64) (time.Duration, bo
 		return 0, false
 	}
 
-	rate := p.rate(elapsed)
+	rate := p.Rate(elapsed)
 	interval := math.Round(1e9 / rate)
 
 	if n := uint64(interval); n != 0 && math.MaxInt64/n < hits {
@@ -254,6 +272,15 @@ func (p LinearPacer) Pace(elapsed time.Duration, hits uint64) (time.Duration, bo
 	return wait, false
 }
 
+// Rate returns a LinearPacer's instantaneous hit rate (i.e. requests per second)
+// at the given elapsed duration of an attack.
+func (p LinearPacer) Rate(elapsed time.Duration) float64 {
+	a := p.Slope
+	x := elapsed.Seconds()
+	b := p.StartAt.hitsPerNs() * 1e9
+	return a*x + b
+}
+
 // hits returns the number of hits that have been sent during an attack
 // lasting t nanoseconds. It returns a float so we can tell exactly how
 // much we've missed our target by when solving numerically in Pace.
@@ -268,12 +295,3 @@ func (p LinearPacer) hits(t time.Duration) float64 {
 
 	return (a*math.Pow(x, 2))/2 + b*x
 }
-
-// rate calculates the instantaneous rate of attack at
-// t nanoseconds after the attack began.
-func (p LinearPacer) rate(t time.Duration) float64 {
-	a := p.Slope
-	x := t.Seconds()
-	b := p.StartAt.hitsPerNs() * 1e9
-	return a*x + b
-}
diff --git a/vendor/github.com/tsenart/vegeta/lib/reporters.go b/vendor/github.com/tsenart/vegeta/v12/lib/reporters.go
similarity index 88%
rename from vendor/github.com/tsenart/vegeta/lib/reporters.go
rename to vendor/github.com/tsenart/vegeta/v12/lib/reporters.go
index e86a8fbdf..aa7e42513 100644
--- a/vendor/github.com/tsenart/vegeta/lib/reporters.go
+++ b/vendor/github.com/tsenart/vegeta/v12/lib/reporters.go
@@ -57,7 +57,7 @@ func NewHistogramReporter(h *Histogram) Reporter {
 func NewTextReporter(m *Metrics) Reporter {
 	const fmtstr = "Requests\t[total, rate, throughput]\t%d, %.2f, %.2f\n" +
 		"Duration\t[total, attack, wait]\t%s, %s, %s\n" +
-		"Latencies\t[mean, 50, 95, 99, max]\t%s, %s, %s, %s, %s\n" +
+		"Latencies\t[min, mean, 50, 90, 95, 99, max]\t%s, %s, %s, %s, %s, %s, %s\n" +
 		"Bytes In\t[total, mean]\t%d, %.2f\n" +
 		"Bytes Out\t[total, mean]\t%d, %.2f\n" +
 		"Success\t[ratio]\t%.2f%%\n" +
@@ -67,8 +67,16 @@ func NewTextReporter(m *Metrics) Reporter {
 		tw := tabwriter.NewWriter(w, 0, 8, 2, ' ', tabwriter.StripEscape)
 		if _, err = fmt.Fprintf(tw, fmtstr,
 			m.Requests, m.Rate, m.Throughput,
-			m.Duration+m.Wait, m.Duration, m.Wait,
-			m.Latencies.Mean, m.Latencies.P50, m.Latencies.P95, m.Latencies.P99, m.Latencies.Max,
+			round(m.Duration+m.Wait),
+			round(m.Duration),
+			round(m.Wait),
+			round(m.Latencies.Min),
+			round(m.Latencies.Mean),
+			round(m.Latencies.P50),
+			round(m.Latencies.P90),
+			round(m.Latencies.P95),
+			round(m.Latencies.P99),
+			round(m.Latencies.Max),
 			m.BytesIn.Total, m.BytesIn.Mean,
 			m.BytesOut.Total, m.BytesOut.Mean,
 			m.Success*100,
@@ -104,6 +112,25 @@ func NewTextReporter(m *Metrics) Reporter {
 	}
 }
 
+var durations = [...]time.Duration{
+	time.Hour,
+	time.Minute,
+	time.Second,
+	time.Millisecond,
+	time.Microsecond,
+	time.Nanosecond,
+}
+
+// round to the next most precise unit
+func round(d time.Duration) time.Duration {
+	for i, unit := range durations {
+		if d >= unit && i < len(durations)-1 {
+			return d.Round(durations[i+1])
+		}
+	}
+	return d
+}
+
 // NewJSONReporter returns a Reporter that writes out Metrics as JSON.
 func NewJSONReporter(m *Metrics) Reporter {
 	return func(w io.Writer) error {
diff --git a/vendor/github.com/tsenart/vegeta/lib/results.go b/vendor/github.com/tsenart/vegeta/v12/lib/results.go
similarity index 78%
rename from vendor/github.com/tsenart/vegeta/lib/results.go
rename to vendor/github.com/tsenart/vegeta/v12/lib/results.go
index 2754cb518..eacd42d01 100644
--- a/vendor/github.com/tsenart/vegeta/lib/results.go
+++ b/vendor/github.com/tsenart/vegeta/v12/lib/results.go
@@ -7,12 +7,15 @@ import (
 	"encoding/csv"
 	"encoding/gob"
 	"io"
+	"net/http"
+	"net/textproto"
 	"sort"
 	"strconv"
+	"strings"
 	"time"
 
 	"github.com/mailru/easyjson/jlexer"
-	jwriter "github.com/mailru/easyjson/jwriter"
+	"github.com/mailru/easyjson/jwriter"
 )
 
 func init() {
@@ -30,6 +33,9 @@ type Result struct {
 	BytesIn   uint64        `json:"bytes_in"`
 	Error     string        `json:"error"`
 	Body      []byte        `json:"body"`
+	Method    string        `json:"method"`
+	URL       string        `json:"url"`
+	Headers   http.Header   `json:"headers"`
 }
 
 // End returns the time at which a Result ended.
@@ -45,7 +51,32 @@ func (r Result) Equal(other Result) bool {
 		r.BytesIn == other.BytesIn &&
 		r.BytesOut == other.BytesOut &&
 		r.Error == other.Error &&
-		bytes.Equal(r.Body, other.Body)
+		bytes.Equal(r.Body, other.Body) &&
+		r.Method == other.Method &&
+		r.URL == other.URL &&
+		headerEqual(r.Headers, other.Headers)
+}
+
+func headerEqual(h1, h2 http.Header) bool {
+	if len(h1) != len(h2) {
+		return false
+	}
+	if h1 == nil || h2 == nil {
+		return h1 == nil && h2 == nil
+	}
+	for key, values1 := range h1 {
+		values2 := h2[key]
+		if len(values1) != len(values2) {
+			return false
+		}
+		for i := range values1 {
+			if values1[i] != values2[i] {
+				return false
+			}
+		}
+	}
+
+	return true
 }
 
 // Results is a slice of Result type elements.
@@ -150,8 +181,10 @@ func NewCSVEncoder(w io.Writer) Encoder {
 			base64.StdEncoding.EncodeToString(r.Body),
 			r.Attack,
 			strconv.FormatUint(r.Seq, 10),
+			r.Method,
+			r.URL,
+			base64.StdEncoding.EncodeToString(headerBytes(r.Headers)),
 		})
-
 		if err != nil {
 			return err
 		}
@@ -162,10 +195,19 @@ func NewCSVEncoder(w io.Writer) Encoder {
 	}
 }
 
+func headerBytes(h http.Header) []byte {
+	if h == nil {
+		return nil
+	}
+	var hdr bytes.Buffer
+	_ = h.Write(&hdr)
+	return append(hdr.Bytes(), '\r', '\n')
+}
+
 // NewCSVDecoder returns a Decoder that decodes CSV encoded Results.
-func NewCSVDecoder(rd io.Reader) Decoder {
-	dec := csv.NewReader(rd)
-	dec.FieldsPerRecord = 9
+func NewCSVDecoder(r io.Reader) Decoder {
+	dec := csv.NewReader(r)
+	dec.FieldsPerRecord = 12
 	dec.TrimLeadingSpace = true
 
 	return func(r *Result) error {
@@ -201,23 +243,42 @@ func NewCSVDecoder(rd io.Reader) Decoder {
 		}
 
 		r.Error = rec[5]
-		r.Body, err = base64.StdEncoding.DecodeString(rec[6])
+		if r.Body, err = base64.StdEncoding.DecodeString(rec[6]); err != nil {
+			return err
+		}
 
 		r.Attack = rec[7]
 		if r.Seq, err = strconv.ParseUint(rec[8], 10, 64); err != nil {
 			return err
 		}
 
+		r.Method = rec[9]
+		r.URL = rec[10]
+
+		if rec[11] != "" {
+			pr := textproto.NewReader(bufio.NewReader(
+				base64.NewDecoder(base64.StdEncoding, strings.NewReader(rec[11]))))
+			hdr, err := pr.ReadMIMEHeader()
+			if err != nil {
+				return err
+			}
+			r.Headers = http.Header(hdr)
+		}
+
 		return err
 	}
 }
 
+//go:generate easyjson -no_std_marshalers -output_filename results_easyjson.go results.go
+//easyjson:json
+type jsonResult Result
+
 // NewJSONEncoder returns an Encoder that dumps the given *Results as a JSON
 // object.
 func NewJSONEncoder(w io.Writer) Encoder {
 	var jw jwriter.Writer
 	return func(r *Result) error {
-		(*jsonResult)(r).encode(&jw)
+		(*jsonResult)(r).MarshalEasyJSON(&jw)
 		if jw.Error != nil {
 			return jw.Error
 		}
@@ -232,10 +293,10 @@ func NewJSONDecoder(r io.Reader) Decoder {
 	rd := bufio.NewReader(r)
 	return func(r *Result) (err error) {
 		var jl jlexer.Lexer
-		if jl.Data, err = rd.ReadSlice('\n'); err != nil {
+		if jl.Data, err = rd.ReadBytes('\n'); err != nil {
 			return err
 		}
-		(*jsonResult)(r).decode(&jl)
+		(*jsonResult)(r).UnmarshalEasyJSON(&jl)
 		return jl.Error()
 	}
 }
diff --git a/vendor/github.com/tsenart/vegeta/v12/lib/results_easyjson.go b/vendor/github.com/tsenart/vegeta/v12/lib/results_easyjson.go
new file mode 100644
index 000000000..3beb22f7d
--- /dev/null
+++ b/vendor/github.com/tsenart/vegeta/v12/lib/results_easyjson.go
@@ -0,0 +1,223 @@
+// Code generated by easyjson for marshaling/unmarshaling. DO NOT EDIT.
+
+package vegeta
+
+import (
+	json "encoding/json"
+	easyjson "github.com/mailru/easyjson"
+	jlexer "github.com/mailru/easyjson/jlexer"
+	jwriter "github.com/mailru/easyjson/jwriter"
+	http "net/http"
+	time "time"
+)
+
+// suppress unused package warning
+var (
+	_ *json.RawMessage
+	_ *jlexer.Lexer
+	_ *jwriter.Writer
+	_ easyjson.Marshaler
+)
+
+func easyjsonBd1621b8DecodeGithubComTsenartVegetaV12Lib(in *jlexer.Lexer, out *jsonResult) {
+	isTopLevel := in.IsStart()
+	if in.IsNull() {
+		if isTopLevel {
+			in.Consumed()
+		}
+		in.Skip()
+		return
+	}
+	in.Delim('{')
+	for !in.IsDelim('}') {
+		key := in.UnsafeString()
+		in.WantColon()
+		if in.IsNull() {
+			in.Skip()
+			in.WantComma()
+			continue
+		}
+		switch key {
+		case "attack":
+			out.Attack = string(in.String())
+		case "seq":
+			out.Seq = uint64(in.Uint64())
+		case "code":
+			out.Code = uint16(in.Uint16())
+		case "timestamp":
+			if data := in.Raw(); in.Ok() {
+				in.AddError((out.Timestamp).UnmarshalJSON(data))
+			}
+		case "latency":
+			out.Latency = time.Duration(in.Int64())
+		case "bytes_out":
+			out.BytesOut = uint64(in.Uint64())
+		case "bytes_in":
+			out.BytesIn = uint64(in.Uint64())
+		case "error":
+			out.Error = string(in.String())
+		case "body":
+			if in.IsNull() {
+				in.Skip()
+				out.Body = nil
+			} else {
+				out.Body = in.Bytes()
+			}
+		case "method":
+			out.Method = string(in.String())
+		case "url":
+			out.URL = string(in.String())
+		case "headers":
+			if in.IsNull() {
+				in.Skip()
+			} else {
+				in.Delim('{')
+				if !in.IsDelim('}') {
+					out.Headers = make(http.Header)
+				} else {
+					out.Headers = nil
+				}
+				for !in.IsDelim('}') {
+					key := string(in.String())
+					in.WantColon()
+					var v2 []string
+					if in.IsNull() {
+						in.Skip()
+						v2 = nil
+					} else {
+						in.Delim('[')
+						if v2 == nil {
+							if !in.IsDelim(']') {
+								v2 = make([]string, 0, 4)
+							} else {
+								v2 = []string{}
+							}
+						} else {
+							v2 = (v2)[:0]
+						}
+						for !in.IsDelim(']') {
+							var v3 string
+							v3 = string(in.String())
+							v2 = append(v2, v3)
+							in.WantComma()
+						}
+						in.Delim(']')
+					}
+					(out.Headers)[key] = v2
+					in.WantComma()
+				}
+				in.Delim('}')
+			}
+		default:
+			in.SkipRecursive()
+		}
+		in.WantComma()
+	}
+	in.Delim('}')
+	if isTopLevel {
+		in.Consumed()
+	}
+}
+func easyjsonBd1621b8EncodeGithubComTsenartVegetaV12Lib(out *jwriter.Writer, in jsonResult) {
+	out.RawByte('{')
+	first := true
+	_ = first
+	{
+		const prefix string = ",\"attack\":"
+		out.RawString(prefix[1:])
+		out.String(string(in.Attack))
+	}
+	{
+		const prefix string = ",\"seq\":"
+		out.RawString(prefix)
+		out.Uint64(uint64(in.Seq))
+	}
+	{
+		const prefix string = ",\"code\":"
+		out.RawString(prefix)
+		out.Uint16(uint16(in.Code))
+	}
+	{
+		const prefix string = ",\"timestamp\":"
+		out.RawString(prefix)
+		out.Raw((in.Timestamp).MarshalJSON())
+	}
+	{
+		const prefix string = ",\"latency\":"
+		out.RawString(prefix)
+		out.Int64(int64(in.Latency))
+	}
+	{
+		const prefix string = ",\"bytes_out\":"
+		out.RawString(prefix)
+		out.Uint64(uint64(in.BytesOut))
+	}
+	{
+		const prefix string = ",\"bytes_in\":"
+		out.RawString(prefix)
+		out.Uint64(uint64(in.BytesIn))
+	}
+	{
+		const prefix string = ",\"error\":"
+		out.RawString(prefix)
+		out.String(string(in.Error))
+	}
+	{
+		const prefix string = ",\"body\":"
+		out.RawString(prefix)
+		out.Base64Bytes(in.Body)
+	}
+	{
+		const prefix string = ",\"method\":"
+		out.RawString(prefix)
+		out.String(string(in.Method))
+	}
+	{
+		const prefix string = ",\"url\":"
+		out.RawString(prefix)
+		out.String(string(in.URL))
+	}
+	{
+		const prefix string = ",\"headers\":"
+		out.RawString(prefix)
+		if in.Headers == nil && (out.Flags&jwriter.NilMapAsEmpty) == 0 {
+			out.RawString(`null`)
+		} else {
+			out.RawByte('{')
+			v6First := true
+			for v6Name, v6Value := range in.Headers {
+				if v6First {
+					v6First = false
+				} else {
+					out.RawByte(',')
+				}
+				out.String(string(v6Name))
+				out.RawByte(':')
+				if v6Value == nil && (out.Flags&jwriter.NilSliceAsEmpty) == 0 {
+					out.RawString("null")
+				} else {
+					out.RawByte('[')
+					for v7, v8 := range v6Value {
+						if v7 > 0 {
+							out.RawByte(',')
+						}
+						out.String(string(v8))
+					}
+					out.RawByte(']')
+				}
+			}
+			out.RawByte('}')
+		}
+	}
+	out.RawByte('}')
+}
+
+// MarshalEasyJSON supports easyjson.Marshaler interface
+func (v jsonResult) MarshalEasyJSON(w *jwriter.Writer) {
+	easyjsonBd1621b8EncodeGithubComTsenartVegetaV12Lib(w, v)
+}
+
+// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
+func (v *jsonResult) UnmarshalEasyJSON(l *jlexer.Lexer) {
+	easyjsonBd1621b8DecodeGithubComTsenartVegetaV12Lib(l, v)
+}
diff --git a/vendor/github.com/tsenart/vegeta/v12/lib/results_fuzz.go b/vendor/github.com/tsenart/vegeta/v12/lib/results_fuzz.go
new file mode 100644
index 000000000..fced203da
--- /dev/null
+++ b/vendor/github.com/tsenart/vegeta/v12/lib/results_fuzz.go
@@ -0,0 +1,63 @@
+// +build gofuzz
+
+package vegeta
+
+import (
+	"bytes"
+	"io"
+)
+
+// FuzzResultsFormatDetection tests result list format detection.
+func FuzzResultsFormatDetection(fuzz []byte) int {
+	decoder := DecoderFor(bytes.NewReader(fuzz))
+	if decoder == nil {
+		return 0
+	}
+	ok := readAllResults(decoder)
+	if !ok {
+		return 0
+	}
+	return 1
+}
+
+// FuzzGobDecoder tests decoding a gob format result list.
+func FuzzGobDecoder(fuzz []byte) int {
+	decoder := NewDecoder(bytes.NewReader(fuzz))
+	ok := readAllResults(decoder)
+	if !ok {
+		return 0
+	}
+	return 1
+}
+
+// FuzzCSVDecoder tests decoding a CSV format result list.
+func FuzzCSVDecoder(fuzz []byte) int {
+	decoder := NewCSVDecoder(bytes.NewReader(fuzz))
+	ok := readAllResults(decoder)
+	if !ok {
+		return 0
+	}
+	return 1
+}
+
+// FuzzJSONDecoder tests decoding a JSON format result list.
+func FuzzJSONDecoder(fuzz []byte) int {
+	decoder := NewJSONDecoder(bytes.NewReader(fuzz))
+	ok := readAllResults(decoder)
+	if !ok {
+		return 0
+	}
+	return 1
+}
+
+func readAllResults(decoder Decoder) (ok bool) {
+	for {
+		result := &Result{}
+		err := decoder.Decode(result)
+		if err == io.EOF {
+			return true
+		} else if err != nil {
+			return false
+		}
+	}
+}
diff --git a/vendor/github.com/tsenart/vegeta/lib/target.schema.json b/vendor/github.com/tsenart/vegeta/v12/lib/target.schema.json
similarity index 100%
rename from vendor/github.com/tsenart/vegeta/lib/target.schema.json
rename to vendor/github.com/tsenart/vegeta/v12/lib/target.schema.json
diff --git a/vendor/github.com/tsenart/vegeta/lib/targets.go b/vendor/github.com/tsenart/vegeta/v12/lib/targets.go
similarity index 98%
rename from vendor/github.com/tsenart/vegeta/lib/targets.go
rename to vendor/github.com/tsenart/vegeta/v12/lib/targets.go
index 41415ffb5..2cb5dc2cf 100644
--- a/vendor/github.com/tsenart/vegeta/lib/targets.go
+++ b/vendor/github.com/tsenart/vegeta/v12/lib/targets.go
@@ -270,7 +270,7 @@ func NewHTTPTargeter(src io.Reader, body []byte, hdr http.Header) Targeter {
 			}
 			line = strings.TrimSpace(sc.Text())
 
-			if len(line) != 0 && line[0] != '#'{
+			if len(line) != 0 && line[0] != '#' {
 				break
 			}
 		}
@@ -300,6 +300,8 @@ func NewHTTPTargeter(src io.Reader, body []byte, hdr http.Header) Targeter {
 		for sc.Scan() {
 			if line = strings.TrimSpace(sc.Text()); line == "" {
 				break
+			} else if strings.HasPrefix(line, "#") {
+				continue
 			} else if strings.HasPrefix(line, "@") {
 				if tgt.Body, err = ioutil.ReadFile(line[1:]); err != nil {
 					return fmt.Errorf("bad body: %s", err)
@@ -327,7 +329,7 @@ func NewHTTPTargeter(src io.Reader, body []byte, hdr http.Header) Targeter {
 	}
 }
 
-var httpMethodChecker = regexp.MustCompile("^[A-Z]+\\s")
+var httpMethodChecker = regexp.MustCompile(`^[A-Z]+\s`)
 
 // A line starts with an http method when the first word is uppercase ascii
 // followed by a space.
diff --git a/vendor/github.com/tsenart/vegeta/lib/targets_easyjson.go b/vendor/github.com/tsenart/vegeta/v12/lib/targets_easyjson.go
similarity index 100%
rename from vendor/github.com/tsenart/vegeta/lib/targets_easyjson.go
rename to vendor/github.com/tsenart/vegeta/v12/lib/targets_easyjson.go
diff --git a/vendor/github.com/tsenart/vegeta/v12/lib/targets_fuzz.go b/vendor/github.com/tsenart/vegeta/v12/lib/targets_fuzz.go
new file mode 100644
index 000000000..87a925fe1
--- /dev/null
+++ b/vendor/github.com/tsenart/vegeta/v12/lib/targets_fuzz.go
@@ -0,0 +1,68 @@
+// +build gofuzz
+
+package vegeta
+
+import (
+	"bytes"
+	"net/http"
+)
+
+// FuzzHTTPTargeter tests decoding an HTTP encoded target list.
+func FuzzHTTPTargeter(fuzz []byte) int {
+	headers, body, fuzz, ok := decodeFuzzTargetDefaults(fuzz)
+	if !ok {
+		return -1
+	}
+	targeter := NewHTTPTargeter(
+		bytes.NewReader(fuzz),
+		body,
+		headers,
+	)
+	_, err := ReadAllTargets(targeter)
+	if err != nil {
+		return 0
+	}
+	return 1
+}
+
+// FuzzJSONTargeter tests decoding a JSON encoded target list.
+func FuzzJSONTargeter(fuzz []byte) int {
+	headers, body, fuzz, ok := decodeFuzzTargetDefaults(fuzz)
+	if !ok {
+		return -1
+	}
+	targeter := NewJSONTargeter(
+		bytes.NewReader(fuzz),
+		body,
+		headers,
+	)
+	_, err := ReadAllTargets(targeter)
+	if err != nil {
+		return 0
+	}
+	return 1
+}
+
+func decodeFuzzTargetDefaults(fuzz []byte) (
+	headers http.Header,
+	body []byte,
+	rest []byte,
+	ok bool,
+) {
+	if len(fuzz) < 2 {
+		return
+	}
+	headers = make(map[string][]string)
+	body = []byte{}
+	rest = []byte{}
+	rest, ok = decodeFuzzHeaders(fuzz, headers)
+	if !ok {
+		return
+	}
+	if len(rest) == 0 {
+		ok = true
+		return
+	}
+	body, rest, ok = extractFuzzByteString(rest)
+	return
+}
diff --git a/vendor/github.com/tsenart/vegeta/v12/lib/util_fuzz.go b/vendor/github.com/tsenart/vegeta/v12/lib/util_fuzz.go
new file mode 100644
index 000000000..60c758fea
--- /dev/null
+++ b/vendor/github.com/tsenart/vegeta/v12/lib/util_fuzz.go
@@ -0,0 +1,120 @@
+// +build gofuzz
+
+package vegeta
+
+func decodeFuzzHeaders(fuzz []byte, headers map[string][]string) (
+	rest []byte,
+	ok bool,
+) {
+	rest = fuzz
+	for {
+		if len(rest) == 0 {
+			// Consumed all fuzz
+			ok = true
+			return
+		}
+		if fuzz[0] == 0 {
+			// Headers terminated
+			if len(rest) == 1 {
+				rest = []byte{}
+			} else {
+				rest = rest[1:]
+			}
+			ok = true
+			return
+		}
+		if len(fuzz) == 1 {
+			// Invalid headers encoding
+			return
+		}
+		rest, ok = decodeFuzzHeader(rest[1:], headers)
+		if !ok {
+			return
+		}
+	}
+}
+
+func decodeFuzzHeader(fuzz []byte, headers map[string][]string) (
+	rest []byte,
+	ok bool,
+) {
+	if len(fuzz) == 0 {
+		ok = true
+		return
+	}
+	name, rest, ok := extractFuzzString(fuzz)
+	if !ok {
+		return
+	}
+	value, rest, ok := extractFuzzString(rest)
+	if !ok {
+		return
+	}
+	if header, ok := headers[name]; ok {
+		headers[name] = append(header, value)
+	} else {
+		headers[name] = []string{value}
+	}
+	ok = true
+	return
+}
+
+func extractFuzzString(fuzz []byte) (
+	value string,
+	rest []byte,
+	ok bool,
+) {
+	if len(fuzz) < 2 {
+		// Invalid string encoding
+		return
+	}
+	length := int(fuzz[0])
+	if length == 0 {
+		// Invalid length
+		return
+	}
+	if len(fuzz) < (length + 1) {
+		// Insufficient fuzz
+		return
+	}
+	value = string(fuzz[1 : length+1])
+	if len(fuzz) == (length + 1) {
+		// Consumed all fuzz
+		rest = []byte{}
+	} else {
+		// More fuzz
+		rest = fuzz[length+1:]
+	}
+	ok = true
+	return
+}
+
+func extractFuzzByteString(fuzz []byte) (
+	value []byte,
+	rest []byte,
+	ok bool,
+) {
+	if len(fuzz) < 2 {
+		// Invalid byte string encoding
+		return
+	}
+	length := int(fuzz[0])
+	if length == 0 {
+		// Invalid length
+		return
+	}
+	if len(fuzz) < (length + 1) {
+		// Insufficient fuzz
+		return
+	}
+	value = fuzz[1 : length+1]
+	if len(fuzz) == (length + 1) {
+		// Consumed all fuzz
+		rest = []byte{}
+	} else {
+		// More fuzz
+		rest = fuzz[length+1:]
+	}
+	ok = true
+	return
+}
diff --git a/vendor/knative.dev/eventing/pkg/apis/messaging/v1/channel_template_types.go b/vendor/knative.dev/eventing/pkg/apis/messaging/v1/channel_template_types.go
index 35f42de7f..6ef23d809 100644
--- a/vendor/knative.dev/eventing/pkg/apis/messaging/v1/channel_template_types.go
+++ b/vendor/knative.dev/eventing/pkg/apis/messaging/v1/channel_template_types.go
@@ -17,8 +17,13 @@ limitations under the License.
 package v1
 
 import (
+	"encoding/json"
+
+	"k8s.io/apimachinery/pkg/api/equality"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime"
+
+	v1 "knative.dev/eventing/pkg/apis/duck/v1"
 )
 
 // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
@@ -40,8 +45,67 @@ type ChannelTemplateSpecInternal struct {
 	// +optional
 	metav1.ObjectMeta `json:"metadata,omitempty"`
 
-	// Spec defines the Spec to use for each channel created. Passed
+	// Spec includes the Channel CR ChannelableSpec and the physical channel spec.
+	// In order to create a new ChannelTemplateSpecInternalSpec, you must use NewChannelTemplateSpecInternalSpec
+	Spec *ChannelTemplateSpecInternalSpec `json:"spec,omitempty"`
+}
+
+// ChannelTemplateSpecInternalSpec merges the "general" spec from Channel CR and the template of the physical channel spec.
+// Note that this struct properly implements only Marshalling, unmarshalling doesn't work!
+type ChannelTemplateSpecInternalSpec struct {
+	// ChannelableSpec includes the fields from the Channel Spec section
+	v1.ChannelableSpec
+
+	// PhysicalChannelSpec includes the fields from the physical channel Spec. Passed
 	// in verbatim to the Channel CRD as Spec section.
 	// +optional
-	Spec *runtime.RawExtension `json:"spec,omitempty"`
+	PhysicalChannelSpec *runtime.RawExtension
+}
+
+// NewChannelTemplateSpecInternalSpec creates a new ChannelTemplateSpecInternalSpec, returning nil if channelableSpec is empty and physicalChannelSpec is nil.
+func NewChannelTemplateSpecInternalSpec(channelableSpec v1.ChannelableSpec, physicalChannelSpec *runtime.RawExtension) *ChannelTemplateSpecInternalSpec {
+	if physicalChannelSpec == nil && equality.Semantic.DeepEqual(channelableSpec, v1.ChannelableSpec{}) {
+		return nil
+	}
+	return &ChannelTemplateSpecInternalSpec{
+		ChannelableSpec:     channelableSpec,
+		PhysicalChannelSpec: physicalChannelSpec,
+	}
+}
+
+func (s ChannelTemplateSpecInternalSpec) MarshalJSON() ([]byte, error) {
+	// Check if empty
+	if s.PhysicalChannelSpec == nil && equality.Semantic.DeepEqual(s.ChannelableSpec, v1.ChannelableSpec{}) {
+		return []byte{}, nil
+	}
+
+	// Let's merge the channel template spec and the channelable spec from channel
+	channelableSpec := make(map[string]interface{})
+	physicalChannelTemplateSpec := make(map[string]interface{})
+
+	rawChannelSpec, err := json.Marshal(s.ChannelableSpec)
+	if err != nil {
+		return nil, err
+	}
+	if err := json.Unmarshal(rawChannelSpec, &channelableSpec); err != nil {
+		return nil, err
+	}
+
+	if s.PhysicalChannelSpec != nil {
+		rawPhysicalChannelTemplateSpec, err := json.Marshal(s.PhysicalChannelSpec)
+		if err != nil {
+			return nil, err
+		}
+		if err := json.Unmarshal(rawPhysicalChannelTemplateSpec, &physicalChannelTemplateSpec); err != nil {
+			return nil, err
+		}
+	}
+
+	// Merge the two maps into channelableSpec
+	for k, v := range physicalChannelTemplateSpec {
+		channelableSpec[k] = v
+	}
+
+	// Just return the merged map marshalled
+	return json.Marshal(channelableSpec)
 }
diff --git a/vendor/knative.dev/eventing/pkg/apis/messaging/v1/zz_generated.deepcopy.go b/vendor/knative.dev/eventing/pkg/apis/messaging/v1/zz_generated.deepcopy.go
index f5158622a..90d160a32 100644
--- a/vendor/knative.dev/eventing/pkg/apis/messaging/v1/zz_generated.deepcopy.go
+++ b/vendor/knative.dev/eventing/pkg/apis/messaging/v1/zz_generated.deepcopy.go
@@ -169,7 +169,7 @@ func (in *ChannelTemplateSpecInternal) DeepCopyInto(out *ChannelTemplateSpecInte
 	in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
 	if in.Spec != nil {
 		in, out := &in.Spec, &out.Spec
-		*out = new(runtime.RawExtension)
+		*out = new(ChannelTemplateSpecInternalSpec)
 		(*in).DeepCopyInto(*out)
 	}
 	return
@@ -193,6 +193,28 @@ func (in *ChannelTemplateSpecInternal) DeepCopyObject() runtime.Object {
 	return nil
 }
 
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *ChannelTemplateSpecInternalSpec) DeepCopyInto(out *ChannelTemplateSpecInternalSpec) {
+	*out = *in
+	in.ChannelableSpec.DeepCopyInto(&out.ChannelableSpec)
+	if in.PhysicalChannelSpec != nil {
+		in, out := &in.PhysicalChannelSpec, &out.PhysicalChannelSpec
+		*out = new(runtime.RawExtension)
+		(*in).DeepCopyInto(*out)
+	}
+	return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ChannelTemplateSpecInternalSpec.
+func (in *ChannelTemplateSpecInternalSpec) DeepCopy() *ChannelTemplateSpecInternalSpec {
+	if in == nil {
+		return nil
+	}
+	out := new(ChannelTemplateSpecInternalSpec)
+	in.DeepCopyInto(out)
+	return out
+}
+
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *InMemoryChannel) DeepCopyInto(out *InMemoryChannel) {
 	*out = *in
diff --git a/vendor/knative.dev/pkg/metrics/config.go b/vendor/knative.dev/pkg/metrics/config.go
index 535c8e9bc..c4c9c7f84 100644
--- a/vendor/knative.dev/pkg/metrics/config.go
+++ b/vendor/knative.dev/pkg/metrics/config.go
@@ -22,7 +22,6 @@ import (
 	"errors"
 	"fmt"
 	"os"
-	"path"
 	"strconv"
 	"strings"
 	"time"
@@ -65,6 +64,12 @@ const (
 	prometheusHostEnvName = "METRICS_PROMETHEUS_HOST"
 )
 
+var (
+	// TestOverrideBundleCount is a variable for testing to reduce the size (number of metrics) buffered before
+	// Stackdriver will send a bundled metric report. Only applies if non-zero.
+	TestOverrideBundleCount = 0
+)
+
 // Metrics backend "enum".
 const (
 	// stackdriver is used for Stackdriver backend
@@ -248,37 +253,8 @@ func createMetricsConfig(ctx context.Context, ops ExporterOptions) (*metricsConf
 		mc.prometheusPort = pp
 		mc.prometheusHost = prometheusHost()
 	case stackdriver:
-		// If stackdriverClientConfig is not provided for stackdriver backend destination, OpenCensus will try to
-		// use the application default credentials. If that is not available, Opencensus would fail to create the
-		// metrics exporter.
-		scc := NewStackdriverClientConfigFromMap(m)
-		mc.stackdriverClientConfig = *scc
-		mc.isStackdriverBackend = true
-		var allowCustomMetrics bool
-		var err error
-		mc.stackdriverMetricTypePrefix = path.Join(mc.domain, mc.component)
-
-		customMetricsSubDomain := m[stackdriverCustomMetricSubDomainKey]
-		if customMetricsSubDomain == "" {
-			customMetricsSubDomain = defaultCustomMetricSubDomain
-		}
-		mc.stackdriverCustomMetricTypePrefix = path.Join(customMetricTypePrefix, customMetricsSubDomain, mc.component)
-		if ascmStr := m[allowStackdriverCustomMetricsKey]; ascmStr != "" {
-			allowCustomMetrics, err = strconv.ParseBool(ascmStr)
-			if err != nil {
-				return nil, fmt.Errorf("invalid %s value %q", allowStackdriverCustomMetricsKey, ascmStr)
-			}
-		}
-
-		mc.recorder = sdCustomMetricsRecorder(mc, allowCustomMetrics)
-
-		if scc.UseSecret {
-			secret, err := getStackdriverSecret(ctx, ops.Secrets)
-			if err != nil {
-				return nil, err
-			}
-
-			mc.secret = secret
+		if err := sdinit(ctx, m, &mc, ops); err != nil {
+			return nil, err
 		}
 	}
 
diff --git a/vendor/knative.dev/pkg/metrics/config_observability.go b/vendor/knative.dev/pkg/metrics/config_observability.go
index ae622c928..2c320bbff 100644
--- a/vendor/knative.dev/pkg/metrics/config_observability.go
+++ b/vendor/knative.dev/pkg/metrics/config_observability.go
@@ -26,7 +26,7 @@ import (
 )
 
 const (
-	// The following is used to set the default log url template
+	// DefaultLogURLTemplate is used to set the default log url template
 	DefaultLogURLTemplate = ""
 
 	// DefaultRequestLogTemplate is the default format for emitting request logs.
diff --git a/vendor/knative.dev/pkg/metrics/gcp_metadata.go b/vendor/knative.dev/pkg/metrics/gcp_metadata.go
index ec6ae878e..3c1a6a09a 100644
--- a/vendor/knative.dev/pkg/metrics/gcp_metadata.go
+++ b/vendor/knative.dev/pkg/metrics/gcp_metadata.go
@@ -1,3 +1,5 @@
+// +build !nostackdriver
+
 /*
 Copyright 2019 The Knative Authors
 
diff --git a/vendor/knative.dev/pkg/metrics/nostackdriver.go b/vendor/knative.dev/pkg/metrics/nostackdriver.go
new file mode 100644
index 000000000..b5c71eb77
--- /dev/null
+++ b/vendor/knative.dev/pkg/metrics/nostackdriver.go
@@ -0,0 +1,35 @@
+// +build nostackdriver
+
+/*
+Copyright 2019 The Knative Authors
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package metrics
+
+import (
+	"context"
+	"errors"
+
+	"go.opencensus.io/stats/view"
+	"go.uber.org/zap"
+)
+
+func sdinit(ctx context.Context, m map[string]string, mc *metricsConfig, ops ExporterOptions) error {
+	return errors.New("Stackdriver support is not included")
+}
+
+func newStackdriverExporter(config *metricsConfig, logger *zap.SugaredLogger) (view.Exporter, ResourceExporterFactory, error) {
+	return nil, nil, errors.New("Stackdriver support is not included")
+}
diff --git a/vendor/knative.dev/pkg/metrics/stackdriver_exporter.go b/vendor/knative.dev/pkg/metrics/stackdriver_exporter.go
index ab14ef266..a875accef 100644
--- a/vendor/knative.dev/pkg/metrics/stackdriver_exporter.go
+++ b/vendor/knative.dev/pkg/metrics/stackdriver_exporter.go
@@ -1,3 +1,5 @@
+// +build !nostackdriver
+
 /*
 Copyright 2019 The Knative Authors
 
@@ -20,6 +22,7 @@ import (
 	"context"
 	"fmt"
 	"path"
+	"strconv"
 	"sync"
 	"time"
 
@@ -88,10 +91,6 @@ var (
 	// metricToResourceLabels provides a quick lookup from a custom metric name to the set of tags
 	// which should be promoted to Stackdriver Resource labels via opencensus resources.
 	metricToResourceLabels = map[string]*resourceTemplate{}
-
-	// TestOverrideBundleCount is a variable for testing to reduce the size (number of metrics) buffered before
-	// Stackdriver will send a bundled metric report. Only applies if non-zero.
-	TestOverrideBundleCount = 0
 )
 
 type resourceTemplate struct {
@@ -99,6 +98,42 @@ type resourceTemplate struct {
 	LabelKeys sets.String
 }
 
+func sdinit(ctx context.Context, m map[string]string, mc *metricsConfig, ops ExporterOptions) error {
+	// If stackdriverClientConfig is not provided for stackdriver backend destination, OpenCensus will try to
+	// use the application default credentials. If that is not available, Opencensus would fail to create the
+	// metrics exporter.
+	scc := NewStackdriverClientConfigFromMap(m)
+	mc.stackdriverClientConfig = *scc
+	mc.isStackdriverBackend = true
+	var allowCustomMetrics bool
+	var err error
+	mc.stackdriverMetricTypePrefix = path.Join(mc.domain, mc.component)
+
+	customMetricsSubDomain := m[stackdriverCustomMetricSubDomainKey]
+	if customMetricsSubDomain == "" {
+		customMetricsSubDomain = defaultCustomMetricSubDomain
+	}
+	mc.stackdriverCustomMetricTypePrefix = path.Join(customMetricTypePrefix, customMetricsSubDomain, mc.component)
+	if ascmStr := m[allowStackdriverCustomMetricsKey]; ascmStr != "" {
+		allowCustomMetrics, err = strconv.ParseBool(ascmStr)
+		if err != nil {
+			return fmt.Errorf("invalid %s value %q", allowStackdriverCustomMetricsKey, ascmStr)
+		}
+	}
+
+	mc.recorder = sdCustomMetricsRecorder(*mc, allowCustomMetrics)
+
+	if scc.UseSecret {
+		secret, err := getStackdriverSecret(ctx, ops.Secrets)
+		if err != nil {
+			return err
+		}
+
+		mc.secret = secret
+	}
+	return nil
+}
+
 // SetStackdriverSecretLocation sets the name and namespace of the Secret that can be used to authenticate with Stackdriver.
 // The Secret is only used if both:
 // 1. This function has been explicitly called to set the name and namespace
diff --git a/vendor/knative.dev/pkg/tracing/nostackdriver.go b/vendor/knative.dev/pkg/tracing/nostackdriver.go
new file mode 100644
index 000000000..f504c1ffd
--- /dev/null
+++ b/vendor/knative.dev/pkg/tracing/nostackdriver.go
@@ -0,0 +1,30 @@
+// +build nostackdriver
+
+/*
+Copyright 2020 The Knative Authors
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package tracing
+
+import (
+	"errors"
+
+	"go.opencensus.io/trace"
+	"knative.dev/pkg/tracing/config"
+)
+
+func newStackdriver(cfg *config.Config) (trace.Exporter, error) {
+	return nil, errors.New("Stackdriver is not configured")
+}
diff --git a/vendor/knative.dev/pkg/tracing/opencensus.go b/vendor/knative.dev/pkg/tracing/opencensus.go
index 4346593ba..fbe27c048 100644
--- a/vendor/knative.dev/pkg/tracing/opencensus.go
+++ b/vendor/knative.dev/pkg/tracing/opencensus.go
@@ -1,3 +1,19 @@
+/*
+Copyright 2020 The Knative Authors
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
 package tracing
 
 import (
@@ -7,9 +23,8 @@ import (
 	"os"
 	"sync"
 
-	"contrib.go.opencensus.io/exporter/stackdriver"
 	oczipkin "contrib.go.opencensus.io/exporter/zipkin"
-	zipkin "github.com/openzipkin/zipkin-go"
+	"github.com/openzipkin/zipkin-go"
 	httpreporter "github.com/openzipkin/zipkin-go/reporter/http"
 	"go.opencensus.io/trace"
 	"go.uber.org/zap"
@@ -128,17 +143,14 @@ func WithExporterFull(name, host string, logger *zap.SugaredLogger) ConfigOption
 		var (
 			exporter trace.Exporter
 			closer   io.Closer
+			err      error
 		)
 		switch cfg.Backend {
 		case config.Stackdriver:
-			exp, err := stackdriver.NewExporter(stackdriver.Options{
-				ProjectID: cfg.StackdriverProjectID,
-			})
+			exporter, err = newStackdriver(cfg)
 			if err != nil {
-				logger.Errorw("error reading project-id from metadata", zap.Error(err))
 				return err
 			}
-			exporter = exp
 		case config.Zipkin:
 			// If host isn't specified, then zipkin.NewEndpoint will return an error saying that it
 			// can't find the host named ''. So, if not specified, default it to this machine's
@@ -161,6 +173,7 @@ func WithExporterFull(name, host string, logger *zap.SugaredLogger) ConfigOption
 			reporter := httpreporter.NewReporter(cfg.ZipkinEndpoint)
 			exporter = oczipkin.NewExporter(reporter, zipEP)
 			closer = reporter
+
 		default:
 			// Disables tracing.
 		}
diff --git a/vendor/knative.dev/pkg/tracing/stackdriver.go b/vendor/knative.dev/pkg/tracing/stackdriver.go
new file mode 100644
index 000000000..b8986a2a7
--- /dev/null
+++ b/vendor/knative.dev/pkg/tracing/stackdriver.go
@@ -0,0 +1,31 @@
+// +build !nostackdriver
+
+/*
+Copyright 2020 The Knative Authors
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package tracing
+
+import (
+	"contrib.go.opencensus.io/exporter/stackdriver"
+	"go.opencensus.io/trace"
+	"knative.dev/pkg/tracing/config"
+)
+
+func newStackdriver(cfg *config.Config) (trace.Exporter, error) {
+	return stackdriver.NewExporter(stackdriver.Options{
+		ProjectID: cfg.StackdriverProjectID,
+	})
+}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 6bd83fd3b..5d471a3dc 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -288,6 +288,7 @@ github.com/konsorten/go-windows-terminal-sequences
 github.com/lightstep/tracecontext.go/traceparent
 github.com/lightstep/tracecontext.go/tracestate
 # github.com/mailru/easyjson v0.7.1-0.20191009090205-6c0755d89d1e
+github.com/mailru/easyjson
 github.com/mailru/easyjson/buffer
 github.com/mailru/easyjson/jlexer
 github.com/mailru/easyjson/jwriter
@@ -351,7 +352,7 @@ github.com/rogpeppe/go-internal/module
 github.com/rogpeppe/go-internal/semver
 # github.com/sirupsen/logrus v1.6.0
 github.com/sirupsen/logrus
-# github.com/slinkydeveloper/loadastic v0.0.0-20191203132749-9afe5a010a57
+# github.com/slinkydeveloper/loadastic v0.0.0-20201218203601-5c69eea3b7d8
 ## explicit
 github.com/slinkydeveloper/loadastic/common
 github.com/slinkydeveloper/loadastic/kafka
@@ -364,8 +365,8 @@ github.com/stretchr/objx
 github.com/stretchr/testify/assert
 github.com/stretchr/testify/mock
 github.com/stretchr/testify/require
-# github.com/tsenart/vegeta v12.7.1-0.20190725001342-b5f4fca92137+incompatible
-github.com/tsenart/vegeta/lib
+# github.com/tsenart/vegeta/v12 v12.8.4
+github.com/tsenart/vegeta/v12/lib
 # github.com/valyala/bytebufferpool v1.0.0
 github.com/valyala/bytebufferpool
 # github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c
@@ -1077,7 +1078,7 @@ k8s.io/utils/buffer
 k8s.io/utils/integer
 k8s.io/utils/pointer
 k8s.io/utils/trace
-# knative.dev/eventing v0.19.1-0.20201216183558-f3468d1c9954
+# knative.dev/eventing v0.19.1-0.20210106094043-f4b5fd47542c
 ## explicit
 knative.dev/eventing/pkg/adapter/v2
 knative.dev/eventing/pkg/adapter/v2/util/crstatusevent
@@ -1211,7 +1212,7 @@ knative.dev/eventing/test/test_images/recordevents
 # knative.dev/hack v0.0.0-20201214230143-4ed1ecb8db24
 ## explicit
 knative.dev/hack
-# knative.dev/pkg v0.0.0-20201222215804-e2d6b4f84573
+# knative.dev/pkg v0.0.0-20201231084629-fb3dc711206a
 ## explicit
 knative.dev/pkg/apis
 knative.dev/pkg/apis/duck


Test patch:
diff --git a/vendor/knative.dev/eventing/pkg/reconciler/testing/v1/channel.go b/vendor/knative.dev/eventing/pkg/reconciler/testing/v1/channel.go
index bee1c09db..066c1506a 100644
--- a/vendor/knative.dev/eventing/pkg/reconciler/testing/v1/channel.go
+++ b/vendor/knative.dev/eventing/pkg/reconciler/testing/v1/channel.go
@@ -102,6 +102,12 @@ func WithBackingChannelReady(c *eventingv1.Channel) {
 	c.Status.MarkBackingChannelReady()
 }
 
+func WithChannelDelivery(d *eventingduckv1.DeliverySpec) ChannelOption {
+	return func(c *eventingv1.Channel) {
+		c.Spec.Delivery = d
+	}
+}
+
 func WithBackingChannelObjRef(objRef *duckv1.KReference) ChannelOption {
 	return func(c *eventingv1.Channel) {
 		c.Status.Channel = objRef
diff --git a/vendor/knative.dev/eventing/pkg/reconciler/testing/v1/inmemorychannel.go b/vendor/knative.dev/eventing/pkg/reconciler/testing/v1/inmemorychannel.go
index d44cabfbf..a0b9c4e4a 100644
--- a/vendor/knative.dev/eventing/pkg/reconciler/testing/v1/inmemorychannel.go
+++ b/vendor/knative.dev/eventing/pkg/reconciler/testing/v1/inmemorychannel.go
@@ -22,11 +22,12 @@ import (
 	appsv1 "k8s.io/api/apps/v1"
 	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"knative.dev/pkg/apis"
+
 	duckv1 "knative.dev/eventing/pkg/apis/duck/v1"
 	"knative.dev/eventing/pkg/apis/eventing"
 	"knative.dev/eventing/pkg/apis/messaging"
 	v1 "knative.dev/eventing/pkg/apis/messaging/v1"
-	"knative.dev/pkg/apis"
 )
 
 // InMemoryChannelOption enables further configuration of a v1.InMemoryChannel.
@@ -171,6 +172,12 @@ func WithInMemoryChannelReadySubscriberAndGeneration(uid string, observedGenerat
 	}
 }
 
+func WithInMemoryChannelDelivery(d *duckv1.DeliverySpec) InMemoryChannelOption {
+	return func(c *v1.InMemoryChannel) {
+		c.Spec.Delivery = d
+	}
+}
+
 func WithInMemoryChannelStatusSubscribers(subscriberStatuses []duckv1.SubscriberStatus) InMemoryChannelOption {
 	return func(imc *v1.InMemoryChannel) {
 		imc.Status.Subscribers = subscriberStatuses
diff --git a/vendor/knative.dev/eventing/test/README.md b/vendor/knative.dev/eventing/test/README.md
index 8616cdde1..2d9bcb3c1 100644
--- a/vendor/knative.dev/eventing/test/README.md
+++ b/vendor/knative.dev/eventing/test/README.md
@@ -92,14 +92,14 @@ not yet support private registries. See
 https://github.com/knative/eventing/issues/1862 for status of this issue.
 
 ```bash
-go test -v -tags=e2e -count=1 ./test/e2e
+SYSTEM_NAMESPACE=knative-eventing go test -v -tags=e2e -count=1 ./test/e2e
 ```
 
 By default, tests run against images with the `latest` tag. To override this
 behavior you can specify a different tag through `-tag`:
 
 ```bash
-go test -v -tags=e2e -count=1 ./test/e2e -tag e2e
+SYSTEM_NAMESPACE=knative-eventing go test -v -tags=e2e -count=1 ./test/e2e -tag e2e
 ```
 
 #### One test case
@@ -108,7 +108,7 @@ To run one e2e test case, e.g. `TestSingleBinaryEventForChannel`, use
 [the `-run` flag with `go test`](https://golang.org/cmd/go/#hdr-Testing_flags):
 
 ```bash
-go test -v -tags=e2e -count=1 ./test/e2e -run ^TestSingleBinaryEventForChannel$
+SYSTEM_NAMESPACE=knative-eventing go test -v -tags=e2e -count=1 ./test/e2e -run ^TestSingleBinaryEventForChannel$
 ```
 
 ## Environment requirements
diff --git a/vendor/knative.dev/eventing/test/e2e/helpers/channel_dls_test_helper.go b/vendor/knative.dev/eventing/test/e2e/helpers/channel_dls_test_helper.go
index ca2742ad1..650910406 100644
--- a/vendor/knative.dev/eventing/test/e2e/helpers/channel_dls_test_helper.go
+++ b/vendor/knative.dev/eventing/test/e2e/helpers/channel_dls_test_helper.go
@@ -24,8 +24,14 @@ import (
 	cloudevents "github.com/cloudevents/sdk-go/v2"
 	. "github.com/cloudevents/sdk-go/v2/test"
 	"github.com/google/uuid"
+	"k8s.io/apimachinery/pkg/api/equality"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/utils/pointer"
 
+	duckv1 "knative.dev/pkg/apis/duck/v1"
+
+	eventingduckv1 "knative.dev/eventing/pkg/apis/duck/v1"
+	messagingv1 "knative.dev/eventing/pkg/apis/messaging/v1"
 	testlib "knative.dev/eventing/test/lib"
 	"knative.dev/eventing/test/lib/recordevents"
 	"knative.dev/eventing/test/lib/resources"
@@ -100,3 +106,83 @@ func ChannelDeadLetterSinkTestHelper(
 		))
 	})
 }
+
+// ChannelDeadLetterDefaultSinkTestHelper is the helper function for channel_deadlettersink_test, but setting the delivery from the channel spec
+func ChannelDeadLetterSinkDefaultTestHelper(
+	ctx context.Context,
+	t *testing.T,
+	channelTestRunner testlib.ComponentsTestRunner,
+	options ...testlib.SetupClientOption) {
+	const (
+		senderName          = "e2e-channelchain-sender"
+		recordEventsPodName = "e2e-channel-dls-recordevents-pod"
+		channelName         = "e2e-channel-dls"
+	)
+	channelGK := messagingv1.SchemeGroupVersion.WithKind("Channel").GroupKind()
+	// subscriptionNames corresponds to Subscriptions
+	subscriptionNames := []string{"e2e-channel-dls-subs1"}
+
+	channelTestRunner.RunTests(t, testlib.FeatureBasic, func(st *testing.T, channel metav1.TypeMeta) {
+		thisChannelGk := channel.GroupVersionKind().GroupKind()
+		if equality.Semantic.DeepEqual(thisChannelGk, channelGK) {
+			st.Skip("It doesn't make sense to create a messaging.Channel with a backing messaging.Channel")
+			return
+		}
+
+		client := testlib.Setup(st, true, options...)
+		defer testlib.TearDown(client)
+
+		// create channel
+		client.CreateChannelV1WithDefaultOrFail(&messagingv1.Channel{
+			ObjectMeta: metav1.ObjectMeta{
+				Name:      channelName,
+				Namespace: client.Namespace,
+			},
+			Spec: messagingv1.ChannelSpec{
+				ChannelTemplate: &messagingv1.ChannelTemplateSpec{
+					TypeMeta: channel,
+				},
+				ChannelableSpec: eventingduckv1.ChannelableSpec{
+					Delivery: &eventingduckv1.DeliverySpec{
+						DeadLetterSink: &duckv1.Destination{
+							Ref: resources.KnativeRefForService(recordEventsPodName, client.Namespace),
+						},
+						Retry: pointer.Int32Ptr(10),
+					},
+				},
+			},
+		})
+		client.WaitForResourcesReadyOrFail(&channel)
+
+		// create event logger pod and service as the subscriber
+		eventTracker, _ := recordevents.StartEventRecordOrFail(ctx, client, recordEventsPodName)
+		// create subscriptions that subscribe to a service that does not exist
+		client.CreateSubscriptionsV1OrFail(
+			subscriptionNames,
+			channelName,
+			&channel,
+			resources.WithSubscriberForSubscriptionV1("does-not-exist"),
+		)
+
+		// wait for all test resources to be ready, so that we can start sending events
+		client.WaitForAllTestResourcesReadyOrFail(ctx)
+
+		// send CloudEvent to the first channel
+		event := cloudevents.NewEvent()
+		event.SetID("test")
+		eventSource := fmt.Sprintf("http://%s.svc/", senderName)
+		event.SetSource(eventSource)
+		event.SetType(testlib.DefaultEventType)
+		body := fmt.Sprintf(`{"msg":"TestChannelDeadLetterSink %s"}`, uuid.New().String())
+		if err := event.SetData(cloudevents.ApplicationJSON, []byte(body)); err != nil {
+			t.Fatal("Cannot set the payload of the event:", err.Error())
+		}
+		client.SendEventToAddressable(ctx, senderName, channelName, &channel, event)
+
+		// check if the logging service receives the correct number of event messages
+		eventTracker.AssertAtLeast(len(subscriptionNames), recordevents.MatchEvent(
+			HasSource(eventSource),
+			HasData([]byte(body)),
+		))
+	})
+}
diff --git a/vendor/knative.dev/eventing/test/e2e/helpers/channel_single_event_helper.go b/vendor/knative.dev/eventing/test/e2e/helpers/channel_single_event_helper.go
index 517c1aa2c..f020ad784 100644
--- a/vendor/knative.dev/eventing/test/e2e/helpers/channel_single_event_helper.go
+++ b/vendor/knative.dev/eventing/test/e2e/helpers/channel_single_event_helper.go
@@ -30,6 +30,7 @@ import (
 	testlib "knative.dev/eventing/test/lib"
 	"knative.dev/eventing/test/lib/recordevents"
 	"knative.dev/eventing/test/lib/resources"
+	"knative.dev/eventing/test/lib/sender"
 )
 
 type SubscriptionVersion string
@@ -108,20 +109,14 @@ func SingleEventForChannelTestHelper(
 			st.Fatalf("Cannot set the payload of the event: %s", err.Error())
 		}
 
-		//TODO(slinkydeveloper) this is temporary, it will be replaced with SendEventToAddressable
-		uri, err := client.GetAddressableURI(channelName, &channel)
-		if err != nil {
-			client.T.Fatalf("Failed to get the URI for %+v-%s", &channel, channelName)
-		}
-
-		recordevents.DeployEventSenderOrFail(
+		client.SendEventToAddressable(
 			ctx,
-			client,
 			senderName,
-			uri,
-			recordevents.InputEvent(event),
-			recordevents.InputEncoding(encoding),
-			recordevents.EnableIncrementalId(),
+			channelName,
+			&channel,
+			event,
+			sender.WithEncoding(encoding),
+			sender.EnableIncrementalId(),
 		)
 
 		// verify the logger service receives the event
diff --git a/vendor/knative.dev/eventing/test/performance/infra/sender/http_load_generator.go b/vendor/knative.dev/eventing/test/performance/infra/sender/http_load_generator.go
index 7b68ed0cc..3ac5756e5 100644
--- a/vendor/knative.dev/eventing/test/performance/infra/sender/http_load_generator.go
+++ b/vendor/knative.dev/eventing/test/performance/infra/sender/http_load_generator.go
@@ -28,7 +28,7 @@ import (
 	"github.com/golang/protobuf/ptypes"
 	"github.com/google/uuid"
 	"github.com/rogpeppe/fastuuid"
-	vegeta "github.com/tsenart/vegeta/lib"
+	vegeta "github.com/tsenart/vegeta/v12/lib"
 
 	"knative.dev/eventing/test/performance/infra/common"
 )
diff --git a/vendor/knative.dev/pkg/metrics/testing.go b/vendor/knative.dev/pkg/metrics/testing.go
index eb048f9cb..28b2e5878 100644
--- a/vendor/knative.dev/pkg/metrics/testing.go
+++ b/vendor/knative.dev/pkg/metrics/testing.go
@@ -16,6 +16,10 @@ limitations under the License.
 
 package metrics
 
+const (
+	testComponent = "testComponent"
+)
+
 // InitForTesting initialize the necessary global variables for unit tests.
 func InitForTesting() {
 	setCurMetricsConfig(&metricsConfig{