feat(delivery): support multi-instance scheduling on a single host
- Per-host instance limit (DELIVERY_HOST_INSTANCE_LIMIT, default 4) - Optional target_host to pin a host from the candidate pool - Regenerate swagger docs
This commit is contained in:
@@ -15,6 +15,7 @@ func TestValidateDeliveryInput(t *testing.T) {
|
||||
full.Topology = "standalone"
|
||||
full.MySQLPort = 13306
|
||||
full.DataDisk = "/disk1"
|
||||
full.TargetHost = "k8s-server-03"
|
||||
full.MemoryMi = 8192
|
||||
full.StorageGi = 2000
|
||||
full.Timezone = "+08:00"
|
||||
@@ -55,6 +56,7 @@ func TestValidateDeliveryInput(t *testing.T) {
|
||||
"port below pool": func(in *MySQLDeliveryInput) { in.MySQLPort = 3307 },
|
||||
"port above pool": func(in *MySQLDeliveryInput) { in.MySQLPort = 14000 },
|
||||
"data disk not in list": func(in *MySQLDeliveryInput) { in.DataDisk = "/mnt/other" },
|
||||
"bad target host": func(in *MySQLDeliveryInput) { in.TargetHost = "-bad-host" },
|
||||
"bad timezone": func(in *MySQLDeliveryInput) { in.Timezone = "UTC+8" },
|
||||
"bad lower case": func(in *MySQLDeliveryInput) { in.LowerCaseTableNames = intPtr(2) },
|
||||
"bad charset": func(in *MySQLDeliveryInput) { in.CharacterSet = "big5" },
|
||||
@@ -77,6 +79,30 @@ func TestValidateDeliveryInput(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestFirstFreeHost(t *testing.T) {
|
||||
hosts := []targetHost{{Name: "node-a"}, {Name: "node-b"}}
|
||||
if h := firstFreeHost(hosts, nil, 1); h == nil || h.Name != "node-a" {
|
||||
t.Fatalf("expected node-a on empty occupancy, got %+v", h)
|
||||
}
|
||||
if h := firstFreeHost(hosts, []string{"node-a"}, 1); h == nil || h.Name != "node-b" {
|
||||
t.Fatalf("expected node-b when node-a is full at limit 1, got %+v", h)
|
||||
}
|
||||
if h := firstFreeHost(hosts, []string{"node-a", "node-b"}, 1); h != nil {
|
||||
t.Fatalf("limit 1 with all hosts taken should return nil, got %+v", h)
|
||||
}
|
||||
// 摊满一轮后回到首台叠加第二个实例
|
||||
if h := firstFreeHost(hosts, []string{"node-a", "node-b"}, 2); h == nil || h.Name != "node-a" {
|
||||
t.Fatalf("expected node-a for second round at limit 2, got %+v", h)
|
||||
}
|
||||
if h := firstFreeHost(hosts, []string{"node-a", "node-a", "node-b", "node-b"}, 2); h != nil {
|
||||
t.Fatalf("limit 2 with all hosts saturated should return nil, got %+v", h)
|
||||
}
|
||||
// limit < 1 退化为一机一实例
|
||||
if h := firstFreeHost(hosts, []string{"node-a"}, 0); h == nil || h.Name != "node-b" {
|
||||
t.Fatalf("limit 0 should degrade to 1, got %+v", h)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAllocatePort(t *testing.T) {
|
||||
if port, err := allocatePort(0, nil); err != nil || port != mysqlPortPoolStart {
|
||||
t.Fatalf("expected first pool port %d, got %d err=%v", mysqlPortPoolStart, port, err)
|
||||
|
||||
Reference in New Issue
Block a user