AlexStocks commented on code in PR #3612:
URL: https://github.com/apache/dubbo-go/pull/3612#discussion_r3853324850
##########
config_center/zookeeper/impl_test.go:
##########
@@ -126,6 +138,335 @@ func TestGetPropertiesWithMockZk(t *testing.T) {
require.Empty(t, empty)
}
+func TestLoadPropertiesRegistersWatchOnlyWhenInactive(t *testing.T) {
+ cluster, client, events, err :=
gxzookeeper.NewMockZookeeperClient("watch-selection", 5*time.Second)
+ if err != nil {
+ t.Skipf("skip mock zk setup: %v", err)
+ }
+ defer cluster.Stop()
+
+ cfg := &zookeeperDynamicConfiguration{
+ rootPath: "/dubbo/config",
+ client: client,
+ url: mustURL(t, "registry://127.0.0.1:2181"),
+ cache: newConfigCache(time.Minute),
+ }
+ activePath := cfg.getPath("active", "group")
+ inactivePath := cfg.getPath("inactive", "group")
+ require.NoError(t, cfg.PublishConfig("active", "group", "v1"))
+ require.NoError(t, cfg.PublishConfig("inactive", "group", "v1"))
+
+ waitForEvent := func(path string, timeout time.Duration) bool {
+ timer := time.NewTimer(timeout)
+ defer timer.Stop()
+ for {
+ select {
+ case event := <-events:
+ if event.Path == path && event.Type ==
zk.EventNodeDataChanged {
+ return true
+ }
+ case <-timer.C:
+ return false
+ }
+ }
+ }
+
+ activeWatcher := &zk.Watcher{}
+ _, watcher, err := cfg.loadProperties(activePath, activeWatcher, false)
+ require.NoError(t, err)
+ require.Same(t, activeWatcher, watcher)
+ _, stat, err := client.GetContent(activePath)
+ require.NoError(t, err)
+ _, err = client.SetContent(activePath, []byte("v2"), stat.Version)
+ require.NoError(t, err)
+ require.False(t, waitForEvent(activePath, time.Second))
+
+ _, watcher, err = cfg.loadProperties(inactivePath, nil, true)
+ require.NoError(t, err)
+ require.NotNil(t, watcher)
+ _, stat, err = client.GetContent(inactivePath)
+ require.NoError(t, err)
+ _, err = client.SetContent(inactivePath, []byte("v2"), stat.Version)
+ require.NoError(t, err)
+ require.True(t, waitForEvent(inactivePath, time.Second))
+}
+
+func TestListenerUsesGroupOption(t *testing.T) {
+ cluster, client, _, err :=
gxzookeeper.NewMockZookeeperClient("listener-group", 5*time.Second)
+ if err != nil {
+ t.Skipf("skip mock zk setup: %v", err)
+ }
+ defer cluster.Stop()
+
+ zkListener := remotingzookeeper.NewZkEventListener(client)
+ defer zkListener.Close()
+ cfg := &zookeeperDynamicConfiguration{
+ rootPath: "/dubbo/config",
+ client: client,
+ url: mustURL(t, "registry://127.0.0.1:2181"),
+ cache: newConfigCache(time.Minute),
+ listener: zkListener,
+ }
+ cfg.cacheListener = newCacheListener(cfg.rootPath, zkListener,
&cfg.cache)
+ key := "app.properties"
+ group := "custom"
+ path := cfg.getPropertiesPath(key, config_center.WithGroup(group))
+ rec := &recListener{}
+
+ cfg.AddListener(key, rec, config_center.WithGroup(group))
+ _, ok := cfg.cacheListener.keyListeners.Load(path)
+ require.True(t, ok)
+
+ cfg.RemoveListener(key, rec, config_center.WithGroup(group))
+ _, ok = cfg.cacheListener.keyListeners.Load(path)
+ require.False(t, ok)
+}
+
+func TestGetPropertiesFallsBackToTTLAtAutoWatchLimit(t *testing.T) {
+ cluster, client, events, err :=
gxzookeeper.NewMockZookeeperClient("watch-limit", 5*time.Second)
+ if err != nil {
+ t.Skipf("skip mock zk setup: %v", err)
+ }
+ defer cluster.Stop()
+
+ cfg := &zookeeperDynamicConfiguration{
+ rootPath: "/dubbo/config",
+ client: client,
+ url: mustURL(t, "registry://127.0.0.1:2181"),
+ cache: newConfigCache(time.Minute),
+ }
+ for i := range maxAutoWatches {
+ require.True(t, cfg.cache.setWatch(fmt.Sprintf("/watch/%d", i),
configWatchState{
+ watcher: &zk.Watcher{},
+ auto: true,
+ }))
+ }
+
+ require.NoError(t, cfg.PublishConfig("fallback", "group", "v1"))
+ value, err := cfg.GetProperties("fallback",
config_center.WithGroup("group"))
+ require.NoError(t, err)
+ require.Equal(t, "v1", value)
+
+ path := cfg.getPath("fallback", "group")
+ _, watchState := cfg.cache.snapshot(path)
+ require.False(t, watchState.tracked())
+ require.Equal(t, maxAutoWatches, cfg.cache.autoWatchCount)
+ require.Zero(t, cfg.cache.autoWatchReservations)
+ _, stat, err := client.GetContent(path)
+ require.NoError(t, err)
+ _, err = client.SetContent(path, []byte("v2"), stat.Version)
+ require.NoError(t, err)
+
+ timer := time.NewTimer(100 * time.Millisecond)
+ defer timer.Stop()
+ for {
+ select {
+ case event := <-events:
+ if event.Path == path && event.Type ==
zk.EventNodeDataChanged {
+ t.Fatal("TTL fallback should not register an
auto watch")
+ }
+ case <-timer.C:
+ value, err = cfg.GetProperties("fallback",
config_center.WithGroup("group"))
+ require.NoError(t, err)
+ require.Equal(t, "v1", value)
+ return
+ }
+ }
+}
+
+func TestGetPropertiesCacheUpdatedByWatch(t *testing.T) {
+ cluster, client, _, err :=
gxzookeeper.NewMockZookeeperClient("cache-watch", 5*time.Second)
+ if err != nil {
+ t.Skipf("skip mock zk setup: %v", err)
+ }
+ defer cluster.Stop()
+ go (&gxzookeeper.DefaultHandler{}).HandleZkEvent(client)
+
+ cfg := &zookeeperDynamicConfiguration{
+ rootPath: "/dubbo/config",
+ client: client,
+ done: make(chan struct{}),
+ url: mustURL(t, "registry://127.0.0.1:2181"),
+ cache: newConfigCache(time.Minute),
+ }
+ cfg.listener = remotingzookeeper.NewZkEventListener(client)
+ cfg.cacheListener = newCacheListener(cfg.rootPath, cfg.listener,
&cfg.cache)
+ cfg.listener.ListenConfigurationEvent(cfg.rootPath, cfg.cacheListener)
+ defer cfg.listener.Close()
Review Comment:
[P1] CI 的 ZooKeeper 严格门禁仍可被 Skip 成绿色
workflow 这里只导出了 `ZOOKEEPER_PATH`,但 `failOrSkipZkUnavailable` 只有在 `ZK_ADDR`
非空时才 `Fatalf`。因此 CI 中 Java、fat jar、启动或连接失败时,这些真实 ZooKeeper 用例仍会 `Skip`,`make
test`/`make test-race` 继续成功。exact Head 对照中,`ZK_ADDR` 未设置时同一用例连接失败后显示 `SKIP` 且退出
0;设置不可用的 `ZK_ADDR=127.0.0.1:1` 后才退出 1。当前 Unit Test 日志里该包非 race 仅 0.123
秒,也没有执行至少包含 1 秒负等待的 watch-selection 用例。请增加独立 CI strict 标记,或让 `ZOOKEEPER_PATH`
同样触发失败模式,并核对这些核心用例实际为 PASS。
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]