add unit test for kubelet trace

Signed-off-by: Ziqi Zhao <zhaoziqi9146@gmail.com>
This commit is contained in:
Ziqi Zhao 2023-12-02 17:09:01 +08:00
parent f035fea63a
commit 24c4d6f7c9

View File

@ -31,6 +31,9 @@ import (
"testing" "testing"
"time" "time"
sdktrace "go.opentelemetry.io/otel/sdk/trace"
"go.opentelemetry.io/otel/sdk/trace/tracetest"
"go.opentelemetry.io/otel/trace"
oteltrace "go.opentelemetry.io/otel/trace" oteltrace "go.opentelemetry.io/otel/trace"
"github.com/golang/mock/gomock" "github.com/golang/mock/gomock"
@ -69,6 +72,7 @@ import (
fakeremote "k8s.io/kubernetes/pkg/kubelet/cri/remote/fake" fakeremote "k8s.io/kubernetes/pkg/kubelet/cri/remote/fake"
"k8s.io/kubernetes/pkg/kubelet/eviction" "k8s.io/kubernetes/pkg/kubelet/eviction"
"k8s.io/kubernetes/pkg/kubelet/images" "k8s.io/kubernetes/pkg/kubelet/images"
"k8s.io/kubernetes/pkg/kubelet/kuberuntime"
"k8s.io/kubernetes/pkg/kubelet/lifecycle" "k8s.io/kubernetes/pkg/kubelet/lifecycle"
"k8s.io/kubernetes/pkg/kubelet/logs" "k8s.io/kubernetes/pkg/kubelet/logs"
"k8s.io/kubernetes/pkg/kubelet/network/dns" "k8s.io/kubernetes/pkg/kubelet/network/dns"
@ -3100,8 +3104,8 @@ func createAndStartFakeRemoteRuntime(t *testing.T) (*fakeremote.RemoteRuntime, s
return fakeRuntime, endpoint return fakeRuntime, endpoint
} }
func createRemoteRuntimeService(endpoint string, t *testing.T) internalapi.RuntimeService { func createRemoteRuntimeService(endpoint string, t *testing.T, tp trace.TracerProvider) internalapi.RuntimeService {
runtimeService, err := remote.NewRemoteRuntimeService(endpoint, 15*time.Second, oteltrace.NewNoopTracerProvider()) runtimeService, err := remote.NewRemoteRuntimeService(endpoint, 15*time.Second, tp)
require.NoError(t, err) require.NoError(t, err)
return runtimeService return runtimeService
} }
@ -3139,7 +3143,7 @@ func TestNewMainKubeletStandAlone(t *testing.T) {
fakeRuntime.Stop() fakeRuntime.Stop()
}() }()
fakeRecorder := &record.FakeRecorder{} fakeRecorder := &record.FakeRecorder{}
rtSvc := createRemoteRuntimeService(endpoint, t) rtSvc := createRemoteRuntimeService(endpoint, t, oteltrace.NewNoopTracerProvider())
kubeDep := &Dependencies{ kubeDep := &Dependencies{
Auth: nil, Auth: nil,
CAdvisorInterface: cadvisor, CAdvisorInterface: cadvisor,
@ -3222,3 +3226,119 @@ func TestNewMainKubeletStandAlone(t *testing.T) {
assert.Nil(t, testMainKubelet.configMapManager, "configmap manager should be nil if kubelet is in standalone mode") assert.Nil(t, testMainKubelet.configMapManager, "configmap manager should be nil if kubelet is in standalone mode")
assert.Nil(t, testMainKubelet.secretManager, "secret manager should be nil if kubelet is in standalone mode") assert.Nil(t, testMainKubelet.secretManager, "secret manager should be nil if kubelet is in standalone mode")
} }
func TestSyncPodSpans(t *testing.T) {
testKubelet := newTestKubelet(t, false)
kubelet := testKubelet.kubelet
recorder := record.NewFakeRecorder(20)
nodeRef := &v1.ObjectReference{
Kind: "Node",
Name: "testNode",
UID: types.UID("testNode"),
Namespace: "",
}
kubelet.dnsConfigurer = dns.NewConfigurer(recorder, nodeRef, nil, nil, "TEST", "")
kubeCfg := &kubeletconfiginternal.KubeletConfiguration{
SyncFrequency: metav1.Duration{Duration: time.Minute},
ConfigMapAndSecretChangeDetectionStrategy: kubeletconfiginternal.WatchChangeDetectionStrategy,
ContainerLogMaxSize: "10Mi",
ContainerLogMaxFiles: 5,
MemoryThrottlingFactor: utilpointer.Float64(0),
}
exp := tracetest.NewInMemoryExporter()
tp := sdktrace.NewTracerProvider(
sdktrace.WithBatcher(exp),
)
kubelet.tracer = tp.Tracer(instrumentationScope)
fakeRuntime, endpoint := createAndStartFakeRemoteRuntime(t)
defer func() {
fakeRuntime.Stop()
}()
runtimeSvc := createRemoteRuntimeService(endpoint, t, tp)
kubelet.runtimeService = runtimeSvc
fakeRuntime.ImageService.SetFakeImageSize(100)
fakeRuntime.ImageService.SetFakeImages([]string{"test:latest"})
imageSvc, err := remote.NewRemoteImageService(endpoint, 15*time.Second, tp)
kubelet.containerRuntime, err = kuberuntime.NewKubeGenericRuntimeManager(
kubelet.recorder,
kubelet.livenessManager,
kubelet.readinessManager,
kubelet.startupManager,
kubelet.rootDirectory,
kubelet.machineInfo,
kubelet.podWorkers,
kubelet.os,
kubelet,
nil,
kubelet.backOff,
kubeCfg.SerializeImagePulls,
kubeCfg.MaxParallelImagePulls,
float32(kubeCfg.RegistryPullQPS),
int(kubeCfg.RegistryBurst),
"",
"",
kubeCfg.CPUCFSQuota,
kubeCfg.CPUCFSQuotaPeriod,
runtimeSvc,
imageSvc,
kubelet.containerManager,
kubelet.containerLogManager,
kubelet.runtimeClassManager,
false,
kubeCfg.MemorySwap.SwapBehavior,
kubelet.containerManager.GetNodeAllocatableAbsolute,
*kubeCfg.MemoryThrottlingFactor,
kubeletutil.NewPodStartupLatencyTracker(),
tp,
)
pod := podWithUIDNameNsSpec("12345678", "foo", "new", v1.PodSpec{
Containers: []v1.Container{
{
Name: "bar",
Image: "test:latest",
ImagePullPolicy: v1.PullAlways,
},
},
EnableServiceLinks: utilpointer.Bool(false),
})
_, err = kubelet.SyncPod(context.Background(), kubetypes.SyncPodCreate, pod, nil, &kubecontainer.PodStatus{})
require.NoError(t, err)
err = tp.ForceFlush(context.Background())
require.NoError(t, err)
assert.NotEmpty(t, exp.GetSpans())
// find root span for syncPod
var rootSpan *tracetest.SpanStub
spans := exp.GetSpans()
for i, span := range spans {
if span.Name == "syncPod" {
rootSpan = &spans[i]
break
}
}
assert.NotNil(t, rootSpan)
imageServiceSpans := make([]tracetest.SpanStub, 0)
runtimeServiceSpans := make([]tracetest.SpanStub, 0)
for _, span := range exp.GetSpans() {
if span.SpanContext.TraceID() == rootSpan.SpanContext.TraceID() && span.Parent.SpanID() == rootSpan.SpanContext.SpanID() {
switch {
case strings.HasPrefix(span.Name, "runtime.v1.ImageService"):
imageServiceSpans = append(imageServiceSpans, span)
case strings.HasPrefix(span.Name, "runtime.v1.RuntimeService"):
runtimeServiceSpans = append(runtimeServiceSpans, span)
}
}
}
assert.NotEmpty(t, imageServiceSpans)
assert.NotEmpty(t, runtimeServiceSpans)
}