generated from kubernetes/kubernetes-template-project
-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
logcheck: check that fmt.Stringer gets implemented properly
If a type inherits String from some embedded field, then the klog text output will only print the result of that function call, which then includes only information about the embedded field (example: kubernetes/kubernetes#115950). The right solution for this problem is TBD.
- Loading branch information
Showing
5 changed files
with
263 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
40 changes: 40 additions & 0 deletions
40
logcheck/testdata/src/k8s.io/apimachinery/pkg/apis/meta/v1/types.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
/* | ||
Copyright 2023 The Kubernetes Authors. | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
|
||
package v1 | ||
|
||
import ( | ||
"fmt" | ||
"strings" | ||
) | ||
|
||
type TypeMeta struct { | ||
Kind string `json:"kind,omitempty" protobuf:"bytes,1,opt,name=kind"` | ||
APIVersion string `json:"apiVersion,omitempty" protobuf:"bytes,2,opt,name=apiVersion"` | ||
} | ||
|
||
// String is generated (https://github.com/kubernetes/apimachinery/blob/v0.26.3/pkg/apis/meta/v1/generated.pb.go#L4757). | ||
func (this *TypeMeta) String() string { | ||
if this == nil { | ||
return "nil" | ||
} | ||
s := strings.Join([]string{`&TypeMeta{`, | ||
`Kind:` + fmt.Sprintf("%v", this.Kind) + `,`, | ||
`APIVersion:` + fmt.Sprintf("%v", this.APIVersion) + `,`, | ||
`}`, | ||
}, "") | ||
return s | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
/* | ||
Copyright 2023 The Kubernetes Authors. | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
|
||
package marshaler | ||
|
||
import ( | ||
klog "k8s.io/klog/v2" | ||
) | ||
|
||
func foo() { | ||
klog.Background().Info("Starting", "config", config{}) // want `The type marshaler.config inherits \(marshaler.Meta\).MarshalLog as implementation of logr.Marshaler, which covers only a subset of the value. Implement MarshalLog for the type or wrap it with klog.Format.` | ||
klog.Background().Info("Starting", "config", configWithMarshaler{}) | ||
klog.Background().Info("Starting", "config", &config{}) // want `The type \*marshaler.config inherits \(marshaler.Meta\).MarshalLog as implementation of logr.Marshaler, which covers only a subset of the value. Implement MarshalLog for the type or wrap it with klog.Format.` | ||
klog.Background().Info("Starting", "config", &configWithMarshaler{}) | ||
klog.Background().Info("Starting", "config", &simpleConfig{}) | ||
} | ||
|
||
type Meta struct { | ||
kind string | ||
} | ||
|
||
func (m Meta) MarshalLog() interface{} { | ||
return m.kind | ||
} | ||
|
||
type config struct { | ||
Meta // implements logr.Marshaler | ||
|
||
RealField int | ||
} | ||
|
||
type configWithMarshaler config | ||
|
||
func (c configWithMarshaler) Size() int { | ||
return 1 | ||
} | ||
|
||
func (c configWithMarshaler) MarshalLog() interface{} { | ||
return "foo" | ||
} | ||
|
||
// simpleConfig only has a single field. In this case inheriting the Marshaler implementation | ||
// is fine. | ||
type simpleConfig struct { | ||
Meta | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
/* | ||
Copyright 2023 The Kubernetes Authors. | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
|
||
package stringer | ||
|
||
import ( | ||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
klog "k8s.io/klog/v2" | ||
) | ||
|
||
func foo() { | ||
klog.Background().Info("Starting", "config", config{}) // No warning because TypeMeta implement String only for pointer receivers. | ||
klog.Background().Info("Starting", "config", configWithStringer{}) | ||
klog.Background().Info("Starting", "config", &config{}) // want `The type \*stringer.config inherits \(\*k8s.io/apimachinery/pkg/apis/meta/v1.TypeMeta\).String as implementation of fmt.Stringer, which covers only a subset of the value. Implement String for the type or wrap it with klog.Format.` | ||
klog.Background().Info("Starting", "config", &configWithStringer{}) | ||
klog.Background().Info("Starting", "config", &simpleConfig{}) | ||
} | ||
|
||
// config mimicks KubeletConfig (see | ||
// https://github.com/kubernetes/kubernetes/pull/115950). As far as logging is | ||
// concerned, the type is broken: it implements fmt.Stringer because it | ||
// embeds TypeMeta, but the result of String() is incomplete. | ||
type config struct { | ||
metav1.TypeMeta // implements fmt.Stringer (but only for addressable values) | ||
|
||
RealField int | ||
} | ||
|
||
type configWithStringer config | ||
|
||
func (c configWithStringer) Size() int { | ||
return 1 | ||
} | ||
|
||
func (c configWithStringer) String() string { | ||
return "foo" | ||
} | ||
|
||
// simpleConfig only has a single field. In this case inheriting the String implementation | ||
// is fine. This occurs for https://pkg.go.dev/k8s.io/apimachinery/pkg/apis/meta/v1#Time. | ||
type simpleConfig struct { | ||
metav1.TypeMeta | ||
} |