Repository: kubernetes-csi/external-attacher
Pull request #292 (2021-02-16 16:56:31)

feat: Add migrated label to metrics
<!--  Thanks for sending a pull request!  Here are some tips for you:

1. If this is your first time, please read our contributor guidelines: https://git.k8s.io/community/contributors/guide#your-first-contribution and developer guide https://git.k8s.io/community/contributors/devel/development.md#development-guide
2. Follow the instructions for writing a release note: https://git.k8s.io/community/contributors/guide/release-notes.md
3. If the PR is unfinished, see how to mark it: https://git.k8s.io/community/contributors/guide/pull-requests.md#marking-unfinished-pull-requests
-->

**What type of PR is this?**
> Uncomment only one ` /kind <>` line, hit enter to put that in a new line, and remove leading whitespaces from that line:
>
> /kind api-change
> /kind bug
> /kind cleanup
> /kind design
> /kind documentation
> /kind failing-test
/kind feature
> /kind flake

**What this PR does / why we need it**:
This PR is an extension to kubernetes-csi/csi-lib-utils#77 to send "migrated" label in the metrics

**Which issue(s) this PR fixes**:
Partially Addressed # kubernetes/kubernetes#98279
<!--
*Automatically closes linked issue when PR is merged.
Usage: `Fixes #<issue number>`, or `Fixes (paste link of issue)`.
_If PR is about `failing-tests or flakes`, please post the related issues/tests in a comment and do not use `Fixes`_*
-->
Fixes #

**Special notes for your reviewer**:

**Does this PR introduce a user-facing change?**:
<!--
If no, just write "NONE" in the release-note block below.
If yes, a release note is required:
Enter your extended release note in the block below. If the PR requires additional action from users switching to the new release, include the string "action required".
-->
```release-note
Set the value of "migrated" field in the metrics to true or false to indicate if the call is a migration enabled feature or not
```


k8s-ci-robot: [APPROVALNOTIFIER] This PR is **NOT APPROVED**

This pull-request has been approved by: *<a href="https://github.com/kubernetes-csi/external-attacher/pull/292#" title="Author self-approved">nearora-msft</a>*
To complete the [pull request process](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process), please assign **lpabon** after the PR has been reviewed.
You can assign the PR to them by writing `/assign @lpabon` in a comment when ready.

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=kubernetes-csi%2Fexternal-attacher).

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

- **[OWNERS](https://github.com/kubernetes-csi/external-attacher/blob/master/OWNERS)**

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":["lpabon"]} -->
k8s-ci-robot: Hi @nearora-msft. Thanks for your PR.

I'm waiting for a [kubernetes-csi](https://github.com/orgs/kubernetes-csi/people) member to verify that this patch is reasonable to test. If it is, they should reply with `/ok-to-test` on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should [join the org](https://git.k8s.io/community/community-membership.md#member) to skip this step.

Once the patch is verified, the new status will be reflected by the `ok-to-test` label.

I understand the commands that are listed [here](https://go.k8s.io/bot-commands?repo=kubernetes-csi%2Fexternal-attacher).

<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.
</details>

k8s-ci-robot: Welcome @nearora-msft! <br><br>It looks like this is your first PR to <a href='https://github.com/kubernetes-csi/external-attacher'>kubernetes-csi/external-attacher</a> 🎉. Please refer to our [pull request process documentation](https://git.k8s.io/community/contributors/guide/pull-requests.md) to help your PR have a smooth ride to approval. <br><br>You will be prompted by a bot to use commands during the review process. Do not be afraid to follow the prompts! It is okay to experiment. [Here is the bot commands documentation](https://go.k8s.io/bot-commands). <br><br>You can also check if kubernetes-csi/external-attacher has [its own contribution guidelines](https://github.com/kubernetes-csi/external-attacher/tree/master/CONTRIBUTING.md). <br><br>You may want to refer to our [testing guide](https://git.k8s.io/community/contributors/devel/sig-testing/testing.md) if you run into trouble with your tests not passing. <br><br>If you are having difficulty getting your pull request seen, please follow the [recommended escalation practices](https://github.com/kubernetes/community/blob/master/contributors/guide/pull-requests.md#why-is-my-pull-request-not-getting-reviewed). Also, for tips and tricks in the contribution process you may want to read the [Kubernetes contributor cheat sheet](https://git.k8s.io/community/contributors/guide/contributor-cheatsheet/README.md). We want to make sure your contribution gets all the attention it needs! <br><br>Thank you, and welcome to Kubernetes. :smiley:
Jiawei0227: /ok-to-test
Jiawei0227: /lgtm
/assign @msau42 
I think it looks good to me. Will leave it to @msau42 for approval. Please also make changes if there is any comments that you got from csi-provisioner so the implementation is in sync.
Jiawei0227: I have tested locally and it worked well.
msau42: I'll wait until comments are resolved in the external-provisioner PR and applied to the other sidecars.
k8s-ci-robot: New changes are detected. LGTM label has been removed.
k8s-ci-robot: [APPROVALNOTIFIER] This PR is **NOT APPROVED**

This pull-request has been approved by: *<a href="https://github.com/kubernetes-csi/external-attacher/pull/292#" title="Author self-approved">nearora-msft</a>*
To complete the [pull request process](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process), please assign **msau42** after the PR has been reviewed.
You can assign the PR to them by writing `/assign @msau42` in a comment when ready.

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=kubernetes-csi%2Fexternal-attacher).

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

- **[OWNERS](https://github.com/kubernetes-csi/external-attacher/blob/master/OWNERS)**

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":["msau42"]} -->
nearora-msft: > I'll wait until comments are resolved in the external-provisioner PR and applied to the other sidecars.

Applied the changes concerning the comments in the external-provisioner

Patch:
diff --git a/cmd/csi-attacher/main.go b/cmd/csi-attacher/main.go
index f5d4678c..53987b68 100644
--- a/cmd/csi-attacher/main.go
+++ b/cmd/csi-attacher/main.go
@@ -151,6 +151,24 @@ func main() {
 	}
 	klog.V(2).Infof("CSI driver name: %q", csiAttacher)
 
+	translator := csitrans.New()
+	if translator.IsMigratedCSIDriverByName(csiAttacher) {
+		metricsManager = metrics.NewCSIMetricsManagerWithOptions(csiAttacher, metrics.WithMigration())
+		migratedCsiClient, err := connection.Connect(*csiAddress, metricsManager, connection.OnConnectionLoss(connection.ExitOnConnectionLoss()))
+		if err != nil {
+			klog.Error(err.Error())
+			os.Exit(1)
+		}
+		csiConn.Close()
+		csiConn = migratedCsiClient
+
+		err = rpc.ProbeForever(csiConn, *timeout)
+		if err != nil {
+			klog.Error(err.Error())
+			os.Exit(1)
+		}
+	}
+
 	// Prepare http endpoint for metrics + leader election healthz
 	mux := http.NewServeMux()
 	if addr != "" {
diff --git a/go.mod b/go.mod
index 0b44c0cc..6427ad42 100644
--- a/go.mod
+++ b/go.mod
@@ -14,7 +14,7 @@ require (
 	github.com/googleapis/gnostic v0.5.3 // indirect
 	github.com/hashicorp/golang-lru v0.5.4 // indirect
 	github.com/imdario/mergo v0.3.11 // indirect
-	github.com/kubernetes-csi/csi-lib-utils v0.9.0
+	github.com/kubernetes-csi/csi-lib-utils v0.9.1
 	github.com/kubernetes-csi/csi-test/v4 v4.0.2
 	github.com/prometheus/client_golang v1.8.0 // indirect
 	github.com/prometheus/common v0.15.0 // indirect
diff --git a/go.sum b/go.sum
index 0f980044..9bc6d18b 100644
--- a/go.sum
+++ b/go.sum
@@ -307,8 +307,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
 github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
 github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
 github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
-github.com/kubernetes-csi/csi-lib-utils v0.9.0 h1:TbuDmxoVqM+fvVkzG/7sShyX/8jUln0ElLHuETcsQJI=
-github.com/kubernetes-csi/csi-lib-utils v0.9.0/go.mod h1:8E2jVUX9j3QgspwHXa6LwyN7IHQDjW9jX3kwoWnSC+M=
+github.com/kubernetes-csi/csi-lib-utils v0.9.1 h1:sGq6ifVujfMSkfTsMZip44Ttv8SDXvsBlFk9GdYl/b8=
+github.com/kubernetes-csi/csi-lib-utils v0.9.1/go.mod h1:8E2jVUX9j3QgspwHXa6LwyN7IHQDjW9jX3kwoWnSC+M=
 github.com/kubernetes-csi/csi-test/v4 v4.0.2 h1:MNj94SFHOGK6lOy+yDgxI+zlFWaPcgByqBH3JZZGyZI=
 github.com/kubernetes-csi/csi-test/v4 v4.0.2/go.mod h1:z3FYigjLFAuzmFzKdHQr8gUPm5Xr4Du2twKcxfys0eI=
 github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
diff --git a/pkg/controller/csi_handler.go b/pkg/controller/csi_handler.go
index d4d538f2..2aa4d66e 100644
--- a/pkg/controller/csi_handler.go
+++ b/pkg/controller/csi_handler.go
@@ -20,9 +20,11 @@ import (
 	"context"
 	"errors"
 	"fmt"
+	"strconv"
 	"sync"
 	"time"
 
+	"github.com/kubernetes-csi/csi-lib-utils/connection"
 	"github.com/kubernetes-csi/external-attacher/pkg/attacher"
 	v1 "k8s.io/api/core/v1"
 	storage "k8s.io/api/storage/v1"
@@ -425,6 +427,7 @@ func (h *csiHandler) csiAttach(va *storage.VolumeAttachment) (*storage.VolumeAtt
 
 	var csiSource *v1.CSIPersistentVolumeSource
 	var pvSpec *v1.PersistentVolumeSpec
+	var migratable bool
 	if va.Spec.Source.PersistentVolumeName != nil {
 		if va.Spec.Source.InlineVolumeSpec != nil {
 			return va, nil, errors.New("both InlineCSIVolumeSource and PersistentVolumeName specified in VA source")
@@ -447,6 +450,7 @@ func (h *csiHandler) csiAttach(va *storage.VolumeAttachment) (*storage.VolumeAtt
 			if err != nil {
 				return va, nil, fmt.Errorf("failed to translate in tree pv to CSI: %v", err)
 			}
+			migratable = true
 		}
 
 		// Both csiSource and pvSpec could be translated here if the PV was
@@ -509,6 +513,7 @@ func (h *csiHandler) csiAttach(va *storage.VolumeAttachment) (*storage.VolumeAtt
 	}
 
 	ctx, cancel := context.WithTimeout(context.Background(), h.timeout)
+	ctx = markAsMigrated(ctx, migratable)
 	defer cancel()
 	// We're not interested in `detached` return value, the controller will
 	// issue Detach to be sure the volume is really detached.
@@ -522,6 +527,7 @@ func (h *csiHandler) csiAttach(va *storage.VolumeAttachment) (*storage.VolumeAtt
 
 func (h *csiHandler) csiDetach(va *storage.VolumeAttachment) (*storage.VolumeAttachment, error) {
 	var csiSource *v1.CSIPersistentVolumeSource
+	var migratable bool
 	if va.Spec.Source.PersistentVolumeName != nil {
 		if va.Spec.Source.InlineVolumeSpec != nil {
 			return va, errors.New("both InlineCSIVolumeSource and PersistentVolumeName specified in VA source")
@@ -535,6 +541,7 @@ func (h *csiHandler) csiDetach(va *storage.VolumeAttachment) (*storage.VolumeAtt
 			if err != nil {
 				return va, fmt.Errorf("failed to translate in tree pv to CSI: %v", err)
 			}
+			migratable = true
 		}
 		csiSource, err = getCSISource(&pv.Spec)
 		if err != nil {
@@ -565,6 +572,7 @@ func (h *csiHandler) csiDetach(va *storage.VolumeAttachment) (*storage.VolumeAtt
 	}
 
 	ctx, cancel := context.WithTimeout(context.Background(), h.timeout)
+	ctx = markAsMigrated(ctx, migratable)
 	defer cancel()
 	err = h.attacher.Detach(ctx, volumeHandle, nodeID, secrets)
 	if err != nil {
@@ -763,3 +771,7 @@ func (h *csiHandler) patchPV(pv, clone *v1.PersistentVolume) (*v1.PersistentVolu
 	}
 	return newPV, nil
 }
+
+func markAsMigrated(parent context.Context, hasMigrated bool) context.Context {
+	return context.WithValue(parent, connection.AdditionalInfoKey, connection.AdditionalInfo{Migrated: strconv.FormatBool(hasMigrated)})
+}
diff --git a/release-tools/README.md b/release-tools/README.md
index 6315a736..60eab2a9 100644
--- a/release-tools/README.md
+++ b/release-tools/README.md
@@ -44,17 +44,10 @@ is the recommended way of maintaining a copy of the rules inside the
 changes also locally, test them and then push them back to the shared
 repository at a later time.
 
-We no longer care about importing the full commit history, so `--squash` should be used
-when submitting a `release-tools` update. Also make sure that the PR for that
-contains the automatically generated commit message in the PR description.
-It contains the list of individual commits that were squashed. The script from
-https://github.com/kubernetes-csi/csi-release-tools/issues/7 can create such
-PRs automatically.
-
 Cheat sheet:
 
-- `git subtree add --squash --prefix=release-tools https://github.com/kubernetes-csi/csi-release-tools.git master` - add release tools to a repo which does not have them yet (only once)
-- `git subtree pull --squash --prefix=release-tools https://github.com/kubernetes-csi/csi-release-tools.git master` - update local copy to latest upstream (whenever upstream changes)
+- `git subtree add --prefix=release-tools https://github.com/kubernetes-csi/csi-release-tools.git master` - add release tools to a repo which does not have them yet (only once)
+- `git subtree pull --prefix=release-tools https://github.com/kubernetes-csi/csi-release-tools.git master` - update local copy to latest upstream (whenever upstream changes)
 - edit, `git commit`, `git subtree push --prefix=release-tools git@github.com:<user>/csi-release-tools.git <my-new-or-existing-branch>` - push to a new branch before submitting a PR
 
 verify-shellcheck.sh
diff --git a/release-tools/boilerplate/boilerplate.py b/release-tools/boilerplate/boilerplate.py
index 5618b9ab..63f74963 100755
--- a/release-tools/boilerplate/boilerplate.py
+++ b/release-tools/boilerplate/boilerplate.py
@@ -19,6 +19,8 @@ from __future__ import print_function
 import argparse
 import difflib
 import glob
+import json
+import mmap
 import os
 import re
 import sys
@@ -31,12 +33,12 @@ parser.add_argument(
     nargs='*')
 
 # Rootdir defaults to the directory **above** the repo-infra dir.
-rootdir = os.path.dirname(__file__) + "./../../"
+rootdir = os.path.dirname(__file__) + "./../../../"
 rootdir = os.path.abspath(rootdir)
 parser.add_argument(
     "--rootdir", default=rootdir, help="root directory to examine")
 
-default_boilerplate_dir = os.path.abspath(os.path.dirname(__file__))
+default_boilerplate_dir = os.path.join(rootdir, "csi-driver-nfs/hack/boilerplate")
 
 parser.add_argument(
     "--boilerplate-dir", default=default_boilerplate_dir)
@@ -197,4 +199,4 @@ def main():
     return 0
 
 if __name__ == "__main__":
-    sys.exit(main())
+    sys.exit(main())
\ No newline at end of file
diff --git a/release-tools/prow.sh b/release-tools/prow.sh
index ec695ec6..d4300550 100755
--- a/release-tools/prow.sh
+++ b/release-tools/prow.sh
@@ -71,7 +71,7 @@ version_to_git () {
     version="$1"
     shift
     case "$version" in
-        latest|master) echo "master";;
+        latest) echo "master";;
         release-*) echo "$version";;
         *) echo "v$version";;
     esac
diff --git a/vendor/github.com/kubernetes-csi/csi-lib-utils/connection/connection.go b/vendor/github.com/kubernetes-csi/csi-lib-utils/connection/connection.go
index ac07d59b..fbd8d37b 100644
--- a/vendor/github.com/kubernetes-csi/csi-lib-utils/connection/connection.go
+++ b/vendor/github.com/kubernetes-csi/csi-lib-utils/connection/connection.go
@@ -150,7 +150,7 @@ func connect(
 		return nil, errors.New("OnConnectionLoss callback only supported for unix:// addresses")
 	}
 
-	klog.Infof("Connecting to %s", address)
+	klog.V(5).Infof("Connecting to %s", address)
 
 	// Connect in background.
 	var conn *grpc.ClientConn
@@ -191,6 +191,13 @@ type ExtendedCSIMetricsManager struct {
 	metrics.CSIMetricsManager
 }
 
+type AdditionalInfo struct {
+	Migrated string
+}
+type AdditionalInfoKeyType struct{}
+
+var AdditionalInfoKey AdditionalInfoKeyType
+
 // RecordMetricsClientInterceptor is a gPRC unary interceptor for recording metrics for CSI operations
 // in a gRPC client.
 func (cmm ExtendedCSIMetricsManager) RecordMetricsClientInterceptor(
@@ -203,11 +210,35 @@ func (cmm ExtendedCSIMetricsManager) RecordMetricsClientInterceptor(
 	start := time.Now()
 	err := invoker(ctx, method, req, reply, cc, opts...)
 	duration := time.Since(start)
-	cmm.RecordMetrics(
+
+	var cmmBase metrics.CSIMetricsManager
+	cmmBase = cmm
+	if cmm.HaveAdditionalLabel(metrics.LabelMigrated) {
+		// record migration status
+		additionalInfo := ctx.Value(AdditionalInfoKey)
+		migrated := "false"
+		if additionalInfo != nil {
+			additionalInfoVal, ok := additionalInfo.(AdditionalInfo)
+			if !ok {
+				klog.Errorf("Failed to record migrated status, cannot convert additional info %v", additionalInfo)
+				return err
+			}
+			migrated = additionalInfoVal.Migrated
+		}
+		cmmv, metricsErr := cmm.WithLabelValues(map[string]string{metrics.LabelMigrated: migrated})
+		if metricsErr != nil {
+			klog.Errorf("Failed to record migrated status, error: %v", metricsErr)
+		} else {
+			cmmBase = cmmv
+		}
+	}
+	// Record the default metric
+	cmmBase.RecordMetrics(
 		method,   /* operationName */
 		err,      /* operationErr */
 		duration, /* operationDuration */
 	)
+
 	return err
 }
 
diff --git a/vendor/github.com/kubernetes-csi/csi-lib-utils/metrics/metrics.go b/vendor/github.com/kubernetes-csi/csi-lib-utils/metrics/metrics.go
index 495e1ff8..3baab8ca 100644
--- a/vendor/github.com/kubernetes-csi/csi-lib-utils/metrics/metrics.go
+++ b/vendor/github.com/kubernetes-csi/csi-lib-utils/metrics/metrics.go
@@ -47,6 +47,9 @@ const (
 	labelGrpcStatusCode   = "grpc_status_code"
 	unknownCSIDriverName  = "unknown-driver"
 
+	// LabelMigrated is the Label that indicate whether this is a CSI migration operation
+	LabelMigrated = "migrated"
+
 	// CSI Operation Latency with status code total - Histogram Metric
 	operationsLatencyMetricName = "operations_seconds"
 	operationsLatencyHelp       = "Container Storage Interface operation duration with gRPC error code status total"
@@ -83,6 +86,10 @@ type CSIMetricsManager interface {
 	// and then accumulates values.
 	WithLabelValues(labels map[string]string) (CSIMetricsManager, error)
 
+	// HaveAdditionalLabel can be used to check if the additional label
+	// value is defined in the metrics manager
+	HaveAdditionalLabel(name string) bool
+
 	// SetDriverName is called to update the CSI driver name. This should be done
 	// as soon as possible, otherwise metrics recorded by this manager will be
 	// recorded with an "unknown-driver" driver_name.
@@ -149,6 +156,13 @@ func WithLabels(labels map[string]string) MetricsManagerOption {
 	}
 }
 
+// WithMigration adds the migrated field to the current metrics label
+func WithMigration() MetricsManagerOption {
+	return func(cmm *csiMetricsManager) {
+		cmm.additionalLabelNames = append(cmm.additionalLabelNames, LabelMigrated)
+	}
+}
+
 // WithProcessStartTime controlls whether process_start_time_seconds is registered
 // in the registry of the metrics manager. It's enabled by default out of convenience
 // (no need to do anything special in most sidecars) but should be disabled in more
@@ -316,7 +330,7 @@ func (cmmv *csiMetricsManagerWithValues) WithLabelValues(labels map[string]strin
 	}
 	// Now add all new values.
 	for name, value := range labels {
-		if !extended.haveAdditionalLabel(name) {
+		if !extended.HaveAdditionalLabel(name) {
 			return nil, fmt.Errorf("label %q was not defined via WithLabelNames", name)
 		}
 		if v, ok := extended.additionalValues[name]; ok {
@@ -327,7 +341,7 @@ func (cmmv *csiMetricsManagerWithValues) WithLabelValues(labels map[string]strin
 	return extended, nil
 }
 
-func (cmm *csiMetricsManager) haveAdditionalLabel(name string) bool {
+func (cmm *csiMetricsManager) HaveAdditionalLabel(name string) bool {
 	for _, n := range cmm.additionalLabelNames {
 		if n == name {
 			return true
diff --git a/vendor/modules.txt b/vendor/modules.txt
index db59f97c..3c50c341 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -60,7 +60,7 @@ github.com/hashicorp/golang-lru/simplelru
 github.com/imdario/mergo
 # github.com/json-iterator/go v1.1.10
 github.com/json-iterator/go
-# github.com/kubernetes-csi/csi-lib-utils v0.9.0
+# github.com/kubernetes-csi/csi-lib-utils v0.9.1
 ## explicit
 github.com/kubernetes-csi/csi-lib-utils/connection
 github.com/kubernetes-csi/csi-lib-utils/leaderelection


Test patch:
diff --git a/pkg/controller/csi_handler_test.go b/pkg/controller/csi_handler_test.go
index 42cf9d80..72ce6a0d 100644
--- a/pkg/controller/csi_handler_test.go
+++ b/pkg/controller/csi_handler_test.go
@@ -17,11 +17,13 @@ limitations under the License.
 package controller
 
 import (
+	"context"
 	"errors"
 	"fmt"
 	"testing"
 	"time"
 
+	"github.com/kubernetes-csi/csi-lib-utils/connection"
 	"github.com/kubernetes-csi/external-attacher/pkg/attacher"
 
 	v1 "k8s.io/api/core/v1"
@@ -1519,3 +1521,20 @@ func TestCSIHandlerReadOnly(t *testing.T) {
 	}
 	runTests(t, csiHandlerFactoryNoReadOnly, tests)
 }
+
+func TestMarkAsMigrated(t *testing.T) {
+	t.Run("context has the migrated label for the migratable plugins", func(t *testing.T) {
+		ctx := context.Background()
+		migratedCtx := markAsMigrated(ctx, true)
+		additionalInfo := migratedCtx.Value(connection.AdditionalInfoKey)
+		if additionalInfo == nil {
+			t.Errorf("test: %s, no migrated label found in the context", t.Name())
+		}
+		additionalInfoVal := additionalInfo.(connection.AdditionalInfo)
+		migrated := additionalInfoVal.Migrated
+
+		if migrated != "true" {
+			t.Errorf("test: %s, expected: %v, got: %v", t.Name(), "true", migrated)
+		}
+	})
+}