golang.org/x/tools@v0.21.0/go/analysis/passes/testinggoroutine/testdata/src/a/a.go (about)

     1  // Copyright 2020 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package a
     6  
     7  import (
     8  	"log"
     9  	"sync"
    10  	"testing"
    11  )
    12  
    13  func TestBadFatalf(t *testing.T) {
    14  	var wg sync.WaitGroup
    15  	defer wg.Wait()
    16  
    17  	for i := 0; i < 2; i++ {
    18  		wg.Add(1)
    19  		go func(id int) {
    20  			defer wg.Done()
    21  			t.Fatalf("TestFailed: id = %v\n", id) // want "call to .+T.+Fatalf from a non-test goroutine"
    22  		}(i)
    23  	}
    24  }
    25  
    26  func TestOKErrorf(t *testing.T) {
    27  	var wg sync.WaitGroup
    28  	defer wg.Wait()
    29  
    30  	for i := 0; i < 2; i++ {
    31  		wg.Add(1)
    32  		go func(id int) {
    33  			defer wg.Done()
    34  			t.Errorf("TestFailed: id = %v\n", id)
    35  		}(i)
    36  	}
    37  }
    38  
    39  func TestBadFatal(t *testing.T) {
    40  	var wg sync.WaitGroup
    41  	defer wg.Wait()
    42  
    43  	for i := 0; i < 2; i++ {
    44  		wg.Add(1)
    45  		go func(id int) {
    46  			defer wg.Done()
    47  			t.Fatal("TestFailed") // want "call to .+T.+Fatal from a non-test goroutine"
    48  		}(i)
    49  	}
    50  }
    51  
    52  func f(t *testing.T, _ string) {
    53  	t.Fatal("TestFailed")
    54  }
    55  
    56  func g() {}
    57  
    58  func TestBadFatalIssue47470(t *testing.T) {
    59  	go f(t, "failed test 1") // want "call to .+T.+Fatal from a non-test goroutine"
    60  
    61  	g := func(t *testing.T, _ string) {
    62  		t.Fatal("TestFailed")
    63  	}
    64  	go g(t, "failed test 2") // want "call to .+T.+Fatal from a non-test goroutine"
    65  }
    66  
    67  func BenchmarkBadFatalf(b *testing.B) {
    68  	var wg sync.WaitGroup
    69  	defer wg.Wait()
    70  
    71  	for i := 0; i < b.N; i++ {
    72  		wg.Add(1)
    73  		go func(id int) {
    74  			defer wg.Done()
    75  			b.Fatalf("TestFailed: id = %v\n", id) // want "call to .+B.+Fatalf from a non-test goroutine"
    76  		}(i)
    77  	}
    78  }
    79  
    80  func BenchmarkBadFatal(b *testing.B) {
    81  	var wg sync.WaitGroup
    82  	defer wg.Wait()
    83  
    84  	for i := 0; i < b.N; i++ {
    85  		wg.Add(1)
    86  		go func(id int) {
    87  			defer wg.Done()
    88  			b.Fatal("TestFailed") // want "call to .+B.+Fatal from a non-test goroutine"
    89  		}(i)
    90  	}
    91  }
    92  
    93  func BenchmarkOKErrorf(b *testing.B) {
    94  	var wg sync.WaitGroup
    95  	defer wg.Wait()
    96  
    97  	for i := 0; i < b.N; i++ {
    98  		wg.Add(1)
    99  		go func(id int) {
   100  			defer wg.Done()
   101  			b.Errorf("TestFailed: %d", i)
   102  		}(i)
   103  	}
   104  }
   105  
   106  func BenchmarkBadFatalGoGo(b *testing.B) {
   107  	var wg sync.WaitGroup
   108  	defer wg.Wait()
   109  
   110  	for i := 0; i < b.N; i++ {
   111  		wg.Add(1)
   112  		go func(id int) {
   113  			go func() {
   114  				defer wg.Done()
   115  				b.Fatal("TestFailed") // want "call to .+B.+Fatal from a non-test goroutine"
   116  			}()
   117  		}(i)
   118  	}
   119  
   120  	if false {
   121  		defer b.Fatal("here")
   122  	}
   123  
   124  	if true {
   125  		go func() {
   126  			b.Fatal("in here") // want "call to .+B.+Fatal from a non-test goroutine"
   127  		}()
   128  	}
   129  
   130  	func() {
   131  		func() {
   132  			func() {
   133  				func() {
   134  					go func() {
   135  						b.Fatal("Here") // want "call to .+B.+Fatal from a non-test goroutine"
   136  					}()
   137  				}()
   138  			}()
   139  		}()
   140  	}()
   141  
   142  	_ = 10 * 10
   143  	_ = func() bool {
   144  		go b.Fatal("Failed") // want "call to .+B.+Fatal from a non-test goroutine"
   145  		return true
   146  	}
   147  
   148  	defer func() {
   149  		go b.Fatal("Here") // want "call to .+B.+Fatal from a non-test goroutine"
   150  	}()
   151  }
   152  
   153  func BenchmarkBadSkip(b *testing.B) {
   154  	for i := 0; i < b.N; i++ {
   155  		if i == 100 {
   156  			go b.Skip("Skipping") // want "call to .+B.+Skip from a non-test goroutine"
   157  		}
   158  		if i == 22 {
   159  			go func() {
   160  				go func() {
   161  					b.Skip("Skipping now") // want "call to .+B.+Skip from a non-test goroutine"
   162  				}()
   163  			}()
   164  		}
   165  	}
   166  }
   167  
   168  func TestBadSkip(t *testing.T) {
   169  	for i := 0; i < 1000; i++ {
   170  		if i == 100 {
   171  			go t.Skip("Skipping") // want "call to .+T.+Skip from a non-test goroutine"
   172  		}
   173  		if i == 22 {
   174  			go func() {
   175  				go func() {
   176  					t.Skip("Skipping now") // want "call to .+T.+Skip from a non-test goroutine"
   177  				}()
   178  			}()
   179  		}
   180  	}
   181  }
   182  
   183  func BenchmarkBadFailNow(b *testing.B) {
   184  	for i := 0; i < b.N; i++ {
   185  		if i == 100 {
   186  			go b.FailNow() // want "call to .+B.+FailNow from a non-test goroutine"
   187  		}
   188  		if i == 22 {
   189  			go func() {
   190  				go func() {
   191  					b.FailNow() // want "call to .+B.+FailNow from a non-test goroutine"
   192  				}()
   193  			}()
   194  		}
   195  	}
   196  }
   197  
   198  func TestBadFailNow(t *testing.T) {
   199  	for i := 0; i < 1000; i++ {
   200  		if i == 100 {
   201  			go t.FailNow() // want "call to .+T.+FailNow from a non-test goroutine"
   202  		}
   203  		if i == 22 {
   204  			go func() {
   205  				go func() {
   206  					t.FailNow() // want "call to .+T.+FailNow from a non-test goroutine"
   207  				}()
   208  			}()
   209  		}
   210  	}
   211  }
   212  
   213  func TestBadWithLoopCond(ty *testing.T) {
   214  	var wg sync.WaitGroup
   215  	defer wg.Wait()
   216  
   217  	for i := 0; i < 10; i++ {
   218  		wg.Add(1)
   219  		go func(id int) {
   220  			defer ty.Fatalf("Why") // want "call to .+T.+Fatalf from a non-test goroutine"
   221  			go func() {
   222  				for j := 0; j < 2; ty.FailNow() { // want "call to .+T.+FailNow from"
   223  					j++
   224  					ty.Errorf("Done here")
   225  				}
   226  			}()
   227  		}(i)
   228  	}
   229  }
   230  
   231  type customType int
   232  
   233  func (ct *customType) Fatalf(fmtSpec string, args ...interface{}) {
   234  	if fmtSpec == "" {
   235  		panic("empty format specifier")
   236  	}
   237  }
   238  
   239  func (ct *customType) FailNow() {}
   240  func (ct *customType) Skip()    {}
   241  
   242  func TestWithLogFatalf(t *testing.T) {
   243  	var wg sync.WaitGroup
   244  	defer wg.Wait()
   245  
   246  	for i := 0; i < 10; i++ {
   247  		wg.Add(1)
   248  		go func(id int) {
   249  			go func() {
   250  				for j := 0; j < 2; j++ {
   251  					log.Fatal("Done here")
   252  				}
   253  			}()
   254  		}(i)
   255  	}
   256  }
   257  
   258  func TestWithCustomType(t *testing.T) {
   259  	var wg sync.WaitGroup
   260  	defer wg.Wait()
   261  
   262  	ct := new(customType)
   263  	defer ct.FailNow()
   264  	defer ct.Skip()
   265  
   266  	for i := 0; i < 10; i++ {
   267  		wg.Add(1)
   268  		go func(id int) {
   269  			go func() {
   270  				for j := 0; j < 2; j++ {
   271  					ct.Fatalf("Done here: %d", i)
   272  				}
   273  			}()
   274  		}(i)
   275  	}
   276  }
   277  
   278  func helpTB(tb testing.TB) {
   279  	tb.FailNow()
   280  }
   281  
   282  func TestTB(t *testing.T) {
   283  	go helpTB(t) // want "call to .+TB.+FailNow from a non-test goroutine"
   284  }
   285  
   286  func TestIssue48124(t *testing.T) {
   287  	go helper(t) // want "call to .+T.+Skip from a non-test goroutine"
   288  }
   289  
   290  func TestEachCall(t *testing.T) {
   291  	go helper(t) // want "call to .+T.+Skip from a non-test goroutine"
   292  	go helper(t) // want "call to .+T.+Skip from a non-test goroutine"
   293  }
   294  
   295  func TestWithSubtest(t *testing.T) {
   296  	t.Run("name", func(t2 *testing.T) {
   297  		t.FailNow() // want "call to .+T.+FailNow on t defined outside of the subtest"
   298  		t2.Fatal()
   299  	})
   300  
   301  	f := func(t3 *testing.T) {
   302  		t.FailNow()
   303  		t3.Fatal()
   304  	}
   305  	t.Run("name", f) // want "call to .+T.+FailNow on t defined outside of the subtest"
   306  
   307  	g := func(t4 *testing.T) {
   308  		t.FailNow()
   309  		t4.Fatal()
   310  	}
   311  	g(t)
   312  
   313  	t.Run("name", helper)
   314  
   315  	go t.Run("name", func(t2 *testing.T) {
   316  		t.FailNow() // want "call to .+T.+FailNow on t defined outside of the subtest"
   317  		t2.Fatal()
   318  	})
   319  }
   320  
   321  func TestMultipleVariables(t *testing.T) {
   322  	{ // short decl
   323  		f, g := func(t1 *testing.T) {
   324  			t1.Fatal()
   325  		}, func(t2 *testing.T) {
   326  			t2.Error()
   327  		}
   328  
   329  		go f(t) // want "call to .+T.+Fatal from a non-test goroutine"
   330  		go g(t)
   331  
   332  		t.Run("name", f)
   333  		t.Run("name", g)
   334  	}
   335  
   336  	{ // var decl
   337  		var f, g = func(t1 *testing.T) {
   338  			t1.Fatal()
   339  		}, func(t2 *testing.T) {
   340  			t2.Error()
   341  		}
   342  
   343  		go f(t) // want "call to .+T.+Fatal from a non-test goroutine"
   344  		go g(t)
   345  
   346  		t.Run("name", f)
   347  		t.Run("name", g)
   348  	}
   349  }
   350  
   351  func BadIgnoresMultipleAssignments(t *testing.T) {
   352  	{
   353  		f := func(t1 *testing.T) {
   354  			t1.Fatal()
   355  		}
   356  		go f(t) // want "call to .+T.+Fatal from a non-test goroutine"
   357  
   358  		f = func(t2 *testing.T) {
   359  			t2.Error()
   360  		}
   361  		go f(t) // want "call to .+T.+Fatal from a non-test goroutine"
   362  	}
   363  	{
   364  		f := func(t1 *testing.T) {
   365  			t1.Error()
   366  		}
   367  		go f(t)
   368  
   369  		f = func(t2 *testing.T) {
   370  			t2.FailNow()
   371  		}
   372  		go f(t) // false negative
   373  	}
   374  }
   375  
   376  func TestGoDoesNotDescendIntoSubtest(t *testing.T) {
   377  	f := func(t2 *testing.T) {
   378  		g := func(t3 *testing.T) {
   379  			t3.Fatal() // fine
   380  		}
   381  		t2.Run("name", g)
   382  		t2.FailNow() // bad
   383  	}
   384  	go f(t) // want "call to .+T.+FailNow from a non-test goroutine"
   385  }
   386  
   387  func TestFreeVariableAssignedWithinEnclosing(t *testing.T) {
   388  	f := func(t2 *testing.T) {
   389  		inner := t
   390  		inner.FailNow()
   391  	}
   392  
   393  	go f(nil) // want "call to .+T.+FailNow from a non-test goroutine"
   394  
   395  	t.Run("name", func(t3 *testing.T) {
   396  		go f(nil) // want "call to .+T.+FailNow from a non-test goroutine"
   397  	})
   398  
   399  	// Without pointer analysis we cannot tell if inner is t or t2.
   400  	// So we accept a false negatives on the following examples.
   401  	t.Run("name", f)
   402  
   403  	go func(_ *testing.T) {
   404  		t.Run("name", f)
   405  	}(nil)
   406  
   407  	go t.Run("name", f)
   408  }
   409  
   410  func TestWithUnusedSelection(t *testing.T) {
   411  	go func() {
   412  		_ = t.FailNow
   413  	}()
   414  	t.Run("name", func(t2 *testing.T) {
   415  		_ = t.FailNow
   416  	})
   417  }
   418  
   419  func TestMethodExprsAreIgnored(t *testing.T) {
   420  	go func() {
   421  		(*testing.T).FailNow(t)
   422  	}()
   423  }
   424  
   425  func TestRecursive(t *testing.T) {
   426  	t.SkipNow()
   427  
   428  	go TestRecursive(t) // want "call to .+T.+SkipNow from a non-test goroutine"
   429  
   430  	t.Run("name", TestRecursive)
   431  }
   432  
   433  func TestMethodSelection(t *testing.T) {
   434  	var h helperType
   435  
   436  	go h.help(t) // want "call to .+T.+SkipNow from a non-test goroutine"
   437  	t.Run("name", h.help)
   438  }
   439  
   440  type helperType struct{}
   441  
   442  func (h *helperType) help(t *testing.T) { t.SkipNow() }
   443  
   444  func TestIssue63799a(t *testing.T) {
   445  	done := make(chan struct{})
   446  	go func() {
   447  		defer close(done)
   448  		t.Run("", func(t *testing.T) {
   449  			t.Fatal() // No warning. This is in a subtest.
   450  		})
   451  	}()
   452  	<-done
   453  }
   454  
   455  func TestIssue63799b(t *testing.T) {
   456  	// Simplified from go.dev/cl/538698
   457  
   458  	// nondet is some unspecified boolean placeholder.
   459  	var nondet func() bool
   460  
   461  	t.Run("nohup", func(t *testing.T) {
   462  		if nondet() {
   463  			t.Skip("ignored")
   464  		}
   465  
   466  		go t.Run("nohup-i", func(t *testing.T) {
   467  			t.Parallel()
   468  			if nondet() {
   469  				if nondet() {
   470  					t.Skip("go.dev/cl/538698 wanted to have skip here")
   471  				}
   472  
   473  				t.Error("ignored")
   474  			} else {
   475  				t.Log("ignored")
   476  			}
   477  		})
   478  	})
   479  }
   480  
   481  func TestIssue63849(t *testing.T) {
   482  	go func() {
   483  		helper(t) // False negative. We do not do an actual interprodecural reachability analysis.
   484  	}()
   485  	go helper(t) // want "call to .+T.+Skip from a non-test goroutine"
   486  }