github.com/zly-app/zapp@v1.3.3/config/watch_test.go (about)

     1  package config
     2  
     3  import (
     4  	"fmt"
     5  	"sync"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/stretchr/testify/require"
    10  
    11  	"github.com/zly-app/zapp/core"
    12  )
    13  
    14  func init() {
    15  	watchWaitWG.Done()
    16  }
    17  
    18  // 测试提供者
    19  type TestWatchProvider struct {
    20  	data              map[string]map[string][]byte // 表示组下的key的数据
    21  	changeDataHandler func(oldData []byte) []byte
    22  	mx                sync.Mutex
    23  }
    24  
    25  // 创建测试提供者
    26  func NewTestWatchProvider(data map[string]map[string][]byte) *TestWatchProvider {
    27  	p := &TestWatchProvider{
    28  		data: data,
    29  	}
    30  	return p
    31  }
    32  func (t *TestWatchProvider) Get(groupName, keyName string) ([]byte, error) {
    33  	t.mx.Lock()
    34  	defer t.mx.Unlock()
    35  
    36  	g, ok := t.data[groupName]
    37  	if !ok {
    38  		return nil, fmt.Errorf("not found group: %s", groupName)
    39  	}
    40  
    41  	data, ok := g[keyName]
    42  	if !ok {
    43  		return nil, fmt.Errorf("not found key: %s.%s", groupName, keyName)
    44  	}
    45  
    46  	return data, nil
    47  }
    48  func (t *TestWatchProvider) Set(groupName, keyName string, data []byte) error {
    49  	t.mx.Lock()
    50  	defer t.mx.Unlock()
    51  
    52  	g, ok := t.data[groupName]
    53  	if !ok {
    54  		g = make(map[string][]byte)
    55  		t.data[groupName] = g
    56  	}
    57  
    58  	g[keyName] = data
    59  	return nil
    60  }
    61  func (t *TestWatchProvider) Watch(groupName, keyName string, callback core.ConfigWatchProviderCallback) error {
    62  	go func(groupName, keyName string, callback core.ConfigWatchProviderCallback) {
    63  		time.Sleep(time.Millisecond * 200)
    64  		t.mx.Lock()
    65  		oldData := t.getData(groupName, keyName)
    66  		newData := t.changeDataHandler(oldData)
    67  		t.data[groupName][keyName] = newData
    68  		t.mx.Unlock()
    69  		callback(groupName, keyName, oldData, newData)
    70  	}(groupName, keyName, callback)
    71  	return nil
    72  }
    73  func (t *TestWatchProvider) getData(groupName, keyName string) []byte {
    74  	g, ok := t.data[groupName]
    75  	if !ok {
    76  		return nil
    77  	}
    78  	return g[keyName]
    79  }
    80  
    81  var testProvider *TestWatchProvider
    82  
    83  func init() {
    84  	p := NewTestWatchProvider(map[string]map[string][]byte{})
    85  	p.changeDataHandler = func(oldData []byte) []byte {
    86  		newData := make([]byte, len(oldData)*2)
    87  		copy(newData, oldData)
    88  		copy(newData[len(oldData):], oldData)
    89  		return newData
    90  	}
    91  	testProvider = p
    92  	RegistryConfigWatchProvider("test", p)
    93  	SetDefaultConfigWatchProvider(p)
    94  }
    95  
    96  func TestSDK(t *testing.T) {
    97  	testGroupName := "g1"
    98  	testKeyName := "k1"
    99  
   100  	err := testProvider.Set(testGroupName, testKeyName, []byte("1"))
   101  	require.Nil(t, err)
   102  
   103  	keyObj := newWatchKeyObject(testGroupName, testKeyName)
   104  
   105  	// 获取原始数据
   106  	y1 := keyObj.GetString()
   107  	require.Equal(t, "1", y1)
   108  
   109  	// 转为 int 值
   110  	y2 := keyObj.GetInt()
   111  	require.Equal(t, 1, y2)
   112  
   113  	// 转为 boolean 值
   114  	y3 := keyObj.GetBool()
   115  	require.Equal(t, true, y3)
   116  
   117  	// 检查复合预期
   118  	b1 := keyObj.Expect("1")
   119  	require.Equal(t, true, b1)
   120  	b2 := keyObj.Expect(1)
   121  	require.Equal(t, true, b2)
   122  	b3 := keyObj.Expect(true)
   123  	require.Equal(t, true, b3)
   124  }
   125  
   126  func TestWatch(t *testing.T) {
   127  	testGroupName := "g2"
   128  	testKeyName := "k2"
   129  
   130  	err := testProvider.Set(testGroupName, testKeyName, []byte("2"))
   131  	require.Nil(t, err)
   132  
   133  	keyObj := newWatchKeyObject(testGroupName, testKeyName)
   134  
   135  	var isCallback bool
   136  	expectFirst := true
   137  	expectOldData := "2"
   138  	expectNewData := "2"
   139  	keyObj.AddCallback(func(first bool, oldData, newData []byte) {
   140  		isCallback = true
   141  		require.Equal(t, expectFirst, first)
   142  		require.Equal(t, expectOldData, string(oldData))
   143  		require.Equal(t, expectNewData, string(newData))
   144  	})
   145  	require.Nil(t, err)
   146  
   147  	require.True(t, isCallback)
   148  	require.Equal(t, expectNewData, keyObj.GetString())
   149  
   150  	isCallback = false
   151  	expectFirst = false
   152  	expectOldData = "2"
   153  	expectNewData = "22"
   154  	time.Sleep(time.Millisecond * 300)
   155  	require.True(t, isCallback)
   156  	require.Equal(t, expectNewData, keyObj.GetString())
   157  }
   158  
   159  func TestExpect(t *testing.T) {
   160  	testGroupName := "g3"
   161  	testKeyName := "k3"
   162  
   163  	err := testProvider.Set(testGroupName, testKeyName, []byte("1"))
   164  	require.Nil(t, err)
   165  
   166  	keyObj := newWatchKeyObject(testGroupName, testKeyName)
   167  
   168  	var tests = []struct {
   169  		expect interface{}
   170  		result bool
   171  	}{
   172  		{[]byte("1"), true},
   173  		{"1", true},
   174  		{[]rune("1"), true},
   175  		{true, true},
   176  		{1, true},
   177  		{int8(1), true},
   178  		{int16(1), true},
   179  		{int32(1), true},
   180  		{int64(1), true},
   181  		{uint(1), true},
   182  		{uint8(1), true},
   183  		{uint16(1), true},
   184  		{uint32(1), true},
   185  		{uint64(1), true},
   186  		{float32(1), true},
   187  		{float64(1), true},
   188  
   189  		{[]byte("2"), false},
   190  		{"2", false},
   191  		{[]rune("2"), false},
   192  		{false, false},
   193  		{2, false},
   194  		{int8(2), false},
   195  		{int16(2), false},
   196  		{int32(2), false},
   197  		{int64(2), false},
   198  		{uint(2), false},
   199  		{uint8(2), false},
   200  		{uint16(2), false},
   201  		{uint32(2), false},
   202  		{uint64(2), false},
   203  		{float32(2), false},
   204  		{float64(2), false},
   205  	}
   206  
   207  	for _, test := range tests {
   208  		result := keyObj.Expect(test.expect)
   209  		require.Equal(t, result, test.result)
   210  	}
   211  }
   212  
   213  func TestConvert(t *testing.T) {
   214  	testGroupName := "g4"
   215  	testKeyName := "k4"
   216  
   217  	err := testProvider.Set(testGroupName, testKeyName, []byte("4"))
   218  	require.Nil(t, err)
   219  
   220  	keyObj := newWatchKeyObject(testGroupName, testKeyName)
   221  
   222  	require.Equal(t, []byte("4"), keyObj.GetData())
   223  	require.Equal(t, "4", keyObj.GetString())
   224  	require.Equal(t, false, keyObj.GetBool())
   225  	require.Equal(t, true, keyObj.GetBool(true))
   226  	require.Equal(t, 4, keyObj.GetInt())
   227  	require.Equal(t, int8(4), keyObj.GetInt8())
   228  	require.Equal(t, int16(4), keyObj.GetInt16())
   229  	require.Equal(t, int32(4), keyObj.GetInt32())
   230  	require.Equal(t, int64(4), keyObj.GetInt64())
   231  	require.Equal(t, uint(4), keyObj.GetUint())
   232  	require.Equal(t, uint8(4), keyObj.GetUint8())
   233  	require.Equal(t, uint16(4), keyObj.GetUint16())
   234  	require.Equal(t, uint32(4), keyObj.GetUint32())
   235  	require.Equal(t, uint64(4), keyObj.GetUint64())
   236  	require.Equal(t, float32(4), keyObj.GetFloat32())
   237  	require.Equal(t, float64(4), keyObj.GetFloat64())
   238  }
   239  
   240  func TestParseJSON(t *testing.T) {
   241  	testGroupName := "g5"
   242  	testKeyName := "k5"
   243  
   244  	value := `{"a": 1, "b": {"c": ["x", "y", "z"]}}`
   245  	err := testProvider.Set(testGroupName, testKeyName, []byte(value))
   246  	require.Nil(t, err)
   247  
   248  	keyObj := newWatchKeyObject(testGroupName, testKeyName)
   249  
   250  	require.Equal(t, keyObj.GetString(), value)
   251  
   252  	var a struct {
   253  		A int `json:"a"`
   254  		B struct {
   255  			C []string `json:"c"`
   256  		} `json:"b"`
   257  	}
   258  	err = keyObj.ParseJSON(&a)
   259  	require.Nil(t, err)
   260  	require.Equal(t, 1, a.A)
   261  	require.Equal(t, []string{"x", "y", "z"}, a.B.C)
   262  }
   263  
   264  func TestParseYaml(t *testing.T) {
   265  	testGroupName := "g6"
   266  	testKeyName := "k6"
   267  
   268  	value := `
   269  a: 1
   270  b:
   271    c:
   272      - x
   273      - y
   274      - z`
   275  	err := testProvider.Set(testGroupName, testKeyName, []byte(value))
   276  	require.Nil(t, err)
   277  
   278  	keyObj := newWatchKeyObject(testGroupName, testKeyName)
   279  
   280  	require.Equal(t, keyObj.GetString(), value)
   281  
   282  	var a struct {
   283  		A int `json:"a"`
   284  		B struct {
   285  			C []string `json:"c"`
   286  		} `json:"b"`
   287  	}
   288  	err = keyObj.ParseYaml(&a)
   289  	require.Nil(t, err)
   290  	require.Equal(t, 1, a.A)
   291  	require.Equal(t, []string{"x", "y", "z"}, a.B.C)
   292  }
   293  
   294  func TestGenericSDKJson(t *testing.T) {
   295  	testGroupName := "g1"
   296  	testKeyName := "k1"
   297  
   298  	rawData := []byte(`{"a":1}`)
   299  	err := testProvider.Set(testGroupName, testKeyName, rawData)
   300  	require.Nil(t, err)
   301  
   302  	type AA struct {
   303  		A int `json:"a"`
   304  	}
   305  
   306  	keyObj := WatchJson[*AA](testGroupName, testKeyName)
   307  	require.NotNil(t, keyObj)
   308  	require.Equal(t, 1, keyObj.Get().A)
   309  	require.Equal(t, rawData, keyObj.GetData())
   310  }
   311  
   312  func TestGenericSDKYaml(t *testing.T) {
   313  	testGroupName := "g1"
   314  	testKeyName := "k1"
   315  
   316  	rawData := []byte(`a: 1`)
   317  	err := testProvider.Set(testGroupName, testKeyName, rawData)
   318  	require.Nil(t, err)
   319  
   320  	type AA struct {
   321  		A int `yaml:"a"`
   322  	}
   323  
   324  	keyObj := WatchYaml[*AA](testGroupName, testKeyName)
   325  	require.NotNil(t, keyObj)
   326  	require.Equal(t, 1, keyObj.Get().A)
   327  	require.Equal(t, rawData, keyObj.GetData())
   328  }
   329  
   330  func TestGenericWatchJson(t *testing.T) {
   331  	testGroupName := "g1"
   332  	testKeyName := "k1"
   333  
   334  	rawData := []byte(`{"a":1}`)
   335  	err := testProvider.Set(testGroupName, testKeyName, rawData)
   336  	require.Nil(t, err)
   337  
   338  	type AA struct {
   339  		A int `json:"a"`
   340  	}
   341  
   342  	keyObj := WatchJson[*AA](testGroupName, testKeyName)
   343  	require.NotNil(t, keyObj)
   344  	require.Equal(t, 1, keyObj.Get().A)
   345  	require.Equal(t, rawData, keyObj.GetData())
   346  
   347  	var isCallback bool
   348  	expectFirst := true
   349  	expectOldData := 1
   350  	expectNewData := 1
   351  	keyObj.AddCallback(func(first bool, oldData, newData *AA) {
   352  		isCallback = true
   353  		require.Equal(t, expectFirst, first)
   354  		require.Equal(t, expectOldData, oldData.A)
   355  		require.Equal(t, expectNewData, newData.A)
   356  	})
   357  	require.Nil(t, err)
   358  
   359  	require.True(t, isCallback)
   360  	require.Equal(t, expectNewData, keyObj.Get().A)
   361  	require.Equal(t, rawData, keyObj.GetData())
   362  
   363  	rawData = []byte(`{"a":2}`)
   364  	testProvider.changeDataHandler = func(oldData []byte) []byte {
   365  		return rawData
   366  	}
   367  
   368  	isCallback = false
   369  	expectFirst = false
   370  	expectOldData = 1
   371  	expectNewData = 2
   372  	time.Sleep(time.Millisecond * 300)
   373  	require.True(t, isCallback)
   374  	require.Equal(t, expectNewData, keyObj.Get().A)
   375  	require.Equal(t, rawData, keyObj.GetData())
   376  }
   377  
   378  func TestGenericWatchYaml(t *testing.T) {
   379  	testGroupName := "g1"
   380  	testKeyName := "k1"
   381  
   382  	rawData := []byte(`a: 1`)
   383  	err := testProvider.Set(testGroupName, testKeyName, rawData)
   384  	require.Nil(t, err)
   385  
   386  	type AA struct {
   387  		A int `yaml:"a"`
   388  	}
   389  
   390  	keyObj := WatchYaml[*AA](testGroupName, testKeyName)
   391  	require.NotNil(t, keyObj)
   392  	require.Equal(t, 1, keyObj.Get().A)
   393  	require.Equal(t, rawData, keyObj.GetData())
   394  
   395  	var isCallback bool
   396  	expectFirst := true
   397  	expectOldData := 1
   398  	expectNewData := 1
   399  	keyObj.AddCallback(func(first bool, oldData, newData *AA) {
   400  		isCallback = true
   401  		require.Equal(t, expectFirst, first)
   402  		require.Equal(t, expectOldData, oldData.A)
   403  		require.Equal(t, expectNewData, newData.A)
   404  	})
   405  	require.Nil(t, err)
   406  
   407  	require.True(t, isCallback)
   408  	require.Equal(t, expectNewData, keyObj.Get().A)
   409  	require.Equal(t, rawData, keyObj.GetData())
   410  
   411  	rawData = []byte(`a: 2`)
   412  	testProvider.changeDataHandler = func(oldData []byte) []byte {
   413  		return rawData
   414  	}
   415  
   416  	isCallback = false
   417  	expectFirst = false
   418  	expectOldData = 1
   419  	expectNewData = 2
   420  	time.Sleep(time.Millisecond * 300)
   421  	require.True(t, isCallback)
   422  	require.Equal(t, expectNewData, keyObj.Get().A)
   423  	require.Equal(t, rawData, keyObj.GetData())
   424  }