-
-
Notifications
You must be signed in to change notification settings - Fork 564
/
Copy pathrandom.go
210 lines (195 loc) Β· 6.23 KB
/
random.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
package expr
import (
"crypto/md5"
"encoding/binary"
"fmt"
"math/rand"
"net"
"strings"
"github.com/manveru/faker"
)
// Randomizer generates consistent random values of different types given a seed.
//
// The random values should be consistent in that given the same seed the same
// random values get generated.
//
// Setting the randomizer to nil disables example generation.
type Randomizer interface {
// ArrayLength decides how long an example array will be
ArrayLength() int
// Int generates an integer example
Int() int
// Int32 generates an int32 example
Int32() int32
// Int64 generates an int64 example
Int64() int64
// String generates a string example
String() string
// Bool generates a bool example
Bool() bool
// Float32 generates a float32 example
Float32() float32
// Float64 generates a float64 example
Float64() float64
// UInt generates a uint example
UInt() uint
// UInt32 generates a uint example
UInt32() uint32
// UInt64 generates a uint example
UInt64() uint64
// Name generates a human name example
Name() string
// Email generates an example email address
Email() string
// Hostname generates an example hostname
Hostname() string
// IPv4Address generates an example IPv4 address
IPv4Address() net.IP
// IPv6Address generates an example IPv6 address
IPv6Address() net.IP
// URL generates an example URL
URL() string
// Characters generates a n-character string example
Characters(n int) string
// UUID generates a random v4 UUID
UUID() string
}
// NewRandom returns a random value generator seeded from the given string
// value, using the faker library to generate random but realistic values.
func NewRandom(seed string) *ExampleGenerator {
return &ExampleGenerator{
Randomizer: NewFakerRandomizer(seed),
}
}
type ExampleGenerator struct {
Randomizer
seen map[string]*any
}
// PreviouslySeen returns the previously seen value for a given ID
func (r *ExampleGenerator) PreviouslySeen(typeID string) (*any, bool) {
if r.seen == nil {
return nil, false
}
val, haveSeen := r.seen[typeID]
return val, haveSeen
}
// HaveSeen stores the seen value in the randomizer, for reuse later
func (r *ExampleGenerator) HaveSeen(typeID string, val *any) {
if r.seen == nil {
r.seen = make(map[string]*any)
}
r.seen[typeID] = val
}
// NewFakerRandomizer creates a randomizer that uses the faker library to
// generate fake but reasonable values.
func NewFakerRandomizer(seed string) Randomizer {
hasher := md5.New()
hasher.Write([]byte(seed))
sint := int64(binary.BigEndian.Uint64(hasher.Sum(nil)))
source := rand.NewSource(sint)
ran := rand.New(source)
faker := &faker.Faker{
Language: "end",
Dict: faker.Dict["en"],
Rand: ran,
}
return &FakerRandomizer{
Seed: seed,
faker: faker,
rand: ran,
}
}
// FakerRandomizer implements the Random interface, using the Faker library.
type FakerRandomizer struct {
Seed string
faker *faker.Faker
rand *rand.Rand
}
func (r *FakerRandomizer) ArrayLength() int {
return r.Int()%3 + 2
}
func (r *FakerRandomizer) Int() int {
return r.rand.Int()
}
func (r *FakerRandomizer) Int32() int32 {
return r.rand.Int31()
}
func (r *FakerRandomizer) Int64() int64 {
return r.rand.Int63()
}
func (r *FakerRandomizer) String() string {
return r.faker.Sentence(2, false)
}
func (r *FakerRandomizer) Bool() bool {
return r.rand.Int()%2 == 0
}
func (r *FakerRandomizer) Float32() float32 {
return r.rand.Float32()
}
func (r *FakerRandomizer) Float64() float64 {
return r.rand.Float64()
}
func (r *FakerRandomizer) UInt() uint {
return uint(r.UInt64())
}
func (r *FakerRandomizer) UInt32() uint32 {
return r.rand.Uint32()
}
func (r *FakerRandomizer) UInt64() uint64 {
return r.rand.Uint64()
}
func (r *FakerRandomizer) Email() string {
return r.faker.Email()
}
func (r *FakerRandomizer) Hostname() string {
return r.faker.DomainName() + "." + r.faker.DomainSuffix()
}
func (r *FakerRandomizer) IPv4Address() net.IP {
return r.faker.IPv4Address()
}
func (r *FakerRandomizer) IPv6Address() net.IP {
return r.faker.IPv6Address()
}
func (r *FakerRandomizer) URL() string {
return r.faker.URL()
}
func (r *FakerRandomizer) Characters(n int) string {
return r.faker.Characters(n)
}
func (r *FakerRandomizer) UUID() string {
uuid := make([]byte, 16)
r.rand.Read(uuid)
uuid[6] = (uuid[6] & 0x0f) | 0x40
uuid[8] = (uuid[8] & 0x3f) | 0x80
return fmt.Sprintf("%x-%x-%x-%x-%x", uuid[0:4], uuid[4:6], uuid[6:8], uuid[8:10], uuid[10:])
}
func (r *FakerRandomizer) Name() string {
return r.faker.Name()
}
// NewDeterministicRandomizer builds a Randomizer that will return hard-coded
// values, removing all randomness from example generation.
func NewDeterministicRandomizer() Randomizer {
return &DeterministicRandomizer{}
}
// DeterministicRandomizer returns hard-coded values, removing all randomness
// from example generation
type DeterministicRandomizer struct{}
func (DeterministicRandomizer) ArrayLength() int { return 1 }
func (DeterministicRandomizer) Int() int { return 1 }
func (DeterministicRandomizer) Int32() int32 { return 1 }
func (DeterministicRandomizer) Int64() int64 { return 1 }
func (DeterministicRandomizer) String() string { return "abc123" }
func (DeterministicRandomizer) Bool() bool { return false }
func (DeterministicRandomizer) Float32() float32 { return 1 }
func (DeterministicRandomizer) Float64() float64 { return 1 }
func (DeterministicRandomizer) UInt() uint { return 1 }
func (DeterministicRandomizer) UInt32() uint32 { return 1 }
func (DeterministicRandomizer) UInt64() uint64 { return 1 }
func (DeterministicRandomizer) Name() string { return "Alice" }
func (DeterministicRandomizer) Email() string { return "[email protected]" }
func (DeterministicRandomizer) Hostname() string { return "example.com" }
func (DeterministicRandomizer) IPv4Address() net.IP { return net.IPv4zero }
func (DeterministicRandomizer) IPv6Address() net.IP { return net.IPv6zero }
func (DeterministicRandomizer) URL() string { return "https://example.com/foo" }
func (DeterministicRandomizer) Characters(n int) string { return strings.Repeat("a", n) }
func (DeterministicRandomizer) UUID() string { return "550e8400-e29b-41d4-a716-446655440000" }