backend2.Hostname: backend2, }, Healthchecks: map[string]*config.Healthcheck{vserverHC.Key(): vserverHC}, Enabled: true, } var expectedServices = map[serviceKey]struct { ip seesaw.IP expectedDests []destination }{ serviceKey{ af: seesaw.IPv4, proto: seesaw.IPProtoUDP, port: 53, }: { ip: seesaw.ParseIP("192.168.255.1"), expectedDests: []destination{ {destinationKey: newDestinationKey(net.ParseIP("1.1.1.10")), stats: &seesaw.DestinationStats{}}, {destinationKey: newDestinationKey(net.ParseIP("1.1.1.11")), stats: &seesaw.DestinationStats{}}, }, }, serviceKey{ af: seesaw.IPv4, proto: seesaw.IPProtoTCP, port: 8053, }: { ip: seesaw.ParseIP("192.168.255.1"), expectedDests: []destination{ {destinationKey: newDestinationKey(net.ParseIP("1.1.1.10")), stats: &seesaw.DestinationStats{}}, {destinationKey: newDestinationKey(net.ParseIP("1.1.1.11")), stats: &seesaw.DestinationStats{}}, },
func TestHealthcheckNotification(t *testing.T) { vserver := newTestVserver(nil) vserver.handleConfigUpdate(&vserverConfig) checkStates(0, vserver, t) // One healthcheck reports healthy, but there are two other // healthchecks per destination, so services and vservers should // still be inactive. key := checkKey{ vserverIP: seesaw.ParseIP("192.168.255.1"), backendIP: seesaw.ParseIP("1.1.1.10"), healthcheckPort: 5, name: "NONE/5_0", } n := &checkNotification{key: key, status: statusHealthy} vserver.handleCheckNotification(n) checkStates(1, vserver, t) // Bringing up all destinations should bring up all services and // vservers. All services and destinations should now be healthy. for _, c := range vserver.checks { n := &checkNotification{key: c.key, status: statusHealthy} vserver.handleCheckNotification(n) } checkStates(2, vserver, t) // One backend is unhealthy, all services should still be active. // All services should be healthy and destinations for other backends // should still be healthy. key = checkKey{ vserverIP: seesaw.ParseIP("192.168.255.1"), backendIP: seesaw.ParseIP("1.1.1.10"), serviceProtocol: seesaw.IPProtoUDP, servicePort: 53, healthcheckPort: 1, name: "NONE/1_0", } n = &checkNotification{key: key, status: statusUnhealthy} vserver.handleCheckNotification(n) checkStates(3, vserver, t) // The other backend is also unhealthy. 192.168.255.1 is anycast, so all // services and the VIP should be inactive. 2012::1 should be unchanged. key.backendIP = seesaw.ParseIP("1.1.1.11") n = &checkNotification{key: key, status: statusUnhealthy} vserver.handleCheckNotification(n) checkStates(4, vserver, t) // Both backends are unhealthy for one service. 2012::1 is unicast so the // other service and the VIP should still be active. key.vserverIP = seesaw.ParseIP("2012::1") key.backendIP = seesaw.ParseIP("2012::10") n = &checkNotification{key: key, status: statusUnhealthy} vserver.handleCheckNotification(n) key.backendIP = seesaw.ParseIP("2012::11") n = &checkNotification{key: key, status: statusUnhealthy} vserver.handleCheckNotification(n) checkStates(5, vserver, t) // Bring down everything. for _, c := range vserver.checks { n := &checkNotification{key: c.key, status: statusUnhealthy} vserver.handleCheckNotification(n) } checkStates(6, vserver, t) }
hcTestHealthchecks = map[string]*config.Healthcheck{ "HTTP/3901": { Type: seesaw.HCTypeHTTP, Port: 3901, Interval: 100 * time.Second, Timeout: 50 * time.Second, Send: "some request", Receive: "some response", Code: 200, Name: "HTTP/3901_0", }, } key1 = checkKey{ vserverIP: seesaw.ParseIP("1.1.1.1"), backendIP: seesaw.ParseIP("1.1.1.2"), healthcheckType: seesaw.HCTypeHTTP, healthcheckPort: 3901, name: "HTTP/3901_0", } key2 = checkKey{ vserverIP: seesaw.ParseIP("2012::cafe"), backendIP: seesaw.ParseIP("2012::cafd"), healthcheckType: seesaw.HCTypeHTTP, healthcheckPort: 3901, name: "HTTP/3901_0", } key3 = checkKey{