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

This commit is contained in:
wzshiming 2021-01-07 10:43:36 +08:00
parent ff4234720d
commit 336e464cae
2 changed files with 127 additions and 1 deletions

View File

@ -371,7 +371,11 @@ 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 {
return err
if !o.IgnoreLogErrors {
return err
}
fmt.Fprintf(o.Out, "error: %v\n", err)
}
}

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) {