You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: api_test.go
    path of file: ./repos/linkerd2/controller/k8s
    
    the code of the file until where you have to start completion: package k8s

import (
	"context"
	"errors"
	"fmt"
	"reflect"
	"strings"
	"testing"

	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
	"k8s.io/apimachinery/pkg/labels"

	"github.com/go-test/deep"
	"github.com/linkerd/linkerd2/pkg/k8s"

	corev1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/runtime"
)

type resources struct {
	results []string
	misc    []string
}

// newMockAPI constructs a mock controller/k8s.API object for testing If
// useInformer is true, it forces informer indexing, enabling informer lookups
func newMockAPI(useInformer bool, res resources) (
	*API,
	*MetadataAPI,
	[]runtime.Object,
	error,
) {
	k8sConfigs := []string{}
	k8sResults := []runtime.Object{}

	for _, config := range res.results {
		obj, err := k8s.ToRuntimeObject(config)
		if err != nil {
			return nil, nil, nil, err
		}
		k8sConfigs = append(k8sConfigs, config)
		k8sResults = append(k8sResults, 
    
func TestGetOwnerKindAndName(t *testing.T) {
	for i, tt := range []struct {
		resources

		expectedOwnerKind string
		expectedOwnerName string
	}{
		{
			expectedOwnerKind: "deployment",
			expectedOwnerName: "t2",
			resources: resources{
				results: []string{`
apiVersion: v1
kind: Pod
metadata:
  name: t2-5f79f964bc-d5jvf
  namespace: default
  ownerReferences:
  - apiVersion: apps/v1
    kind: ReplicaSet
    name: t2-5f79f964bc`,
				},
				misc: []string{`
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: t2-5f79f964bc
  namespace: default
  ownerReferences:
  - apiVersion: apps/v1
    kind: Deployment
    name: t2`,
				},
			},
		},
		{
			expectedOwnerKind: "replicaset",
			expectedOwnerName: "t1-b4f55d87f",
			resources: resources{
				results: []string{`
apiVersion: v1
kind: Pod
metadata:
  name: t1-b4f55d87f-98dbz
  namespace: default
  ownerReferences:
  - apiVersion: apps/v1
    kind: ReplicaSet
    name: t1-b4f55d87f`,
				},
			},
		},
		{
			expectedOwnerKind: "job",
			expectedOwnerName: "slow-cooker",
			resources: resources{
				results: []string{`
apiVersion: v1
kind: Pod
metadata:
  name: slow-cooker-bxtnq
  namespace: default
  ownerReferences:
  - apiVersion: batch/v1
    kind: Job
    name: slow-cooker`,
				},
			},
		},
		{
			expectedOwnerKind: "replicationcontroller",
			expectedOwnerName: "web",
			resources: resources{
				results: []string{`
apiVersion: v1
kind: Pod
metadata:
  name: web-dcfq4
  namespace: default
  ownerReferences:
  - apiVersion: v1
    kind: ReplicationController
    name: web`,
				},
			},
		},
		{
			expectedOwnerKind: "pod",
			expectedOwnerName: "vote-bot",
			resources: resources{
				results: []string{`
apiVersion: v1
kind: Pod
metadata:
  name: vote-bot
  namespace: default`,
				},
			},
		},
		{
			expectedOwnerKind: "cronjob",
			expectedOwnerName: "my-cronjob",
			resources: resources{
				results: []string{`
apiVersion: v1
kind: Pod
metadata:
  name: my-pod
  namespace: my-ns
  ownerReferences:
  - apiVersion: batch/v1
    kind: Job
    name: my-job`,
				},
				misc: []string{`
apiVersion: batch/v1
kind: Job
metadata:
  name: my-job
  namespace: my-ns
  ownerReferences:
  - apiVersion: batch/v1
    kind: CronJob
    name: my-cronjob`,
				},
			},
		},
		{
			expectedOwnerKind: "replicaset",
			expectedOwnerName: "invalid-rs-parent-2abdffa",
			resources: resources{
				results: []string{`
apiVersion: v1
kind: Pod
metadata:
  name: invalid-rs-parent-dcfq4
  namespace: default
  ownerReferences:
  - apiVersion: v1
    kind: ReplicaSet
    name: invalid-rs-parent-2abdffa`,
				},
				misc: []string{`
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: invalid-rs-parent-2abdffa
  namespace: default
  ownerReferences:
  - apiVersion: invalidParent/v1
    kind: InvalidParentKind
    name: invalid-parent`,
				},
			},
		},
	} {
		tt := tt // pin
		for _, retry := range []bool{
			false,
			true,
		} {
			retry := retry // pin
			t.Run(fmt.Sprintf("%d/retry:%t", i, retry), func(t *testing.T) {
				api, metadataAPI, objs, err := newMockAPI(!retry, tt.resources)
				if err != nil {
					t.Fatalf("newMockAPI error: %s", err)
				}

				pod := objs[0].(*corev1.Pod)
				ownerKind, ownerName := api.GetOwnerKindAndName(context.Background(), pod, retry)

				if ownerKind != tt.expectedOwnerKind {
					t.Fatalf("Expected kind to be [%s], got [%s]", tt.expectedOwnerKind, ownerKind)
				}

				if ownerName != tt.expectedOwnerName {
					t.Fatalf("Expected name to be [%s], got [%s]", tt.expectedOwnerName, ownerName)
				}

				ownerKind, ownerName, err = metadataAPI.GetOwnerKindAndName(context.Background(), pod, retry)
				if err != nil {
					t.Fatalf("Unexpected error: %s", err)
				}

				if ownerKind != tt.expectedOwnerKind {
					t.Fatalf("Expected kind to be [%s], got [%s]", tt.expectedOwnerKind, ownerKind)
				}

				if ownerName != tt.expectedOwnerName {
					t.Fatalf("Expected name to be [%s], got [%s]", tt.expectedOwnerName, ownerName)
				}
			})
		}
	}
}