Skip to content

Commit 264bb40

Browse files
authored
Merge pull request #3645 from serathius/resource-size-deterministic
Make randomized data in pods deterministic to avoid pod recreation
2 parents df10c37 + a400771 commit 264bb40

File tree

7 files changed

+76
-9
lines changed

7 files changed

+76
-9
lines changed

clusterloader2/pkg/config/template_functions.go

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@ limitations under the License.
1717
package config
1818

1919
import (
20+
"crypto/sha256"
21+
"encoding/binary"
2022
"fmt"
23+
"io"
2124
"io/fs"
2225
"io/ioutil"
2326
"math"
@@ -34,8 +37,10 @@ import (
3437
"k8s.io/klog/v2"
3538
)
3639

40+
var globalRand *rand.Rand
41+
3742
func init() {
38-
rand.Seed(time.Now().UnixNano())
43+
globalRand = rand.New(rand.NewSource(time.Now().UnixNano()))
3944
}
4045

4146
// GetFuncs returns map of names to functions, that are supported by template provider.
@@ -60,6 +65,7 @@ func GetFuncs(fsys fs.FS) template.FuncMap {
6065
"MultiplyFloat": multiplyFloat,
6166
"MultiplyInt": multiplyInt,
6267
"RandData": randData,
68+
"RandDataWithSeed": randDataWithSeed,
6369
"RandInt": randInt,
6470
"RandIntRange": randIntRange,
6571
"Seq": seq,
@@ -108,9 +114,29 @@ func toFloat64(val interface{}) float64 {
108114

109115
// randData returns pseudo-random string of i length.
110116
func randData(i interface{}) string {
111-
const alphabet = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
112117
typedI := int(toFloat64(i))
113-
b := make([]byte, typedI)
118+
return randString(globalRand, typedI)
119+
}
120+
121+
// randData returns pseudo-random string of i length with a provided seed to allow deterministic result.
122+
func randDataWithSeed(i, j interface{}) string {
123+
typedI := int(toFloat64(i))
124+
if typedI == 0 {
125+
return ""
126+
}
127+
typedJ := j.(string)
128+
h := sha256.New()
129+
_, err := io.WriteString(h, typedJ)
130+
if err != nil {
131+
panic(fmt.Sprintf("failed to write %q to sha256 hash", typedJ))
132+
}
133+
seed := int64(binary.BigEndian.Uint64(h.Sum(nil)))
134+
return randString(rand.New(rand.NewSource(seed)), typedI)
135+
}
136+
137+
func randString(rand *rand.Rand, length int) string {
138+
const alphabet = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
139+
b := make([]byte, length)
114140
for i := range b {
115141
b[i] = alphabet[rand.Intn(len(alphabet))]
116142
}
@@ -120,7 +146,7 @@ func randData(i interface{}) string {
120146
// randInt returns pseudo-random int in [0, i].
121147
func randInt(i interface{}) int {
122148
typedI := int(toFloat64(i))
123-
return rand.Intn(typedI + 1)
149+
return globalRand.Intn(typedI + 1)
124150
}
125151

126152
// randIntRange returns pseudo-random int in [i, j].
@@ -131,7 +157,7 @@ func randIntRange(i, j interface{}) int {
131157
if typedI >= typedJ {
132158
return typedI
133159
}
134-
return typedI + rand.Intn(typedJ-typedI+1)
160+
return typedI + globalRand.Intn(typedJ-typedI+1)
135161
}
136162

137163
func addInt(numbers ...interface{}) int {

clusterloader2/pkg/config/template_functions_test.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,40 @@ func TestTemplateRandData(t *testing.T) {
3939
}
4040
}
4141
}
42+
43+
func TestTemplateRandDataWithSeed(t *testing.T) {
44+
tests := []struct {
45+
length int
46+
seed string
47+
wantData string
48+
}{
49+
{
50+
length: 0,
51+
seed: "test",
52+
wantData: "",
53+
},
54+
{
55+
length: 1,
56+
seed: "test-1",
57+
wantData: "n",
58+
},
59+
{
60+
length: 1,
61+
seed: "test-2",
62+
wantData: "P",
63+
},
64+
{
65+
length: 100,
66+
seed: "test",
67+
wantData: "HlXm60Fjrvvp0pE3RK7lDhhhuQZpI6ECS18Gp0qqwFlOKjlZH4rFS3pk9pBkVRLzyqIWUv1Omfnmj7djTRjxL4bnp2kG7O5xD2Rf",
68+
},
69+
}
70+
71+
for i, tt := range tests {
72+
data := randDataWithSeed(tt.length, tt.seed)
73+
74+
if tt.wantData != data {
75+
t.Errorf("%d: wanted: %q, got: %q", i, tt.wantData, data)
76+
}
77+
}
78+
}

clusterloader2/testing/load/daemonset.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ spec:
3535
- name: TEST_ENV
3636
value: {{$Env}}
3737
- name: ENV_VAR
38-
value: {{RandData $podPayloadSize}}
38+
value: {{RandDataWithSeed $podPayloadSize .Name}}
3939
resources:
4040
# Keep the CpuRequest/MemoryRequest request equal percentage of 1-core, 4GB node.
4141
# For now we're setting it to 0.5%.

clusterloader2/testing/load/deployment.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ spec:
8181
{{end}}
8282
env:
8383
- name: ENV_VAR
84-
value: {{RandData $podPayloadSize}}
84+
value: {{RandDataWithSeed $podPayloadSize .Name}}
8585
resources:
8686
requests:
8787
cpu: {{$CpuRequest}}

clusterloader2/testing/load/job.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
{{$HostNetworkMode := DefaultParam .CL2_USE_HOST_NETWORK_PODS false}}
22
{{$RUN_ON_ARM_NODES := DefaultParam .CL2_RUN_ON_ARM_NODES false}}
33
{{$Image := DefaultParam .Image "registry.k8s.io/pause:3.9"}}
4+
{{$podPayloadSize := DefaultParam .CL2_JOB_POD_PAYLOAD_SIZE 0}}
45

56
apiVersion: batch/v1
67
kind: Job
@@ -27,6 +28,9 @@ spec:
2728
- name: {{.Name}}
2829
# TODO(#799): We should test the "run-to-completion" workflow and hence don't use pause pods.
2930
image: {{$Image}}
31+
env:
32+
- name: ENV_VAR
33+
value: {{RandDataWithSeed $podPayloadSize .Name}}
3034
resources:
3135
# Keep the CpuRequest/MemoryRequest request equal percentage of 1-core, 4GB node.
3236
# For now we're setting it to 0.5%.

clusterloader2/testing/load/simple-deployment.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ spec:
3131
containers:
3232
- env:
3333
- name: ENV_VAR
34-
value: {{RandData $podPayloadSize}}
34+
value: {{RandDataWithSeed $podPayloadSize .Name}}
3535
image: {{$Image}}
3636
imagePullPolicy: IfNotPresent
3737
name: {{.Name}}

clusterloader2/testing/load/statefulset.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ spec:
3030
image: {{$Image}}
3131
env:
3232
- name: ENV_VAR
33-
value: {{RandData $podPayloadSize}}
33+
value: {{RandDataWithSeed $podPayloadSize .Name}}
3434
ports:
3535
- containerPort: 80
3636
name: web

0 commit comments

Comments
 (0)