feat: remove module/rollout config key
This commit is contained in:
@@ -41,7 +41,6 @@ func TestAPKProxyCachesIndexAndPackages(t *testing.T) {
|
||||
Name: "apk",
|
||||
Domain: "apk.hub.local",
|
||||
Type: "apk",
|
||||
Module: "apk",
|
||||
Upstream: stub.URL,
|
||||
},
|
||||
},
|
||||
|
||||
@@ -41,7 +41,6 @@ func TestAptPackagesCachedWithoutRevalidate(t *testing.T) {
|
||||
Name: "apt",
|
||||
Domain: "apt.hub.local",
|
||||
Type: "debian",
|
||||
Module: "debian",
|
||||
Upstream: stub.URL,
|
||||
},
|
||||
},
|
||||
|
||||
@@ -36,7 +36,6 @@ func TestAptUpdateCachesIndexes(t *testing.T) {
|
||||
Name: "apt",
|
||||
Domain: "apt.hub.local",
|
||||
Type: "debian",
|
||||
Module: "debian",
|
||||
Upstream: stub.URL,
|
||||
},
|
||||
},
|
||||
|
||||
@@ -44,7 +44,6 @@ func TestCacheFlowWithConditionalRequest(t *testing.T) {
|
||||
Name: "docker",
|
||||
Domain: "docker.hub.local",
|
||||
Type: "docker",
|
||||
Module: "docker",
|
||||
Upstream: upstream.URL,
|
||||
},
|
||||
},
|
||||
@@ -146,7 +145,6 @@ func TestDockerManifestHeadDoesNotOverwriteCache(t *testing.T) {
|
||||
Name: "docker",
|
||||
Domain: "docker.hub.local",
|
||||
Type: "docker",
|
||||
Module: "docker",
|
||||
Upstream: upstream.URL,
|
||||
},
|
||||
},
|
||||
|
||||
@@ -35,7 +35,6 @@ func TestCacheStrategyOverrides(t *testing.T) {
|
||||
Name: "npm-ttl",
|
||||
Domain: "ttl.npm.local",
|
||||
Type: "npm",
|
||||
Module: "npm",
|
||||
Upstream: stub.URL,
|
||||
CacheTTL: config.Duration(ttl),
|
||||
},
|
||||
@@ -111,7 +110,6 @@ func TestCacheStrategyOverrides(t *testing.T) {
|
||||
Name: "npm-novalidation",
|
||||
Domain: "novalidation.npm.local",
|
||||
Type: "npm",
|
||||
Module: "npm",
|
||||
Upstream: stub.URL,
|
||||
CacheTTL: config.Duration(ttl),
|
||||
ValidationMode: string(hubmodule.ValidationModeNever),
|
||||
|
||||
@@ -1,118 +0,0 @@
|
||||
package integration
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/any-hub/any-hub/internal/config"
|
||||
"github.com/any-hub/any-hub/internal/hubmodule"
|
||||
"github.com/any-hub/any-hub/internal/hubmodule/legacy"
|
||||
"github.com/any-hub/any-hub/internal/server"
|
||||
)
|
||||
|
||||
func TestLegacyAdapterRolloutToggle(t *testing.T) {
|
||||
const moduleKey = "rollout-toggle-test"
|
||||
_ = hubmodule.Register(hubmodule.ModuleMetadata{Key: moduleKey})
|
||||
|
||||
logger := logrus.New()
|
||||
logger.SetOutput(io.Discard)
|
||||
|
||||
baseHub := config.HubConfig{
|
||||
Name: "dual-mode",
|
||||
Domain: "dual.local",
|
||||
Type: "docker",
|
||||
Upstream: "https://registry.npmjs.org",
|
||||
Module: moduleKey,
|
||||
}
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
rolloutFlag string
|
||||
expectKey string
|
||||
expectFlag legacy.RolloutFlag
|
||||
}{
|
||||
{
|
||||
name: "force legacy",
|
||||
rolloutFlag: "legacy-only",
|
||||
expectKey: hubmodule.DefaultModuleKey(),
|
||||
expectFlag: legacy.RolloutLegacyOnly,
|
||||
},
|
||||
{
|
||||
name: "dual mode",
|
||||
rolloutFlag: "dual",
|
||||
expectKey: moduleKey,
|
||||
expectFlag: legacy.RolloutDual,
|
||||
},
|
||||
{
|
||||
name: "full modular",
|
||||
rolloutFlag: "modular",
|
||||
expectKey: moduleKey,
|
||||
expectFlag: legacy.RolloutModular,
|
||||
},
|
||||
{
|
||||
name: "rollback to legacy",
|
||||
rolloutFlag: "legacy-only",
|
||||
expectKey: hubmodule.DefaultModuleKey(),
|
||||
expectFlag: legacy.RolloutLegacyOnly,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
cfg := &config.Config{
|
||||
Global: config.GlobalConfig{
|
||||
ListenPort: 6100,
|
||||
CacheTTL: config.Duration(time.Minute),
|
||||
},
|
||||
Hubs: []config.HubConfig{
|
||||
func() config.HubConfig {
|
||||
h := baseHub
|
||||
h.Rollout = tc.rolloutFlag
|
||||
return h
|
||||
}(),
|
||||
},
|
||||
}
|
||||
|
||||
registry, err := server.NewHubRegistry(cfg)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to build registry: %v", err)
|
||||
}
|
||||
|
||||
recorder := &routeRecorder{}
|
||||
app := mustNewApp(t, cfg.Global.ListenPort, logger, registry, recorder)
|
||||
|
||||
req := httptest.NewRequest("GET", "http://dual.local/v2/", nil)
|
||||
req.Host = "dual.local"
|
||||
resp, err := app.Test(req)
|
||||
if err != nil {
|
||||
t.Fatalf("request failed: %v", err)
|
||||
}
|
||||
if resp.StatusCode != fiber.StatusNoContent {
|
||||
t.Fatalf("unexpected status: %d", resp.StatusCode)
|
||||
}
|
||||
|
||||
if recorder.moduleKey != tc.expectKey {
|
||||
t.Fatalf("expected module %s, got %s", tc.expectKey, recorder.moduleKey)
|
||||
}
|
||||
if recorder.rolloutFlag != tc.expectFlag {
|
||||
t.Fatalf("expected rollout flag %s, got %s", tc.expectFlag, recorder.rolloutFlag)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
type routeRecorder struct {
|
||||
moduleKey string
|
||||
rolloutFlag legacy.RolloutFlag
|
||||
}
|
||||
|
||||
func (r *routeRecorder) Handle(c fiber.Ctx, route *server.HubRoute) error {
|
||||
r.moduleKey = route.ModuleKey
|
||||
r.rolloutFlag = route.RolloutFlag
|
||||
return c.SendStatus(fiber.StatusNoContent)
|
||||
}
|
||||
@@ -13,7 +13,6 @@ import (
|
||||
|
||||
"github.com/any-hub/any-hub/internal/config"
|
||||
"github.com/any-hub/any-hub/internal/hubmodule"
|
||||
"github.com/any-hub/any-hub/internal/hubmodule/legacy"
|
||||
"github.com/any-hub/any-hub/internal/proxy/hooks"
|
||||
"github.com/any-hub/any-hub/internal/server"
|
||||
"github.com/any-hub/any-hub/internal/server/routes"
|
||||
@@ -37,21 +36,17 @@ func TestModuleDiagnosticsEndpoints(t *testing.T) {
|
||||
CacheTTL: config.Duration(30 * time.Minute),
|
||||
},
|
||||
Hubs: []config.HubConfig{
|
||||
{
|
||||
Name: "legacy-hub",
|
||||
Domain: "legacy.local",
|
||||
Type: "docker",
|
||||
Upstream: "https://registry-1.docker.io",
|
||||
Module: hubmodule.DefaultModuleKey(),
|
||||
Rollout: string(legacy.RolloutLegacyOnly),
|
||||
},
|
||||
{
|
||||
Name: "modern-hub",
|
||||
Domain: "modern.local",
|
||||
Type: "npm",
|
||||
Upstream: "https://registry.npmjs.org",
|
||||
Module: moduleKey,
|
||||
Rollout: "dual",
|
||||
},
|
||||
{
|
||||
Name: "docker-hub",
|
||||
Domain: "docker.local",
|
||||
Type: "docker",
|
||||
Upstream: "https://registry-1.docker.io",
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -77,12 +72,10 @@ func TestModuleDiagnosticsEndpoints(t *testing.T) {
|
||||
var payload struct {
|
||||
Modules []map[string]any `json:"modules"`
|
||||
Hubs []struct {
|
||||
HubName string `json:"hub_name"`
|
||||
ModuleKey string `json:"module_key"`
|
||||
Rollout string `json:"rollout_flag"`
|
||||
Domain string `json:"domain"`
|
||||
Port int `json:"port"`
|
||||
LegacyOnly bool `json:"legacy_only"`
|
||||
HubName string `json:"hub_name"`
|
||||
ModuleKey string `json:"module_key"`
|
||||
Domain string `json:"domain"`
|
||||
Port int `json:"port"`
|
||||
} `json:"hubs"`
|
||||
}
|
||||
body, _ := io.ReadAll(resp.Body)
|
||||
@@ -111,22 +104,13 @@ func TestModuleDiagnosticsEndpoints(t *testing.T) {
|
||||
}
|
||||
for _, hub := range payload.Hubs {
|
||||
switch hub.HubName {
|
||||
case "legacy-hub":
|
||||
if hub.ModuleKey != hubmodule.DefaultModuleKey() {
|
||||
t.Fatalf("legacy hub should expose legacy module, got %s", hub.ModuleKey)
|
||||
}
|
||||
if !hub.LegacyOnly {
|
||||
t.Fatalf("legacy hub should be marked legacy_only")
|
||||
}
|
||||
case "modern-hub":
|
||||
if hub.ModuleKey != moduleKey {
|
||||
t.Fatalf("modern hub should expose %s, got %s", moduleKey, hub.ModuleKey)
|
||||
if hub.ModuleKey != "npm" {
|
||||
t.Fatalf("modern hub should expose npm, got %s", hub.ModuleKey)
|
||||
}
|
||||
if hub.Rollout != "dual" {
|
||||
t.Fatalf("modern hub rollout flag should be dual, got %s", hub.Rollout)
|
||||
}
|
||||
if hub.LegacyOnly {
|
||||
t.Fatalf("modern hub should not be marked legacy_only")
|
||||
case "docker-hub":
|
||||
if hub.ModuleKey != "docker" {
|
||||
t.Fatalf("docker hub should expose docker, got %s", hub.ModuleKey)
|
||||
}
|
||||
default:
|
||||
t.Fatalf("unexpected hub %s", hub.HubName)
|
||||
|
||||
@@ -1,107 +1,100 @@
|
||||
package integration
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
"io"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/any-hub/any-hub/internal/config"
|
||||
"github.com/any-hub/any-hub/internal/hubmodule"
|
||||
"github.com/any-hub/any-hub/internal/server"
|
||||
"github.com/any-hub/any-hub/internal/config"
|
||||
"github.com/any-hub/any-hub/internal/server"
|
||||
)
|
||||
|
||||
func TestModuleRoutingIsolation(t *testing.T) {
|
||||
_ = hubmodule.Register(hubmodule.ModuleMetadata{Key: "module-routing-test"})
|
||||
cfg := &config.Config{
|
||||
Global: config.GlobalConfig{
|
||||
ListenPort: 6000,
|
||||
CacheTTL: config.Duration(3600),
|
||||
},
|
||||
Hubs: []config.HubConfig{
|
||||
{
|
||||
Name: "docker-hub",
|
||||
Domain: "legacy.hub.local",
|
||||
Type: "docker",
|
||||
Upstream: "https://registry-1.docker.io",
|
||||
},
|
||||
{
|
||||
Name: "npm-hub",
|
||||
Domain: "test.hub.local",
|
||||
Type: "npm",
|
||||
Upstream: "https://registry.example.com",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
cfg := &config.Config{
|
||||
Global: config.GlobalConfig{
|
||||
ListenPort: 6000,
|
||||
CacheTTL: config.Duration(3600),
|
||||
},
|
||||
Hubs: []config.HubConfig{
|
||||
{
|
||||
Name: "legacy",
|
||||
Domain: "legacy.hub.local",
|
||||
Type: "docker",
|
||||
Module: "legacy",
|
||||
Upstream: "https://registry-1.docker.io",
|
||||
},
|
||||
{
|
||||
Name: "test",
|
||||
Domain: "test.hub.local",
|
||||
Type: "npm",
|
||||
Module: "module-routing-test",
|
||||
Upstream: "https://registry.example.com",
|
||||
},
|
||||
},
|
||||
}
|
||||
registry, err := server.NewHubRegistry(cfg)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create registry: %v", err)
|
||||
}
|
||||
|
||||
registry, err := server.NewHubRegistry(cfg)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create registry: %v", err)
|
||||
}
|
||||
logger := logrus.New()
|
||||
logger.SetOutput(io.Discard)
|
||||
|
||||
logger := logrus.New()
|
||||
logger.SetOutput(io.Discard)
|
||||
recorder := &moduleRecorder{}
|
||||
app := mustNewApp(t, cfg.Global.ListenPort, logger, registry, recorder)
|
||||
|
||||
recorder := &moduleRecorder{}
|
||||
app := mustNewApp(t, cfg.Global.ListenPort, logger, registry, recorder)
|
||||
legacyReq := httptest.NewRequest("GET", "http://legacy.hub.local/v2/", nil)
|
||||
legacyReq.Host = "legacy.hub.local"
|
||||
legacyReq.Header.Set("Host", "legacy.hub.local")
|
||||
resp, err := app.Test(legacyReq)
|
||||
if err != nil {
|
||||
t.Fatalf("legacy request failed: %v", err)
|
||||
}
|
||||
if resp.StatusCode != fiber.StatusNoContent {
|
||||
t.Fatalf("legacy hub should return 204, got %d", resp.StatusCode)
|
||||
}
|
||||
if recorder.moduleKey != "docker" {
|
||||
t.Fatalf("expected docker module, got %s", recorder.moduleKey)
|
||||
}
|
||||
|
||||
legacyReq := httptest.NewRequest("GET", "http://legacy.hub.local/v2/", nil)
|
||||
legacyReq.Host = "legacy.hub.local"
|
||||
legacyReq.Header.Set("Host", "legacy.hub.local")
|
||||
resp, err := app.Test(legacyReq)
|
||||
if err != nil {
|
||||
t.Fatalf("legacy request failed: %v", err)
|
||||
}
|
||||
if resp.StatusCode != fiber.StatusNoContent {
|
||||
t.Fatalf("legacy hub should return 204, got %d", resp.StatusCode)
|
||||
}
|
||||
if recorder.moduleKey != "legacy" {
|
||||
t.Fatalf("expected legacy module, got %s", recorder.moduleKey)
|
||||
}
|
||||
|
||||
testReq := httptest.NewRequest("GET", "http://test.hub.local/v2/", nil)
|
||||
testReq.Host = "test.hub.local"
|
||||
testReq.Header.Set("Host", "test.hub.local")
|
||||
resp2, err := app.Test(testReq)
|
||||
if err != nil {
|
||||
t.Fatalf("test request failed: %v", err)
|
||||
}
|
||||
if resp2.StatusCode != fiber.StatusNoContent {
|
||||
t.Fatalf("test hub should return 204, got %d", resp2.StatusCode)
|
||||
}
|
||||
if recorder.moduleKey != "module-routing-test" {
|
||||
t.Fatalf("expected module-routing-test module, got %s", recorder.moduleKey)
|
||||
}
|
||||
testReq := httptest.NewRequest("GET", "http://test.hub.local/v2/", nil)
|
||||
testReq.Host = "test.hub.local"
|
||||
testReq.Header.Set("Host", "test.hub.local")
|
||||
resp2, err := app.Test(testReq)
|
||||
if err != nil {
|
||||
t.Fatalf("test request failed: %v", err)
|
||||
}
|
||||
if resp2.StatusCode != fiber.StatusNoContent {
|
||||
t.Fatalf("test hub should return 204, got %d", resp2.StatusCode)
|
||||
}
|
||||
if recorder.moduleKey != "npm" {
|
||||
t.Fatalf("expected npm module, got %s", recorder.moduleKey)
|
||||
}
|
||||
}
|
||||
|
||||
func mustNewApp(t *testing.T, port int, logger *logrus.Logger, registry *server.HubRegistry, handler server.ProxyHandler) *fiber.App {
|
||||
t.Helper()
|
||||
app, err := server.NewApp(server.AppOptions{
|
||||
Logger: logger,
|
||||
Registry: registry,
|
||||
Proxy: handler,
|
||||
ListenPort: port,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create app: %v", err)
|
||||
}
|
||||
return app
|
||||
t.Helper()
|
||||
app, err := server.NewApp(server.AppOptions{
|
||||
Logger: logger,
|
||||
Registry: registry,
|
||||
Proxy: handler,
|
||||
ListenPort: port,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create app: %v", err)
|
||||
}
|
||||
return app
|
||||
}
|
||||
|
||||
type moduleRecorder struct {
|
||||
routeName string
|
||||
moduleKey string
|
||||
rollout string
|
||||
routeName string
|
||||
moduleKey string
|
||||
}
|
||||
|
||||
func (p *moduleRecorder) Handle(c fiber.Ctx, route *server.HubRoute) error {
|
||||
p.routeName = route.Config.Name
|
||||
p.moduleKey = route.ModuleKey
|
||||
p.rollout = string(route.RolloutFlag)
|
||||
return c.SendStatus(fiber.StatusNoContent)
|
||||
p.routeName = route.Config.Name
|
||||
p.moduleKey = route.ModuleKey
|
||||
return c.SendStatus(fiber.StatusNoContent)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user