mirror of https://github.com/k3s-io/k3s
Do not mutate original object even temporarily to avoid data races
parent
6a845c67f0
commit
483ee1853b
|
@ -10,6 +10,7 @@ go_test(
|
||||||
name = "go_default_test",
|
name = "go_default_test",
|
||||||
srcs = ["unstructured_test.go"],
|
srcs = ["unstructured_test.go"],
|
||||||
library = ":go_default_library",
|
library = ":go_default_library",
|
||||||
|
deps = ["//vendor/github.com/stretchr/testify/assert:go_default_library"],
|
||||||
)
|
)
|
||||||
|
|
||||||
go_library(
|
go_library(
|
||||||
|
|
|
@ -702,9 +702,12 @@ func (unstructuredJSONScheme) Encode(obj runtime.Object, w io.Writer) error {
|
||||||
for _, i := range t.Items {
|
for _, i := range t.Items {
|
||||||
items = append(items, i.Object)
|
items = append(items, i.Object)
|
||||||
}
|
}
|
||||||
t.Object["items"] = items
|
listObj := make(map[string]interface{}, len(t.Object)+1)
|
||||||
defer func() { delete(t.Object, "items") }()
|
for k, v := range t.Object { // Make a shallow copy
|
||||||
return json.NewEncoder(w).Encode(t.Object)
|
listObj[k] = v
|
||||||
|
}
|
||||||
|
listObj["items"] = items
|
||||||
|
return json.NewEncoder(w).Encode(listObj)
|
||||||
case *runtime.Unknown:
|
case *runtime.Unknown:
|
||||||
// TODO: Unstructured needs to deal with ContentType.
|
// TODO: Unstructured needs to deal with ContentType.
|
||||||
_, err := w.Write(t.Raw)
|
_, err := w.Write(t.Raw)
|
||||||
|
|
|
@ -16,7 +16,31 @@ limitations under the License.
|
||||||
|
|
||||||
package unstructured
|
package unstructured
|
||||||
|
|
||||||
import "testing"
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
"sync"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TestCodecOfUnstructuredList tests that there are no data races in Encode().
|
||||||
|
// i.e. that it does not mutate the object being encoded.
|
||||||
|
func TestCodecOfUnstructuredList(t *testing.T) {
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
concurrency := 10
|
||||||
|
list := UnstructuredList{
|
||||||
|
Object: map[string]interface{}{},
|
||||||
|
}
|
||||||
|
wg.Add(concurrency)
|
||||||
|
for i := 0; i < concurrency; i++ {
|
||||||
|
go func() {
|
||||||
|
defer wg.Done()
|
||||||
|
assert.NoError(t, UnstructuredJSONScheme.Encode(&list, ioutil.Discard))
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
wg.Wait()
|
||||||
|
}
|
||||||
|
|
||||||
func TestUnstructuredList(t *testing.T) {
|
func TestUnstructuredList(t *testing.T) {
|
||||||
list := &UnstructuredList{
|
list := &UnstructuredList{
|
||||||
|
|
Loading…
Reference in New Issue