github.com/lingyao2333/mo-zero@v1.4.1/core/discov/subscriber_test.go (about)

     1  package discov
     2  
     3  import (
     4  	"sync/atomic"
     5  	"testing"
     6  
     7  	"github.com/lingyao2333/mo-zero/core/discov/internal"
     8  	"github.com/lingyao2333/mo-zero/core/stringx"
     9  	"github.com/stretchr/testify/assert"
    10  )
    11  
    12  const (
    13  	actionAdd = iota
    14  	actionDel
    15  )
    16  
    17  func TestContainer(t *testing.T) {
    18  	type action struct {
    19  		act int
    20  		key string
    21  		val string
    22  	}
    23  	tests := []struct {
    24  		name   string
    25  		do     []action
    26  		expect []string
    27  	}{
    28  		{
    29  			name: "add one",
    30  			do: []action{
    31  				{
    32  					act: actionAdd,
    33  					key: "first",
    34  					val: "a",
    35  				},
    36  			},
    37  			expect: []string{
    38  				"a",
    39  			},
    40  		},
    41  		{
    42  			name: "add two",
    43  			do: []action{
    44  				{
    45  					act: actionAdd,
    46  					key: "first",
    47  					val: "a",
    48  				},
    49  				{
    50  					act: actionAdd,
    51  					key: "second",
    52  					val: "b",
    53  				},
    54  			},
    55  			expect: []string{
    56  				"a",
    57  				"b",
    58  			},
    59  		},
    60  		{
    61  			name: "add two, delete one",
    62  			do: []action{
    63  				{
    64  					act: actionAdd,
    65  					key: "first",
    66  					val: "a",
    67  				},
    68  				{
    69  					act: actionAdd,
    70  					key: "second",
    71  					val: "b",
    72  				},
    73  				{
    74  					act: actionDel,
    75  					key: "first",
    76  				},
    77  			},
    78  			expect: []string{"b"},
    79  		},
    80  		{
    81  			name: "add two, delete two",
    82  			do: []action{
    83  				{
    84  					act: actionAdd,
    85  					key: "first",
    86  					val: "a",
    87  				},
    88  				{
    89  					act: actionAdd,
    90  					key: "second",
    91  					val: "b",
    92  				},
    93  				{
    94  					act: actionDel,
    95  					key: "first",
    96  				},
    97  				{
    98  					act: actionDel,
    99  					key: "second",
   100  				},
   101  			},
   102  			expect: []string{},
   103  		},
   104  		{
   105  			name: "add three, dup values, delete two",
   106  			do: []action{
   107  				{
   108  					act: actionAdd,
   109  					key: "first",
   110  					val: "a",
   111  				},
   112  				{
   113  					act: actionAdd,
   114  					key: "second",
   115  					val: "b",
   116  				},
   117  				{
   118  					act: actionAdd,
   119  					key: "third",
   120  					val: "a",
   121  				},
   122  				{
   123  					act: actionDel,
   124  					key: "first",
   125  				},
   126  				{
   127  					act: actionDel,
   128  					key: "second",
   129  				},
   130  			},
   131  			expect: []string{"a"},
   132  		},
   133  		{
   134  			name: "add three, dup values, delete two, delete not added",
   135  			do: []action{
   136  				{
   137  					act: actionAdd,
   138  					key: "first",
   139  					val: "a",
   140  				},
   141  				{
   142  					act: actionAdd,
   143  					key: "second",
   144  					val: "b",
   145  				},
   146  				{
   147  					act: actionAdd,
   148  					key: "third",
   149  					val: "a",
   150  				},
   151  				{
   152  					act: actionDel,
   153  					key: "first",
   154  				},
   155  				{
   156  					act: actionDel,
   157  					key: "second",
   158  				},
   159  				{
   160  					act: actionDel,
   161  					key: "forth",
   162  				},
   163  			},
   164  			expect: []string{"a"},
   165  		},
   166  	}
   167  
   168  	exclusives := []bool{true, false}
   169  	for _, test := range tests {
   170  		for _, exclusive := range exclusives {
   171  			t.Run(test.name, func(t *testing.T) {
   172  				var changed bool
   173  				c := newContainer(exclusive)
   174  				c.addListener(func() {
   175  					changed = true
   176  				})
   177  				assert.Nil(t, c.getValues())
   178  				assert.False(t, changed)
   179  
   180  				for _, order := range test.do {
   181  					if order.act == actionAdd {
   182  						c.OnAdd(internal.KV{
   183  							Key: order.key,
   184  							Val: order.val,
   185  						})
   186  					} else {
   187  						c.OnDelete(internal.KV{
   188  							Key: order.key,
   189  							Val: order.val,
   190  						})
   191  					}
   192  				}
   193  
   194  				assert.True(t, changed)
   195  				assert.True(t, c.dirty.True())
   196  				assert.ElementsMatch(t, test.expect, c.getValues())
   197  				assert.False(t, c.dirty.True())
   198  				assert.ElementsMatch(t, test.expect, c.getValues())
   199  			})
   200  		}
   201  	}
   202  }
   203  
   204  func TestSubscriber(t *testing.T) {
   205  	sub := new(Subscriber)
   206  	Exclusive()(sub)
   207  	sub.items = newContainer(sub.exclusive)
   208  	var count int32
   209  	sub.AddListener(func() {
   210  		atomic.AddInt32(&count, 1)
   211  	})
   212  	sub.items.notifyChange()
   213  	assert.Empty(t, sub.Values())
   214  	assert.Equal(t, int32(1), atomic.LoadInt32(&count))
   215  }
   216  
   217  func TestWithSubEtcdAccount(t *testing.T) {
   218  	endpoints := []string{"localhost:2379"}
   219  	user := stringx.Rand()
   220  	WithSubEtcdAccount(user, "bar")(&Subscriber{
   221  		endpoints: endpoints,
   222  	})
   223  	account, ok := internal.GetAccount(endpoints)
   224  	assert.True(t, ok)
   225  	assert.Equal(t, user, account.User)
   226  	assert.Equal(t, "bar", account.Pass)
   227  }