github.com/sunvim/utils@v0.1.0/linear_ac/linear_ac_test.go (about) 1 // reference to 2 // https://github.com/crazybie/linear_ac 3 package linear_ac 4 5 import ( 6 "fmt" 7 "math/rand" 8 "runtime" 9 "sync" 10 "testing" 11 "time" 12 ) 13 14 type EnumA int32 15 16 const ( 17 EnumVal1 EnumA = 1 18 EnumVal2 EnumA = 2 19 ) 20 21 type PbItem struct { 22 Id *int 23 Price *int 24 Class *int 25 Name *string 26 Active *bool 27 EnumVal *EnumA 28 } 29 30 type PbData struct { 31 Age *int 32 Items []*PbItem 33 InUse *PbItem 34 } 35 36 func Test_GoRoutineId(t *testing.T) { 37 id := goRoutineId() 38 if id != goRoutineIdSlow() { 39 t.Fail() 40 } 41 } 42 43 func Test_LinearAlloc(t *testing.T) { 44 ac := BindNew() 45 var d *PbData 46 ac.New(&d) 47 d.Age = ac.Int(11) 48 49 n := 3 50 for i := 0; i < n; i++ { 51 var item *PbItem 52 ac.New(&item) 53 item.Id = ac.Int(i + 1) 54 item.Active = ac.Bool(true) 55 item.Price = ac.Int(100 + i) 56 item.Class = ac.Int(3 + i) 57 item.Name = ac.String("name") 58 59 ac.SliceAppend(&d.Items, item) 60 } 61 62 if *d.Age != 11 { 63 t.Errorf("age") 64 } 65 66 if len(d.Items) != int(n) { 67 t.Errorf("item") 68 } 69 for i := 0; i < n; i++ { 70 if *d.Items[i].Id != i+1 { 71 t.Errorf("item.id") 72 } 73 if *d.Items[i].Price != i+100 { 74 t.Errorf("item.price") 75 } 76 if *d.Items[i].Class != i+3 { 77 t.Errorf("item.class") 78 } 79 } 80 ac.reset() 81 ac.Release() 82 } 83 84 func Test_String(t *testing.T) { 85 ac := BindNew() 86 87 type D struct { 88 s [5]*string 89 } 90 var d *D 91 ac.New(&d) 92 for i := range d.s { 93 d.s[i] = ac.String(fmt.Sprintf("str%v", i)) 94 runtime.GC() 95 } 96 for i, p := range d.s { 97 if *p != fmt.Sprintf("str%v", i) { 98 t.Errorf("elem %v is gced", i) 99 } 100 } 101 ac.Release() 102 } 103 104 func TestLinearAllocator_NewMap(t *testing.T) { 105 ac := BindNew() 106 107 type D struct { 108 m map[int]*int 109 } 110 data := [10]*D{} 111 for i := 0; i < len(data); i++ { 112 var d *D 113 ac.New(&d) 114 ac.NewMap(&d.m) 115 d.m[1] = ac.Int(i) 116 data[i] = d 117 runtime.GC() 118 } 119 for i, d := range data { 120 if *d.m[1] != i { 121 t.Fail() 122 } 123 } 124 ac.Release() 125 } 126 127 func TestLinearAllocator_NewSlice(t *testing.T) { 128 DbgMode = true 129 ac := BindNew() 130 s := make([]*int, 0) 131 ac.SliceAppend(&s, ac.Int(2)) 132 if len(s) != 1 && *s[0] != 2 { 133 t.Fail() 134 } 135 136 ac.NewSlice(&s, 0, 32) 137 ac.SliceAppend(&s, ac.Int(1)) 138 if cap(s) != 32 || *s[0] != 1 { 139 t.Fail() 140 } 141 142 intSlice := []int{} 143 ac.SliceAppend(&intSlice, 11) 144 if len(intSlice) != 1 || intSlice[0] != 11 { 145 t.Fail() 146 } 147 148 byteSlice := []byte{} 149 ac.SliceAppend(&byteSlice, byte(11)) 150 if len(byteSlice) != 1 || byteSlice[0] != 11 { 151 t.Fail() 152 } 153 154 type Data struct { 155 d [2]uint64 156 } 157 structSlice := []Data{} 158 d1 := uint64(0xcdcdefefcdcdefdc) 159 d2 := uint64(0xcfcdefefcdcfffde) 160 ac.SliceAppend(&structSlice, Data{d: [2]uint64{d1, d2}}) 161 if len(structSlice) != 1 || structSlice[0].d[0] != d1 || structSlice[0].d[1] != d2 { 162 t.Fail() 163 } 164 165 f := func() []int { 166 var r []int 167 ac.NewSlice(&r, 0, 1) 168 ac.SliceAppend(&r, 1) 169 return r 170 } 171 r := f() 172 if len(r) != 1 { 173 t.Errorf("return slice") 174 } 175 176 { 177 var s []*PbItem 178 ac.SliceAppend(&s, nil) 179 if len(s) != 1 || s[0] != nil { 180 t.Errorf("nil") 181 } 182 } 183 184 { 185 s := []int{2, 3, 4} 186 r := ac.CopySlice(s).([]int) 187 s[0] = 1 188 s[1] = 1 189 s[2] = 1 190 if len(r) != len(s) { 191 t.Errorf("copy") 192 } 193 for i := range s { 194 if s[i] == r[i] { 195 t.Errorf("copy elem") 196 } 197 } 198 } 199 200 ac.Release() 201 } 202 203 func TestLinearAllocator_NewCopy(b *testing.T) { 204 ac := BindNew() 205 for i := 0; i < 3; i++ { 206 d := ac.NewCopy(&PbItem{ 207 Id: ac.Int(1 + i), 208 Class: ac.Int(2 + i), 209 Price: ac.Int(3 + i), 210 Name: ac.String("test"), 211 }).(*PbItem) 212 213 if *d.Id != 1+i { 214 b.Fail() 215 } 216 if *d.Class != 2+i { 217 b.Fail() 218 } 219 if *d.Price != 3+i { 220 b.Fail() 221 } 222 if *d.Name != "test" { 223 b.Fail() 224 } 225 } 226 ac.Release() 227 } 228 229 func TestAllocator_Enum(t *testing.T) { 230 ac := BindNew() 231 e := EnumVal2 232 v := ac.Enum(e).(*EnumA) 233 if *v != e { 234 t.Fail() 235 } 236 ac.Release() 237 } 238 239 func TestBuildInAllocator_All(t *testing.T) { 240 ac := buildInAc 241 var item *PbItem 242 ac.New(&item) 243 item.Id = ac.Int(11) 244 if *item.Id != 11 { 245 t.Fail() 246 } 247 id2 := 22 248 item = ac.NewCopy(&PbItem{Id: &id2}).(*PbItem) 249 if *item.Id != 22 { 250 t.Fail() 251 } 252 var s []*PbItem 253 ac.NewSlice(&s, 0, 3) 254 if cap(s) != 3 || len(s) != 0 { 255 t.Fail() 256 } 257 ac.SliceAppend(&s, item) 258 if len(s) != 1 || *s[0].Id != 22 { 259 t.Fail() 260 } 261 var m map[int]string 262 ac.NewMap(&m) 263 m[1] = "test" 264 if m[1] != "test" { 265 t.Fail() 266 } 267 e := EnumVal1 268 v := ac.Enum(e).(*EnumA) 269 if *v != e { 270 t.Fail() 271 } 272 ac.Release() 273 } 274 275 func TestBindAc(t *testing.T) { 276 useAc := func() *Allocator { 277 return Get() 278 } 279 280 wg := sync.WaitGroup{} 281 for i := 0; i < 1000; i++ { 282 go func() { 283 wg.Add(1) 284 285 ac := BindNew() 286 defer ac.Release() 287 288 time.Sleep(time.Duration(rand.Float32()*1000) * time.Millisecond) 289 290 if useAc() != ac { 291 t.Fail() 292 } 293 wg.Done() 294 }() 295 } 296 wg.Wait() 297 }