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
|
package fasthttp
import (
"fmt"
"reflect"
"runtime"
"testing"
"time"
)
func TestUserData(t *testing.T) {
t.Parallel()
var u userData
for i := 0; i < 10; i++ {
key := []byte(fmt.Sprintf("key_%d", i))
u.SetBytes(key, i+5)
testUserDataGet(t, &u, key, i+5)
u.SetBytes(key, i)
testUserDataGet(t, &u, key, i)
}
for i := 0; i < 10; i++ {
key := []byte(fmt.Sprintf("key_%d", i))
testUserDataGet(t, &u, key, i)
}
u.Reset()
for i := 0; i < 10; i++ {
key := []byte(fmt.Sprintf("key_%d", i))
testUserDataGet(t, &u, key, nil)
}
}
func testUserDataGet(t *testing.T, u *userData, key []byte, value any) {
v := u.GetBytes(key)
if v == nil && value != nil {
t.Fatalf("cannot obtain value for key=%q", key)
}
if !reflect.DeepEqual(v, value) {
t.Fatalf("unexpected value for key=%q: %d. Expecting %d", key, v, value)
}
}
func TestUserDataValueClose(t *testing.T) {
t.Parallel()
var u userData
closeCalls := 0
// store values implementing io.Closer
for i := 0; i < 5; i++ {
key := fmt.Sprintf("key_%d", i)
u.Set(key, &closerValue{closeCalls: &closeCalls})
}
// store values without io.Closer
for i := 0; i < 10; i++ {
key := fmt.Sprintf("key_noclose_%d", i)
u.Set(key, i)
}
u.Reset()
if closeCalls != 5 {
t.Fatalf("unexpected number of Close calls: %d. Expecting 10", closeCalls)
}
}
type closerValue struct {
closeCalls *int
}
func (cv *closerValue) Close() error {
(*cv.closeCalls)++
return nil
}
func TestUserDataDelete(t *testing.T) {
t.Parallel()
var u userData
for i := 0; i < 10; i++ {
key := fmt.Sprintf("key_%d", i)
u.Set(key, i)
testUserDataGet(t, &u, []byte(key), i)
}
for i := 0; i < 10; i += 2 {
k := fmt.Sprintf("key_%d", i)
u.Remove(k)
if val := u.Get(k); val != nil {
t.Fatalf("unexpected key= %q, value =%v ,Expecting key= %q, value = nil", k, val, k)
}
kk := fmt.Sprintf("key_%d", i+1)
testUserDataGet(t, &u, []byte(kk), i+1)
}
for i := 0; i < 10; i++ {
key := fmt.Sprintf("key_new_%d", i)
u.Set(key, i)
testUserDataGet(t, &u, []byte(key), i)
}
}
func TestUserDataSetAndRemove(t *testing.T) {
var (
u userData
shortKey = "[]"
longKey = "[ ]"
)
u.Set(shortKey, "")
u.Set(longKey, "")
u.Remove(shortKey)
u.Set(shortKey, "")
testUserDataGet(t, &u, []byte(shortKey), "")
testUserDataGet(t, &u, []byte(longKey), "")
}
func TestUserData_GC(t *testing.T) {
t.Parallel()
var u userData
key := "foo"
final := make(chan struct{})
func() {
val := &RequestHeader{}
runtime.SetFinalizer(val, func(v *RequestHeader) {
close(final)
})
u.Set(key, val)
}()
u.Reset()
runtime.GC()
select {
case <-final:
case <-time.After(time.Second):
t.Fatalf("value is garbage collected")
}
// Keep u alive, otherwise val will always get garbage collected.
u.Set("bar", 1)
}
|