forked from statsig-io/go-sdk
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathutil.go
117 lines (101 loc) · 2.5 KB
/
util.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
package statsig
import (
"crypto/sha256"
"encoding/base64"
"encoding/binary"
"encoding/json"
"errors"
"strconv"
"testing"
"time"
)
func defaultString(v, d string) string {
if v == "" {
return d
}
return v
}
func getHash(key string) []byte {
hasher := sha256.New()
bytes := []byte(key)
hasher.Write(bytes)
return hasher.Sum(nil)
}
func getDJB2Hash(key string) string {
hash := uint64(0)
bytes := []byte(key)
for _, b := range bytes {
hash = ((hash << 5) - hash) + uint64(b)
hash = hash & ((1 << 32) - 1)
}
return strconv.FormatUint(hash, 10)
}
func getHashUint64Encoding(key string) uint64 {
hash := getHash(key)
return binary.BigEndian.Uint64(hash)
}
func getHashBase64StringEncoding(configName string) string {
hash := getHash(configName)
return base64.StdEncoding.EncodeToString(hash)
}
func safeGetFirst(slice []string) string {
if len(slice) > 0 {
return slice[0]
}
return ""
}
func safeParseJSONint64(val interface{}) int64 {
if num, ok := val.(json.Number); ok {
i64, _ := strconv.ParseInt(string(num), 10, 64)
return i64
} else {
return 0
}
}
func compareMetadata(t *testing.T, metadata map[string]string, expected map[string]string, time int64) {
v, _ := json.Marshal(metadata)
var rawMetadata map[string]string
_ = json.Unmarshal(v, &rawMetadata)
for key, value1 := range expected {
if value2, exists := metadata[key]; exists {
if value1 != value2 {
t.Errorf("Values for key '%s' do not match. Expected: %+v. Received: %+v", key, value1, value2)
}
} else {
t.Errorf("Key '%s' does not exist in metadata", key)
}
}
for _, key := range []string{"configSyncTime", "initTime"} {
value, exists := metadata[key]
if !exists {
t.Errorf("'%s' does not exist in metadata", key)
}
if strconv.FormatInt(time, 10) != value {
t.Errorf("'%s' does not have the expected time %d. Actual %s", key, time, value)
}
}
now := getUnixMilli()
serverTime, _ := strconv.ParseInt(metadata["serverTime"], 10, 64)
if now-1000 <= serverTime && serverTime <= now+1000 {
return
}
t.Errorf("serverTime is outside of the valid range. Expected %d (±2000), Actual %d", now, serverTime)
}
func toError(err interface{}) error {
errAsError, ok := err.(error)
if ok {
return errAsError
} else {
errAsString, ok := err.(string)
if ok {
return errors.New(errAsString)
} else {
return errors.New("")
}
}
}
func getUnixMilli() int64 {
// time.Now().UnixMilli() wasn't added until go 1.17
unixNano := time.Now().UnixNano()
return unixNano / int64(time.Millisecond)
}