Merge pull request #137189 from dhruv7539/codex/getlogs-reactor-support

client-go: make fake Pods.GetLogs honor reactors

Kubernetes-commit: 44b486f43c9792e812f849d9509449ac69edf55c
This commit is contained in:
Kubernetes Publisher
2026-02-27 02:05:55 +05:30
2 changed files with 92 additions and 3 deletions

View File

@@ -17,16 +17,17 @@ limitations under the License.
package fake
import (
"bytes"
"context"
"fmt"
"io"
"net/http"
"strings"
v1 "k8s.io/api/core/v1"
policyv1 "k8s.io/api/policy/v1"
policyv1beta1 "k8s.io/api/policy/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/kubernetes/scheme"
restclient "k8s.io/client-go/rest"
fakerest "k8s.io/client-go/rest/fake"
@@ -63,12 +64,26 @@ func (c *fakePods) GetLogs(name string, opts *v1.PodLogOptions) *restclient.Requ
action.Subresource = "log"
action.Value = opts
_, _ = c.Fake.Invokes(action, &v1.Pod{})
defaultLogResponse := &runtime.Unknown{Raw: []byte("fake logs")}
obj, err := c.Fake.Invokes(action, defaultLogResponse)
logs := defaultLogResponse.Raw
if err == nil {
unknown, ok := obj.(*runtime.Unknown)
if !ok || unknown == nil {
err = fmt.Errorf("fake Pods.GetLogs expected reactor to return *runtime.Unknown, got %T", obj)
} else {
logs = unknown.Raw
}
}
fakeClient := &fakerest.RESTClient{
Client: fakerest.CreateHTTPClient(func(request *http.Request) (*http.Response, error) {
if err != nil {
return nil, err
}
resp := &http.Response{
StatusCode: http.StatusOK,
Body: io.NopCloser(strings.NewReader("fake logs")),
Body: io.NopCloser(bytes.NewReader(logs)),
}
return resp, nil
}),

View File

@@ -19,10 +19,13 @@ package fake
import (
"bytes"
"context"
"errors"
"io"
"strings"
"testing"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/runtime"
cgtesting "k8s.io/client-go/testing"
)
@@ -46,3 +49,74 @@ func TestFakePodsGetLogs(t *testing.T) {
t.Fatal("Close response body:", err)
}
}
func TestFakePodsGetLogsReactorError(t *testing.T) {
fake := &cgtesting.Fake{}
fp := newFakePods(&FakeCoreV1{Fake: fake}, "default")
expectedErr := errors.New("reactor get logs failure")
fake.PrependReactor("get", "pods/log", func(action cgtesting.Action) (bool, runtime.Object, error) {
genericAction, ok := action.(cgtesting.GenericAction)
if !ok {
t.Fatalf("expected GenericAction, got %T", action)
}
opts, ok := genericAction.GetValue().(*corev1.PodLogOptions)
if !ok {
t.Fatalf("expected *corev1.PodLogOptions, got %T", genericAction.GetValue())
}
if opts.Container != "ctr" {
t.Fatalf("expected container ctr, got %q", opts.Container)
}
return true, nil, expectedErr
})
req := fp.GetLogs("foo", &corev1.PodLogOptions{Container: "ctr"})
_, err := req.Stream(context.Background())
if !errors.Is(err, expectedErr) {
t.Fatalf("expected stream error %v, got %v", expectedErr, err)
}
}
func TestFakePodsGetLogsReactorResponse(t *testing.T) {
fake := &cgtesting.Fake{}
fp := newFakePods(&FakeCoreV1{Fake: fake}, "default")
expectedLogs := "reactor logs"
fake.PrependReactor("get", "pods/log", func(action cgtesting.Action) (bool, runtime.Object, error) {
return true, &runtime.Unknown{Raw: []byte(expectedLogs)}, nil
})
req := fp.GetLogs("foo", &corev1.PodLogOptions{})
body, err := req.Stream(context.Background())
if err != nil {
t.Fatalf("Stream pod logs: %v", err)
}
defer func() {
if err := body.Close(); err != nil {
t.Fatalf("Close response body: %v", err)
}
}()
logs, err := io.ReadAll(body)
if err != nil {
t.Fatalf("Read pod logs: %v", err)
}
if string(logs) != expectedLogs {
t.Fatalf("expected logs %q, got %q", expectedLogs, string(logs))
}
}
func TestFakePodsGetLogsReactorInvalidObject(t *testing.T) {
fake := &cgtesting.Fake{}
fp := newFakePods(&FakeCoreV1{Fake: fake}, "default")
fake.PrependReactor("get", "pods/log", func(action cgtesting.Action) (bool, runtime.Object, error) {
return true, &corev1.Pod{}, nil
})
req := fp.GetLogs("foo", &corev1.PodLogOptions{})
_, err := req.Stream(context.Background())
if err == nil {
t.Fatal("expected stream error")
}
if !strings.Contains(err.Error(), "expected reactor to return *runtime.Unknown") {
t.Fatalf("expected helpful reactor object type error, got: %v", err)
}
}