mirror of
https://gitee.com/johng/gf
synced 2026-06-07 02:12:11 +08:00
This pull request standardizes the use of the Go 1.18+ `any` type alias
instead of `interface{}` throughout the codebase. The change improves
code readability and aligns with modern Go best practices. The update
touches many files, including core data structures, code generation
templates, logging utilities, and test data, ensuring consistency across
all usages.
**Type alias migration to `any`:**
* Replaced all instances of `interface{}` with `any` in core data
structures such as `garray` and in generated model structs (e.g.,
`TableUser`, `User1`, `User2`) to modernize type usage.
[[1]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L31-R31)
[[2]](diffhunk://#diff-6c19859cb32c7516ea95ddc8f8235460818eb2f24d2204308e0d9e1b19e7d90fL15-R19)
[[3]](diffhunk://#diff-a15ba2f5e830b4833c47b902515a4f9e5a4f83a3707698f3229b307ec3776b41L15-R18)
[[4]](diffhunk://#diff-52e0837e84d49221d1b810d88fdf78221f36cffcd664fb42f8aba49a79b974dcL15-R19)
[[5]](diffhunk://#diff-11c3457d1a23a4ca6ecd00d6b856289774936b6a708384cf03aff164044e7546L15-R19)
[[6]](diffhunk://#diff-2cff9cf8e6a0cc34087326d8c8149c3bbaf74c76fdbdf5a73daed13cc04249e1L15-R19)
* Updated function signatures, method parameters, and return types from
`interface{}` to `any` in various parts of the codebase, including code
generation, service logic, and logging utilities (e.g., `mlog`).
[[1]](diffhunk://#diff-175edfeea54490b8fe4e18ffcbea5835efaf8f0b8acf623359073987cae7eb76L48-R55)
[[2]](diffhunk://#diff-2b1953fb78cf3593d8c2c7d911e95b65fd0b847c30ed0b4d167d16fe6d781235L54-R74)
[[3]](diffhunk://#diff-e001b7a4b63603b9b14f00de78a4d570bb76c5f57d856a24643f071032e12356L66-R73)
[[4]](diffhunk://#diff-5582954e8a9983988dc8854ad82067fb2ac6269b988e07357ad8db1dfec5f1a0L39-R41)
[[5]](diffhunk://#diff-c5d51d56f487779a2b6207c7ad26c7a20bbadcc846ce094fe60ab4cabff58c51L107-R107)
[[6]](diffhunk://#diff-f96e6a9fdb416eb1804ceaba1fe0ac637bff22c43837f8bb849c2366ce72d4a1L116-R121)
[[7]](diffhunk://#diff-f94c83a1b08ae060d9346f4a6031fc4a7b9a0b894e02d9afaa09018b6598eac0L112-R112)
[[8]](diffhunk://#diff-748b11dbe8828dd4c040ec23cae0b8fe57ecf0a2d1b7694ea39102294e633c64L36-R36)
[[9]](diffhunk://#diff-748b11dbe8828dd4c040ec23cae0b8fe57ecf0a2d1b7694ea39102294e633c64L74-R74)
[[10]](diffhunk://#diff-748b11dbe8828dd4c040ec23cae0b8fe57ecf0a2d1b7694ea39102294e633c64L96-R96)
**Generated code and templates:**
* Adjusted generated files and code generation templates to output `any`
instead of `interface{}` for relevant struct fields and function
signatures, ensuring that new code generation aligns with the updated
convention.
[[1]](diffhunk://#diff-6c19859cb32c7516ea95ddc8f8235460818eb2f24d2204308e0d9e1b19e7d90fL15-R19)
[[2]](diffhunk://#diff-a15ba2f5e830b4833c47b902515a4f9e5a4f83a3707698f3229b307ec3776b41L15-R18)
[[3]](diffhunk://#diff-52e0837e84d49221d1b810d88fdf78221f36cffcd664fb42f8aba49a79b974dcL15-R19)
[[4]](diffhunk://#diff-11c3457d1a23a4ca6ecd00d6b856289774936b6a708384cf03aff164044e7546L15-R19)
[[5]](diffhunk://#diff-2cff9cf8e6a0cc34087326d8c8149c3bbaf74c76fdbdf5a73daed13cc04249e1L15-R19)
[[6]](diffhunk://#diff-175edfeea54490b8fe4e18ffcbea5835efaf8f0b8acf623359073987cae7eb76L48-R55)
[[7]](diffhunk://#diff-e001b7a4b63603b9b14f00de78a4d570bb76c5f57d856a24643f071032e12356L66-R73)
[[8]](diffhunk://#diff-5582954e8a9983988dc8854ad82067fb2ac6269b988e07357ad8db1dfec5f1a0L39-R41)
**Container and utility updates:**
* Refactored the `garray` container implementation and related
constructors/methods to use `[]any` instead of `[]interface{}`, along
with corresponding function signatures.
[[1]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L31-R31)
[[2]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L52-R52)
[[3]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L62-R62)
[[4]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L73-R86)
[[5]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L96-R97)
[[6]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L107-R114)
[[7]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L124-R124)
[[8]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L135-R143)
[[9]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L167-R167)
These changes collectively modernize the codebase and prepare it for
future Go developments by using the idiomatic `any` type.
446 lines
11 KiB
Go
446 lines
11 KiB
Go
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
|
|
//
|
|
// This Source Code Form is subject to the terms of the MIT License.
|
|
// If a copy of the MIT was not distributed with this file,
|
|
// You can obtain one at https://github.com/gogf/gf.
|
|
|
|
package consul
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/gogf/gf/v2/net/gsvc"
|
|
"github.com/gogf/gf/v2/test/gtest"
|
|
)
|
|
|
|
const (
|
|
testServiceName = "test-service"
|
|
testServiceVersion = "1.0.0"
|
|
testServiceAddress = "127.0.0.1"
|
|
testServicePort = 8000
|
|
)
|
|
|
|
func createTestService() gsvc.Service {
|
|
return &gsvc.LocalService{
|
|
Name: testServiceName,
|
|
Version: testServiceVersion,
|
|
Metadata: map[string]any{
|
|
"region": "cn-east-1",
|
|
"zone": "a",
|
|
},
|
|
Endpoints: []gsvc.Endpoint{
|
|
gsvc.NewEndpoint(fmt.Sprintf("%s:%d", testServiceAddress, testServicePort)),
|
|
},
|
|
}
|
|
}
|
|
|
|
func Test_Registry_Basic(t *testing.T) {
|
|
gtest.C(t, func(t *gtest.T) {
|
|
// Create registry
|
|
registry, err := New()
|
|
t.AssertNil(err)
|
|
t.Assert(registry != nil, true)
|
|
|
|
// Test invalid service
|
|
invalidService := &gsvc.LocalService{
|
|
Name: testServiceName,
|
|
Version: testServiceVersion,
|
|
}
|
|
_, err = registry.Register(context.Background(), invalidService)
|
|
t.AssertNE(err, nil) // Should fail due to no endpoints
|
|
|
|
// Create service with invalid metadata
|
|
serviceWithInvalidMeta := &gsvc.LocalService{
|
|
Name: testServiceName,
|
|
Version: testServiceVersion,
|
|
Metadata: map[string]any{
|
|
"invalid": make(chan int), // This will fail JSON marshaling
|
|
},
|
|
Endpoints: []gsvc.Endpoint{
|
|
gsvc.NewEndpoint(fmt.Sprintf("%s:%d", testServiceAddress, testServicePort)),
|
|
},
|
|
}
|
|
_, err = registry.Register(context.Background(), serviceWithInvalidMeta)
|
|
t.AssertNE(err, nil) // Should fail due to invalid metadata
|
|
|
|
// Create service
|
|
service := createTestService()
|
|
|
|
// Register service
|
|
ctx := context.Background()
|
|
registeredService, err := registry.Register(ctx, service)
|
|
t.AssertNil(err)
|
|
t.Assert(registeredService != nil, true)
|
|
|
|
// Wait for service to be registered
|
|
time.Sleep(2 * time.Second)
|
|
|
|
// Search service
|
|
services, err := registry.Search(ctx, gsvc.SearchInput{
|
|
Name: testServiceName,
|
|
Version: testServiceVersion,
|
|
})
|
|
t.AssertNil(err)
|
|
t.Assert(len(services), 1)
|
|
|
|
// Test service properties
|
|
foundService := services[0]
|
|
t.Assert(foundService.GetName(), testServiceName)
|
|
t.Assert(foundService.GetVersion(), testServiceVersion)
|
|
t.Assert(len(foundService.GetEndpoints()), 1)
|
|
|
|
endpoint := foundService.GetEndpoints()[0]
|
|
t.Assert(endpoint.Host(), testServiceAddress)
|
|
t.Assert(endpoint.Port(), testServicePort)
|
|
|
|
metadata := foundService.GetMetadata()
|
|
t.Assert(metadata != nil, true)
|
|
t.Assert(metadata["region"], "cn-east-1")
|
|
t.Assert(metadata["zone"], "a")
|
|
|
|
// Search with invalid metadata
|
|
servicesWithInvalidMeta, err := registry.Search(ctx, gsvc.SearchInput{
|
|
Name: testServiceName,
|
|
Version: testServiceVersion,
|
|
Metadata: map[string]any{"nonexistent": "value"},
|
|
})
|
|
t.AssertNil(err)
|
|
t.Assert(len(servicesWithInvalidMeta), 0)
|
|
|
|
// Test deregister with invalid service
|
|
err = registry.Deregister(ctx, invalidService)
|
|
t.AssertNE(err, nil) // Should fail due to no endpoints
|
|
|
|
// Deregister service
|
|
err = registry.Deregister(ctx, service)
|
|
t.AssertNil(err)
|
|
|
|
// Wait for service to be deregistered
|
|
time.Sleep(2 * time.Second)
|
|
|
|
// Verify service is deregistered
|
|
deregisteredServices, err := registry.Search(ctx, gsvc.SearchInput{
|
|
Name: testServiceName,
|
|
Version: testServiceVersion,
|
|
})
|
|
t.AssertNil(err)
|
|
t.Assert(len(deregisteredServices), 0)
|
|
})
|
|
}
|
|
|
|
func Test_Registry_Watch(t *testing.T) {
|
|
gtest.C(t, func(t *gtest.T) {
|
|
// Create registry
|
|
registry, err := New()
|
|
t.AssertNil(err)
|
|
|
|
// Create service
|
|
service := createTestService()
|
|
|
|
// Register service first
|
|
ctx := context.Background()
|
|
_, err = registry.Register(ctx, service)
|
|
t.AssertNil(err)
|
|
defer registry.Deregister(ctx, service)
|
|
|
|
// Wait for service to be registered
|
|
time.Sleep(time.Second)
|
|
|
|
// Create watcher after service is registered
|
|
watcher, err := registry.Watch(ctx, testServiceName)
|
|
t.AssertNil(err)
|
|
t.Assert(watcher != nil, true)
|
|
defer watcher.Close()
|
|
|
|
// Wait for initial service query
|
|
time.Sleep(time.Second)
|
|
|
|
// Should receive initial service list
|
|
services, err := watcher.Proceed()
|
|
t.AssertNil(err)
|
|
t.Assert(len(services), 1)
|
|
t.Assert(services[0].GetName(), testServiceName)
|
|
t.Assert(services[0].GetVersion(), testServiceVersion)
|
|
|
|
// Test closing watcher
|
|
err = watcher.Close()
|
|
t.AssertNil(err)
|
|
|
|
// Test watch with invalid service name
|
|
watcher, err = registry.Watch(ctx, "nonexistent-service")
|
|
t.AssertNil(err)
|
|
defer watcher.Close()
|
|
|
|
// Wait for initial query
|
|
time.Sleep(time.Second)
|
|
|
|
// Should receive empty service list for non-existent service
|
|
services, err = watcher.Proceed()
|
|
t.AssertNil(err)
|
|
t.Assert(len(services), 0)
|
|
|
|
// Test watch after service deregistration
|
|
watcher, err = registry.Watch(ctx, testServiceName)
|
|
t.AssertNil(err)
|
|
defer watcher.Close()
|
|
|
|
// Wait for initial query
|
|
time.Sleep(time.Second)
|
|
|
|
err = registry.Deregister(ctx, service)
|
|
t.AssertNil(err)
|
|
|
|
// Wait for service to be deregistered
|
|
time.Sleep(time.Second)
|
|
|
|
// Should receive empty service list after deregistration
|
|
services, err = watcher.Proceed()
|
|
t.AssertNil(err)
|
|
t.Assert(len(services), 0)
|
|
})
|
|
}
|
|
|
|
func Test_Registry_MultipleServices(t *testing.T) {
|
|
gtest.C(t, func(t *gtest.T) {
|
|
// Create registry
|
|
registry, err := New()
|
|
t.AssertNil(err)
|
|
|
|
// Create multiple services
|
|
service1 := &gsvc.LocalService{
|
|
Name: testServiceName,
|
|
Version: "1.0.0",
|
|
Metadata: map[string]any{
|
|
"region": "us-east-1",
|
|
},
|
|
Endpoints: []gsvc.Endpoint{
|
|
gsvc.NewEndpoint("127.0.0.1:8001"),
|
|
},
|
|
}
|
|
|
|
service2 := &gsvc.LocalService{
|
|
Name: testServiceName,
|
|
Version: "2.0.0",
|
|
Metadata: map[string]any{
|
|
"region": "us-west-1",
|
|
},
|
|
Endpoints: []gsvc.Endpoint{
|
|
gsvc.NewEndpoint("127.0.0.1:8002"),
|
|
},
|
|
}
|
|
|
|
// Register services
|
|
ctx := context.Background()
|
|
_, err = registry.Register(ctx, service1)
|
|
t.AssertNil(err)
|
|
defer registry.Deregister(ctx, service1)
|
|
|
|
_, err = registry.Register(ctx, service2)
|
|
t.AssertNil(err)
|
|
defer registry.Deregister(ctx, service2)
|
|
|
|
// Wait for services to be registered
|
|
time.Sleep(2 * time.Second)
|
|
|
|
// Search all services without version filter
|
|
allServices, err := registry.Search(ctx, gsvc.SearchInput{
|
|
Name: testServiceName,
|
|
})
|
|
t.AssertNil(err)
|
|
t.Assert(len(allServices), 2)
|
|
|
|
// Test search with different versions
|
|
services1, err := registry.Search(ctx, gsvc.SearchInput{
|
|
Name: testServiceName,
|
|
Version: "1.0.0",
|
|
})
|
|
t.AssertNil(err)
|
|
t.Assert(len(services1), 1)
|
|
t.Assert(services1[0].GetVersion(), "1.0.0")
|
|
|
|
services2, err := registry.Search(ctx, gsvc.SearchInput{
|
|
Name: testServiceName,
|
|
Version: "2.0.0",
|
|
})
|
|
t.AssertNil(err)
|
|
t.Assert(len(services2), 1)
|
|
t.Assert(services2[0].GetVersion(), "2.0.0")
|
|
|
|
// Test search with metadata
|
|
servicesEast, err := registry.Search(ctx, gsvc.SearchInput{
|
|
Name: testServiceName,
|
|
Metadata: map[string]any{
|
|
"region": "us-east-1",
|
|
},
|
|
})
|
|
t.AssertNil(err)
|
|
t.Assert(len(servicesEast), 1)
|
|
t.Assert(servicesEast[0].GetMetadata()["region"], "us-east-1")
|
|
|
|
// Watch both services
|
|
watcher, err := registry.Watch(ctx, testServiceName)
|
|
t.AssertNil(err)
|
|
defer watcher.Close()
|
|
|
|
// Wait for initial query
|
|
time.Sleep(time.Second)
|
|
|
|
// Should receive updates for both services
|
|
services, err := watcher.Proceed()
|
|
t.AssertNil(err)
|
|
t.Assert(len(services), 2)
|
|
|
|
// Verify services are sorted by version
|
|
t.Assert(services[0].GetVersion() < services[1].GetVersion(), true)
|
|
})
|
|
}
|
|
|
|
func Test_Registry_Options(t *testing.T) {
|
|
gtest.C(t, func(t *gtest.T) {
|
|
// Test with custom address
|
|
registry1, err := New(WithAddress("localhost:8500"))
|
|
t.AssertNil(err)
|
|
t.Assert(registry1.(*Registry).GetAddress(), "localhost:8500")
|
|
|
|
// Test with token
|
|
registry2, err := New(WithAddress("localhost:8500"), WithToken("test-token"))
|
|
t.AssertNil(err)
|
|
t.Assert(registry2.(*Registry).options["token"], "test-token")
|
|
|
|
// Test with invalid address (should still create registry but fail on operations)
|
|
registry3, err := New(WithAddress("invalid:99999"))
|
|
t.AssertNil(err)
|
|
_, err = registry3.Register(context.Background(), createTestService())
|
|
t.AssertNE(err, nil)
|
|
})
|
|
}
|
|
|
|
func Test_Registry_MultipleServicesMetadataFiltering(t *testing.T) {
|
|
gtest.C(t, func(t *gtest.T) {
|
|
// Create registry
|
|
registry, err := New()
|
|
t.AssertNil(err)
|
|
|
|
// Create multiple services
|
|
service1 := &gsvc.LocalService{
|
|
Name: testServiceName,
|
|
Version: "1.0.0",
|
|
Metadata: map[string]any{
|
|
"region": "us-east-1",
|
|
"env": "dev",
|
|
},
|
|
Endpoints: []gsvc.Endpoint{
|
|
gsvc.NewEndpoint("127.0.0.1:8001"),
|
|
},
|
|
}
|
|
|
|
service2 := &gsvc.LocalService{
|
|
Name: testServiceName,
|
|
Version: "2.0.0",
|
|
Metadata: map[string]any{
|
|
"region": "us-west-1",
|
|
"env": "prod",
|
|
},
|
|
Endpoints: []gsvc.Endpoint{
|
|
gsvc.NewEndpoint("127.0.0.1:8002"),
|
|
},
|
|
}
|
|
|
|
// Register services
|
|
ctx := context.Background()
|
|
_, err = registry.Register(ctx, service1)
|
|
t.AssertNil(err)
|
|
defer registry.Deregister(ctx, service1)
|
|
|
|
_, err = registry.Register(ctx, service2)
|
|
t.AssertNil(err)
|
|
defer registry.Deregister(ctx, service2)
|
|
|
|
time.Sleep(time.Second) // Wait for services to be registered
|
|
|
|
// Test search with metadata filtering
|
|
servicesDev, err := registry.Search(ctx, gsvc.SearchInput{
|
|
Name: testServiceName,
|
|
Metadata: map[string]any{
|
|
"env": "dev",
|
|
},
|
|
})
|
|
t.AssertNil(err)
|
|
t.Assert(len(servicesDev), 1)
|
|
t.Assert(servicesDev[0].GetMetadata()["env"], "dev")
|
|
|
|
servicesProd, err := registry.Search(ctx, gsvc.SearchInput{
|
|
Name: testServiceName,
|
|
Metadata: map[string]any{
|
|
"env": "prod",
|
|
},
|
|
})
|
|
t.AssertNil(err)
|
|
t.Assert(len(servicesProd), 1)
|
|
t.Assert(servicesProd[0].GetMetadata()["env"], "prod")
|
|
})
|
|
}
|
|
|
|
func Test_Registry_MultipleServicesVersionFiltering(t *testing.T) {
|
|
gtest.C(t, func(t *gtest.T) {
|
|
// Create registry
|
|
registry, err := New()
|
|
t.AssertNil(err)
|
|
|
|
// Create multiple services
|
|
service1 := &gsvc.LocalService{
|
|
Name: testServiceName,
|
|
Version: "1.0.0",
|
|
Metadata: map[string]any{
|
|
"region": "us-east-1",
|
|
},
|
|
Endpoints: []gsvc.Endpoint{
|
|
gsvc.NewEndpoint("127.0.0.1:8001"),
|
|
},
|
|
}
|
|
|
|
service2 := &gsvc.LocalService{
|
|
Name: testServiceName,
|
|
Version: "2.0.0",
|
|
Metadata: map[string]any{
|
|
"region": "us-west-1",
|
|
},
|
|
Endpoints: []gsvc.Endpoint{
|
|
gsvc.NewEndpoint("127.0.0.1:8002"),
|
|
},
|
|
}
|
|
|
|
// Register services
|
|
ctx := context.Background()
|
|
_, err = registry.Register(ctx, service1)
|
|
t.AssertNil(err)
|
|
defer registry.Deregister(ctx, service1)
|
|
|
|
_, err = registry.Register(ctx, service2)
|
|
t.AssertNil(err)
|
|
defer registry.Deregister(ctx, service2)
|
|
|
|
time.Sleep(time.Second) // Wait for services to be registered
|
|
|
|
// Test search with version filtering
|
|
services, err := registry.Search(ctx, gsvc.SearchInput{
|
|
Name: testServiceName,
|
|
Version: "1.0.0",
|
|
})
|
|
t.AssertNil(err)
|
|
t.Assert(len(services), 1)
|
|
t.Assert(services[0].GetVersion(), "1.0.0")
|
|
|
|
services, err = registry.Search(ctx, gsvc.SearchInput{
|
|
Name: testServiceName,
|
|
Version: "2.0.0",
|
|
})
|
|
t.AssertNil(err)
|
|
t.Assert(len(services), 1)
|
|
t.Assert(services[0].GetVersion(), "2.0.0")
|
|
})
|
|
}
|