github.com/tencent/goom@v1.0.1/internal/patch/monkey_test.go (about)

     1  // Package patch_test patch 功能测试
     2  package patch_test
     3  
     4  import (
     5  	"reflect"
     6  	"runtime"
     7  	"testing"
     8  	"time"
     9  
    10  	"github.com/tencent/goom/internal/logger"
    11  	"github.com/tencent/goom/internal/patch"
    12  	"github.com/tencent/goom/internal/patch/test"
    13  
    14  	"github.com/stretchr/testify/assert"
    15  )
    16  
    17  // init 初始化
    18  func init() {
    19  	logger.SetLog2Console(true)
    20  }
    21  
    22  // TestTimePatch timePatch 测试
    23  func TestTimePatch(t *testing.T) {
    24  	before := time.Now()
    25  
    26  	guard, err := patch.Patch(time.Now, func() time.Time {
    27  		return time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC)
    28  	})
    29  	if err != nil {
    30  		t.Error(err)
    31  	}
    32  
    33  	guard.Apply()
    34  
    35  	during := time.Now()
    36  	assert.True(t, patch.Unpatch(time.Now))
    37  	after := time.Now()
    38  
    39  	assert.Equal(t, time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC), during)
    40  	assert.NotEqual(t, before, during)
    41  	assert.NotEqual(t, during, after)
    42  }
    43  
    44  // TestGC GC 测试
    45  func TestGC(t *testing.T) {
    46  	value := true
    47  	g, _ := patch.Patch(test.No, func() bool {
    48  		return value
    49  	})
    50  	g.Apply()
    51  
    52  	defer patch.UnpatchAll()
    53  	runtime.GC()
    54  	assert.True(t, test.No())
    55  }
    56  
    57  // TestSimple 测试降低函数
    58  func TestSimple(t *testing.T) {
    59  	assert.False(t, test.No())
    60  	g, _ := patch.Patch(test.No, test.Yes)
    61  	g.Apply()
    62  	assert.True(t, test.No())
    63  	assert.True(t, patch.Unpatch(test.No))
    64  	assert.False(t, test.No())
    65  	assert.False(t, patch.Unpatch(test.No))
    66  }
    67  
    68  // TestGuard 测试 guard.Apply()
    69  func TestGuard(t *testing.T) {
    70  	var guard *patch.Guard
    71  	guard, _ = patch.Patch(test.No, func() bool {
    72  		guard.Unpatch()
    73  		defer guard.Restore()
    74  		return !test.No()
    75  	})
    76  	guard.Apply()
    77  
    78  	for i := 0; i < 100; i++ {
    79  		assert.True(t, test.No())
    80  	}
    81  	patch.Unpatch(test.No)
    82  }
    83  
    84  // TestUnpatchAll 测试取消 patch
    85  func TestUnpatchAll(t *testing.T) {
    86  	assert.False(t, test.No())
    87  	g, _ := patch.Patch(test.No, test.Yes)
    88  	g.Apply()
    89  	assert.True(t, test.No())
    90  	patch.UnpatchAll()
    91  	assert.False(t, test.No())
    92  }
    93  
    94  // TestWithInstanceMethod 测试实例方法
    95  func TestWithInstanceMethod(t *testing.T) {
    96  	i := &test.S{}
    97  
    98  	assert.False(t, test.No())
    99  
   100  	g, _ := patch.Patch(test.No, i.Yes)
   101  	g.Apply()
   102  
   103  	assert.True(t, test.No())
   104  
   105  	patch.Unpatch(test.No)
   106  	assert.False(t, test.No())
   107  }
   108  
   109  // TestOnInstanceMethod 测试实例方法
   110  func TestOnInstanceMethod(t *testing.T) {
   111  	i := &test.F{}
   112  	assert.False(t, i.No())
   113  	g, _ := patch.InstanceMethod(reflect.TypeOf(i), "No", func(_ *test.F) bool { return true })
   114  	g.Apply()
   115  	assert.True(t, i.No())
   116  	assert.True(t, patch.UnpatchInstanceMethod(reflect.TypeOf(i), "No"))
   117  	assert.False(t, i.No())
   118  }
   119  
   120  // TestNotFunction 测试 patch 到非函数类型
   121  func TestNotFunction(t *testing.T) {
   122  	assert.Panics(t, func() {
   123  		g, _ := patch.Patch(test.No, 1)
   124  		g.Apply()
   125  	})
   126  	assert.Panics(t, func() {
   127  		g, _ := patch.Patch(1, test.Yes)
   128  		g.Apply()
   129  	})
   130  }
   131  
   132  // TestNotCompatible 测试 patch 到参数不一致的函数
   133  func TestNotCompatible(t *testing.T) {
   134  	assert.Panics(t, func() {
   135  		g, _ := patch.Patch(test.No(), func() {})
   136  		g.Apply()
   137  	})
   138  }