Merge pull request #97686 from wzshiming/fix-logs-all-containers

Fix --ignore-errors does not take effect if multiple logs are printed and unfollowed

Kubernetes-commit: bce5d7a0158444080ed95aae6a5684ce4dd9444b
This commit is contained in:
Kubernetes Publisher 2021-02-25 23:50:15 -08:00
commit e909d3918e
2 changed files with 127 additions and 1 deletions

View File

@ -375,8 +375,12 @@ func (o LogsOptions) sequentialConsumeRequest(requests map[corev1.ObjectReferenc
for objRef, request := range requests {
out := o.addPrefixIfNeeded(objRef, o.Out)
if err := o.ConsumeRequestFn(request, out); err != nil {
if !o.IgnoreLogErrors {
return err
}
fmt.Fprintf(o.Out, "error: %v\n", err)
}
}
return nil

View File

@ -377,6 +377,128 @@ func TestLog(t *testing.T) {
},
expectedErr: "Error from the ConsumeRequestFn",
},
{
name: "get logs from multiple requests and ignores the error if the container fails",
opts: func(streams genericclioptions.IOStreams) *LogsOptions {
mock := &logTestMock{
logsForObjectRequests: map[corev1.ObjectReference]restclient.ResponseWrapper{
{
Kind: "Pod",
Name: "some-pod-error-container",
FieldPath: "spec.containers{some-container}",
}: &responseWrapperMock{err: errors.New("error-container")},
{
Kind: "Pod",
Name: "some-pod-1",
FieldPath: "spec.containers{some-container}",
}: &responseWrapperMock{data: strings.NewReader("test log content from source 1\n")},
{
Kind: "Pod",
Name: "some-pod-2",
FieldPath: "spec.containers{some-container}",
}: &responseWrapperMock{data: strings.NewReader("test log content from source 2\n")},
},
}
o := NewLogsOptions(streams, false)
o.LogsForObject = mock.mockLogsForObject
o.ConsumeRequestFn = mock.mockConsumeRequest
o.IgnoreLogErrors = true
return o
},
expectedOutSubstrings: []string{
"error-container\n",
"test log content from source 1\n",
"test log content from source 2\n",
},
},
{
name: "get logs from multiple requests and an container fails",
opts: func(streams genericclioptions.IOStreams) *LogsOptions {
mock := &logTestMock{
logsForObjectRequests: map[corev1.ObjectReference]restclient.ResponseWrapper{
{
Kind: "Pod",
Name: "some-pod-error-container",
FieldPath: "spec.containers{some-container}",
}: &responseWrapperMock{err: errors.New("error-container")},
{
Kind: "Pod",
Name: "some-pod",
FieldPath: "spec.containers{some-container}",
}: &responseWrapperMock{data: strings.NewReader("test log content from source\n")},
},
}
o := NewLogsOptions(streams, false)
o.LogsForObject = mock.mockLogsForObject
o.ConsumeRequestFn = mock.mockConsumeRequest
return o
},
expectedErr: "error-container",
},
{
name: "follow logs from multiple requests and ignores the error if the container fails",
opts: func(streams genericclioptions.IOStreams) *LogsOptions {
mock := &logTestMock{
logsForObjectRequests: map[corev1.ObjectReference]restclient.ResponseWrapper{
{
Kind: "Pod",
Name: "some-pod-error-container",
FieldPath: "spec.containers{some-container}",
}: &responseWrapperMock{err: errors.New("error-container")},
{
Kind: "Pod",
Name: "some-pod-1",
FieldPath: "spec.containers{some-container}",
}: &responseWrapperMock{data: strings.NewReader("test log content from source 1\n")},
{
Kind: "Pod",
Name: "some-pod-2",
FieldPath: "spec.containers{some-container}",
}: &responseWrapperMock{data: strings.NewReader("test log content from source 2\n")},
},
}
o := NewLogsOptions(streams, false)
o.LogsForObject = mock.mockLogsForObject
o.ConsumeRequestFn = mock.mockConsumeRequest
o.IgnoreLogErrors = true
o.Follow = true
return o
},
expectedOutSubstrings: []string{
"error-container\n",
"test log content from source 1\n",
"test log content from source 2\n",
},
},
{
name: "follow logs from multiple requests and an container fails",
opts: func(streams genericclioptions.IOStreams) *LogsOptions {
mock := &logTestMock{
logsForObjectRequests: map[corev1.ObjectReference]restclient.ResponseWrapper{
{
Kind: "Pod",
Name: "some-pod-error-container",
FieldPath: "spec.containers{some-container}",
}: &responseWrapperMock{err: errors.New("error-container")},
{
Kind: "Pod",
Name: "some-pod",
FieldPath: "spec.containers{some-container}",
}: &responseWrapperMock{data: strings.NewReader("test log content from source\n")},
},
}
o := NewLogsOptions(streams, false)
o.LogsForObject = mock.mockLogsForObject
o.ConsumeRequestFn = mock.mockConsumeRequest
o.Follow = true
return o
},
expectedErr: "error-container",
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {