github.com/pingcap/failpoint@v0.0.0-20240412033321-fd0796e60f86/code/rewriter_test.go (about)

     1  // Copyright 2019 PingCAP, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package code_test
    16  
    17  import (
    18  	"io/ioutil"
    19  	"os"
    20  	"path/filepath"
    21  	"strings"
    22  	"testing"
    23  
    24  	"github.com/stretchr/testify/require"
    25  
    26  	"github.com/pingcap/failpoint/code"
    27  )
    28  
    29  func TestRewrite(t *testing.T) {
    30  	var cases = []struct {
    31  		filepath string
    32  		original string
    33  		expected string
    34  	}{
    35  		{
    36  			filepath: "func-args-test.go",
    37  			original: `
    38  package rewriter_test
    39  
    40  import (
    41  	"fmt"
    42  
    43  	"github.com/pingcap/failpoint"
    44  )
    45  
    46  func main() {
    47  	f := func(g func() error) {}
    48  	f(func() error {
    49  		failpoint.Inject("failpoint-name", func(val failpoint.Value) {
    50  			fmt.Println("unit-test", val)
    51  		})
    52  		return nil
    53  	})
    54  }
    55  `,
    56  			expected: `
    57  package rewriter_test
    58  
    59  import (
    60  	"fmt"
    61  
    62  	"github.com/pingcap/failpoint"
    63  )
    64  
    65  func main() {
    66  	f := func(g func() error) {}
    67  	f(func() error {
    68  		if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
    69  			fmt.Println("unit-test", val)
    70  		}
    71  		return nil
    72  	})
    73  }
    74  `,
    75  		},
    76  
    77  		{
    78  			filepath: "basic-test.go",
    79  			original: `
    80  package rewriter_test
    81  
    82  import (
    83  	"fmt"
    84  
    85  	"github.com/pingcap/failpoint"
    86  )
    87  
    88  func unittest() {
    89  	failpoint.Inject("failpoint-name", func(val failpoint.Value) {
    90  		fmt.Println("unit-test", val)
    91  	})
    92  }
    93  `,
    94  			expected: `
    95  package rewriter_test
    96  
    97  import (
    98  	"fmt"
    99  
   100  	"github.com/pingcap/failpoint"
   101  )
   102  
   103  func unittest() {
   104  	if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
   105  		fmt.Println("unit-test", val)
   106  	}
   107  }
   108  `,
   109  		},
   110  
   111  		{
   112  			filepath: "basic-test2.go",
   113  			original: `
   114  package rewriter_test
   115  
   116  import (
   117  	"fmt"
   118  
   119  	"github.com/pingcap/failpoint"
   120  )
   121  
   122  func unittest() {
   123  	failpoint.Inject("failpoint-name", func() {
   124  		fmt.Println("unit-test")
   125  	})
   126  }
   127  `,
   128  			expected: `
   129  package rewriter_test
   130  
   131  import (
   132  	"fmt"
   133  
   134  	"github.com/pingcap/failpoint"
   135  )
   136  
   137  func unittest() {
   138  	if _, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
   139  		fmt.Println("unit-test")
   140  	}
   141  }
   142  `,
   143  		},
   144  
   145  		{
   146  			filepath: "basic-test-ignore-val.go",
   147  			original: `
   148  package rewriter_test
   149  
   150  import (
   151  	"fmt"
   152  
   153  	"github.com/pingcap/failpoint"
   154  )
   155  
   156  func unittest() {
   157  	failpoint.Inject("failpoint-name", func(_ failpoint.Value) {
   158  		fmt.Println("unit-test")
   159  	})
   160  }
   161  `,
   162  			expected: `
   163  package rewriter_test
   164  
   165  import (
   166  	"fmt"
   167  
   168  	"github.com/pingcap/failpoint"
   169  )
   170  
   171  func unittest() {
   172  	if _, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
   173  		fmt.Println("unit-test")
   174  	}
   175  }
   176  `,
   177  		},
   178  
   179  		{
   180  			filepath: "basic-test-with-ctx.go",
   181  			original: `
   182  package rewriter_test
   183  
   184  import (
   185  	"context"
   186  	"fmt"
   187  
   188  	"github.com/pingcap/failpoint"
   189  )
   190  
   191  var ctx = context.Background()
   192  
   193  func unittest() {
   194  	failpoint.InjectContext(ctx, "failpoint-name", func(val failpoint.Value) {
   195  		fmt.Println("unit-test", val)
   196  	})
   197  }
   198  `,
   199  			expected: `
   200  package rewriter_test
   201  
   202  import (
   203  	"context"
   204  	"fmt"
   205  
   206  	"github.com/pingcap/failpoint"
   207  )
   208  
   209  var ctx = context.Background()
   210  
   211  func unittest() {
   212  	if val, _err_ := failpoint.EvalContext(ctx, _curpkg_("failpoint-name")); _err_ == nil {
   213  		fmt.Println("unit-test", val)
   214  	}
   215  }
   216  `,
   217  		},
   218  
   219  		{
   220  			filepath: "type-check-test-with-ctx.go",
   221  			original: `
   222  package rewriter_test
   223  
   224  import (
   225      "context"
   226      "fmt"
   227  
   228      "github.com/pingcap/failpoint"
   229  )
   230  
   231  type S struct {
   232      ctx context.Context
   233  }
   234  
   235  const failPoint = "abc"
   236  
   237  func (s * S) unittest() {
   238      failpoint.InjectContext(s.ctx, failPoint, func(val failpoint.Value) {
   239  		fmt.Println("unit-test", val)
   240  	})
   241  }
   242  `,
   243  			expected: `
   244  package rewriter_test
   245  
   246  import (
   247  	"context"
   248  	"fmt"
   249  
   250  	"github.com/pingcap/failpoint"
   251  )
   252  
   253  type S struct {
   254  	ctx context.Context
   255  }
   256  
   257  const failPoint = "abc"
   258  
   259  func (s *S) unittest() {
   260  	if val, _err_ := failpoint.EvalContext(s.ctx, _curpkg_(failPoint)); _err_ == nil {
   261  		fmt.Println("unit-test", val)
   262  	}
   263  }
   264  `,
   265  		},
   266  
   267  		{
   268  			filepath: "basic-test-with-ctx-ignore.go",
   269  			original: `
   270  package rewriter_test
   271  
   272  import (
   273  	"context"
   274  	"fmt"
   275  
   276  	"github.com/pingcap/failpoint"
   277  )
   278  
   279  func unittest() {
   280  	failpoint.InjectContext(nil, "failpoint-name", func(val failpoint.Value) {
   281  		fmt.Println("unit-test", val)
   282  	})
   283  }
   284  `,
   285  			expected: `
   286  package rewriter_test
   287  
   288  import (
   289  	"context"
   290  	"fmt"
   291  
   292  	"github.com/pingcap/failpoint"
   293  )
   294  
   295  func unittest() {
   296  	if val, _err_ := failpoint.EvalContext(nil, _curpkg_("failpoint-name")); _err_ == nil {
   297  		fmt.Println("unit-test", val)
   298  	}
   299  }
   300  `,
   301  		},
   302  
   303  		{
   304  			filepath: "basic-test-with-ctx-ignore-all.go",
   305  			original: `
   306  package rewriter_test
   307  
   308  import (
   309  	"context"
   310  	"fmt"
   311  
   312  	"github.com/pingcap/failpoint"
   313  )
   314  
   315  func unittest() {
   316  	failpoint.InjectContext(nil, "failpoint-name", func(_ failpoint.Value) {
   317  		fmt.Println("unit-test")
   318  	})
   319  }
   320  `,
   321  			expected: `
   322  package rewriter_test
   323  
   324  import (
   325  	"context"
   326  	"fmt"
   327  
   328  	"github.com/pingcap/failpoint"
   329  )
   330  
   331  func unittest() {
   332  	if _, _err_ := failpoint.EvalContext(nil, _curpkg_("failpoint-name")); _err_ == nil {
   333  		fmt.Println("unit-test")
   334  	}
   335  }
   336  `,
   337  		},
   338  
   339  		{
   340  			filepath: "basic-test-format-code.go",
   341  			original: `
   342  package rewriter_test
   343  
   344  import (
   345  	"fmt"
   346  
   347  	"github.com/pingcap/failpoint"
   348  )
   349  
   350  type CustomStruct struct {
   351  	FieldWithLongName string
   352  	Key               int
   353  	Value             interface{}
   354  }
   355  
   356  func unittest() {
   357  	failpoint.Inject("failpoint-name", func(val failpoint.Value) {
   358  		cs := &CustomStruct{
   359  			FieldWithLongName: "name",
   360  			Key:               12,
   361  			Value:             []byte("hello"),
   362  		}
   363  		fmt.Println("unit-test", val, cs)
   364  	})
   365  }
   366  `,
   367  			expected: `
   368  package rewriter_test
   369  
   370  import (
   371  	"fmt"
   372  
   373  	"github.com/pingcap/failpoint"
   374  )
   375  
   376  type CustomStruct struct {
   377  	FieldWithLongName string
   378  	Key               int
   379  	Value             interface{}
   380  }
   381  
   382  func unittest() {
   383  	if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
   384  		cs := &CustomStruct{
   385  			FieldWithLongName: "name",
   386  			Key:               12,
   387  			Value:             []byte("hello"),
   388  		}
   389  		fmt.Println("unit-test", val, cs)
   390  	}
   391  }
   392  `,
   393  		},
   394  
   395  		{
   396  			filepath: "no-body-function.go",
   397  			original: `
   398  package rewriter_test
   399  
   400  import (
   401  	"fmt"
   402  	_ "unsafe"
   403  
   404  	"github.com/pingcap/failpoint"
   405  )
   406  
   407  //go:linkname runtimeNano runtime.nanotime
   408  func runtimeNano() int64
   409  
   410  func unittest() {
   411  	failpoint.Inject("failpoint-name", func(val failpoint.Value) {
   412  		fmt.Println("unit-test", val)
   413  	})
   414  	fmt.Printf("nano() runs successfully: %d\n", runtimeNano())
   415  }
   416  `,
   417  			expected: `
   418  package rewriter_test
   419  
   420  import (
   421  	"fmt"
   422  	_ "unsafe"
   423  
   424  	"github.com/pingcap/failpoint"
   425  )
   426  
   427  //go:linkname runtimeNano runtime.nanotime
   428  func runtimeNano() int64
   429  
   430  func unittest() {
   431  	if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
   432  		fmt.Println("unit-test", val)
   433  	}
   434  	fmt.Printf("nano() runs successfully: %d\n", runtimeNano())
   435  }
   436  `,
   437  		},
   438  
   439  		{
   440  			filepath: "anonymous-function.go",
   441  			original: `
   442  package rewriter_test
   443  
   444  import (
   445  	"fmt"
   446  
   447  	"github.com/pingcap/failpoint"
   448  )
   449  
   450  func unittest() {
   451  	func() {
   452  		failpoint.Inject("failpoint-name", func(val failpoint.Value) {
   453  			fmt.Println("unit-test", val)
   454  		})
   455  		func() {
   456  			failpoint.Inject("failpoint-name", func(val failpoint.Value) {
   457  				fmt.Println("unit-test", val)
   458  			})
   459  		}()
   460  	}()
   461  }
   462  `,
   463  			expected: `
   464  package rewriter_test
   465  
   466  import (
   467  	"fmt"
   468  
   469  	"github.com/pingcap/failpoint"
   470  )
   471  
   472  func unittest() {
   473  	func() {
   474  		if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
   475  			fmt.Println("unit-test", val)
   476  		}
   477  		func() {
   478  			if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
   479  				fmt.Println("unit-test", val)
   480  			}
   481  		}()
   482  	}()
   483  }
   484  `,
   485  		},
   486  
   487  		{
   488  			filepath: "simple-assign-with-function.go",
   489  			original: `
   490  package rewriter_test
   491  
   492  import (
   493  	"fmt"
   494  
   495  	"github.com/pingcap/failpoint"
   496  )
   497  
   498  func unittest() {
   499  	var _, f1, f2 = 10, func() {
   500  		failpoint.Inject("failpoint-name", func(val failpoint.Value) {
   501  			fmt.Println("unit-test", val)
   502  		})
   503  	}, func() {
   504  		failpoint.Inject("failpoint-name", func(val failpoint.Value) {
   505  			fmt.Println("unit-test", val)
   506  		})
   507  	}
   508  	f1()
   509  	f2()
   510  }
   511  `,
   512  			expected: `
   513  package rewriter_test
   514  
   515  import (
   516  	"fmt"
   517  
   518  	"github.com/pingcap/failpoint"
   519  )
   520  
   521  func unittest() {
   522  	var _, f1, f2 = 10, func() {
   523  		if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
   524  			fmt.Println("unit-test", val)
   525  		}
   526  	}, func() {
   527  		if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
   528  			fmt.Println("unit-test", val)
   529  		}
   530  	}
   531  	f1()
   532  	f2()
   533  }
   534  `,
   535  		},
   536  
   537  		{
   538  			filepath: "simple-assign-with-function-2.go",
   539  			original: `
   540  package rewriter_test
   541  
   542  import (
   543  	"fmt"
   544  
   545  	"github.com/pingcap/failpoint"
   546  )
   547  
   548  func unittest() {
   549  	_, f1, f2 := 10, func() {
   550  		failpoint.Inject("failpoint-name", func(val failpoint.Value) {
   551  			fmt.Println("unit-test", val)
   552  		})
   553  	}, func() {
   554  		failpoint.Inject("failpoint-name", func(val failpoint.Value) {
   555  			fmt.Println("unit-test", val)
   556  		})
   557  	}
   558  	f1()
   559  	f2()
   560  }
   561  `,
   562  			expected: `
   563  package rewriter_test
   564  
   565  import (
   566  	"fmt"
   567  
   568  	"github.com/pingcap/failpoint"
   569  )
   570  
   571  func unittest() {
   572  	_, f1, f2 := 10, func() {
   573  		if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
   574  			fmt.Println("unit-test", val)
   575  		}
   576  	}, func() {
   577  		if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
   578  			fmt.Println("unit-test", val)
   579  		}
   580  	}
   581  	f1()
   582  	f2()
   583  }
   584  `,
   585  		},
   586  
   587  		{
   588  			filepath: "simple-go-statement.go",
   589  			original: `
   590  package rewriter_test
   591  
   592  import (
   593  	"fmt"
   594  
   595  	"github.com/pingcap/failpoint"
   596  )
   597  
   598  func unittest() {
   599  	go func() {
   600  		failpoint.Inject("failpoint-name", func(val failpoint.Value) {
   601  			fmt.Println("unit-test", val)
   602  		})
   603  	}()
   604  }
   605  `,
   606  			expected: `
   607  package rewriter_test
   608  
   609  import (
   610  	"fmt"
   611  
   612  	"github.com/pingcap/failpoint"
   613  )
   614  
   615  func unittest() {
   616  	go func() {
   617  		if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
   618  			fmt.Println("unit-test", val)
   619  		}
   620  	}()
   621  }
   622  `,
   623  		},
   624  
   625  		{
   626  			filepath: "complicate-go-statement.go",
   627  			original: `
   628  package rewriter_test
   629  
   630  import (
   631  	"fmt"
   632  
   633  	"github.com/pingcap/failpoint"
   634  )
   635  
   636  func unittest() {
   637  	go func(_ func()) {
   638  		failpoint.Inject("failpoint-name", func(val failpoint.Value) {
   639  			fmt.Println("unit-test", val)
   640  		})
   641  	}(func() {
   642  		failpoint.Inject("failpoint-name", func(val failpoint.Value) {
   643  			fmt.Println("unit-test", val)
   644  		})
   645  	})
   646  }
   647  `,
   648  			expected: `
   649  package rewriter_test
   650  
   651  import (
   652  	"fmt"
   653  
   654  	"github.com/pingcap/failpoint"
   655  )
   656  
   657  func unittest() {
   658  	go func(_ func()) {
   659  		if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
   660  			fmt.Println("unit-test", val)
   661  		}
   662  	}(func() {
   663  		if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
   664  			fmt.Println("unit-test", val)
   665  		}
   666  	})
   667  }
   668  `,
   669  		},
   670  
   671  		{
   672  			filepath: "simple-defer-statement.go",
   673  			original: `
   674  package rewriter_test
   675  
   676  import (
   677  	"fmt"
   678  
   679  	"github.com/pingcap/failpoint"
   680  )
   681  
   682  func unittest() {
   683  	defer func() {
   684  		failpoint.Inject("failpoint-name", func(val failpoint.Value) {
   685  			fmt.Println("unit-test", val)
   686  		})
   687  	}()
   688  }
   689  `,
   690  			expected: `
   691  package rewriter_test
   692  
   693  import (
   694  	"fmt"
   695  
   696  	"github.com/pingcap/failpoint"
   697  )
   698  
   699  func unittest() {
   700  	defer func() {
   701  		if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
   702  			fmt.Println("unit-test", val)
   703  		}
   704  	}()
   705  }
   706  `,
   707  		},
   708  
   709  		{
   710  			filepath: "complicate-defer-statement.go",
   711  			original: `
   712  package rewriter_test
   713  
   714  import (
   715  	"fmt"
   716  
   717  	"github.com/pingcap/failpoint"
   718  )
   719  
   720  func unittest() {
   721  	defer func(_ func()) {
   722  		failpoint.Inject("failpoint-name", func(val failpoint.Value) {
   723  			fmt.Println("unit-test", val)
   724  		})
   725  	}(func() {
   726  		failpoint.Inject("failpoint-name", func(val failpoint.Value) {
   727  			fmt.Println("unit-test", val)
   728  		})
   729  	})
   730  }
   731  `,
   732  			expected: `
   733  package rewriter_test
   734  
   735  import (
   736  	"fmt"
   737  
   738  	"github.com/pingcap/failpoint"
   739  )
   740  
   741  func unittest() {
   742  	defer func(_ func()) {
   743  		if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
   744  			fmt.Println("unit-test", val)
   745  		}
   746  	}(func() {
   747  		if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
   748  			fmt.Println("unit-test", val)
   749  		}
   750  	})
   751  }
   752  `,
   753  		},
   754  
   755  		{
   756  			filepath: "return-statement.go",
   757  			original: `
   758  package rewriter_test
   759  
   760  import (
   761  	"fmt"
   762  
   763  	"github.com/pingcap/failpoint"
   764  )
   765  
   766  func unittest() {
   767  	return func() (func(), int) {
   768  			failpoint.Inject("failpoint-name", func(val failpoint.Value) {
   769  				fmt.Println("unit-test", val)
   770  			})
   771  		}, func() int {
   772  			failpoint.Inject("failpoint-name", func(val failpoint.Value) {
   773  				fmt.Println("unit-test", val)
   774  			})
   775  			return 1000
   776  		}()
   777  }
   778  `,
   779  			expected: `
   780  package rewriter_test
   781  
   782  import (
   783  	"fmt"
   784  
   785  	"github.com/pingcap/failpoint"
   786  )
   787  
   788  func unittest() {
   789  	return func() (func(), int) {
   790  			if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
   791  				fmt.Println("unit-test", val)
   792  			}
   793  		}, func() int {
   794  			if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
   795  				fmt.Println("unit-test", val)
   796  			}
   797  			return 1000
   798  		}()
   799  }
   800  `,
   801  		},
   802  
   803  		{
   804  			filepath: "if-statement.go",
   805  			original: `
   806  package rewriter_test
   807  
   808  import (
   809  	"fmt"
   810  	"math/rand"
   811  
   812  	"github.com/pingcap/failpoint"
   813  )
   814  
   815  func unittest() {
   816  	x := rand.Float32()
   817  	if x > 0.5 {
   818  		failpoint.Inject("failpoint-name", func(val failpoint.Value) {
   819  			fmt.Println("unit-test", val)
   820  		})
   821  	} else if x > 0.2 {
   822  		failpoint.Inject("failpoint-name", func(val failpoint.Value) {
   823  			fmt.Println("unit-test", val)
   824  		})
   825  	} else {
   826  		failpoint.Inject("failpoint-name", func(val failpoint.Value) {
   827  			fmt.Println("unit-test", val)
   828  		})
   829  	}
   830  }
   831  `,
   832  			expected: `
   833  package rewriter_test
   834  
   835  import (
   836  	"fmt"
   837  	"math/rand"
   838  
   839  	"github.com/pingcap/failpoint"
   840  )
   841  
   842  func unittest() {
   843  	x := rand.Float32()
   844  	if x > 0.5 {
   845  		if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
   846  			fmt.Println("unit-test", val)
   847  		}
   848  	} else if x > 0.2 {
   849  		if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
   850  			fmt.Println("unit-test", val)
   851  		}
   852  	} else {
   853  		if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
   854  			fmt.Println("unit-test", val)
   855  		}
   856  	}
   857  }
   858  `,
   859  		},
   860  
   861  		{
   862  			filepath: "if-statement-2.go",
   863  			original: `
   864  package rewriter_test
   865  
   866  import (
   867  	"fmt"
   868  	"math/rand"
   869  
   870  	"github.com/pingcap/failpoint"
   871  )
   872  
   873  func unittest() {
   874  	if a, b := func() {
   875  		failpoint.Inject("failpoint-name", func(val failpoint.Value) {
   876  			fmt.Println("unit-test", val)
   877  		})
   878  	}, func() int { return rand.Intn(200) }(); b > 100 {
   879  		a()
   880  		failpoint.Inject("failpoint-name", func(val failpoint.Value) {
   881  			fmt.Println("unit-test", val)
   882  		})
   883  	}
   884  }
   885  `,
   886  			expected: `
   887  package rewriter_test
   888  
   889  import (
   890  	"fmt"
   891  	"math/rand"
   892  
   893  	"github.com/pingcap/failpoint"
   894  )
   895  
   896  func unittest() {
   897  	if a, b := func() {
   898  		if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
   899  			fmt.Println("unit-test", val)
   900  		}
   901  	}, func() int { return rand.Intn(200) }(); b > 100 {
   902  		a()
   903  		if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
   904  			fmt.Println("unit-test", val)
   905  		}
   906  	}
   907  }
   908  `,
   909  		},
   910  
   911  		{
   912  			filepath: "if-statement-3.go",
   913  			original: `
   914  package rewriter_test
   915  
   916  import (
   917  	"fmt"
   918  	"math/rand"
   919  
   920  	"github.com/pingcap/failpoint"
   921  )
   922  
   923  func unittest() {
   924  	if a, b := func() {
   925  		failpoint.Inject("failpoint-name", func(val failpoint.Value) {
   926  			fmt.Println("unit-test", val)
   927  		})
   928  	}, func() int { return rand.Intn(200) }(); b > func() int {
   929  		failpoint.Inject("failpoint-name", func(val failpoint.Value) {
   930  			fmt.Println("unit-test", val)
   931  		})
   932  		return rand.Intn(3000)
   933  	}() && b < func() int {
   934  		failpoint.Inject("failpoint-name", func(val failpoint.Value) {
   935  			fmt.Println("unit-test", val)
   936  		})
   937  		return rand.Intn(6000)
   938  	}() {
   939  		a()
   940  		failpoint.Inject("failpoint-name", func(val failpoint.Value) {
   941  			fmt.Println("unit-test", val)
   942  		})
   943  	}
   944  }
   945  `,
   946  			expected: `
   947  package rewriter_test
   948  
   949  import (
   950  	"fmt"
   951  	"math/rand"
   952  
   953  	"github.com/pingcap/failpoint"
   954  )
   955  
   956  func unittest() {
   957  	if a, b := func() {
   958  		if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
   959  			fmt.Println("unit-test", val)
   960  		}
   961  	}, func() int { return rand.Intn(200) }(); b > func() int {
   962  		if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
   963  			fmt.Println("unit-test", val)
   964  		}
   965  		return rand.Intn(3000)
   966  	}() && b < func() int {
   967  		if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
   968  			fmt.Println("unit-test", val)
   969  		}
   970  		return rand.Intn(6000)
   971  	}() {
   972  		a()
   973  		if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
   974  			fmt.Println("unit-test", val)
   975  		}
   976  	}
   977  }
   978  `,
   979  		},
   980  
   981  		{
   982  			filepath: "if-statement-4.go",
   983  			original: `
   984  package rewriter_test
   985  
   986  import (
   987  	"fmt"
   988  
   989  	"github.com/pingcap/failpoint"
   990  )
   991  
   992  const success = 200
   993  
   994  func unittest() {
   995  	var i int
   996  	if func(v *int) {
   997  		failpoint.Inject("failpoint-name", func(val failpoint.Value) {
   998  			fmt.Println("unit-test", val)
   999  		})
  1000  		*v = success
  1001  	}(&i); i == success {
  1002  		failpoint.Inject("failpoint-name", func(val failpoint.Value) {
  1003  			fmt.Println("unit-test", val)
  1004  		})
  1005  		fmt.Printf("i = %d success\n", i)
  1006  	}
  1007  }
  1008  `,
  1009  			expected: `
  1010  package rewriter_test
  1011  
  1012  import (
  1013  	"fmt"
  1014  
  1015  	"github.com/pingcap/failpoint"
  1016  )
  1017  
  1018  const success = 200
  1019  
  1020  func unittest() {
  1021  	var i int
  1022  	if func(v *int) {
  1023  		if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
  1024  			fmt.Println("unit-test", val)
  1025  		}
  1026  		*v = success
  1027  	}(&i); i == success {
  1028  		if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
  1029  			fmt.Println("unit-test", val)
  1030  		}
  1031  		fmt.Printf("i = %d success\n", i)
  1032  	}
  1033  }
  1034  `,
  1035  		},
  1036  
  1037  		{
  1038  			filepath: "switch-statement.go",
  1039  			original: `
  1040  package rewriter_test
  1041  
  1042  import (
  1043  	"fmt"
  1044  	"math/rand"
  1045  
  1046  	"github.com/pingcap/failpoint"
  1047  )
  1048  
  1049  func unittest() {
  1050  	switch x, y := rand.Intn(10), func() int { return rand.Intn(1000) }(); x - y + func() int {
  1051  		failpoint.Inject("failpoint-name", func(val failpoint.Value) {
  1052  			fmt.Println("unit-test", val)
  1053  		})
  1054  		return rand.Intn(50)
  1055  	}() {
  1056  	case func() int {
  1057  		failpoint.Inject("failpoint-name", func(val failpoint.Value) {
  1058  			fmt.Println("unit-test", val)
  1059  		})
  1060  		return rand.Intn(5)
  1061  	}(), func() int {
  1062  		failpoint.Inject("failpoint-name", func(val failpoint.Value) {
  1063  			fmt.Println("unit-test", val)
  1064  		})
  1065  		return rand.Intn(8)
  1066  	}():
  1067  		failpoint.Inject("failpoint-name", func(val failpoint.Value) {
  1068  			fmt.Println("unit-test", val)
  1069  		})
  1070  		failpoint.Inject("failpoint-name", func(val failpoint.Value) {
  1071  			fmt.Println("unit-test", val)
  1072  		})
  1073  	default:
  1074  		failpoint.Inject("failpoint-name", func(val failpoint.Value) {
  1075  			fmt.Println("unit-test", val)
  1076  		})
  1077  		failpoint.Inject("failpoint-name", func(val failpoint.Value) {
  1078  			fmt.Println("unit-test", val)
  1079  		})
  1080  	}
  1081  }
  1082  `,
  1083  			expected: `
  1084  package rewriter_test
  1085  
  1086  import (
  1087  	"fmt"
  1088  	"math/rand"
  1089  
  1090  	"github.com/pingcap/failpoint"
  1091  )
  1092  
  1093  func unittest() {
  1094  	switch x, y := rand.Intn(10), func() int { return rand.Intn(1000) }(); x - y + func() int {
  1095  		if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
  1096  			fmt.Println("unit-test", val)
  1097  		}
  1098  		return rand.Intn(50)
  1099  	}() {
  1100  	case func() int {
  1101  		if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
  1102  			fmt.Println("unit-test", val)
  1103  		}
  1104  		return rand.Intn(5)
  1105  	}(), func() int {
  1106  		if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
  1107  			fmt.Println("unit-test", val)
  1108  		}
  1109  		return rand.Intn(8)
  1110  	}():
  1111  		if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
  1112  			fmt.Println("unit-test", val)
  1113  		}
  1114  		if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
  1115  			fmt.Println("unit-test", val)
  1116  		}
  1117  	default:
  1118  		if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
  1119  			fmt.Println("unit-test", val)
  1120  		}
  1121  		if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
  1122  			fmt.Println("unit-test", val)
  1123  		}
  1124  	}
  1125  }
  1126  `,
  1127  		},
  1128  
  1129  		{
  1130  			filepath: "switch-statement-2.go",
  1131  			original: `
  1132  package rewriter_test
  1133  
  1134  import (
  1135  	"fmt"
  1136  	"math/rand"
  1137  
  1138  	"github.com/pingcap/failpoint"
  1139  )
  1140  
  1141  func unittest() {
  1142  	switch x, y := rand.Intn(10), func() int {
  1143  		failpoint.Inject("failpoint-name", func(val failpoint.Value) {
  1144  			fmt.Println("unit-test", val)
  1145  		})
  1146  		return rand.Intn(1000)
  1147  	}(); func(x, y int) int {
  1148  		failpoint.Inject("failpoint-name", func(val failpoint.Value) {
  1149  			fmt.Println("unit-test", val)
  1150  		})
  1151  		return rand.Intn(50) + x + y
  1152  	}(x, y) {
  1153  	case func() int {
  1154  		failpoint.Inject("failpoint-name", func(val failpoint.Value) {
  1155  			fmt.Println("unit-test", val)
  1156  		})
  1157  		return rand.Intn(5)
  1158  	}(), func() int {
  1159  		failpoint.Inject("failpoint-name", func(val failpoint.Value) {
  1160  			fmt.Println("unit-test", val)
  1161  		})
  1162  		return rand.Intn(8)
  1163  	}():
  1164  		failpoint.Inject("failpoint-name", func(val failpoint.Value) {
  1165  			fmt.Println("unit-test", val)
  1166  		})
  1167  	default:
  1168  		failpoint.Inject("failpoint-name", func(val failpoint.Value) {
  1169  			fmt.Println("unit-test", val)
  1170  		})
  1171  		fn := func() {
  1172  			failpoint.Inject("failpoint-name", func(val failpoint.Value) {
  1173  				fmt.Println("unit-test", val)
  1174  			})
  1175  		}
  1176  		fn()
  1177  	}
  1178  }
  1179  `,
  1180  			expected: `
  1181  package rewriter_test
  1182  
  1183  import (
  1184  	"fmt"
  1185  	"math/rand"
  1186  
  1187  	"github.com/pingcap/failpoint"
  1188  )
  1189  
  1190  func unittest() {
  1191  	switch x, y := rand.Intn(10), func() int {
  1192  		if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
  1193  			fmt.Println("unit-test", val)
  1194  		}
  1195  		return rand.Intn(1000)
  1196  	}(); func(x, y int) int {
  1197  		if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
  1198  			fmt.Println("unit-test", val)
  1199  		}
  1200  		return rand.Intn(50) + x + y
  1201  	}(x, y) {
  1202  	case func() int {
  1203  		if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
  1204  			fmt.Println("unit-test", val)
  1205  		}
  1206  		return rand.Intn(5)
  1207  	}(), func() int {
  1208  		if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
  1209  			fmt.Println("unit-test", val)
  1210  		}
  1211  		return rand.Intn(8)
  1212  	}():
  1213  		if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
  1214  			fmt.Println("unit-test", val)
  1215  		}
  1216  	default:
  1217  		if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
  1218  			fmt.Println("unit-test", val)
  1219  		}
  1220  		fn := func() {
  1221  			if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
  1222  				fmt.Println("unit-test", val)
  1223  			}
  1224  		}
  1225  		fn()
  1226  	}
  1227  }
  1228  `,
  1229  		},
  1230  
  1231  		{
  1232  			filepath: "type-switch-statement.go",
  1233  			original: `
  1234  package rewriter_test
  1235  
  1236  import (
  1237  	"fmt"
  1238  
  1239  	"github.com/pingcap/failpoint"
  1240  )
  1241  
  1242  func unittest() {
  1243  	typeSwitch := func(i interface{}) {
  1244  		inner := func(i interface{}) interface{} {
  1245  			failpoint.Inject("failpoint-name", func(val failpoint.Value) {
  1246  				fmt.Println("unit-test", val)
  1247  			})
  1248  			return i
  1249  		}
  1250  		switch t := inner(i).(type) {
  1251  		case int:
  1252  			failpoint.Inject("failpoint-name", func(val failpoint.Value) {
  1253  				fmt.Println("unit-test", val)
  1254  			})
  1255  			fmt.Println("int type")
  1256  		default:
  1257  			failpoint.Inject("failpoint-name", func(val failpoint.Value) {
  1258  				fmt.Println("unit-test", val)
  1259  			})
  1260  			fmt.Printf("unsupported type %T\n", t)
  1261  		}
  1262  	}
  1263  
  1264  	typeSwitch2 := func(i interface{}) {
  1265  		switch i.(type) {
  1266  		case int:
  1267  			failpoint.Inject("failpoint-name", func(val failpoint.Value) {
  1268  				fmt.Println("unit-test", val)
  1269  			})
  1270  			fmt.Println("int type")
  1271  		}
  1272  	}
  1273  
  1274  	typeSwitch3 := func(i interface{}) {
  1275  		switch func(inf interface{}){
  1276  			failpoint.Inject("failpoint-name", func(val failpoint.Value) {
  1277  				fmt.Println("unit-test", val)
  1278  			})
  1279  			return inf
  1280  		}(i).(type) {
  1281  		case int:
  1282  			failpoint.Inject("failpoint-name", func(val failpoint.Value) {
  1283  				fmt.Println("unit-test", val)
  1284  			})
  1285  			fmt.Println("int type")
  1286  		}
  1287  	}
  1288  
  1289  	num := 42
  1290  	typeSwitch(num)
  1291  	typeSwitch2(num)
  1292  	typeSwitch3(num)
  1293  }
  1294  `,
  1295  			expected: `
  1296  package rewriter_test
  1297  
  1298  import (
  1299  	"fmt"
  1300  
  1301  	"github.com/pingcap/failpoint"
  1302  )
  1303  
  1304  func unittest() {
  1305  	typeSwitch := func(i interface{}) {
  1306  		inner := func(i interface{}) interface{} {
  1307  			if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
  1308  				fmt.Println("unit-test", val)
  1309  			}
  1310  			return i
  1311  		}
  1312  		switch t := inner(i).(type) {
  1313  		case int:
  1314  			if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
  1315  				fmt.Println("unit-test", val)
  1316  			}
  1317  			fmt.Println("int type")
  1318  		default:
  1319  			if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
  1320  				fmt.Println("unit-test", val)
  1321  			}
  1322  			fmt.Printf("unsupported type %T\n", t)
  1323  		}
  1324  	}
  1325  
  1326  	typeSwitch2 := func(i interface{}) {
  1327  		switch i.(type) {
  1328  		case int:
  1329  			if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
  1330  				fmt.Println("unit-test", val)
  1331  			}
  1332  			fmt.Println("int type")
  1333  		}
  1334  	}
  1335  
  1336  	typeSwitch3 := func(i interface{}) {
  1337  		switch func(inf interface{}) {
  1338  			if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
  1339  				fmt.Println("unit-test", val)
  1340  			}
  1341  			return inf
  1342  		}(i).(type) {
  1343  		case int:
  1344  			if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
  1345  				fmt.Println("unit-test", val)
  1346  			}
  1347  			fmt.Println("int type")
  1348  		}
  1349  	}
  1350  
  1351  	num := 42
  1352  	typeSwitch(num)
  1353  	typeSwitch2(num)
  1354  	typeSwitch3(num)
  1355  }
  1356  `,
  1357  		},
  1358  
  1359  		{
  1360  			filepath: "select-statement.go",
  1361  			original: `
  1362  package rewriter_test
  1363  
  1364  import (
  1365  	"fmt"
  1366  	"math/rand"
  1367  
  1368  	"github.com/pingcap/failpoint"
  1369  )
  1370  
  1371  func unittest() {
  1372  	select {
  1373  	case ch := <-func() chan bool {
  1374  		failpoint.Inject("failpoint-name", func(val failpoint.Value) {
  1375  			fmt.Println("unit-test", val)
  1376  		})
  1377  		return make(chan bool)
  1378  	}():
  1379  		fmt.Println(ch)
  1380  		failpoint.Inject("failpoint-name", func(val failpoint.Value) {
  1381  			fmt.Println("unit-test", val)
  1382  		})
  1383  
  1384  	case <-func() chan bool {
  1385  		failpoint.Inject("failpoint-name", func(val failpoint.Value) {
  1386  			fmt.Println("unit-test", val)
  1387  		})
  1388  		return make(chan bool)
  1389  	}():
  1390  		failpoint.Inject("failpoint-name", func(val failpoint.Value) {
  1391  			fmt.Println("unit-test", val)
  1392  		})
  1393  
  1394  	case <-func() chan bool {
  1395  		failpoint.Inject("failpoint-name", func(val failpoint.Value) {
  1396  			fmt.Println("unit-test", val)
  1397  		})
  1398  		return make(chan bool)
  1399  	}():
  1400  		failpoint.Inject("failpoint-name", func(val failpoint.Value) {
  1401  			fmt.Println("unit-test", val)
  1402  		})
  1403  	default:
  1404  		failpoint.Inject("failpoint-name", func(val failpoint.Value) {
  1405  			fmt.Println("unit-test", val)
  1406  		})
  1407  	}
  1408  }
  1409  `,
  1410  			expected: `
  1411  package rewriter_test
  1412  
  1413  import (
  1414  	"fmt"
  1415  	"math/rand"
  1416  
  1417  	"github.com/pingcap/failpoint"
  1418  )
  1419  
  1420  func unittest() {
  1421  	select {
  1422  	case ch := <-func() chan bool {
  1423  		if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
  1424  			fmt.Println("unit-test", val)
  1425  		}
  1426  		return make(chan bool)
  1427  	}():
  1428  		fmt.Println(ch)
  1429  		if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
  1430  			fmt.Println("unit-test", val)
  1431  		}
  1432  
  1433  	case <-func() chan bool {
  1434  		if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
  1435  			fmt.Println("unit-test", val)
  1436  		}
  1437  		return make(chan bool)
  1438  	}():
  1439  		if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
  1440  			fmt.Println("unit-test", val)
  1441  		}
  1442  
  1443  	case <-func() chan bool {
  1444  		if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
  1445  			fmt.Println("unit-test", val)
  1446  		}
  1447  		return make(chan bool)
  1448  	}():
  1449  		if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
  1450  			fmt.Println("unit-test", val)
  1451  		}
  1452  	default:
  1453  		if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
  1454  			fmt.Println("unit-test", val)
  1455  		}
  1456  	}
  1457  }
  1458  `,
  1459  		},
  1460  
  1461  		{
  1462  			filepath: "for-statement.go",
  1463  			original: `
  1464  package rewriter_test
  1465  
  1466  import (
  1467  	"fmt"
  1468  	"math/rand"
  1469  
  1470  	"github.com/pingcap/failpoint"
  1471  )
  1472  
  1473  func unittest() {
  1474  	for i := func() int {
  1475  		failpoint.Inject("failpoint-name", func(val failpoint.Value) {
  1476  			fmt.Println("unit-test", val)
  1477  		})
  1478  		return rand.Intn(100)
  1479  	}(); i < func() int {
  1480  		failpoint.Inject("failpoint-name", func(val failpoint.Value) {
  1481  			fmt.Println("unit-test", val)
  1482  		})
  1483  		return rand.Intn(10000)
  1484  	}(); i += func() int {
  1485  		failpoint.Inject("failpoint-name", func(val failpoint.Value) {
  1486  			fmt.Println("unit-test", val)
  1487  		})
  1488  		return rand.Intn(100)
  1489  	}() {
  1490  		failpoint.Inject("failpoint-name", func(val failpoint.Value) {
  1491  			fmt.Println("unit-test", val)
  1492  		})
  1493  	}
  1494  }
  1495  `,
  1496  			expected: `
  1497  package rewriter_test
  1498  
  1499  import (
  1500  	"fmt"
  1501  	"math/rand"
  1502  
  1503  	"github.com/pingcap/failpoint"
  1504  )
  1505  
  1506  func unittest() {
  1507  	for i := func() int {
  1508  		if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
  1509  			fmt.Println("unit-test", val)
  1510  		}
  1511  		return rand.Intn(100)
  1512  	}(); i < func() int {
  1513  		if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
  1514  			fmt.Println("unit-test", val)
  1515  		}
  1516  		return rand.Intn(10000)
  1517  	}(); i += func() int {
  1518  		if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
  1519  			fmt.Println("unit-test", val)
  1520  		}
  1521  		return rand.Intn(100)
  1522  	}() {
  1523  		if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
  1524  			fmt.Println("unit-test", val)
  1525  		}
  1526  	}
  1527  }
  1528  `,
  1529  		},
  1530  
  1531  		{
  1532  			filepath: "for-statement2.go",
  1533  			original: `
  1534  package rewriter_test
  1535  
  1536  import (
  1537  	"fmt"
  1538  
  1539  	"github.com/pingcap/failpoint"
  1540  )
  1541  
  1542  type Iterator struct {
  1543  	count int
  1544  	max   int
  1545  }
  1546  
  1547  func (i *Iterator) Begin(fn func()) int {
  1548  	i.count = 0
  1549  	return i.count
  1550  }
  1551  
  1552  func (i *Iterator) Next(fn func()) int {
  1553  	if i.count >= i.max {
  1554  		panic("iterator to end")
  1555  	}
  1556  	i.count++
  1557  	return i.count
  1558  }
  1559  
  1560  func (i *Iterator) End(fn func()) bool {
  1561  	return i.count == i.max
  1562  }
  1563  
  1564  func unittest() {
  1565  	iter := &Iterator{max: 10}
  1566  	for iter.Begin(func() {
  1567  		failpoint.Inject("failpoint-name", func(val failpoint.Value) {
  1568  			fmt.Println("unit-test", val)
  1569  		})
  1570  	}); !iter.End(func() {
  1571  		failpoint.Inject("failpoint-name", func(val failpoint.Value) {
  1572  			fmt.Println("unit-test", val)
  1573  		})
  1574  	}); {
  1575  		failpoint.Inject("failpoint-name", func(val failpoint.Value) {
  1576  			fmt.Println("unit-test", val)
  1577  		})
  1578  		i := iter.Next(func() {})
  1579  		fmt.Printf("get value: %d\n", i)
  1580  	}
  1581  }
  1582  `,
  1583  			expected: `
  1584  package rewriter_test
  1585  
  1586  import (
  1587  	"fmt"
  1588  
  1589  	"github.com/pingcap/failpoint"
  1590  )
  1591  
  1592  type Iterator struct {
  1593  	count int
  1594  	max   int
  1595  }
  1596  
  1597  func (i *Iterator) Begin(fn func()) int {
  1598  	i.count = 0
  1599  	return i.count
  1600  }
  1601  
  1602  func (i *Iterator) Next(fn func()) int {
  1603  	if i.count >= i.max {
  1604  		panic("iterator to end")
  1605  	}
  1606  	i.count++
  1607  	return i.count
  1608  }
  1609  
  1610  func (i *Iterator) End(fn func()) bool {
  1611  	return i.count == i.max
  1612  }
  1613  
  1614  func unittest() {
  1615  	iter := &Iterator{max: 10}
  1616  	for iter.Begin(func() {
  1617  		if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
  1618  			fmt.Println("unit-test", val)
  1619  		}
  1620  	}); !iter.End(func() {
  1621  		if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
  1622  			fmt.Println("unit-test", val)
  1623  		}
  1624  	}); {
  1625  		if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
  1626  			fmt.Println("unit-test", val)
  1627  		}
  1628  		i := iter.Next(func() {})
  1629  		fmt.Printf("get value: %d\n", i)
  1630  	}
  1631  }
  1632  `,
  1633  		},
  1634  
  1635  		{
  1636  			filepath: "range-statement.go",
  1637  			original: `
  1638  package rewriter_test
  1639  
  1640  import (
  1641  	"fmt"
  1642  	"math/rand"
  1643  
  1644  	"github.com/pingcap/failpoint"
  1645  )
  1646  
  1647  func unittest() {
  1648  	for x, y := range func() map[int]int {
  1649  		failpoint.Inject("failpoint-name", func(val failpoint.Value) {
  1650  			fmt.Println("unit-test", val)
  1651  		})
  1652  		return make(map[int]int, rand.Intn(10))
  1653  	}() {
  1654  		failpoint.Inject("failpoint-name", func(val failpoint.Value) {
  1655  			fmt.Println("unit-test", val)
  1656  		})
  1657  		fn := func() {
  1658  			failpoint.Inject("failpoint-name", func(val failpoint.Value) {
  1659  				fmt.Println("unit-test", val, x, y)
  1660  			})
  1661  		}
  1662  		fn()
  1663  	}
  1664  }
  1665  `,
  1666  			expected: `
  1667  package rewriter_test
  1668  
  1669  import (
  1670  	"fmt"
  1671  	"math/rand"
  1672  
  1673  	"github.com/pingcap/failpoint"
  1674  )
  1675  
  1676  func unittest() {
  1677  	for x, y := range func() map[int]int {
  1678  		if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
  1679  			fmt.Println("unit-test", val)
  1680  		}
  1681  		return make(map[int]int, rand.Intn(10))
  1682  	}() {
  1683  		if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
  1684  			fmt.Println("unit-test", val)
  1685  		}
  1686  		fn := func() {
  1687  			if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
  1688  				fmt.Println("unit-test", val, x, y)
  1689  			}
  1690  		}
  1691  		fn()
  1692  	}
  1693  }
  1694  `,
  1695  		},
  1696  
  1697  		{
  1698  			filepath: "control-flow-statement.go",
  1699  			original: `
  1700  package rewriter_test
  1701  
  1702  import (
  1703  	"fmt"
  1704  	"math/rand"
  1705  
  1706  	"github.com/pingcap/failpoint"
  1707  )
  1708  
  1709  func unittest() {
  1710  	failpoint.Label("outer")
  1711  	for i := 0; i < 100; i++ {
  1712  		failpoint.Label("inner")
  1713  		for j := 0; j < 1000; j++ {
  1714  			switch rand.Intn(j) + i {
  1715  			case j / 3:
  1716  				failpoint.Break("inner")
  1717  			case j / 4:
  1718  				failpoint.Break("outer")
  1719  			case j / 5:
  1720  				failpoint.Break()
  1721  			case j / 6:
  1722  				failpoint.Continue("inner")
  1723  			case j / 7:
  1724  				failpoint.Continue("outer")
  1725  			case j / 8:
  1726  				failpoint.Continue()
  1727  			case j / 9:
  1728  				failpoint.Fallthrough()
  1729  			case j / 10:
  1730  				failpoint.Goto("outer")
  1731  			default:
  1732  				failpoint.Inject("failpoint-name", func(val failpoint.Value) {
  1733  					fmt.Println("unit-test", val.(int))
  1734  					if val == j/11 {
  1735  						failpoint.Goto("inner")
  1736  					} else {
  1737  						failpoint.Goto("outer")
  1738  					}
  1739  				})
  1740  			}
  1741  		}
  1742  	}
  1743  }
  1744  `,
  1745  			expected: `
  1746  package rewriter_test
  1747  
  1748  import (
  1749  	"fmt"
  1750  	"math/rand"
  1751  
  1752  	"github.com/pingcap/failpoint"
  1753  )
  1754  
  1755  func unittest() {
  1756  outer:
  1757  	for i := 0; i < 100; i++ {
  1758  	inner:
  1759  		for j := 0; j < 1000; j++ {
  1760  			switch rand.Intn(j) + i {
  1761  			case j / 3:
  1762  				break inner
  1763  			case j / 4:
  1764  				break outer
  1765  			case j / 5:
  1766  				break
  1767  			case j / 6:
  1768  				continue inner
  1769  			case j / 7:
  1770  				continue outer
  1771  			case j / 8:
  1772  				continue
  1773  			case j / 9:
  1774  				fallthrough
  1775  			case j / 10:
  1776  				goto outer
  1777  			default:
  1778  				if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
  1779  					fmt.Println("unit-test", val.(int))
  1780  					if val == j/11 {
  1781  						goto inner
  1782  					} else {
  1783  						goto outer
  1784  					}
  1785  				}
  1786  			}
  1787  		}
  1788  	}
  1789  }
  1790  `,
  1791  		},
  1792  
  1793  		{
  1794  			filepath: "test-block-statement.go",
  1795  			original: `
  1796  package rewriter_test
  1797  
  1798  import (
  1799  	"fmt"
  1800  	"math/rand"
  1801  
  1802  	"github.com/pingcap/failpoint"
  1803  )
  1804  
  1805  func unittest() {
  1806  	{
  1807  		failpoint.Inject("failpoint-name", func() {
  1808  			fmt.Println("unit-test")
  1809  		})
  1810  	}
  1811  }
  1812  `,
  1813  			expected: `
  1814  package rewriter_test
  1815  
  1816  import (
  1817  	"fmt"
  1818  	"math/rand"
  1819  
  1820  	"github.com/pingcap/failpoint"
  1821  )
  1822  
  1823  func unittest() {
  1824  	{
  1825  		if _, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
  1826  			fmt.Println("unit-test")
  1827  		}
  1828  	}
  1829  }
  1830  `,
  1831  		},
  1832  
  1833  		{
  1834  			filepath: "test-send-statement.go",
  1835  			original: `
  1836  package rewriter_test
  1837  
  1838  import (
  1839  	"fmt"
  1840  	"math/rand"
  1841  
  1842  	"github.com/pingcap/failpoint"
  1843  )
  1844  
  1845  func unittest() {
  1846  	func() chan struct{} {
  1847  		failpoint.Inject("failpoint-name", func() chan struct{}{
  1848  			return make(chan struct{}, 1)
  1849  		})
  1850  		return make(chan struct{}, 1)
  1851  	}() <- func() struct{} {
  1852  		failpoint.Inject("failpoint-name", func() struct{} {
  1853  			return struct{}{}
  1854  		})
  1855  		return struct{}{}
  1856  	}()
  1857  }
  1858  `,
  1859  			expected: `
  1860  package rewriter_test
  1861  
  1862  import (
  1863  	"fmt"
  1864  	"math/rand"
  1865  
  1866  	"github.com/pingcap/failpoint"
  1867  )
  1868  
  1869  func unittest() {
  1870  	func() chan struct{} {
  1871  		if _, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
  1872  			return make(chan struct{}, 1)
  1873  		}
  1874  		return make(chan struct{}, 1)
  1875  	}() <- func() struct{} {
  1876  		if _, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
  1877  			return struct{}{}
  1878  		}
  1879  		return struct{}{}
  1880  	}()
  1881  }
  1882  `,
  1883  		},
  1884  
  1885  		{
  1886  			filepath: "test-label-statement.go",
  1887  			original: `
  1888  package rewriter_test
  1889  
  1890  import (
  1891  	"fmt"
  1892  	"math/rand"
  1893  
  1894  	"github.com/pingcap/failpoint"
  1895  )
  1896  
  1897  func unittest() {
  1898  	labelSend:
  1899  	func() chan struct{} {
  1900  		failpoint.Inject("failpoint-name", func() chan struct{} {
  1901  			return make(chan struct{}, 1)
  1902  		})
  1903  		return make(chan struct{}, 1)
  1904  	}() <- func() struct{} {
  1905  		failpoint.Inject("failpoint-name", func() struct{} {
  1906  			return struct{}{}
  1907  		})
  1908  		return struct{}{}
  1909  	}()
  1910  	if rand.Intn(10) > 5 {
  1911  		goto labelSend
  1912  	}
  1913  
  1914  	switch rand.Intn(10) {
  1915  	case 1:
  1916  		goto labelFor
  1917  	case 2:
  1918  		goto labelCall
  1919  	}
  1920  
  1921  labelFor:
  1922  	for i := range []int{10, 20} {
  1923  		if i%rand.Intn(2) == i {
  1924  		labelIf:
  1925  			if rand.Intn(1000) > 500 {
  1926  				failpoint.Inject("failpoint-name", func() {
  1927  					fmt.Println("output in failpoint")
  1928  				})
  1929  				goto labelIf
  1930  			}
  1931  			goto labelFor
  1932  		}
  1933  		if rand.Intn(20) > 10 {
  1934  			goto labelBreak
  1935  		}
  1936  	labelBreak:
  1937  		break
  1938  	}
  1939  
  1940  labelCall:
  1941  	failpoint.Inject("failpoint-name", func() {
  1942  		fmt.Println("output in failpoint")
  1943  	})
  1944  }
  1945  `,
  1946  			expected: `
  1947  package rewriter_test
  1948  
  1949  import (
  1950  	"fmt"
  1951  	"math/rand"
  1952  
  1953  	"github.com/pingcap/failpoint"
  1954  )
  1955  
  1956  func unittest() {
  1957  labelSend:
  1958  	func() chan struct{} {
  1959  		if _, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
  1960  			return make(chan struct{}, 1)
  1961  		}
  1962  		return make(chan struct{}, 1)
  1963  	}() <- func() struct{} {
  1964  		if _, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
  1965  			return struct{}{}
  1966  		}
  1967  		return struct{}{}
  1968  	}()
  1969  	if rand.Intn(10) > 5 {
  1970  		goto labelSend
  1971  	}
  1972  
  1973  	switch rand.Intn(10) {
  1974  	case 1:
  1975  		goto labelFor
  1976  	case 2:
  1977  		goto labelCall
  1978  	}
  1979  
  1980  labelFor:
  1981  	for i := range []int{10, 20} {
  1982  		if i%rand.Intn(2) == i {
  1983  		labelIf:
  1984  			if rand.Intn(1000) > 500 {
  1985  				if _, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
  1986  					fmt.Println("output in failpoint")
  1987  				}
  1988  				goto labelIf
  1989  			}
  1990  			goto labelFor
  1991  		}
  1992  		if rand.Intn(20) > 10 {
  1993  			goto labelBreak
  1994  		}
  1995  	labelBreak:
  1996  		break
  1997  	}
  1998  
  1999  labelCall:
  2000  	if _, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
  2001  		fmt.Println("output in failpoint")
  2002  	}
  2003  }
  2004  `,
  2005  		},
  2006  
  2007  		{
  2008  			filepath: "test-index-expression.go",
  2009  			original: `
  2010  package rewriter_test
  2011  
  2012  import (
  2013  	"fmt"
  2014  	"math/rand"
  2015  
  2016  	"github.com/pingcap/failpoint"
  2017  )
  2018  
  2019  func unittest() {
  2020  	x := func() []int {
  2021  		failpoint.Inject("failpoint-name", func() []int {
  2022  			return make([]int, 1)
  2023  		})
  2024  		return make([]int, 10)
  2025  	}()[func() int {
  2026  		failpoint.Inject("failpoint-name", func() int {
  2027  			return rand.Intn(1)
  2028  		})
  2029  		return rand.Intn(10)
  2030  	}()]
  2031  	fmt.Println(x)
  2032  }
  2033  `,
  2034  			expected: `
  2035  package rewriter_test
  2036  
  2037  import (
  2038  	"fmt"
  2039  	"math/rand"
  2040  
  2041  	"github.com/pingcap/failpoint"
  2042  )
  2043  
  2044  func unittest() {
  2045  	x := func() []int {
  2046  		if _, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
  2047  			return make([]int, 1)
  2048  		}
  2049  		return make([]int, 10)
  2050  	}()[func() int {
  2051  		if _, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
  2052  			return rand.Intn(1)
  2053  		}
  2054  		return rand.Intn(10)
  2055  	}()]
  2056  	fmt.Println(x)
  2057  }
  2058  `,
  2059  		},
  2060  
  2061  		{
  2062  			filepath: "test-slice-expression.go",
  2063  			original: `
  2064  package rewriter_test
  2065  
  2066  import (
  2067  	"fmt"
  2068  	"math/rand"
  2069  
  2070  	"github.com/pingcap/failpoint"
  2071  )
  2072  
  2073  func unittest() {
  2074  	x := func() []int {
  2075  		failpoint.Inject("failpoint-name", func() []int {
  2076  			return make([]int, 1)
  2077  		})
  2078  		return make([]int, 10)
  2079  	}()[func() int {
  2080  		failpoint.Inject("failpoint-name", func() int {
  2081  			return rand.Intn(1)
  2082  		})
  2083  		return rand.Intn(10)
  2084  	}():func() int {
  2085  		failpoint.Inject("failpoint-name", func() int {
  2086  			return rand.Intn(1)
  2087  		})
  2088  		return rand.Intn(10)
  2089  	}()]
  2090  	fmt.Println(x)
  2091  }
  2092  `,
  2093  			expected: `
  2094  package rewriter_test
  2095  
  2096  import (
  2097  	"fmt"
  2098  	"math/rand"
  2099  
  2100  	"github.com/pingcap/failpoint"
  2101  )
  2102  
  2103  func unittest() {
  2104  	x := func() []int {
  2105  		if _, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
  2106  			return make([]int, 1)
  2107  		}
  2108  		return make([]int, 10)
  2109  	}()[func() int {
  2110  		if _, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
  2111  			return rand.Intn(1)
  2112  		}
  2113  		return rand.Intn(10)
  2114  	}():func() int {
  2115  		if _, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
  2116  			return rand.Intn(1)
  2117  		}
  2118  		return rand.Intn(10)
  2119  	}()]
  2120  	fmt.Println(x)
  2121  }
  2122  `,
  2123  		},
  2124  
  2125  		{
  2126  			filepath: "test-star-expression.go",
  2127  			original: `
  2128  package rewriter_test
  2129  
  2130  import (
  2131  	"fmt"
  2132  	"math/rand"
  2133  
  2134  	"github.com/pingcap/failpoint"
  2135  )
  2136  
  2137  func unittest() {
  2138  	type X struct {
  2139  		A string
  2140  	}
  2141  	x := *func() *X {
  2142  		failpoint.Inject("failpoint-name", func() *X {
  2143  			return &X{A: "from-failpoint"}
  2144  		})
  2145  		return &X{A: "normal path"}
  2146  	}()
  2147  	fmt.Println(x.A)
  2148  }
  2149  `,
  2150  			expected: `
  2151  package rewriter_test
  2152  
  2153  import (
  2154  	"fmt"
  2155  	"math/rand"
  2156  
  2157  	"github.com/pingcap/failpoint"
  2158  )
  2159  
  2160  func unittest() {
  2161  	type X struct {
  2162  		A string
  2163  	}
  2164  	x := *func() *X {
  2165  		if _, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
  2166  			return &X{A: "from-failpoint"}
  2167  		}
  2168  		return &X{A: "normal path"}
  2169  	}()
  2170  	fmt.Println(x.A)
  2171  }
  2172  `,
  2173  		},
  2174  
  2175  		{
  2176  			filepath: "test-kv-expression.go",
  2177  			original: `
  2178  package rewriter_test
  2179  
  2180  import (
  2181  	"fmt"
  2182  	"math/rand"
  2183  
  2184  	"github.com/pingcap/failpoint"
  2185  )
  2186  
  2187  func unittest() {
  2188  	type X struct {
  2189  		A string
  2190  	}
  2191  	x := X{
  2192  		A: func() string {
  2193  			failpoint.Inject("failpoint-name", func() string {
  2194  				return "from-failpoint"
  2195  			})
  2196  			return "from-normal-path"
  2197  		}(),
  2198  	}
  2199  	fmt.Println(x.A)
  2200  }
  2201  `,
  2202  			expected: `
  2203  package rewriter_test
  2204  
  2205  import (
  2206  	"fmt"
  2207  	"math/rand"
  2208  
  2209  	"github.com/pingcap/failpoint"
  2210  )
  2211  
  2212  func unittest() {
  2213  	type X struct {
  2214  		A string
  2215  	}
  2216  	x := X{
  2217  		A: func() string {
  2218  			if _, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
  2219  				return "from-failpoint"
  2220  			}
  2221  			return "from-normal-path"
  2222  		}(),
  2223  	}
  2224  	fmt.Println(x.A)
  2225  }
  2226  `,
  2227  		},
  2228  
  2229  		{
  2230  			filepath: "test-nil-closure.go",
  2231  			original: `
  2232  package rewriter_test
  2233  
  2234  import (
  2235  	"fmt"
  2236  
  2237  	"github.com/pingcap/failpoint"
  2238  )
  2239  
  2240  func unittest() {
  2241  	failpoint.Inject("failpoint-name", nil)
  2242  
  2243  	failpoint.Inject("failpoint-name", nil)
  2244  }
  2245  `,
  2246  			expected: `
  2247  package rewriter_test
  2248  
  2249  import (
  2250  	"fmt"
  2251  
  2252  	"github.com/pingcap/failpoint"
  2253  )
  2254  
  2255  func unittest() {
  2256  	failpoint.Eval(_curpkg_("failpoint-name"))
  2257  
  2258  	failpoint.Eval(_curpkg_("failpoint-name"))
  2259  }
  2260  `,
  2261  		},
  2262  
  2263  		{
  2264  			filepath: "test-nil-closure-ctx.go",
  2265  			original: `
  2266  package rewriter_test
  2267  
  2268  import (
  2269  	"fmt"
  2270  
  2271  	"github.com/pingcap/failpoint"
  2272  )
  2273  
  2274  func unittest() {
  2275  	failpoint.InjectContext(nil, "failpoint-name", nil)
  2276  
  2277  	failpoint.InjectContext(nil, "failpoint-name", nil)
  2278  }
  2279  `,
  2280  			expected: `
  2281  package rewriter_test
  2282  
  2283  import (
  2284  	"fmt"
  2285  
  2286  	"github.com/pingcap/failpoint"
  2287  )
  2288  
  2289  func unittest() {
  2290  	failpoint.EvalContext(nil, _curpkg_("failpoint-name"))
  2291  
  2292  	failpoint.EvalContext(nil, _curpkg_("failpoint-name"))
  2293  }
  2294  `,
  2295  		},
  2296  
  2297  		{
  2298  			filepath: "test-return-marker.go",
  2299  			original: `
  2300  package rewriter_test
  2301  
  2302  import (
  2303  	"fmt"
  2304  
  2305  	"github.com/pingcap/failpoint"
  2306  )
  2307  
  2308  func unittest() (int, int, error) {
  2309  	failpoint.Inject("failpoint-name", func() {
  2310  		failpoint.Return(123, 456, errors.New("something"))
  2311  	})
  2312  }
  2313  `,
  2314  			expected: `
  2315  package rewriter_test
  2316  
  2317  import (
  2318  	"fmt"
  2319  
  2320  	"github.com/pingcap/failpoint"
  2321  )
  2322  
  2323  func unittest() (int, int, error) {
  2324  	if _, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
  2325  		return 123, 456, errors.New("something")
  2326  	}
  2327  }
  2328  `,
  2329  		},
  2330  
  2331  		{
  2332  			filepath: "test-return-marker-with-value.go",
  2333  			original: `
  2334  package rewriter_test
  2335  
  2336  import (
  2337  	"fmt"
  2338  
  2339  	"github.com/pingcap/failpoint"
  2340  )
  2341  
  2342  func unittest() (int, int, error) {
  2343  	failpoint.Inject("failpoint-name", func(val failpoint.Value) {
  2344  		failpoint.Return(val.(int), 456, errors.New("something"))
  2345  	})
  2346  }
  2347  `,
  2348  			expected: `
  2349  package rewriter_test
  2350  
  2351  import (
  2352  	"fmt"
  2353  
  2354  	"github.com/pingcap/failpoint"
  2355  )
  2356  
  2357  func unittest() (int, int, error) {
  2358  	if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
  2359  		return val.(int), 456, errors.New("something")
  2360  	}
  2361  }
  2362  `,
  2363  		},
  2364  
  2365  		{
  2366  			filepath: "test-inc-dec-statement.go",
  2367  			original: `
  2368  package rewriter_test
  2369  
  2370  import (
  2371  	"fmt"
  2372  
  2373  	"github.com/pingcap/failpoint"
  2374  )
  2375  
  2376  func unittest() {
  2377  	type X struct {
  2378  		Y int
  2379  	}
  2380  	func() *X {
  2381  		failpoint.Inject("failpoint-name", func(val failpoint.Value) *X {
  2382  			return &X{Y: val.(int)}
  2383  		})
  2384  		return &X{Y: 100}
  2385  	}().Y++
  2386  }
  2387  `,
  2388  			expected: `
  2389  package rewriter_test
  2390  
  2391  import (
  2392  	"fmt"
  2393  
  2394  	"github.com/pingcap/failpoint"
  2395  )
  2396  
  2397  func unittest() {
  2398  	type X struct {
  2399  		Y int
  2400  	}
  2401  	func() *X {
  2402  		if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
  2403  			return &X{Y: val.(int)}
  2404  		}
  2405  		return &X{Y: 100}
  2406  	}().Y++
  2407  }
  2408  `,
  2409  		},
  2410  
  2411  		{
  2412  			filepath: "test-empty-body.go",
  2413  			original: `
  2414  package rewriter_test
  2415  
  2416  import (
  2417  	"github.com/pingcap/failpoint"
  2418  )
  2419  
  2420  func unittest() {
  2421  	failpoint.Inject("failpoint-name", func() {})
  2422  	failpoint.Inject("failpoint-name", nil)
  2423  }
  2424  `,
  2425  			expected: `
  2426  package rewriter_test
  2427  
  2428  import (
  2429  	"github.com/pingcap/failpoint"
  2430  )
  2431  
  2432  func unittest() {
  2433  	failpoint.Eval(_curpkg_("failpoint-name"))
  2434  	failpoint.Eval(_curpkg_("failpoint-name"))
  2435  }
  2436  `,
  2437  		},
  2438  	}
  2439  
  2440  	// Create temp files
  2441  	err := os.MkdirAll(rewritePath, 0755)
  2442  	require.NoError(t, err)
  2443  	for _, cs := range cases {
  2444  		original := filepath.Join(rewritePath, cs.filepath)
  2445  		err := ioutil.WriteFile(original, []byte(cs.original), 0644)
  2446  		require.NoError(t, err)
  2447  	}
  2448  
  2449  	// Clean all temp files
  2450  	defer func() {
  2451  		err := os.RemoveAll(rewritePath)
  2452  		require.NoError(t, err)
  2453  	}()
  2454  
  2455  	rewriter := code.NewRewriter(rewritePath)
  2456  	err = rewriter.Rewrite()
  2457  	require.NoError(t, err)
  2458  
  2459  	for _, cs := range cases {
  2460  		expected := filepath.Join(rewritePath, cs.filepath)
  2461  		content, err := ioutil.ReadFile(expected)
  2462  		require.NoError(t, err)
  2463  		require.Equalf(t, strings.TrimSpace(cs.expected), strings.TrimSpace(string(content)), "%v", cs.filepath)
  2464  	}
  2465  
  2466  	// Restore workspace
  2467  	restorer := code.NewRestorer(rewritePath)
  2468  	err = restorer.Restore()
  2469  	require.NoError(t, err)
  2470  
  2471  	for _, cs := range cases {
  2472  		original := filepath.Join(rewritePath, cs.filepath)
  2473  		content, err := ioutil.ReadFile(original)
  2474  		require.NoError(t, err)
  2475  		require.Equal(t, cs.original, string(content))
  2476  	}
  2477  }
  2478  
  2479  func TestRewriteBad(t *testing.T) {
  2480  	var cases = []struct {
  2481  		filepath string
  2482  		errormsg string
  2483  		original string
  2484  	}{
  2485  
  2486  		{
  2487  			filepath: "bad-basic-test.go",
  2488  			errormsg: `failpoint\.Inject: invalid signature.*`,
  2489  			original: `
  2490  package rewriter_test
  2491  
  2492  import (
  2493  	"fmt"
  2494  
  2495  	"github.com/pingcap/failpoint"
  2496  )
  2497  
  2498  func unittest() {
  2499  	failpoint.Inject("failpoint-name", func(val int) {
  2500  		fmt.Println("unit-test", val)
  2501  	})
  2502  }
  2503  `,
  2504  		},
  2505  
  2506  		{
  2507  			filepath: "bad-basic-test2.go",
  2508  			errormsg: `failpoint\.Inject: closure signature illegal .*`,
  2509  			original: `
  2510  package rewriter_test
  2511  
  2512  import (
  2513  	"fmt"
  2514  
  2515  	"github.com/pingcap/failpoint"
  2516  )
  2517  
  2518  func unittest() {
  2519  	failpoint.Inject("failpoint-name", func(ctx context.Context, val int) {
  2520  		fmt.Println("unit-test", val)
  2521  	})
  2522  }
  2523  `,
  2524  		},
  2525  
  2526  		{
  2527  			filepath: "bad-basic-test3.go",
  2528  			errormsg: `failpoint\.Inject: closure signature illegal .*`,
  2529  			original: `
  2530  package rewriter_test
  2531  
  2532  import (
  2533  	"fmt"
  2534  
  2535  	"github.com/pingcap/failpoint"
  2536  )
  2537  
  2538  func unittest() {
  2539  	failpoint.Inject("failpoint-name", func(ctx context.Context, val int, val2 string) {
  2540  		fmt.Println("unit-test", val)
  2541  	})
  2542  }
  2543  `,
  2544  		},
  2545  
  2546  		{
  2547  			filepath: "bad-basic-test4.go",
  2548  			errormsg: `failpoint\.Inject: expect 2 arguments but got 3.*`,
  2549  			original: `
  2550  package rewriter_test
  2551  
  2552  import (
  2553  	"fmt"
  2554  
  2555  	"github.com/pingcap/failpoint"
  2556  )
  2557  
  2558  func unittest() {
  2559  	failpoint.Inject("failpoint-name", "invalid string", func(ctx context.Context, val int, val2 string) {
  2560  		fmt.Println("unit-test", val)
  2561  	})
  2562  }
  2563  `,
  2564  		},
  2565  
  2566  		{
  2567  			filepath: "bad-basic-test5.go",
  2568  			errormsg: `failpoint\.Inject: closure signature illegal .*`,
  2569  			original: `
  2570  package rewriter_test
  2571  
  2572  import (
  2573  	"fmt"
  2574  
  2575  	"github.com/pingcap/failpoint"
  2576  )
  2577  
  2578  func unittest() {
  2579  	failpoint.Inject("failpoint-name", func(val int, val2 int) {
  2580  		fmt.Println("unit-test", val)
  2581  	})
  2582  }
  2583  `,
  2584  		},
  2585  
  2586  		{
  2587  			filepath: "bad-basic-test5-1.go",
  2588  			errormsg: `failpoint\.Inject: closure signature illegal .*`,
  2589  			original: `
  2590  package rewriter_test
  2591  
  2592  import (
  2593  	"fmt"
  2594  
  2595  	"github.com/pingcap/failpoint"
  2596  )
  2597  
  2598  func unittest() {
  2599  	failpoint.Inject("failpoint-name", func(val, val2 int) {
  2600  		fmt.Println("unit-test", val)
  2601  	})
  2602  }
  2603  `,
  2604  		},
  2605  
  2606  		{
  2607  			filepath: "bad-basic-test6.go",
  2608  			errormsg: `failpoint\.Inject: second argument expect closure in.*`,
  2609  			original: `
  2610  package rewriter_test
  2611  
  2612  import (
  2613  	"fmt"
  2614  
  2615  	"github.com/pingcap/failpoint"
  2616  )
  2617  
  2618  func unittest() {
  2619  	failpoint.Inject(func(val int, val2 int) {
  2620  		fmt.Println("unit-test", val)
  2621  	}, "failpoint-name")
  2622  }
  2623  `,
  2624  		},
  2625  
  2626  		{
  2627  			filepath: "bad-basic-test7.go",
  2628  			errormsg: `failpoint\.Inject: second argument expect closure in.*`,
  2629  			original: `
  2630  package rewriter_test
  2631  
  2632  import (
  2633  	"fmt"
  2634  
  2635  	"github.com/pingcap/failpoint"
  2636  )
  2637  
  2638  func unittest() {
  2639  	failpoint.Inject("failpoint-name", "failpoint-name")
  2640  }
  2641  `,
  2642  		},
  2643  
  2644  		{
  2645  			filepath: "bad-basic-ctx-test1.go",
  2646  			errormsg: `failpoint\.InjectContext: expect 3 arguments but got 4.*`,
  2647  			original: `
  2648  package rewriter_test
  2649  
  2650  import (
  2651  	"fmt"
  2652  
  2653  	"github.com/pingcap/failpoint"
  2654  )
  2655  
  2656  func unittest() {
  2657  	failpoint.InjectContext("failpoint-name", nil, nil, func(val int, val2 int) {
  2658  		fmt.Println("unit-test", val)
  2659  	})
  2660  }
  2661  `,
  2662  		},
  2663  
  2664  		{
  2665  			filepath: "bad-basic-ctx-test2.go",
  2666  			errormsg: `failpoint\.InjectContext: closure signature illegal in.*`,
  2667  			original: `
  2668  package rewriter_test
  2669  
  2670  import (
  2671  	"fmt"
  2672  
  2673  	"github.com/pingcap/failpoint"
  2674  )
  2675  
  2676  func unittest() {
  2677  	failpoint.InjectContext(func(){}, nil, func(val int, val2 int) {
  2678  		fmt.Println("unit-test", val)
  2679  	})
  2680  }
  2681  `,
  2682  		},
  2683  
  2684  		{
  2685  			filepath: "bad-basic-ctx-test3.go",
  2686  			errormsg: `failpoint\.InjectContext: closure signature illegal in.*`,
  2687  			original: `
  2688  package rewriter_test
  2689  
  2690  import (
  2691  	"fmt"
  2692  
  2693  	"github.com/pingcap/failpoint"
  2694  )
  2695  
  2696  func unittest() {
  2697  	failpoint.InjectContext(nil, func(){}, func(val int, val2 int) {
  2698  		fmt.Println("unit-test", val)
  2699  	})
  2700  }
  2701  `,
  2702  		},
  2703  
  2704  		{
  2705  			filepath: "bad-basic-ctx-test4.go",
  2706  			errormsg: `failpoint\.InjectContext: third argument expect closure in.*`,
  2707  			original: `
  2708  package rewriter_test
  2709  
  2710  import (
  2711  	"fmt"
  2712  
  2713  	"github.com/pingcap/failpoint"
  2714  )
  2715  
  2716  func unittest() {
  2717  	failpoint.InjectContext(nil, "failpoint-name", "string literal")
  2718  }
  2719  `,
  2720  		},
  2721  
  2722  		{
  2723  			filepath: "bad-basic-ctx-test5.go",
  2724  			errormsg: `failpoint\.InjectContext: closure signature illegal.*`,
  2725  			original: `
  2726  package rewriter_test
  2727  
  2728  import (
  2729  	"fmt"
  2730  
  2731  	"github.com/pingcap/failpoint"
  2732  )
  2733  
  2734  func unittest() {
  2735  	failpoint.InjectContext(nil, "failpoint-name", func(val int, val int) {})
  2736  }
  2737  `,
  2738  		},
  2739  
  2740  		{
  2741  			filepath: "bad-basic-ctx-test6.go",
  2742  			errormsg: `failpoint\.InjectContext: closure signature illegal.*`,
  2743  			original: `
  2744  package rewriter_test
  2745  
  2746  import (
  2747  	"fmt"
  2748  
  2749  	"github.com/pingcap/failpoint"
  2750  )
  2751  
  2752  func unittest() {
  2753  	failpoint.InjectContext(nil, "failpoint-name", func(val, val int) {})
  2754  }
  2755  `,
  2756  		},
  2757  
  2758  		{
  2759  			filepath: "bad-case-break.go",
  2760  			errormsg: `failpoint\.Break expect 1 or 0 arguments, but got.*`,
  2761  			original: `
  2762  package rewriter_test
  2763  
  2764  import (
  2765  	"fmt"
  2766  
  2767  	"github.com/pingcap/failpoint"
  2768  )
  2769  
  2770  func unittest() {
  2771  	failpoint.Break("11", "22")
  2772  }
  2773  `,
  2774  		},
  2775  
  2776  		{
  2777  			filepath: "bad-case-continue.go",
  2778  			errormsg: `failpoint\.Continue expect 1 or 0 arguments, but got.*`,
  2779  			original: `
  2780  package rewriter_test
  2781  
  2782  import (
  2783  	"fmt"
  2784  
  2785  	"github.com/pingcap/failpoint"
  2786  )
  2787  
  2788  func unittest() {
  2789  	failpoint.Continue("11", "22")
  2790  }
  2791  `,
  2792  		},
  2793  
  2794  		{
  2795  			filepath: "bad-case-label.go",
  2796  			errormsg: `failpoint\.Label expect 1 arguments, but got.*`,
  2797  			original: `
  2798  package rewriter_test
  2799  
  2800  import (
  2801  	"fmt"
  2802  
  2803  	"github.com/pingcap/failpoint"
  2804  )
  2805  
  2806  func unittest() {
  2807  	failpoint.Label("11", "22")
  2808  }
  2809  `,
  2810  		},
  2811  
  2812  		{
  2813  			filepath: "bad-case-goto.go",
  2814  			errormsg: `failpoint\.Goto expect 1 arguments, but got .*`,
  2815  			original: `
  2816  package rewriter_test
  2817  
  2818  import (
  2819  	"fmt"
  2820  
  2821  	"github.com/pingcap/failpoint"
  2822  )
  2823  
  2824  func unittest() {
  2825  	failpoint.Goto("11", "22")
  2826  }
  2827  `,
  2828  		},
  2829  
  2830  		{
  2831  			filepath: "bad-case-func-literal.go",
  2832  			errormsg: `failpoint\.Goto expect 1 arguments, but got .*`,
  2833  			original: `
  2834  package rewriter_test
  2835  
  2836  import (
  2837  	"fmt"
  2838  
  2839  	"github.com/pingcap/failpoint"
  2840  )
  2841  
  2842  func unittest() {
  2843  	x = func() {
  2844  		failpoint.Goto("11", "22")
  2845  	}
  2846  	x()
  2847  }
  2848  `,
  2849  		},
  2850  
  2851  		{
  2852  			filepath: "bad-case-if-stmt-init.go",
  2853  			errormsg: `failpoint\.Goto expect 1 arguments, but got .*`,
  2854  			original: `
  2855  package rewriter_test
  2856  
  2857  import (
  2858  	"fmt"
  2859  
  2860  	"github.com/pingcap/failpoint"
  2861  )
  2862  
  2863  func unittest() {
  2864  	if x := func() int {
  2865  		failpoint.Goto("11", "22")
  2866  		return 10
  2867  	}; x() > rand.Intn(20) {
  2868  		failpoint.Goto("11", "22")
  2869  	}
  2870  }
  2871  `,
  2872  		},
  2873  
  2874  		{
  2875  			filepath: "bad-case-if-stmt-cond.go",
  2876  			errormsg: `failpoint\.Goto expect 1 arguments, but got .*`,
  2877  			original: `
  2878  package rewriter_test
  2879  
  2880  import (
  2881  	"fmt"
  2882  
  2883  	"github.com/pingcap/failpoint"
  2884  )
  2885  
  2886  func unittest() {
  2887  	if x := rand.Intn(20); x > func() int {
  2888  		failpoint.Goto("11", "22")
  2889  		return 10
  2890  	}() {
  2891  		failpoint.Goto("11", "22")
  2892  	}
  2893  }
  2894  `,
  2895  		},
  2896  
  2897  		{
  2898  			filepath: "bad-case-if-stmt-body.go",
  2899  			errormsg: `failpoint\.Goto expect 1 arguments, but got .*`,
  2900  			original: `
  2901  package rewriter_test
  2902  
  2903  import (
  2904  	"fmt"
  2905  
  2906  	"github.com/pingcap/failpoint"
  2907  )
  2908  
  2909  func unittest() {
  2910  	if x := rand.Intn(20); x > 10 {
  2911  		failpoint.Goto("11", "22")
  2912  	}
  2913  }
  2914  `,
  2915  		},
  2916  
  2917  		{
  2918  			filepath: "bad-IndexExpr.go",
  2919  			errormsg: `failpoint\.Goto expect 1 arguments, but got .*`,
  2920  			original: `
  2921  package rewriter_test
  2922  
  2923  import (
  2924  	"fmt"
  2925  
  2926  	"github.com/pingcap/failpoint"
  2927  )
  2928  
  2929  func unittest() {
  2930  	_ := func() []int {
  2931  		failpoint.Goto("11", "22")
  2932  		return []int{1}
  2933  	}()[0]
  2934  }
  2935  `,
  2936  		},
  2937  
  2938  		{
  2939  			filepath: "bad-rewriteExpr-SliceExpr-Low.go",
  2940  			errormsg: `failpoint\.Goto expect 1 arguments, but got .*`,
  2941  			original: `
  2942  package rewriter_test
  2943  
  2944  import (
  2945  	"fmt"
  2946  
  2947  	"github.com/pingcap/failpoint"
  2948  )
  2949  
  2950  func unittest() {
  2951  	_ := []int{1,2,3}[func() int {
  2952  		failpoint.Goto("11", "22")
  2953  		return 0
  2954  	}():1]
  2955  }
  2956  `,
  2957  		},
  2958  
  2959  		{
  2960  			filepath: "bad-rewriteExpr-SliceExpr-High.go",
  2961  			errormsg: `failpoint\.Goto expect 1 arguments, but got .*`,
  2962  			original: `
  2963  package rewriter_test
  2964  
  2965  import (
  2966  	"fmt"
  2967  
  2968  	"github.com/pingcap/failpoint"
  2969  )
  2970  
  2971  func unittest() {
  2972  	_ := []int{1,2,3}[0:func() int {
  2973  		failpoint.Goto("11", "22")
  2974  		return 1
  2975  	}()]
  2976  }
  2977  `,
  2978  		},
  2979  
  2980  		{
  2981  			filepath: "bad-rewriteExpr-SliceExpr-Max.go",
  2982  			errormsg: `failpoint\.Goto expect 1 arguments, but got .*`,
  2983  			original: `
  2984  package rewriter_test
  2985  
  2986  import (
  2987  	"fmt"
  2988  
  2989  	"github.com/pingcap/failpoint"
  2990  )
  2991  
  2992  func unittest() {
  2993  	arr := []int{1,2,3}
  2994  	_ := arr[0:1:func() int {
  2995  		failpoint.Goto("11", "22")
  2996  		return 2
  2997  	}()]
  2998  }
  2999  `,
  3000  		},
  3001  
  3002  		{
  3003  			filepath: "bad-rewriteExpr-CompositeLit-Elt.go",
  3004  			errormsg: `failpoint\.Goto expect 1 arguments, but got .*`,
  3005  			original: `
  3006  package rewriter_test
  3007  
  3008  import (
  3009  	"fmt"
  3010  
  3011  	"github.com/pingcap/failpoint"
  3012  )
  3013  
  3014  func unittest() {
  3015  	_ := []int{func() int {
  3016  		failpoint.Goto("11", "22")
  3017  		return 1
  3018  	}()}
  3019  }
  3020  `,
  3021  		},
  3022  
  3023  		{
  3024  			filepath: "bad-rewriteExpr-CallExpr-Fun.go",
  3025  			errormsg: `failpoint\.Goto expect 1 arguments, but got .*`,
  3026  			original: `
  3027  package rewriter_test
  3028  
  3029  import (
  3030  	"fmt"
  3031  
  3032  	"github.com/pingcap/failpoint"
  3033  )
  3034  
  3035  func unittest() {
  3036  	return func() {
  3037  		failpoint.Goto("11", "22")
  3038  	}()
  3039  }
  3040  `,
  3041  		},
  3042  
  3043  		{
  3044  			filepath: "bad-rewriteExpr-CallExpr-Args.go",
  3045  			errormsg: `failpoint\.Goto expect 1 arguments, but got .*`,
  3046  			original: `
  3047  package rewriter_test
  3048  
  3049  import (
  3050  	"fmt"
  3051  
  3052  	"github.com/pingcap/failpoint"
  3053  )
  3054  
  3055  func unittest() {
  3056  	return func(_ func()) {} (func() {
  3057  		failpoint.Goto("11", "22")
  3058  	})
  3059  }
  3060  `,
  3061  		},
  3062  
  3063  		{
  3064  			filepath: "bad-rewriteExpr-BinaryExpr-X.go",
  3065  			errormsg: `failpoint\.Goto expect 1 arguments, but got .*`,
  3066  			original: `
  3067  package rewriter_test
  3068  
  3069  import (
  3070  	"fmt"
  3071  
  3072  	"github.com/pingcap/failpoint"
  3073  )
  3074  
  3075  func unittest() {
  3076  	_ := func() bool {
  3077  		failpoint.Goto("11", "22")
  3078  		return true
  3079  	}() && true
  3080  }
  3081  `,
  3082  		},
  3083  
  3084  		{
  3085  			filepath: "bad-rewriteExpr-ParenExpr.go",
  3086  			errormsg: `failpoint\.Goto expect 1 arguments, but got .*`,
  3087  			original: `
  3088  package rewriter_test
  3089  
  3090  import (
  3091  	"fmt"
  3092  
  3093  	"github.com/pingcap/failpoint"
  3094  )
  3095  
  3096  func unittest() {
  3097  	_ := (func () {
  3098  		failpoint.Goto("11", "22")
  3099  	}())
  3100  }
  3101  `,
  3102  		},
  3103  
  3104  		{
  3105  			filepath: "bad-rewriteExprs.go",
  3106  			errormsg: `failpoint\.Goto expect 1 arguments, but got .*`,
  3107  			original: `
  3108  package rewriter_test
  3109  
  3110  import (
  3111  	"fmt"
  3112  
  3113  	"github.com/pingcap/failpoint"
  3114  )
  3115  
  3116  func unittest() int {
  3117  	return func() int {
  3118  		failpoint.Goto("11", "22")
  3119  		return 1
  3120  	}()
  3121  }
  3122  `,
  3123  		},
  3124  
  3125  		{
  3126  			filepath: "bad-rewriteStmts.go",
  3127  			errormsg: `failpoint\.Goto expect 1 arguments, but got .*`,
  3128  			original: `
  3129  package rewriter_test
  3130  
  3131  import (
  3132  	"fmt"
  3133  
  3134  	"github.com/pingcap/failpoint"
  3135  )
  3136  
  3137  func unittest() {
  3138  	var a, b = 1, func() {
  3139  		failpoint.Goto("11", "22")
  3140  	}
  3141  	_, _ = a, b
  3142  }
  3143  `,
  3144  		},
  3145  
  3146  		{
  3147  			filepath: "bad-rewriteStmts-GoStmt.go",
  3148  			errormsg: `failpoint\.Goto expect 1 arguments, but got .*`,
  3149  			original: `
  3150  package rewriter_test
  3151  
  3152  import (
  3153  	"fmt"
  3154  
  3155  	"github.com/pingcap/failpoint"
  3156  )
  3157  
  3158  func unittest() {
  3159  	go func() {
  3160  		failpoint.Goto("11", "22")
  3161  	}()
  3162  }
  3163  `,
  3164  		},
  3165  
  3166  		{
  3167  			filepath: "bad-rewriteStmts-DeferStmt.go",
  3168  			errormsg: `failpoint\.Goto expect 1 arguments, but got .*`,
  3169  			original: `
  3170  package rewriter_test
  3171  
  3172  import (
  3173  	"fmt"
  3174  
  3175  	"github.com/pingcap/failpoint"
  3176  )
  3177  
  3178  func unittest() {
  3179  	defer func() {
  3180  		failpoint.Goto("11", "22")
  3181  	}()
  3182  }
  3183  `,
  3184  		},
  3185  
  3186  		{
  3187  			filepath: "bad-rewriteStmts-BlockStmt.go",
  3188  			errormsg: `failpoint\.Goto expect 1 arguments, but got .*`,
  3189  			original: `
  3190  package rewriter_test
  3191  
  3192  import (
  3193  	"fmt"
  3194  
  3195  	"github.com/pingcap/failpoint"
  3196  )
  3197  
  3198  func unittest() {
  3199  	{
  3200  		failpoint.Goto("11", "22")
  3201  	}
  3202  }
  3203  `,
  3204  		},
  3205  
  3206  		{
  3207  			filepath: "bad-rewriteStmts-CaseClause-List.go",
  3208  			errormsg: `failpoint\.Goto expect 1 arguments, but got .*`,
  3209  			original: `
  3210  package rewriter_test
  3211  
  3212  import (
  3213  	"fmt"
  3214  
  3215  	"github.com/pingcap/failpoint"
  3216  )
  3217  
  3218  func unittest() {
  3219  	switch rand.Intn(10) {
  3220  	case (func () int {
  3221  		failpoint.Goto("11", "22")
  3222  		return 1
  3223  	}()):
  3224  		return
  3225  	}
  3226  }
  3227  `,
  3228  		},
  3229  
  3230  		{
  3231  			filepath: "bad-rewriteStmts-CaseClause-Body.go",
  3232  			errormsg: `failpoint\.Goto expect 1 arguments, but got .*`,
  3233  			original: `
  3234  package rewriter_test
  3235  
  3236  import (
  3237  	"fmt"
  3238  
  3239  	"github.com/pingcap/failpoint"
  3240  )
  3241  
  3242  func unittest() {
  3243  	switch rand.Intn(10) {
  3244  	case 1:
  3245  		failpoint.Goto("11", "22")
  3246  	}
  3247  }
  3248  `,
  3249  		},
  3250  
  3251  		{
  3252  			filepath: "bad-rewriteStmts-SwitchStmt-Init.go",
  3253  			errormsg: `failpoint\.Goto expect 1 arguments, but got .*`,
  3254  			original: `
  3255  package rewriter_test
  3256  
  3257  import (
  3258  	"fmt"
  3259  
  3260  	"github.com/pingcap/failpoint"
  3261  )
  3262  
  3263  func unittest() {
  3264  	switch a := (func () {
  3265  		failpoint.Goto("11", "22")
  3266  	}()); {
  3267  	case 1:
  3268  	}
  3269  }
  3270  `,
  3271  		},
  3272  
  3273  		{
  3274  			filepath: "bad-rewriteStmts-SwitchStmt-Tag.go",
  3275  			errormsg: `failpoint\.Goto expect 1 arguments, but got .*`,
  3276  			original: `
  3277  package rewriter_test
  3278  
  3279  import (
  3280  	"fmt"
  3281  
  3282  	"github.com/pingcap/failpoint"
  3283  )
  3284  
  3285  func unittest() {
  3286  	switch (func () {
  3287  		failpoint.Goto("11", "22")
  3288  	}()) {
  3289  	case 1:
  3290  	}
  3291  }
  3292  `,
  3293  		},
  3294  
  3295  		{
  3296  			filepath: "bad-rewriteStmts-CommClause-AssignStmt.go",
  3297  			errormsg: `failpoint\.Goto expect 1 arguments, but got .*`,
  3298  			original: `
  3299  package rewriter_test
  3300  
  3301  import (
  3302  	"fmt"
  3303  
  3304  	"github.com/pingcap/failpoint"
  3305  )
  3306  
  3307  func unittest() {
  3308  	select {
  3309  	case ch := func () chan bool {
  3310  		failpoint.Goto("11", "22")
  3311  		return make(chan bool, 1)
  3312  	}():
  3313  	}
  3314  }
  3315  `,
  3316  		},
  3317  
  3318  		{
  3319  			filepath: "bad-rewriteStmts-CommClause-ExprStmt.go",
  3320  			errormsg: `failpoint\.Goto expect 1 arguments, but got .*`,
  3321  			original: `
  3322  package rewriter_test
  3323  
  3324  import (
  3325  	"fmt"
  3326  
  3327  	"github.com/pingcap/failpoint"
  3328  )
  3329  
  3330  func unittest() {
  3331  	select {
  3332  	case <- func () chan bool {
  3333  		failpoint.Goto("11", "22")
  3334  		return make(chan bool, 1)
  3335  	}():
  3336  	}
  3337  }
  3338  `,
  3339  		},
  3340  
  3341  		{
  3342  			filepath: "bad-rewriteStmts-CommClause-Body.go",
  3343  			errormsg: `failpoint\.Goto expect 1 arguments, but got .*`,
  3344  			original: `
  3345  package rewriter_test
  3346  
  3347  import (
  3348  	"fmt"
  3349  
  3350  	"github.com/pingcap/failpoint"
  3351  )
  3352  
  3353  func unittest() {
  3354  	select {
  3355  	case <- ch:
  3356  		failpoint.Goto("11", "22")
  3357  	}
  3358  }
  3359  `,
  3360  		},
  3361  
  3362  		{
  3363  			filepath: "bad-rewriteStmts-SelectStmt-empty.go",
  3364  			errormsg: `failpoint\.Goto expect 1 arguments, but got .*`,
  3365  			original: `
  3366  package rewriter_test
  3367  
  3368  import (
  3369  	"fmt"
  3370  
  3371  	"github.com/pingcap/failpoint"
  3372  )
  3373  
  3374  func unittest() {
  3375  	select {}
  3376  	failpoint.Goto("11", "22")
  3377  }
  3378  `,
  3379  		},
  3380  
  3381  		{
  3382  			filepath: "bad-rewriteStmts-ForStmt-Init.go",
  3383  			errormsg: `failpoint\.Goto expect 1 arguments, but got .*`,
  3384  			original: `
  3385  package rewriter_test
  3386  
  3387  import (
  3388  	"fmt"
  3389  
  3390  	"github.com/pingcap/failpoint"
  3391  )
  3392  
  3393  func unittest() {
  3394  	for i := (func () {
  3395  		failpoint.Goto("11", "22")
  3396  	}());; {}
  3397  }
  3398  `,
  3399  		},
  3400  
  3401  		{
  3402  			filepath: "bad-rewriteStmts-ForStmt-Cond.go",
  3403  			errormsg: `failpoint\.Goto expect 1 arguments, but got .*`,
  3404  			original: `
  3405  package rewriter_test
  3406  
  3407  import (
  3408  	"fmt"
  3409  
  3410  	"github.com/pingcap/failpoint"
  3411  )
  3412  
  3413  func unittest() {
  3414  	for i < (func () {
  3415  		failpoint.Goto("11", "22")
  3416  	}()) {}
  3417  }
  3418  `,
  3419  		},
  3420  
  3421  		{
  3422  			filepath: "bad-rewriteStmts-ForStmt-Post.go",
  3423  			errormsg: `failpoint\.Goto expect 1 arguments, but got .*`,
  3424  			original: `
  3425  package rewriter_test
  3426  
  3427  import (
  3428  	"fmt"
  3429  
  3430  	"github.com/pingcap/failpoint"
  3431  )
  3432  
  3433  func unittest() {
  3434  	for ;;i+=(func () {
  3435  		failpoint.Goto("11", "22")
  3436  	}()) {}
  3437  }
  3438  `,
  3439  		},
  3440  
  3441  		{
  3442  			filepath: "bad-rewriteStmts-ForStmt-Body.go",
  3443  			errormsg: `failpoint\.Goto expect 1 arguments, but got .*`,
  3444  			original: `
  3445  package rewriter_test
  3446  
  3447  import (
  3448  	"fmt"
  3449  
  3450  	"github.com/pingcap/failpoint"
  3451  )
  3452  
  3453  func unittest() {
  3454  	for {
  3455  		failpoint.Goto("11", "22")
  3456  	}
  3457  }
  3458  `,
  3459  		},
  3460  
  3461  		{
  3462  			filepath: "bad-rewriteStmts-RangeStmt-X.go",
  3463  			errormsg: `failpoint\.Goto expect 1 arguments, but got .*`,
  3464  			original: `
  3465  package rewriter_test
  3466  
  3467  import (
  3468  	"fmt"
  3469  
  3470  	"github.com/pingcap/failpoint"
  3471  )
  3472  
  3473  func unittest() {
  3474  	for x := range (func () {
  3475  		failpoint.Goto("11", "22")
  3476  	}()) {}
  3477  }
  3478  `,
  3479  		},
  3480  
  3481  		{
  3482  			filepath: "bad-rewriteStmts-RangeStmt-Body.go",
  3483  			errormsg: `failpoint\.Goto expect 1 arguments, but got .*`,
  3484  			original: `
  3485  package rewriter_test
  3486  
  3487  import (
  3488  	"fmt"
  3489  
  3490  	"github.com/pingcap/failpoint"
  3491  )
  3492  
  3493  func unittest() {
  3494  	for x := range y {
  3495  		failpoint.Goto("11", "22")
  3496  	}
  3497  }
  3498  `,
  3499  		},
  3500  
  3501  		{
  3502  			filepath: "bad-rewriteStmts-TypeSwitchStmt-AssignStmt.go",
  3503  			errormsg: `failpoint\.Goto expect 1 arguments, but got .*`,
  3504  			original: `
  3505  package rewriter_test
  3506  
  3507  import (
  3508  	"fmt"
  3509  
  3510  	"github.com/pingcap/failpoint"
  3511  )
  3512  
  3513  func unittest() {
  3514  	switch x := (func () {
  3515  		failpoint.Goto("11", "22")
  3516  	}()).(type) {}
  3517  }
  3518  `,
  3519  		},
  3520  
  3521  		{
  3522  			filepath: "bad-rewriteStmts-TypeSwitchStmt-ExprStmt.go",
  3523  			errormsg: `failpoint\.Goto expect 1 arguments, but got .*`,
  3524  			original: `
  3525  package rewriter_test
  3526  
  3527  import (
  3528  	"fmt"
  3529  
  3530  	"github.com/pingcap/failpoint"
  3531  )
  3532  
  3533  func unittest() {
  3534  	switch (func () {
  3535  		failpoint.Goto("11", "22")
  3536  	}()).(type) {}
  3537  }
  3538  `,
  3539  		},
  3540  
  3541  		{
  3542  			filepath: "bad-rewriteStmts-TypeSwitchStmt-Body.go",
  3543  			errormsg: `failpoint\.Goto expect 1 arguments, but got .*`,
  3544  			original: `
  3545  package rewriter_test
  3546  
  3547  import (
  3548  	"fmt"
  3549  
  3550  	"github.com/pingcap/failpoint"
  3551  )
  3552  
  3553  func unittest() {
  3554  	switch y.(type) {
  3555  	case x:
  3556  		failpoint.Goto("11", "22")
  3557  	}
  3558  }
  3559  `,
  3560  		},
  3561  
  3562  		{
  3563  			filepath: "bad-rewriteStmts-SendStmt.go",
  3564  			errormsg: `failpoint\.Goto expect 1 arguments, but got .*`,
  3565  			original: `
  3566  package rewriter_test
  3567  
  3568  import (
  3569  	"fmt"
  3570  
  3571  	"github.com/pingcap/failpoint"
  3572  )
  3573  
  3574  func unittest() {
  3575  	a <- func () {
  3576  		failpoint.Goto("11", "22")
  3577  	}()
  3578  }
  3579  `,
  3580  		},
  3581  
  3582  		{
  3583  			filepath: "bad-rewriteStmts-LabeledStmt.go",
  3584  			errormsg: `failpoint\.Goto expect 1 arguments, but got .*`,
  3585  			original: `
  3586  package rewriter_test
  3587  
  3588  import (
  3589  	"fmt"
  3590  
  3591  	"github.com/pingcap/failpoint"
  3592  )
  3593  
  3594  func unittest() {
  3595  label:
  3596  	failpoint.Goto("11", "22")
  3597  }
  3598  `,
  3599  		},
  3600  	}
  3601  
  3602  	// Create temp files
  3603  	err := os.MkdirAll(rewritePath, 0755)
  3604  	require.NoError(t, err)
  3605  	for _, cs := range cases {
  3606  		original := filepath.Join(rewritePath, cs.filepath)
  3607  		err := ioutil.WriteFile(original, []byte(cs.original), 0644)
  3608  		require.NoError(t, err)
  3609  	}
  3610  
  3611  	// Clean all temp files
  3612  	defer func() {
  3613  		err := os.RemoveAll(rewritePath)
  3614  		require.NoError(t, err)
  3615  	}()
  3616  
  3617  	// Workspace should keep clean if some error occurred
  3618  	for _, cs := range cases {
  3619  		original := filepath.Join(rewritePath, cs.filepath)
  3620  		rewriter := code.NewRewriter(original)
  3621  		err = rewriter.Rewrite()
  3622  		require.Error(t, err)
  3623  		require.Regexp(t, cs.errormsg, err.Error(), "%v", cs.filepath)
  3624  
  3625  		content, err := ioutil.ReadFile(original)
  3626  		require.NoError(t, err)
  3627  		require.Equalf(t, cs.original, string(content), "%v", cs.filepath)
  3628  	}
  3629  }