From 4ce1fb7d40beb9010e56d60792c4da25e8d86ed0 Mon Sep 17 00:00:00 2001 From: Mikhail Mazurskiy Date: Sat, 17 Nov 2018 16:45:36 +1100 Subject: [PATCH] Cleanup math/rand package usage --- cmd/kubelet/app/server.go | 3 -- .../dockershim/libdocker/fake_client.go | 2 +- .../client-go/tools/cache/controller_test.go | 7 ++--- .../k8s.io/client-go/tools/record/event.go | 9 ++---- .../client-go/tools/record/event_test.go | 7 ++--- .../client-go/tools/record/main_test.go | 29 +++++++++++++++++++ .../src/k8s.io/client-go/util/workqueue/BUILD | 1 + .../util/workqueue/delaying_queue_test.go | 4 +-- .../client-go/util/workqueue/main_test.go | 29 +++++++++++++++++++ .../azure/azure_fakes.go | 2 -- test/e2e/e2e_test.go | 7 +++++ test/e2e/framework/util.go | 3 +- test/e2e/network/service.go | 1 - test/e2e/storage/pd.go | 14 ++++----- 14 files changed, 83 insertions(+), 35 deletions(-) create mode 100644 staging/src/k8s.io/client-go/tools/record/main_test.go create mode 100644 staging/src/k8s.io/client-go/util/workqueue/main_test.go diff --git a/cmd/kubelet/app/server.go b/cmd/kubelet/app/server.go index d9e2d0525eb..163ba0726a4 100644 --- a/cmd/kubelet/app/server.go +++ b/cmd/kubelet/app/server.go @@ -22,7 +22,6 @@ import ( "crypto/tls" "errors" "fmt" - "math/rand" "net" "net/http" "net/url" @@ -702,8 +701,6 @@ func run(s *options.KubeletServer, kubeDeps *kubelet.Dependencies, stopCh <-chan utilruntime.ReallyCrash = s.ReallyCrashForTesting - rand.Seed(time.Now().UnixNano()) - // TODO(vmarmol): Do this through container config. oomAdjuster := kubeDeps.OOMAdjuster if err := oomAdjuster.ApplyOOMScoreAdj(0, int(s.OOMScoreAdj)); err != nil { diff --git a/pkg/kubelet/dockershim/libdocker/fake_client.go b/pkg/kubelet/dockershim/libdocker/fake_client.go index 3f58211380b..7e95cf36516 100644 --- a/pkg/kubelet/dockershim/libdocker/fake_client.go +++ b/pkg/kubelet/dockershim/libdocker/fake_client.go @@ -536,7 +536,7 @@ func (f *FakeDockerClient) normalSleep(mean, stdDev, cutOffMillis int) { return } cutoff := (time.Duration)(cutOffMillis) * time.Millisecond - delay := (time.Duration)(rand.NormFloat64()*float64(stdDev)+float64(mean)) * time.Millisecond + delay := (time.Duration)(f.RandGenerator.NormFloat64()*float64(stdDev)+float64(mean)) * time.Millisecond if delay < cutoff { delay = cutoff } diff --git a/staging/src/k8s.io/client-go/tools/cache/controller_test.go b/staging/src/k8s.io/client-go/tools/cache/controller_test.go index 64aca8d7d0b..2ce1dddf196 100644 --- a/staging/src/k8s.io/client-go/tools/cache/controller_test.go +++ b/staging/src/k8s.io/client-go/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/staging/src/k8s.io/client-go/tools/record/event.go b/staging/src/k8s.io/client-go/tools/record/event.go index 65e48c0238a..7bd1ef5ed57 100644 --- a/staging/src/k8s.io/client-go/tools/record/event.go +++ b/staging/src/k8s.io/client-go/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/staging/src/k8s.io/client-go/tools/record/event_test.go b/staging/src/k8s.io/client-go/tools/record/event_test.go index 4fcebc35371..02e34c7d168 100644 --- a/staging/src/k8s.io/client-go/tools/record/event_test.go +++ b/staging/src/k8s.io/client-go/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/staging/src/k8s.io/client-go/tools/record/main_test.go b/staging/src/k8s.io/client-go/tools/record/main_test.go new file mode 100644 index 00000000000..b3c74f25bc7 --- /dev/null +++ b/staging/src/k8s.io/client-go/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/staging/src/k8s.io/client-go/util/workqueue/BUILD b/staging/src/k8s.io/client-go/util/workqueue/BUILD index a298ba0710f..538ad31cde9 100644 --- a/staging/src/k8s.io/client-go/util/workqueue/BUILD +++ b/staging/src/k8s.io/client-go/util/workqueue/BUILD @@ -11,6 +11,7 @@ go_test( srcs = [ "default_rate_limiters_test.go", "delaying_queue_test.go", + "main_test.go", "metrics_test.go", "queue_test.go", "rate_limiting_queue_test.go", diff --git a/staging/src/k8s.io/client-go/util/workqueue/delaying_queue_test.go b/staging/src/k8s.io/client-go/util/workqueue/delaying_queue_test.go index 3c8ebf13a3f..4e427c6b081 100644 --- a/staging/src/k8s.io/client-go/util/workqueue/delaying_queue_test.go +++ b/staging/src/k8s.io/client-go/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/staging/src/k8s.io/client-go/util/workqueue/main_test.go b/staging/src/k8s.io/client-go/util/workqueue/main_test.go new file mode 100644 index 00000000000..41274b2c251 --- /dev/null +++ b/staging/src/k8s.io/client-go/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()) +} diff --git a/staging/src/k8s.io/legacy-cloud-providers/azure/azure_fakes.go b/staging/src/k8s.io/legacy-cloud-providers/azure/azure_fakes.go index f24831970d7..63df4f1a47a 100644 --- a/staging/src/k8s.io/legacy-cloud-providers/azure/azure_fakes.go +++ b/staging/src/k8s.io/legacy-cloud-providers/azure/azure_fakes.go @@ -23,7 +23,6 @@ import ( "net/http" "strings" "sync" - "time" "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/types" @@ -486,7 +485,6 @@ func (fNSG *fakeAzureNSGClient) List(ctx context.Context, resourceGroupName stri } func getRandomIPPtr() *string { - rand.Seed(time.Now().UnixNano()) return to.StringPtr(fmt.Sprintf("%d.%d.%d.%d", rand.Intn(256), rand.Intn(256), rand.Intn(256), rand.Intn(256))) } diff --git a/test/e2e/e2e_test.go b/test/e2e/e2e_test.go index 58a64f2db2f..373e038cc0c 100644 --- a/test/e2e/e2e_test.go +++ b/test/e2e/e2e_test.go @@ -19,8 +19,10 @@ package e2e import ( "flag" "fmt" + "math/rand" "os" "testing" + "time" // Never, ever remove the line with "/ginkgo". Without it, // the ginkgo test runner will not detect that this @@ -92,6 +94,11 @@ func init() { } +func TestMain(m *testing.M) { + rand.Seed(time.Now().UnixNano()) + os.Exit(m.Run()) +} + func TestE2E(t *testing.T) { RunE2ETests(t) } diff --git a/test/e2e/framework/util.go b/test/e2e/framework/util.go index b45a411562d..65fc4f38cd2 100644 --- a/test/e2e/framework/util.go +++ b/test/e2e/framework/util.go @@ -2054,8 +2054,7 @@ func LoadClientset() (*clientset.Clientset, error) { // need to use such a function and can instead // use the UUID utility function. func RandomSuffix() string { - r := rand.New(rand.NewSource(time.Now().UnixNano())) - return strconv.Itoa(r.Int() % 10000) + return strconv.Itoa(rand.Intn(10000)) } // ExpectError expects an error happens, otherwise an exception raises diff --git a/test/e2e/network/service.go b/test/e2e/network/service.go index 97ca2675c41..05fbc2039a0 100644 --- a/test/e2e/network/service.go +++ b/test/e2e/network/service.go @@ -1161,7 +1161,6 @@ var _ = SIGDescribe("Services", func() { } outOfRangeNodePort := 0 - rand.Seed(time.Now().UnixNano()) for { outOfRangeNodePort = 1 + rand.Intn(65535) if !framework.ServiceNodePortRange.Contains(outOfRangeNodePort) { diff --git a/test/e2e/storage/pd.go b/test/e2e/storage/pd.go index e0c31653fa4..2727a324eb9 100644 --- a/test/e2e/storage/pd.go +++ b/test/e2e/storage/pd.go @@ -18,7 +18,7 @@ package storage import ( "fmt" - mathrand "math/rand" + "math/rand" "strings" "time" @@ -80,8 +80,6 @@ var _ = utils.SIGDescribe("Pod Disks", func() { gomega.Expect(len(nodes.Items)).To(gomega.BeNumerically(">=", minNodes), fmt.Sprintf("Requires at least %d nodes", minNodes)) host0Name = types.NodeName(nodes.Items[0].ObjectMeta.Name) host1Name = types.NodeName(nodes.Items[1].ObjectMeta.Name) - - mathrand.Seed(time.Now().UnixNano()) }) ginkgo.Context("schedule pods each with a PD, delete pod and verify detach [Slow]", func() { @@ -179,7 +177,7 @@ var _ = utils.SIGDescribe("Pod Disks", func() { ginkgo.By("writing content to host0Pod on node0") containerName = "mycontainer" testFile = "/testpd1/tracker" - testFileContents = fmt.Sprintf("%v", mathrand.Int()) + testFileContents = fmt.Sprintf("%v", rand.Int()) framework.ExpectNoError(f.WriteFileViaContainer(host0Pod.Name, containerName, testFile, testFileContents)) e2elog.Logf("wrote %q to file %q in pod %q on node %q", testFileContents, testFile, host0Pod.Name, host0Name) ginkgo.By("verifying PD is present in node0's VolumeInUse list") @@ -279,11 +277,11 @@ var _ = utils.SIGDescribe("Pod Disks", func() { ginkgo.By(fmt.Sprintf("writing %d file(s) via a container", numPDs)) containerName := "mycontainer" if numContainers > 1 { - containerName = fmt.Sprintf("mycontainer%v", mathrand.Intn(numContainers)+1) + containerName = fmt.Sprintf("mycontainer%v", rand.Intn(numContainers)+1) } for x := 1; x <= numPDs; x++ { testFile := fmt.Sprintf("/testpd%d/tracker%d", x, i) - testFileContents := fmt.Sprintf("%v", mathrand.Int()) + testFileContents := fmt.Sprintf("%v", rand.Int()) fileAndContentToVerify[testFile] = testFileContents framework.ExpectNoError(f.WriteFileViaContainer(host0Pod.Name, containerName, testFile, testFileContents)) e2elog.Logf("wrote %q to file %q in pod %q (container %q) on node %q", testFileContents, testFile, host0Pod.Name, containerName, host0Name) @@ -291,7 +289,7 @@ var _ = utils.SIGDescribe("Pod Disks", func() { ginkgo.By("verifying PD contents via a container") if numContainers > 1 { - containerName = fmt.Sprintf("mycontainer%v", mathrand.Intn(numContainers)+1) + containerName = fmt.Sprintf("mycontainer%v", rand.Intn(numContainers)+1) } verifyPDContentsViaContainer(f, host0Pod.Name, containerName, fileAndContentToVerify) @@ -378,7 +376,7 @@ var _ = utils.SIGDescribe("Pod Disks", func() { ginkgo.By("writing content to host0Pod") testFile := "/testpd1/tracker" - testFileContents := fmt.Sprintf("%v", mathrand.Int()) + testFileContents := fmt.Sprintf("%v", rand.Int()) framework.ExpectNoError(f.WriteFileViaContainer(host0Pod.Name, containerName, testFile, testFileContents)) e2elog.Logf("wrote %q to file %q in pod %q on node %q", testFileContents, testFile, host0Pod.Name, host0Name)