From c90a87409af231a1c78a79fa7eefe1712f2560ac Mon Sep 17 00:00:00 2001 From: Mikhail Mazurskiy Date: Sat, 17 Nov 2018 16:45:36 +1100 Subject: [PATCH 1/2] Cleanup math/rand package usage Kubernetes-commit: 4ce1fb7d40beb9010e56d60792c4da25e8d86ed0 --- tools/cache/controller_test.go | 7 +++---- tools/record/event.go | 9 +++------ tools/record/event_test.go | 7 ++----- tools/record/main_test.go | 29 +++++++++++++++++++++++++++ util/workqueue/delaying_queue_test.go | 4 +--- util/workqueue/main_test.go | 29 +++++++++++++++++++++++++++ 6 files changed, 67 insertions(+), 18 deletions(-) create mode 100644 tools/record/main_test.go create mode 100644 util/workqueue/main_test.go diff --git a/tools/cache/controller_test.go b/tools/cache/controller_test.go index 64aca8d7..2ce1dddf 100644 --- a/tools/cache/controller_test.go +++ b/tools/cache/controller_test.go @@ -242,16 +242,15 @@ func TestHammerController(t *testing.T) { currentNames := sets.String{} rs := rand.NewSource(rand.Int63()) f := fuzz.New().NilChance(.5).NumElements(0, 2).RandSource(rs) - r := rand.New(rs) // Mustn't use r and f concurrently! for i := 0; i < 100; i++ { var name string var isNew bool - if currentNames.Len() == 0 || r.Intn(3) == 1 { + if currentNames.Len() == 0 || rand.Intn(3) == 1 { f.Fuzz(&name) isNew = true } else { l := currentNames.List() - name = l[r.Intn(len(l))] + name = l[rand.Intn(len(l))] } pod := &v1.Pod{} @@ -266,7 +265,7 @@ func TestHammerController(t *testing.T) { source.Add(pod) continue } - switch r.Intn(2) { + switch rand.Intn(2) { case 0: currentNames.Insert(name) source.Modify(pod) diff --git a/tools/record/event.go b/tools/record/event.go index 65e48c02..7bd1ef5e 100644 --- a/tools/record/event.go +++ b/tools/record/event.go @@ -162,17 +162,14 @@ type eventBroadcasterImpl struct { // The return value can be ignored or used to stop recording, if desired. // TODO: make me an object with parameterizable queue length and retry interval func (eventBroadcaster *eventBroadcasterImpl) StartRecordingToSink(sink EventSink) watch.Interface { - // The default math/rand package functions aren't thread safe, so create a - // new Rand object for each StartRecording call. - randGen := rand.New(rand.NewSource(time.Now().UnixNano())) eventCorrelator := NewEventCorrelatorWithOptions(eventBroadcaster.options) return eventBroadcaster.StartEventWatcher( func(event *v1.Event) { - recordToSink(sink, event, eventCorrelator, randGen, eventBroadcaster.sleepDuration) + recordToSink(sink, event, eventCorrelator, eventBroadcaster.sleepDuration) }) } -func recordToSink(sink EventSink, event *v1.Event, eventCorrelator *EventCorrelator, randGen *rand.Rand, sleepDuration time.Duration) { +func recordToSink(sink EventSink, event *v1.Event, eventCorrelator *EventCorrelator, sleepDuration time.Duration) { // Make a copy before modification, because there could be multiple listeners. // Events are safe to copy like this. eventCopy := *event @@ -197,7 +194,7 @@ func recordToSink(sink EventSink, event *v1.Event, eventCorrelator *EventCorrela // Randomize the first sleep so that various clients won't all be // synced up if the master goes down. if tries == 1 { - time.Sleep(time.Duration(float64(sleepDuration) * randGen.Float64())) + time.Sleep(time.Duration(float64(sleepDuration) * rand.Float64())) } else { time.Sleep(sleepDuration) } diff --git a/tools/record/event_test.go b/tools/record/event_test.go index 4fcebc35..02e34c7d 100644 --- a/tools/record/event_test.go +++ b/tools/record/event_test.go @@ -19,7 +19,6 @@ package record import ( "encoding/json" "fmt" - "math/rand" "net/http" "strconv" "testing" @@ -417,7 +416,6 @@ func TestWriteEventError(t *testing.T) { clock := clock.IntervalClock{Time: time.Now(), Duration: time.Second} eventCorrelator := NewEventCorrelator(&clock) - randGen := rand.New(rand.NewSource(time.Now().UnixNano())) for caseName, ent := range table { attempts := 0 @@ -431,7 +429,7 @@ func TestWriteEventError(t *testing.T) { }, } ev := &v1.Event{} - recordToSink(sink, ev, eventCorrelator, randGen, 0) + recordToSink(sink, ev, eventCorrelator, 0) if attempts != ent.attemptsWanted { t.Errorf("case %v: wanted %d, got %d attempts", caseName, ent.attemptsWanted, attempts) } @@ -441,7 +439,6 @@ func TestWriteEventError(t *testing.T) { func TestUpdateExpiredEvent(t *testing.T) { clock := clock.IntervalClock{Time: time.Now(), Duration: time.Second} eventCorrelator := NewEventCorrelator(&clock) - randGen := rand.New(rand.NewSource(time.Now().UnixNano())) var createdEvent *v1.Event @@ -462,7 +459,7 @@ func TestUpdateExpiredEvent(t *testing.T) { ev := &v1.Event{} ev.ResourceVersion = "updated-resource-version" ev.Count = 2 - recordToSink(sink, ev, eventCorrelator, randGen, 0) + recordToSink(sink, ev, eventCorrelator, 0) if createdEvent == nil { t.Error("Event did not get created after patch failed") diff --git a/tools/record/main_test.go b/tools/record/main_test.go new file mode 100644 index 00000000..b3c74f25 --- /dev/null +++ b/tools/record/main_test.go @@ -0,0 +1,29 @@ +/* +Copyright 2018 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 record + +import ( + "math/rand" + "os" + "testing" + "time" +) + +func TestMain(m *testing.M) { + rand.Seed(time.Now().UnixNano()) + os.Exit(m.Run()) +} diff --git a/util/workqueue/delaying_queue_test.go b/util/workqueue/delaying_queue_test.go index 3c8ebf13..4e427c6b 100644 --- a/util/workqueue/delaying_queue_test.go +++ b/util/workqueue/delaying_queue_test.go @@ -216,15 +216,13 @@ func TestCopyShifting(t *testing.T) { } func BenchmarkDelayingQueue_AddAfter(b *testing.B) { - r := rand.New(rand.NewSource(time.Now().Unix())) - fakeClock := clock.NewFakeClock(time.Now()) q := newDelayingQueue(fakeClock, "") // Add items for n := 0; n < b.N; n++ { data := fmt.Sprintf("%d", n) - q.AddAfter(data, time.Duration(r.Int63n(int64(10*time.Minute)))) + q.AddAfter(data, time.Duration(rand.Int63n(int64(10*time.Minute)))) } // Exercise item removal as well diff --git a/util/workqueue/main_test.go b/util/workqueue/main_test.go new file mode 100644 index 00000000..41274b2c --- /dev/null +++ b/util/workqueue/main_test.go @@ -0,0 +1,29 @@ +/* +Copyright 2018 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 workqueue + +import ( + "math/rand" + "os" + "testing" + "time" +) + +func TestMain(m *testing.M) { + rand.Seed(time.Now().UnixNano()) + os.Exit(m.Run()) +} From 458bdf6a674050a4be3cf3f6a9f8e82acdaa4351 Mon Sep 17 00:00:00 2001 From: Mikhail Mazurskiy Date: Wed, 30 Jan 2019 15:27:39 +1100 Subject: [PATCH 2/2] Add missing TestMain() functions Kubernetes-commit: ca38fba0af59e1193625a18002d0bf1408c4106c --- tools/cache/main_test.go | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 tools/cache/main_test.go diff --git a/tools/cache/main_test.go b/tools/cache/main_test.go new file mode 100644 index 00000000..16933a4b --- /dev/null +++ b/tools/cache/main_test.go @@ -0,0 +1,29 @@ +/* +Copyright 2018 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 cache + +import ( + "math/rand" + "os" + "testing" + "time" +) + +func TestMain(m *testing.M) { + rand.Seed(time.Now().UnixNano()) + os.Exit(m.Run()) +}