github.com/angenalZZZ/gofunc@v0.0.0-20210507121333-48ff1be3917b/data/shm/shm_test.go (about) 1 package shm_test 2 3 import ( 4 "github.com/angenalZZZ/gofunc/data/shm" 5 "io" 6 "reflect" 7 "strings" 8 "sync" 9 "testing" 10 ) 11 12 func create(t *testing.T, tag string, size int32) *shm.SharedMemory { 13 t.Helper() 14 15 m, err := shm.Create(tag, size) 16 if err != nil { 17 t.Fatalf("fail: create shared memroy %v", err) 18 } 19 return m 20 } 21 22 func open(t *testing.T, tag string, size int32) *shm.SharedMemory { 23 t.Helper() 24 25 m, err := shm.Open(tag, size) 26 if err != nil { 27 t.Fatalf("fail: open shared memroy %v", err) 28 } 29 return m 30 } 31 32 func TestNewOpen(t *testing.T) { 33 for d := uint(1); d <= 30; d++ { 34 size := int32(1) << d 35 36 // create shared memory 37 w, err := shm.Create("test_t", size) 38 if err != nil { 39 t.Errorf("warn: fail create %d byte shared memroy %v", size, err) 40 continue 41 } 42 43 // open shared memory 44 r, err := shm.Open("test_t", size) 45 if err != nil { 46 w.Close() 47 t.Errorf("warn: fail open %d byte shared memroy %v", size, err) 48 continue 49 } 50 51 w.Close() 52 r.Close() 53 } 54 } 55 56 func TestReadWriteAt(t *testing.T) { 57 tests := []struct { 58 size int 59 data string 60 }{ 61 {size: 1, data: "a"}, // single 62 {size: 63, data: strings.Repeat("a", 63)}, // full - 1 63 {size: 64, data: strings.Repeat("b", 64)}, // full 64 {size: 64, data: strings.Repeat("c", 65)}, // shrink 65 } 66 67 // create shared memory 68 w := create(t, "test_t", 64) 69 defer w.Close() 70 71 // open shared memory 72 r := open(t, "test_t", 64) 73 defer r.Close() 74 75 // read/write test 76 for _, tt := range tests { 77 data := []byte(tt.data) 78 79 n, err := w.WriteAt(data, 0) 80 if err != nil { 81 t.Fatalf("fail: write shared memroy %v", err) 82 } 83 if n != tt.size { 84 t.Fatalf("fail: write shared memroy %d byte, want %d byte", n, tt.size) 85 } 86 87 buf := make([]byte, len(data)) 88 n, err = r.ReadAt(buf, 0) 89 if err != nil { 90 t.Fatalf("fail: read shared memroy %v", err) 91 } 92 if n != tt.size { 93 t.Fatalf("fail: read shared memroy %d byte, want %d byte", n, tt.size) 94 } 95 if !reflect.DeepEqual(buf[:tt.size], data[:tt.size]) { 96 t.Fatalf("fail: read shared memroy %v, want %v", buf[:tt.size], data[:tt.size]) 97 } 98 } 99 } 100 101 func TestReadWriteAt_OverPosition(t *testing.T) { 102 tests := []struct { 103 pos int 104 succ bool 105 }{ 106 {pos: 0, succ: true}, 107 {pos: 63, succ: true}, 108 {pos: 64, succ: false}, 109 } 110 111 // create shared memory 112 w := create(t, "test_t", 64) 113 defer w.Close() 114 115 // open shared memory 116 r := open(t, "test_t", 64) 117 defer r.Close() 118 119 // write dummy 120 { 121 data := []byte(strings.Repeat("a", 64)) 122 n, err := w.WriteAt(data, 0) 123 if err != nil { 124 t.Fatalf("fail: write shared memroy %v", err) 125 } 126 if n != 64 { 127 t.Fatalf("fail: write shared memroy %d byte, want %d byte", n, 64) 128 } 129 } 130 131 // read/write test 132 for _, tt := range tests { 133 data := []byte("b") 134 n, err := w.WriteAt(data, int64(tt.pos)) 135 if tt.succ { 136 // success 137 if err != nil { 138 t.Fatalf("fail: write shared memroy %v", err) 139 } 140 if n != 1 { 141 t.Fatalf("fail: write shared memroy %d byte, want %d byte", n, 1) 142 } 143 } else { 144 // fail 145 if err != io.EOF { 146 t.Fatalf("fail: write shared memroy raise %v, want %v", err, io.EOF) 147 } 148 } 149 150 buf := make([]byte, 1) 151 n, err = r.ReadAt(buf, int64(tt.pos)) 152 if tt.succ { 153 // success 154 if err != nil { 155 t.Fatalf("fail: read shared memroy %v", err) 156 } 157 if n != 1 { 158 t.Fatalf("fail: read shared memroy %d byte, want %d byte", n, 1) 159 } 160 if !reflect.DeepEqual(buf, data) { 161 t.Fatalf("fail: read shared memroy %v, want %v", buf, data) 162 } 163 } else { 164 // fail 165 if err != io.EOF { 166 t.Fatalf("fail: read shared memroy raise %v, want %v", err, io.EOF) 167 } 168 } 169 } 170 } 171 172 func TestReadWriteAt_MultiThreads(t *testing.T) { 173 tests := []struct { 174 size int 175 data string 176 }{ 177 {size: 1, data: "a"}, // single 178 {size: 63, data: strings.Repeat("a", 63)}, // full - 1 179 {size: 64, data: strings.Repeat("b", 64)}, // full 180 {size: 64, data: strings.Repeat("c", 65)}, // shrink 181 } 182 183 // create shared memory 184 w := create(t, "test_t", 64) 185 defer w.Close() 186 187 // open shared memory 188 r := open(t, "test_t", 64) 189 defer r.Close() 190 191 wg := new(sync.WaitGroup) 192 written := make(chan bool) 193 readone := make(chan bool) 194 195 // write thread 196 wg.Add(1) 197 go func() { 198 defer wg.Done() 199 for _, tt := range tests { 200 // write data 201 data := []byte(tt.data) 202 n, err := w.WriteAt(data, 0) 203 if err != nil { 204 written <- false 205 t.Fatalf("fail: write shared memroy %v", err) 206 } 207 if n != tt.size { 208 written <- false 209 t.Fatalf("fail: write shared memroy %d byte, want %d byte", n, tt.size) 210 } 211 written <- true 212 213 // wait 214 succ := <-readone 215 if !succ { 216 return 217 } 218 } 219 }() 220 221 // read thread 222 wg.Add(1) 223 go func() { 224 defer wg.Done() 225 for _, tt := range tests { 226 // wait 227 succ := <-written 228 if !succ { 229 return 230 } 231 232 // read data 233 data := []byte(tt.data) 234 buf := make([]byte, len(data)) 235 n, err := r.ReadAt(buf, 0) 236 if err != nil { 237 readone <- false 238 t.Fatalf("fail: read shared memroy %v", err) 239 } 240 if n != tt.size { 241 readone <- false 242 t.Fatalf("fail: read shared memroy %d byte, want %d byte", n, tt.size) 243 } 244 if !reflect.DeepEqual(buf[:tt.size], data[:tt.size]) { 245 readone <- false 246 t.Fatalf("fail: read shared memroy %v, want %v", buf[:tt.size], data[:tt.size]) 247 } 248 readone <- true 249 } 250 }() 251 252 wg.Wait() 253 } 254 255 func TestReadWrite(t *testing.T) { 256 tests := []struct { 257 succ bool 258 data string 259 }{ 260 {succ: true, data: "a"}, // single 261 {succ: true, data: strings.Repeat("b", 63)}, // full 262 {succ: false, data: "c"}, // overflow (EOF) 263 } 264 265 // create shared memory 266 w := create(t, "test_t", 64) 267 defer w.Close() 268 269 // open shared memory 270 r := open(t, "test_t", 64) 271 defer r.Close() 272 273 // read/write test 274 for _, tt := range tests { 275 data := []byte(tt.data) 276 277 n, err := w.Write(data) 278 if tt.succ { 279 // success 280 if err != nil { 281 t.Fatalf("fail: write shared memroy %v", err) 282 } 283 if n != len(data) { 284 t.Fatalf("fail: write shared memroy %d byte, want %d byte", n, len(data)) 285 } 286 } else { 287 // fail 288 if err != io.EOF { 289 t.Fatalf("fail: write shared memroy raise %v, want %v", err, io.EOF) 290 } 291 } 292 293 buf := make([]byte, len(data)) 294 n, err = r.Read(buf) 295 if tt.succ { 296 // success 297 if err != nil { 298 t.Fatalf("fail: read shared memroy %v", err) 299 } 300 if n != len(data) { 301 t.Fatalf("fail: read shared memroy %d byte, want %d byte", n, len(data)) 302 } 303 if !reflect.DeepEqual(buf, data) { 304 t.Fatalf("fail: read shared memroy %v, want %v", buf, data) 305 } 306 } else { 307 // fail 308 if err != io.EOF { 309 t.Fatalf("fail: read shared memroy raise %v, want %v", err, io.EOF) 310 } 311 } 312 } 313 } 314 315 func TestReadWrite_MultiThreads(t *testing.T) { 316 tests := []struct { 317 size int 318 data string 319 }{ 320 {size: 1, data: "a"}, // single 321 {size: 62, data: strings.Repeat("a", 62)}, // full - 1 322 {size: 1, data: strings.Repeat("b", 10)}, // shrink 323 } 324 325 // create shared memory 326 w := create(t, "test_t", 64) 327 defer w.Close() 328 329 // open shared memory 330 r := open(t, "test_t", 64) 331 defer r.Close() 332 333 wg := new(sync.WaitGroup) 334 written := make(chan bool) 335 readone := make(chan bool) 336 337 // write thread 338 wg.Add(1) 339 go func() { 340 defer wg.Done() 341 for _, tt := range tests { 342 // write data 343 data := []byte(tt.data) 344 n, err := w.Write(data) 345 if err != nil { 346 written <- false 347 t.Fatalf("fail: write shared memroy %v", err) 348 } 349 if n != tt.size { 350 written <- false 351 t.Fatalf("fail: write shared memroy %d byte, want %d byte", n, tt.size) 352 } 353 written <- true 354 355 // wait 356 succ := <-readone 357 if !succ { 358 return 359 } 360 } 361 }() 362 363 // read thread 364 wg.Add(1) 365 go func() { 366 defer wg.Done() 367 for _, tt := range tests { 368 // wait 369 succ := <-written 370 if !succ { 371 return 372 } 373 374 // read data 375 data := []byte(tt.data) 376 buf := make([]byte, len(data)) 377 n, err := r.Read(buf) 378 if err != nil { 379 readone <- false 380 t.Fatalf("fail: read shared memroy %v", err) 381 } 382 if n != tt.size { 383 readone <- false 384 t.Fatalf("fail: read shared memroy %d byte, want %d byte", n, tt.size) 385 } 386 if !reflect.DeepEqual(buf[:tt.size], data[:tt.size]) { 387 readone <- false 388 t.Fatalf("fail: read shared memroy %v, want %v", buf[:tt.size], data[:tt.size]) 389 } 390 readone <- true 391 } 392 }() 393 394 wg.Wait() 395 }