1
2
3
4
5 package race_test
6
7 import (
8 "runtime"
9 "testing"
10 "time"
11 )
12
13 func TestNoRaceChanSync(t *testing.T) {
14 v := 0
15 _ = v
16 c := make(chan int)
17 go func() {
18 v = 1
19 c <- 0
20 }()
21 <-c
22 v = 2
23 }
24
25 func TestNoRaceChanSyncRev(t *testing.T) {
26 v := 0
27 _ = v
28 c := make(chan int)
29 go func() {
30 c <- 0
31 v = 2
32 }()
33 v = 1
34 <-c
35 }
36
37 func TestNoRaceChanAsync(t *testing.T) {
38 v := 0
39 _ = v
40 c := make(chan int, 10)
41 go func() {
42 v = 1
43 c <- 0
44 }()
45 <-c
46 v = 2
47 }
48
49 func TestRaceChanAsyncRev(t *testing.T) {
50 v := 0
51 _ = v
52 c := make(chan int, 10)
53 go func() {
54 c <- 0
55 v = 1
56 }()
57 v = 2
58 <-c
59 }
60
61 func TestNoRaceChanAsyncCloseRecv(t *testing.T) {
62 v := 0
63 _ = v
64 c := make(chan int, 10)
65 go func() {
66 v = 1
67 close(c)
68 }()
69 func() {
70 defer func() {
71 recover()
72 v = 2
73 }()
74 <-c
75 }()
76 }
77
78 func TestNoRaceChanAsyncCloseRecv2(t *testing.T) {
79 v := 0
80 _ = v
81 c := make(chan int, 10)
82 go func() {
83 v = 1
84 close(c)
85 }()
86 _, _ = <-c
87 v = 2
88 }
89
90 func TestNoRaceChanAsyncCloseRecv3(t *testing.T) {
91 v := 0
92 _ = v
93 c := make(chan int, 10)
94 go func() {
95 v = 1
96 close(c)
97 }()
98 for range c {
99 }
100 v = 2
101 }
102
103 func TestNoRaceChanSyncCloseRecv(t *testing.T) {
104 v := 0
105 _ = v
106 c := make(chan int)
107 go func() {
108 v = 1
109 close(c)
110 }()
111 func() {
112 defer func() {
113 recover()
114 v = 2
115 }()
116 <-c
117 }()
118 }
119
120 func TestNoRaceChanSyncCloseRecv2(t *testing.T) {
121 v := 0
122 _ = v
123 c := make(chan int)
124 go func() {
125 v = 1
126 close(c)
127 }()
128 _, _ = <-c
129 v = 2
130 }
131
132 func TestNoRaceChanSyncCloseRecv3(t *testing.T) {
133 v := 0
134 _ = v
135 c := make(chan int)
136 go func() {
137 v = 1
138 close(c)
139 }()
140 for range c {
141 }
142 v = 2
143 }
144
145 func TestRaceChanSyncCloseSend(t *testing.T) {
146 v := 0
147 _ = v
148 c := make(chan int)
149 go func() {
150 v = 1
151 close(c)
152 }()
153 func() {
154 defer func() {
155 recover()
156 }()
157 c <- 0
158 }()
159 v = 2
160 }
161
162 func TestRaceChanAsyncCloseSend(t *testing.T) {
163 v := 0
164 _ = v
165 c := make(chan int, 10)
166 go func() {
167 v = 1
168 close(c)
169 }()
170 func() {
171 defer func() {
172 recover()
173 }()
174 for {
175 c <- 0
176 }
177 }()
178 v = 2
179 }
180
181 func TestRaceChanCloseClose(t *testing.T) {
182 compl := make(chan bool, 2)
183 v1 := 0
184 v2 := 0
185 _ = v1 + v2
186 c := make(chan int)
187 go func() {
188 defer func() {
189 if recover() != nil {
190 v2 = 2
191 }
192 compl <- true
193 }()
194 v1 = 1
195 close(c)
196 }()
197 go func() {
198 defer func() {
199 if recover() != nil {
200 v1 = 2
201 }
202 compl <- true
203 }()
204 v2 = 1
205 close(c)
206 }()
207 <-compl
208 <-compl
209 }
210
211 func TestRaceChanSendLen(t *testing.T) {
212 v := 0
213 _ = v
214 c := make(chan int, 10)
215 go func() {
216 v = 1
217 c <- 1
218 }()
219 for len(c) == 0 {
220 runtime.Gosched()
221 }
222 v = 2
223 }
224
225 func TestRaceChanRecvLen(t *testing.T) {
226 v := 0
227 _ = v
228 c := make(chan int, 10)
229 c <- 1
230 go func() {
231 v = 1
232 <-c
233 }()
234 for len(c) != 0 {
235 runtime.Gosched()
236 }
237 v = 2
238 }
239
240 func TestRaceChanSendSend(t *testing.T) {
241 compl := make(chan bool, 2)
242 v1 := 0
243 v2 := 0
244 _ = v1 + v2
245 c := make(chan int, 1)
246 go func() {
247 v1 = 1
248 select {
249 case c <- 1:
250 default:
251 v2 = 2
252 }
253 compl <- true
254 }()
255 go func() {
256 v2 = 1
257 select {
258 case c <- 1:
259 default:
260 v1 = 2
261 }
262 compl <- true
263 }()
264 <-compl
265 <-compl
266 }
267
268 func TestNoRaceChanPtr(t *testing.T) {
269 type msg struct {
270 x int
271 }
272 c := make(chan *msg)
273 go func() {
274 c <- &msg{1}
275 }()
276 m := <-c
277 m.x = 2
278 }
279
280 func TestRaceChanWrongSend(t *testing.T) {
281 v1 := 0
282 v2 := 0
283 _ = v1 + v2
284 c := make(chan int, 2)
285 go func() {
286 v1 = 1
287 c <- 1
288 }()
289 go func() {
290 v2 = 2
291 c <- 2
292 }()
293 time.Sleep(1e7)
294 if <-c == 1 {
295 v2 = 3
296 } else {
297 v1 = 3
298 }
299 }
300
301 func TestRaceChanWrongClose(t *testing.T) {
302 v1 := 0
303 v2 := 0
304 _ = v1 + v2
305 c := make(chan int, 1)
306 done := make(chan bool)
307 go func() {
308 defer func() {
309 recover()
310 }()
311 v1 = 1
312 c <- 1
313 done <- true
314 }()
315 go func() {
316 time.Sleep(1e7)
317 v2 = 2
318 close(c)
319 done <- true
320 }()
321 time.Sleep(2e7)
322 if _, who := <-c; who {
323 v2 = 2
324 } else {
325 v1 = 2
326 }
327 <-done
328 <-done
329 }
330
331 func TestRaceChanSendClose(t *testing.T) {
332 compl := make(chan bool, 2)
333 c := make(chan int, 1)
334 go func() {
335 defer func() {
336 recover()
337 compl <- true
338 }()
339 c <- 1
340 }()
341 go func() {
342 time.Sleep(10 * time.Millisecond)
343 close(c)
344 compl <- true
345 }()
346 <-compl
347 <-compl
348 }
349
350 func TestRaceChanSendSelectClose(t *testing.T) {
351 compl := make(chan bool, 2)
352 c := make(chan int, 1)
353 c1 := make(chan int)
354 go func() {
355 defer func() {
356 recover()
357 compl <- true
358 }()
359 time.Sleep(10 * time.Millisecond)
360 select {
361 case c <- 1:
362 case <-c1:
363 }
364 }()
365 go func() {
366 close(c)
367 compl <- true
368 }()
369 <-compl
370 <-compl
371 }
372
373 func TestRaceSelectReadWriteAsync(t *testing.T) {
374 done := make(chan bool)
375 x := 0
376 c1 := make(chan int, 10)
377 c2 := make(chan int, 10)
378 c3 := make(chan int)
379 c2 <- 1
380 go func() {
381 select {
382 case c1 <- x:
383 case c3 <- 1:
384 }
385 done <- true
386 }()
387 select {
388 case x = <-c2:
389 case c3 <- 1:
390 }
391 <-done
392 }
393
394 func TestRaceSelectReadWriteSync(t *testing.T) {
395 done := make(chan bool)
396 x := 0
397 c1 := make(chan int)
398 c2 := make(chan int)
399 c3 := make(chan int)
400
401 go func() {
402 <-c1
403 }()
404 go func() {
405 c2 <- 1
406 }()
407 go func() {
408 select {
409 case c1 <- x:
410 case c3 <- 1:
411 }
412 done <- true
413 }()
414 select {
415 case x = <-c2:
416 case c3 <- 1:
417 }
418 <-done
419 }
420
421 func TestNoRaceSelectReadWriteAsync(t *testing.T) {
422 done := make(chan bool)
423 x := 0
424 c1 := make(chan int)
425 c2 := make(chan int)
426 go func() {
427 select {
428 case c1 <- x:
429 case c2 <- 1:
430 }
431 done <- true
432 }()
433 select {
434 case x = <-c1:
435 case c2 <- 1:
436 }
437 <-done
438 }
439
440 func TestRaceChanReadWriteAsync(t *testing.T) {
441 done := make(chan bool)
442 c1 := make(chan int, 10)
443 c2 := make(chan int, 10)
444 c2 <- 10
445 x := 0
446 go func() {
447 c1 <- x
448 done <- true
449 }()
450 x = <-c2
451 <-done
452 }
453
454 func TestRaceChanReadWriteSync(t *testing.T) {
455 done := make(chan bool)
456 c1 := make(chan int)
457 c2 := make(chan int)
458
459 go func() {
460 <-c1
461 }()
462 go func() {
463 c2 <- 10
464 }()
465 x := 0
466 go func() {
467 c1 <- x
468 done <- true
469 }()
470 x = <-c2
471 <-done
472 }
473
474 func TestNoRaceChanReadWriteAsync(t *testing.T) {
475 done := make(chan bool)
476 c1 := make(chan int, 10)
477 x := 0
478 go func() {
479 c1 <- x
480 done <- true
481 }()
482 x = <-c1
483 <-done
484 }
485
486 func TestNoRaceProducerConsumerUnbuffered(t *testing.T) {
487 type Task struct {
488 f func()
489 done chan bool
490 }
491
492 queue := make(chan Task)
493
494 go func() {
495 t := <-queue
496 t.f()
497 t.done <- true
498 }()
499
500 doit := func(f func()) {
501 done := make(chan bool, 1)
502 queue <- Task{f, done}
503 <-done
504 }
505
506 x := 0
507 doit(func() {
508 x = 1
509 })
510 _ = x
511 }
512
513 func TestRaceChanItselfSend(t *testing.T) {
514 compl := make(chan bool, 1)
515 c := make(chan int, 10)
516 go func() {
517 c <- 0
518 compl <- true
519 }()
520 c = make(chan int, 20)
521 <-compl
522 }
523
524 func TestRaceChanItselfRecv(t *testing.T) {
525 compl := make(chan bool, 1)
526 c := make(chan int, 10)
527 c <- 1
528 go func() {
529 <-c
530 compl <- true
531 }()
532 time.Sleep(1e7)
533 c = make(chan int, 20)
534 <-compl
535 }
536
537 func TestRaceChanItselfNil(t *testing.T) {
538 c := make(chan int, 10)
539 go func() {
540 c <- 0
541 }()
542 time.Sleep(1e7)
543 c = nil
544 _ = c
545 }
546
547 func TestRaceChanItselfClose(t *testing.T) {
548 compl := make(chan bool, 1)
549 c := make(chan int)
550 go func() {
551 close(c)
552 compl <- true
553 }()
554 c = make(chan int)
555 <-compl
556 }
557
558 func TestRaceChanItselfLen(t *testing.T) {
559 compl := make(chan bool, 1)
560 c := make(chan int)
561 go func() {
562 _ = len(c)
563 compl <- true
564 }()
565 c = make(chan int)
566 <-compl
567 }
568
569 func TestRaceChanItselfCap(t *testing.T) {
570 compl := make(chan bool, 1)
571 c := make(chan int)
572 go func() {
573 _ = cap(c)
574 compl <- true
575 }()
576 c = make(chan int)
577 <-compl
578 }
579
580 func TestNoRaceChanCloseLen(t *testing.T) {
581 c := make(chan int, 10)
582 r := make(chan int, 10)
583 go func() {
584 r <- len(c)
585 }()
586 go func() {
587 close(c)
588 r <- 0
589 }()
590 <-r
591 <-r
592 }
593
594 func TestNoRaceChanCloseCap(t *testing.T) {
595 c := make(chan int, 10)
596 r := make(chan int, 10)
597 go func() {
598 r <- cap(c)
599 }()
600 go func() {
601 close(c)
602 r <- 0
603 }()
604 <-r
605 <-r
606 }
607
608 func TestRaceChanCloseSend(t *testing.T) {
609 compl := make(chan bool, 1)
610 c := make(chan int, 10)
611 go func() {
612 close(c)
613 compl <- true
614 }()
615 c <- 0
616 <-compl
617 }
618
619 func TestNoRaceChanMutex(t *testing.T) {
620 done := make(chan struct{})
621 mtx := make(chan struct{}, 1)
622 data := 0
623 _ = data
624 go func() {
625 mtx <- struct{}{}
626 data = 42
627 <-mtx
628 done <- struct{}{}
629 }()
630 mtx <- struct{}{}
631 data = 43
632 <-mtx
633 <-done
634 }
635
636 func TestNoRaceSelectMutex(t *testing.T) {
637 done := make(chan struct{})
638 mtx := make(chan struct{}, 1)
639 aux := make(chan bool)
640 data := 0
641 _ = data
642 go func() {
643 select {
644 case mtx <- struct{}{}:
645 case <-aux:
646 }
647 data = 42
648 select {
649 case <-mtx:
650 case <-aux:
651 }
652 done <- struct{}{}
653 }()
654 select {
655 case mtx <- struct{}{}:
656 case <-aux:
657 }
658 data = 43
659 select {
660 case <-mtx:
661 case <-aux:
662 }
663 <-done
664 }
665
666 func TestRaceChanSem(t *testing.T) {
667 done := make(chan struct{})
668 mtx := make(chan bool, 2)
669 data := 0
670 _ = data
671 go func() {
672 mtx <- true
673 data = 42
674 <-mtx
675 done <- struct{}{}
676 }()
677 mtx <- true
678 data = 43
679 <-mtx
680 <-done
681 }
682
683 func TestNoRaceChanWaitGroup(t *testing.T) {
684 const N = 10
685 chanWg := make(chan bool, N/2)
686 data := make([]int, N)
687 for i := 0; i < N; i++ {
688 chanWg <- true
689 go func(i int) {
690 data[i] = 42
691 <-chanWg
692 }(i)
693 }
694 for i := 0; i < cap(chanWg); i++ {
695 chanWg <- true
696 }
697 for i := 0; i < N; i++ {
698 _ = data[i]
699 }
700 }
701
702
703 func TestNoRaceBlockedSendSync(t *testing.T) {
704 c := make(chan *int, 1)
705 c <- nil
706 go func() {
707 i := 42
708 c <- &i
709 }()
710
711
712
713
714 time.Sleep(10 * time.Millisecond)
715 <-c
716 p := <-c
717 if *p != 42 {
718 t.Fatal()
719 }
720 }
721
722
723 func TestNoRaceBlockedSelectSendSync(t *testing.T) {
724 c := make(chan *int, 1)
725 c <- nil
726 go func() {
727 i := 42
728 c <- &i
729 }()
730 time.Sleep(10 * time.Millisecond)
731 <-c
732 select {
733 case p := <-c:
734 if *p != 42 {
735 t.Fatal()
736 }
737 case <-make(chan int):
738 }
739 }
740
741
742
743 func TestNoRaceCloseHappensBeforeRead(t *testing.T) {
744 for i := 0; i < 100; i++ {
745 var loc int
746 var write = make(chan struct{})
747 var read = make(chan struct{})
748
749 go func() {
750 select {
751 case <-write:
752 _ = loc
753 default:
754 }
755 close(read)
756 }()
757
758 go func() {
759 loc = 1
760 close(write)
761 }()
762
763 <-read
764 }
765 }
766
767
768
769 func TestNoRaceElemSize0(t *testing.T) {
770 var x, y int
771 var c = make(chan struct{}, 2)
772 c <- struct{}{}
773 c <- struct{}{}
774 go func() {
775 x += 1
776 <-c
777 }()
778 go func() {
779 y += 1
780 <-c
781 }()
782 time.Sleep(10 * time.Millisecond)
783 c <- struct{}{}
784 c <- struct{}{}
785 x += 1
786 y += 1
787 }
788
View as plain text