func (s *RBSuite) TestRebalancerRemoveServer(c *C) { a, b := testutils.NewResponder("a"), testutils.NewResponder("b") defer a.Close() defer b.Close() fwd, err := forward.New() c.Assert(err, IsNil) lb, err := New(fwd) c.Assert(err, IsNil) rb, err := NewRebalancer(lb) c.Assert(err, IsNil) rb.UpsertServer(testutils.ParseURI(a.URL)) rb.UpsertServer(testutils.ParseURI(b.URL)) proxy := httptest.NewServer(rb) defer proxy.Close() c.Assert(seq(c, proxy.URL, 3), DeepEquals, []string{"a", "b", "a"}) c.Assert(rb.RemoveServer(testutils.ParseURI(a.URL)), IsNil) c.Assert(seq(c, proxy.URL, 3), DeepEquals, []string{"b", "b", "b"}) }
func (s *RRSuite) TestWeighted(c *C) { a := testutils.NewResponder("a") defer a.Close() b := testutils.NewResponder("b") defer b.Close() fwd, err := forward.New() c.Assert(err, IsNil) lb, err := New(fwd) c.Assert(err, IsNil) lb.UpsertServer(testutils.ParseURI(a.URL), Weight(3)) lb.UpsertServer(testutils.ParseURI(b.URL), Weight(2)) proxy := httptest.NewServer(lb) defer proxy.Close() c.Assert(seq(c, proxy.URL, 6), DeepEquals, []string{"a", "a", "b", "a", "b", "a"}) w, ok := lb.ServerWeight(testutils.ParseURI(a.URL)) c.Assert(w, Equals, 3) c.Assert(ok, Equals, true) w, ok = lb.ServerWeight(testutils.ParseURI(b.URL)) c.Assert(w, Equals, 2) c.Assert(ok, Equals, true) w, ok = lb.ServerWeight(testutils.ParseURI("http://caramba:4000")) c.Assert(w, Equals, -1) c.Assert(ok, Equals, false) }
func (s *RBSuite) TestRebalancerLive(c *C) { a, b := testutils.NewResponder("a"), testutils.NewResponder("b") defer a.Close() defer b.Close() fwd, err := forward.New() c.Assert(err, IsNil) lb, err := New(fwd) c.Assert(err, IsNil) rb, err := NewRebalancer(lb, RebalancerBackoff(time.Millisecond), RebalancerClock(s.clock)) c.Assert(err, IsNil) rb.UpsertServer(testutils.ParseURI(a.URL)) rb.UpsertServer(testutils.ParseURI(b.URL)) rb.UpsertServer(testutils.ParseURI("http://localhost:62345")) proxy := httptest.NewServer(rb) defer proxy.Close() for i := 0; i < 1000; i += 1 { testutils.Get(proxy.URL) if i%10 == 0 { s.clock.CurrentTime = s.clock.CurrentTime.Add(rb.backoffDuration + time.Second) } } // load balancer changed weights c.Assert(rb.servers[0].curWeight, Equals, FSMMaxWeight) c.Assert(rb.servers[1].curWeight, Equals, FSMMaxWeight) c.Assert(rb.servers[2].curWeight, Equals, 1) }
func (s *RRSuite) TestUpsertWeight(c *C) { a := testutils.NewResponder("a") defer a.Close() b := testutils.NewResponder("b") defer b.Close() fwd, err := forward.New() c.Assert(err, IsNil) lb, err := New(fwd) c.Assert(err, IsNil) c.Assert(lb.UpsertServer(testutils.ParseURI(a.URL)), IsNil) c.Assert(lb.UpsertServer(testutils.ParseURI(b.URL)), IsNil) proxy := httptest.NewServer(lb) defer proxy.Close() c.Assert(seq(c, proxy.URL, 3), DeepEquals, []string{"a", "b", "a"}) c.Assert(lb.UpsertServer(testutils.ParseURI(b.URL), Weight(3)), IsNil) c.Assert(seq(c, proxy.URL, 4), DeepEquals, []string{"b", "b", "a", "b"}) }
// Test scenario when increaing the weight on good endpoints made it worse func (s *RBSuite) TestRebalancerCascading(c *C) { a, b, d := testutils.NewResponder("a"), testutils.NewResponder("b"), testutils.NewResponder("d") defer a.Close() defer b.Close() defer d.Close() fwd, err := forward.New() c.Assert(err, IsNil) lb, err := New(fwd) c.Assert(err, IsNil) newMeter := func() (Meter, error) { return &testMeter{}, nil } rb, err := NewRebalancer(lb, RebalancerMeter(newMeter), RebalancerClock(s.clock), RebalancerLogger(s.log)) c.Assert(err, IsNil) rb.UpsertServer(testutils.ParseURI(a.URL)) rb.UpsertServer(testutils.ParseURI(b.URL)) rb.UpsertServer(testutils.ParseURI(d.URL)) rb.servers[0].meter.(*testMeter).rating = 0.3 proxy := httptest.NewServer(rb) defer proxy.Close() for i := 0; i < 6; i += 1 { testutils.Get(proxy.URL) testutils.Get(proxy.URL) s.clock.CurrentTime = s.clock.CurrentTime.Add(rb.backoffDuration + time.Second) } // We have increased the load, and the situation became worse as the other servers started failing c.Assert(rb.servers[0].curWeight, Equals, 1) c.Assert(rb.servers[1].curWeight, Equals, FSMMaxWeight) c.Assert(rb.servers[2].curWeight, Equals, FSMMaxWeight) // server a is now recovering, the weights should go back to the original state rb.servers[0].meter.(*testMeter).rating = 0.3 rb.servers[1].meter.(*testMeter).rating = 0.2 rb.servers[2].meter.(*testMeter).rating = 0.2 for i := 0; i < 6; i += 1 { testutils.Get(proxy.URL) testutils.Get(proxy.URL) s.clock.CurrentTime = s.clock.CurrentTime.Add(rb.backoffDuration + time.Second) } // the algo reverted it back c.Assert(rb.servers[0].curWeight, Equals, 1) c.Assert(rb.servers[1].curWeight, Equals, 1) c.Assert(rb.servers[2].curWeight, Equals, 1) }
// Test scenario when one server goes down after what it recovers func (s *RBSuite) TestRebalancerRecovery(c *C) { a, b := testutils.NewResponder("a"), testutils.NewResponder("b") defer a.Close() defer b.Close() fwd, err := forward.New() c.Assert(err, IsNil) lb, err := New(fwd) c.Assert(err, IsNil) newMeter := func() (Meter, error) { return &testMeter{}, nil } rb, err := NewRebalancer(lb, RebalancerMeter(newMeter), RebalancerClock(s.clock), RebalancerLogger(s.log)) c.Assert(err, IsNil) rb.UpsertServer(testutils.ParseURI(a.URL)) rb.UpsertServer(testutils.ParseURI(b.URL)) rb.servers[0].meter.(*testMeter).rating = 0.3 proxy := httptest.NewServer(rb) defer proxy.Close() for i := 0; i < 6; i += 1 { testutils.Get(proxy.URL) testutils.Get(proxy.URL) s.clock.CurrentTime = s.clock.CurrentTime.Add(rb.backoffDuration + time.Second) } c.Assert(rb.servers[0].curWeight, Equals, 1) c.Assert(rb.servers[1].curWeight, Equals, FSMMaxWeight) c.Assert(lb.servers[0].weight, Equals, 1) c.Assert(lb.servers[1].weight, Equals, FSMMaxWeight) // server a is now recovering, the weights should go back to the original state rb.servers[0].meter.(*testMeter).rating = 0 for i := 0; i < 6; i += 1 { testutils.Get(proxy.URL) testutils.Get(proxy.URL) s.clock.CurrentTime = s.clock.CurrentTime.Add(rb.backoffDuration + time.Second) } c.Assert(rb.servers[0].curWeight, Equals, 1) c.Assert(rb.servers[1].curWeight, Equals, 1) // Make sure we have applied the weights to the inner load balancer c.Assert(lb.servers[0].weight, Equals, 1) c.Assert(lb.servers[1].weight, Equals, 1) }
func (s *ServerSuite) TestTakeFiles(c *C) { e := testutils.NewResponder("Hi, I'm endpoint 1") defer e.Close() c.Assert(s.mux.Start(), IsNil) b := MakeBatch(Batch{ Addr: "localhost:41000", Route: `Path("/")`, URL: e.URL, Protocol: engine.HTTPS, KeyPair: &engine.KeyPair{Key: localhostKey, Cert: localhostCert}, }) c.Assert(s.mux.UpsertHost(b.H), IsNil) c.Assert(s.mux.UpsertServer(b.BK, b.S), IsNil) c.Assert(s.mux.UpsertFrontend(b.F), IsNil) c.Assert(s.mux.UpsertListener(b.L), IsNil) c.Assert(GETResponse(c, b.FrontendURL("/")), Equals, "Hi, I'm endpoint 1") mux2, err := New(s.lastId, s.st, Options{}) c.Assert(err, IsNil) e2 := testutils.NewResponder("Hi, I'm endpoint 2") defer e2.Close() b2 := MakeBatch(Batch{ Addr: "localhost:41000", Route: `Path("/")`, URL: e2.URL, Protocol: engine.HTTPS, KeyPair: &engine.KeyPair{Key: localhostKey2, Cert: localhostCert2}, }) c.Assert(mux2.UpsertHost(b2.H), IsNil) c.Assert(mux2.UpsertServer(b2.BK, b2.S), IsNil) c.Assert(mux2.UpsertFrontend(b2.F), IsNil) c.Assert(mux2.UpsertListener(b2.L), IsNil) files, err := s.mux.GetFiles() c.Assert(err, IsNil) c.Assert(mux2.TakeFiles(files), IsNil) c.Assert(mux2.Start(), IsNil) s.mux.Stop(true) defer mux2.Stop(true) c.Assert(GETResponse(c, b2.FrontendURL("/")), Equals, "Hi, I'm endpoint 2") }
func (s *VESuite) TestExpiringServer(c *C) { server := testutils.NewResponder("e1") defer server.Close() server2 := testutils.NewResponder("e2") defer server2.Close() // Create backend and servers b, url, url2 := "bk1", server.URL, server2.URL srv, srv2 := "s1", "s2" _, err := s.client.Set(s.path("backends", b, "backend"), `{"Type": "http"}`, 0) c.Assert(err, IsNil) // This one will stay _, err = s.client.Set(s.path("backends", b, "servers", srv), fmt.Sprintf(`{"URL": "%s"}`, url), 0) c.Assert(err, IsNil) // This one will expire _, err = s.client.Set(s.path("backends", b, "servers", srv2), fmt.Sprintf(`{"URL": "%s"}`, url2), 2) c.Assert(err, IsNil) // Add frontend fId := "fr1" _, err = s.client.Set(s.path("frontends", fId, "frontend"), `{"Type": "http", "BackendId": "bk1", "Route": "Path(\"/path\")"}`, 0) c.Assert(err, IsNil) time.Sleep(time.Second) responses1 := make(map[string]bool) for i := 0; i < 3; i += 1 { response, body, err := testutils.Get(fmt.Sprintf("%s%s", s.serviceUrl, "/path")) c.Assert(err, IsNil) c.Assert(response.StatusCode, Equals, http.StatusOK) responses1[string(body)] = true } c.Assert(responses1, DeepEquals, map[string]bool{"e1": true, "e2": true}) // Now the second endpoint should expire time.Sleep(time.Second * 2) responses2 := make(map[string]bool) for i := 0; i < 3; i += 1 { response, body, err := testutils.Get(fmt.Sprintf("%s%s", s.serviceUrl, "/path")) c.Assert(err, IsNil) c.Assert(response.StatusCode, Equals, http.StatusOK) responses2[string(body)] = true } c.Assert(responses2, DeepEquals, map[string]bool{"e1": true}) }
func (s *ServerSuite) TestHostKeyPairUpdate(c *C) { e := testutils.NewResponder("Hi, I'm endpoint") defer e.Close() c.Assert(s.mux.Start(), IsNil) b := MakeBatch(Batch{ Addr: "localhost:31000", Route: `Path("/")`, URL: e.URL, Protocol: engine.HTTPS, KeyPair: &engine.KeyPair{Key: localhostKey, Cert: localhostCert}, }) c.Assert(s.mux.UpsertHost(b.H), IsNil) c.Assert(s.mux.UpsertServer(b.BK, b.S), IsNil) c.Assert(s.mux.UpsertFrontend(b.F), IsNil) c.Assert(s.mux.UpsertListener(b.L), IsNil) c.Assert(GETResponse(c, b.FrontendURL("/")), Equals, "Hi, I'm endpoint") b.H.Settings.KeyPair = &engine.KeyPair{Key: localhostKey2, Cert: localhostCert2} c.Assert(s.mux.UpsertHost(b.H), IsNil) c.Assert(GETResponse(c, b.FrontendURL("/")), Equals, "Hi, I'm endpoint") }
func (s *ServerSuite) TestListenerScopeUpdate(c *C) { e := testutils.NewResponder("Hi, I'm endpoint") defer e.Close() c.Assert(s.mux.Start(), IsNil) b := MakeBatch(Batch{Addr: "localhost:41000", Route: `Path("/")`, URL: e.URL}) c.Assert(s.mux.UpsertServer(b.BK, b.S), IsNil) c.Assert(s.mux.UpsertFrontend(b.F), IsNil) c.Assert(s.mux.UpsertListener(b.L), IsNil) re, body, err := testutils.Get(b.FrontendURL("/"), testutils.Host("otherhost")) c.Assert(err, IsNil) c.Assert(re.StatusCode, Equals, http.StatusOK) c.Assert(string(body), Equals, "Hi, I'm endpoint") b.L.Scope = `Host("localhost")` c.Assert(s.mux.UpsertListener(b.L), IsNil) re, body, err = testutils.Get(b.FrontendURL("/"), testutils.Host("localhost")) c.Assert(err, IsNil) c.Assert(re.StatusCode, Equals, http.StatusOK) c.Assert(string(body), Equals, "Hi, I'm endpoint") re, _, err = testutils.Get(b.FrontendURL("/"), testutils.Host("otherhost")) c.Assert(err, IsNil) c.Assert(re.StatusCode, Equals, http.StatusNotFound) }
func (s *ServerSuite) TestFrontendUpdateRoute(c *C) { c.Assert(s.mux.Start(), IsNil) e := testutils.NewResponder("hola") defer e.Close() b := MakeBatch(Batch{ Addr: "localhost:31000", Route: `Path("/")`, URL: e.URL, }) c.Assert(s.mux.UpsertServer(b.BK, b.S), IsNil) c.Assert(s.mux.UpsertFrontend(b.F), IsNil) c.Assert(s.mux.UpsertListener(b.L), IsNil) c.Assert(GETResponse(c, b.FrontendURL("/")), Equals, "hola") b.F.Route = `Path("/new")` c.Assert(s.mux.UpsertFrontend(b.F), IsNil) c.Assert(GETResponse(c, b.FrontendURL("/new")), Equals, "hola") response, _, err := testutils.Get(MakeURL(b.L, "/")) c.Assert(err, IsNil) c.Assert(response.StatusCode, Equals, http.StatusNotFound) }
func (s *ServerSuite) TestPerfMon(c *C) { c.Assert(s.mux.Start(), IsNil) e1 := testutils.NewResponder("Hi, I'm endpoint 1") defer e1.Close() b := MakeBatch(Batch{Addr: "localhost:11300", Route: `Path("/")`, URL: e1.URL}) c.Assert(s.mux.UpsertServer(b.BK, b.S), IsNil) c.Assert(s.mux.UpsertFrontend(b.F), IsNil) c.Assert(s.mux.UpsertListener(b.L), IsNil) c.Assert(GETResponse(c, b.FrontendURL("/")), Equals, "Hi, I'm endpoint 1") sURL, err := url.Parse(b.S.URL) c.Assert(err, IsNil) // Make sure server has been added to the performance monitor c.Assert(s.mux.frontends[b.FK].watcher.hasServer(sURL), Equals, true) c.Assert(s.mux.DeleteFrontend(b.FK), IsNil) // Delete the backend c.Assert(s.mux.DeleteBackend(b.BK), IsNil) }
func (s *ServerSuite) TestMiddlewareCRUD(c *C) { e := testutils.NewResponder("Hi, I'm endpoint 1") defer e.Close() c.Assert(s.mux.Start(), IsNil) b := MakeBatch(Batch{ Addr: "localhost:31000", Route: `Path("/")`, URL: e.URL, }) c.Assert(s.mux.UpsertServer(b.BK, b.S), IsNil) c.Assert(s.mux.UpsertFrontend(b.F), IsNil) c.Assert(s.mux.UpsertListener(b.L), IsNil) // 1 request per second rl := MakeRateLimit(UID("rl"), 1, "client.ip", 1, 1) _, err := rl.Middleware.NewHandler(nil) c.Assert(err, IsNil) c.Assert(s.mux.UpsertMiddleware(b.FK, rl), IsNil) c.Assert(GETResponse(c, b.FrontendURL("/")), Equals, "Hi, I'm endpoint 1") re, _, err := testutils.Get(MakeURL(b.L, "/")) c.Assert(err, IsNil) c.Assert(re.StatusCode, Equals, 429) // too many requests c.Assert(s.mux.DeleteMiddleware(engine.MiddlewareKey{FrontendKey: b.FK, Id: rl.Id}), IsNil) for i := 0; i < 3; i++ { c.Assert(GETResponse(c, b.FrontendURL("/")), Equals, "Hi, I'm endpoint 1") c.Assert(GETResponse(c, b.FrontendURL("/")), Equals, "Hi, I'm endpoint 1") } }
func (s *ServerSuite) TestFrontendSwitchBackend(c *C) { c.Assert(s.mux.Start(), IsNil) e1 := testutils.NewResponder("1") defer e1.Close() e2 := testutils.NewResponder("2") defer e2.Close() e3 := testutils.NewResponder("3") defer e3.Close() b := MakeBatch(Batch{ Addr: "localhost:31000", Route: `Path("/")`, URL: e1.URL, }) s1, s2, s3 := MakeServer(e1.URL), MakeServer(e2.URL), MakeServer(e3.URL) c.Assert(s.mux.UpsertServer(b.BK, s1), IsNil) c.Assert(s.mux.UpsertServer(b.BK, s2), IsNil) c.Assert(s.mux.UpsertFrontend(b.F), IsNil) c.Assert(s.mux.UpsertListener(b.L), IsNil) b2 := MakeBackend() b2k := engine.BackendKey{Id: b2.Id} c.Assert(s.mux.UpsertServer(b2k, s2), IsNil) c.Assert(s.mux.UpsertServer(b2k, s3), IsNil) responseSet := make(map[string]bool) responseSet[GETResponse(c, b.FrontendURL("/"))] = true responseSet[GETResponse(c, b.FrontendURL("/"))] = true c.Assert(responseSet, DeepEquals, map[string]bool{"1": true, "2": true}) b.F.BackendId = b2k.Id c.Assert(s.mux.UpsertFrontend(b.F), IsNil) responseSet = make(map[string]bool) responseSet[GETResponse(c, b.FrontendURL("/"))] = true responseSet[GETResponse(c, b.FrontendURL("/"))] = true c.Assert(responseSet, DeepEquals, map[string]bool{"2": true, "3": true}) }
// Removing the server resets the state func (s *RBSuite) TestRebalancerReset(c *C) { a, b, d := testutils.NewResponder("a"), testutils.NewResponder("b"), testutils.NewResponder("d") defer a.Close() defer b.Close() defer d.Close() fwd, err := forward.New() c.Assert(err, IsNil) lb, err := New(fwd) c.Assert(err, IsNil) newMeter := func() (Meter, error) { return &testMeter{}, nil } rb, err := NewRebalancer(lb, RebalancerMeter(newMeter), RebalancerClock(s.clock), RebalancerLogger(s.log)) c.Assert(err, IsNil) rb.UpsertServer(testutils.ParseURI(a.URL)) rb.UpsertServer(testutils.ParseURI(b.URL)) rb.UpsertServer(testutils.ParseURI(d.URL)) rb.servers[0].meter.(*testMeter).rating = 0.3 rb.servers[1].meter.(*testMeter).rating = 0 rb.servers[2].meter.(*testMeter).rating = 0 proxy := httptest.NewServer(rb) defer proxy.Close() for i := 0; i < 6; i += 1 { testutils.Get(proxy.URL) testutils.Get(proxy.URL) s.clock.CurrentTime = s.clock.CurrentTime.Add(rb.backoffDuration + time.Second) } // load balancer changed weights c.Assert(rb.servers[0].curWeight, Equals, 1) c.Assert(rb.servers[1].curWeight, Equals, FSMMaxWeight) c.Assert(rb.servers[2].curWeight, Equals, FSMMaxWeight) // Removing servers has reset the state rb.RemoveServer(testutils.ParseURI(d.URL)) c.Assert(rb.servers[0].curWeight, Equals, 1) c.Assert(rb.servers[1].curWeight, Equals, 1) }
func (s *ServerSuite) TestGetStats(c *C) { e1 := testutils.NewResponder("Hi, I'm endpoint 1") defer e1.Close() e2 := testutils.NewResponder("Hi, I'm endpoint 2") defer e2.Close() c.Assert(s.mux.Start(), IsNil) b := MakeBatch(Batch{Addr: "localhost:11300", Route: `Path("/")`, URL: e1.URL}) srv2 := MakeServer(e2.URL) c.Assert(s.mux.UpsertServer(b.BK, b.S), IsNil) c.Assert(s.mux.UpsertServer(b.BK, srv2), IsNil) c.Assert(s.mux.UpsertFrontend(b.F), IsNil) c.Assert(s.mux.UpsertListener(b.L), IsNil) for i := 0; i < 10; i++ { GETResponse(c, MakeURL(b.L, "/")) } stats, err := s.mux.ServerStats(b.SK) c.Assert(err, IsNil) c.Assert(stats, NotNil) fStats, err := s.mux.FrontendStats(b.FK) c.Assert(fStats, NotNil) c.Assert(err, IsNil) bStats, err := s.mux.BackendStats(b.BK) c.Assert(bStats, NotNil) c.Assert(err, IsNil) topF, err := s.mux.TopFrontends(nil) c.Assert(err, IsNil) c.Assert(len(topF), Equals, 1) topServers, err := s.mux.TopServers(nil) c.Assert(err, IsNil) c.Assert(len(topServers), Equals, 2) // emit stats works without errors c.Assert(s.mux.emitMetrics(), IsNil) }
func (s *ServerSuite) TestSNI(c *C) { e := testutils.NewResponder("Hi, I'm endpoint 1") defer e.Close() e2 := testutils.NewResponder("Hi, I'm endpoint 2") defer e2.Close() c.Assert(s.mux.Start(), IsNil) b := MakeBatch(Batch{ Host: "localhost", Addr: "localhost:41000", Route: `Host("localhost") && Path("/")`, URL: e.URL, Protocol: engine.HTTPS, KeyPair: &engine.KeyPair{Key: localhostKey, Cert: localhostCert}, }) b2 := MakeBatch(Batch{ Host: "otherhost", Addr: "localhost:41000", Route: `Host("otherhost") && Path("/")`, URL: e2.URL, Protocol: engine.HTTPS, KeyPair: &engine.KeyPair{Key: localhostKey2, Cert: localhostCert2}, }) b2.H.Settings.Default = true c.Assert(s.mux.UpsertHost(b.H), IsNil) c.Assert(s.mux.UpsertHost(b2.H), IsNil) c.Assert(s.mux.UpsertServer(b.BK, b.S), IsNil) c.Assert(s.mux.UpsertServer(b2.BK, b2.S), IsNil) c.Assert(s.mux.UpsertFrontend(b.F), IsNil) c.Assert(s.mux.UpsertFrontend(b2.F), IsNil) c.Assert(s.mux.UpsertListener(b.L), IsNil) c.Assert(GETResponse(c, b.FrontendURL("/"), testutils.Host("localhost")), Equals, "Hi, I'm endpoint 1") c.Assert(GETResponse(c, b.FrontendURL("/"), testutils.Host("otherhost")), Equals, "Hi, I'm endpoint 2") }
func (s *RBSuite) TestRebalancerNormalOperation(c *C) { a, b := testutils.NewResponder("a"), testutils.NewResponder("b") defer a.Close() defer b.Close() fwd, err := forward.New() c.Assert(err, IsNil) lb, err := New(fwd) c.Assert(err, IsNil) rb, err := NewRebalancer(lb) c.Assert(err, IsNil) rb.UpsertServer(testutils.ParseURI(a.URL)) c.Assert(rb.Servers()[0].String(), Equals, a.URL) proxy := httptest.NewServer(rb) defer proxy.Close() c.Assert(seq(c, proxy.URL, 3), DeepEquals, []string{"a", "a", "a"}) }
func (s *ServerSuite) TestServerUpsertURL(c *C) { c.Assert(s.mux.Start(), IsNil) e1 := testutils.NewResponder("Hi, I'm endpoint 1") defer e1.Close() e2 := testutils.NewResponder("Hi, I'm endpoint 2") defer e2.Close() b := MakeBatch(Batch{Addr: "localhost:11300", Route: `Path("/")`, URL: e1.URL}) c.Assert(s.mux.UpsertServer(b.BK, b.S), IsNil) c.Assert(s.mux.UpsertFrontend(b.F), IsNil) c.Assert(s.mux.UpsertListener(b.L), IsNil) c.Assert(GETResponse(c, b.FrontendURL("/")), Equals, "Hi, I'm endpoint 1") b.S.URL = e2.URL c.Assert(s.mux.UpsertServer(b.BK, b.S), IsNil) c.Assert(GETResponse(c, b.FrontendURL("/")), Equals, "Hi, I'm endpoint 2") }
func (s *ServerSuite) TestBackendUpdate(c *C) { c.Assert(s.mux.Start(), IsNil) e1 := testutils.NewResponder("1") defer e1.Close() e2 := testutils.NewResponder("2") defer e2.Close() b := MakeBatch(Batch{ Addr: "localhost:31000", Route: `Path("/")`, URL: e1.URL, }) s1, s2 := MakeServer(e1.URL), MakeServer(e2.URL) c.Assert(s.mux.UpsertServer(b.BK, s1), IsNil) c.Assert(s.mux.UpsertServer(b.BK, s2), IsNil) c.Assert(s.mux.UpsertFrontend(b.F), IsNil) c.Assert(s.mux.UpsertListener(b.L), IsNil) responseSet := make(map[string]bool) responseSet[GETResponse(c, b.FrontendURL("/"))] = true responseSet[GETResponse(c, b.FrontendURL("/"))] = true c.Assert(responseSet, DeepEquals, map[string]bool{"1": true, "2": true}) sk2 := engine.ServerKey{BackendKey: b.BK, Id: s2.Id} c.Assert(s.mux.DeleteServer(sk2), IsNil) responseSet = make(map[string]bool) responseSet[GETResponse(c, b.FrontendURL("/"))] = true responseSet[GETResponse(c, b.FrontendURL("/"))] = true c.Assert(responseSet, DeepEquals, map[string]bool{"1": true}) }
// Test case when you have two hosts on the same socket func (s *ServerSuite) TestTwoHosts(c *C) { e := testutils.NewResponder("Hi, I'm endpoint 1") defer e.Close() e2 := testutils.NewResponder("Hi, I'm endpoint 2") defer e2.Close() c.Assert(s.mux.Start(), IsNil) b := MakeBatch(Batch{Addr: "localhost:41000", Route: `Host("localhost") && Path("/")`, URL: e.URL}) b2 := MakeBatch(Batch{Addr: "localhost:41000", Route: `Host("otherhost") && Path("/")`, URL: e2.URL}) c.Assert(s.mux.UpsertServer(b.BK, b.S), IsNil) c.Assert(s.mux.UpsertServer(b2.BK, b2.S), IsNil) c.Assert(s.mux.UpsertFrontend(b.F), IsNil) c.Assert(s.mux.UpsertFrontend(b2.F), IsNil) c.Assert(s.mux.UpsertListener(b.L), IsNil) c.Assert(GETResponse(c, b.FrontendURL("/"), testutils.Host("localhost")), Equals, "Hi, I'm endpoint 1") c.Assert(GETResponse(c, b.FrontendURL("/"), testutils.Host("otherhost")), Equals, "Hi, I'm endpoint 2") }
func (s *ServerSuite) TestOCSPStapling(c *C) { e := testutils.NewResponder("Hi, I'm endpoint") defer e.Close() c.Assert(s.mux.Start(), IsNil) srv := NewOCSPResponder() defer srv.Close() b := MakeBatch(Batch{ Addr: "localhost:31000", Route: `Path("/")`, URL: e.URL, Protocol: engine.HTTPS, }) b.H.Settings = engine.HostSettings{ KeyPair: &engine.KeyPair{Key: LocalhostKey, Cert: LocalhostCertChain}, OCSP: engine.OCSPSettings{Enabled: true, Period: "1h", Responders: []string{srv.URL}, SkipSignatureCheck: true}, } c.Assert(s.mux.UpsertHost(b.H), IsNil) c.Assert(s.mux.UpsertServer(b.BK, b.S), IsNil) c.Assert(s.mux.UpsertFrontend(b.F), IsNil) c.Assert(s.mux.UpsertListener(b.L), IsNil) conn, err := tls.Dial("tcp", b.L.Address.Address, &tls.Config{ InsecureSkipVerify: true, }) c.Assert(err, IsNil) fmt.Fprintf(conn, "GET / HTTP/1.0\r\n\r\n") status, err := bufio.NewReader(conn).ReadString('\n') c.Assert(err, IsNil) c.Assert(status, Equals, "HTTP/1.0 200 OK\r\n") re := conn.OCSPResponse() c.Assert(re, DeepEquals, OCSPResponseBytes) conn.Close() // Make sure that deleting the host clears the cache hk := engine.HostKey{Name: b.H.Name} c.Assert(s.mux.stapler.HasHost(hk), Equals, true) c.Assert(s.mux.DeleteHost(hk), IsNil) c.Assert(s.mux.stapler.HasHost(hk), Equals, false) }
func (s *ServerSuite) TestServerDefaultListener(c *C) { e := testutils.NewResponder("Hi, I'm endpoint") defer e.Close() b := MakeBatch(Batch{Addr: "localhost:41000", Route: `Path("/")`, URL: e.URL}) m, err := New(s.lastId, s.st, Options{DefaultListener: &b.L}) defer m.Stop(true) c.Assert(err, IsNil) s.mux = m c.Assert(s.mux.UpsertServer(b.BK, b.S), IsNil) c.Assert(s.mux.UpsertFrontend(b.F), IsNil) c.Assert(s.mux.Start(), IsNil) c.Assert(GETResponse(c, b.FrontendURL("/")), Equals, "Hi, I'm endpoint") }
func (s *ServerSuite) TestServerUpsertSame(c *C) { e := testutils.NewResponder("Hi, I'm endpoint") defer e.Close() b := MakeBatch(Batch{Addr: "localhost:11300", Route: `Path("/")`, URL: e.URL}) c.Assert(s.mux.UpsertServer(b.BK, b.S), IsNil) c.Assert(s.mux.UpsertFrontend(b.F), IsNil) c.Assert(s.mux.UpsertListener(b.L), IsNil) c.Assert(s.mux.Start(), IsNil) c.Assert(GETResponse(c, b.FrontendURL("/")), Equals, "Hi, I'm endpoint") c.Assert(s.mux.UpsertServer(b.BK, b.S), IsNil) c.Assert(len(s.mux.backends[b.BK].servers), Equals, 1) c.Assert(GETResponse(c, b.FrontendURL("/")), Equals, "Hi, I'm endpoint") }
// Here we upsert only server that creates backend with default settings func (s *ServerSuite) TestServerCRUD(c *C) { e := testutils.NewResponder("Hi, I'm endpoint") defer e.Close() b := MakeBatch(Batch{Addr: "localhost:11300", Route: `Path("/")`, URL: e.URL}) c.Assert(s.mux.UpsertServer(b.BK, b.S), IsNil) c.Assert(s.mux.UpsertFrontend(b.F), IsNil) c.Assert(s.mux.UpsertListener(b.L), IsNil) c.Assert(s.mux.Start(), IsNil) c.Assert(GETResponse(c, b.FrontendURL("/")), Equals, "Hi, I'm endpoint") c.Assert(s.mux.DeleteListener(b.LK), IsNil) _, _, err := testutils.Get(b.FrontendURL("/")) c.Assert(err, NotNil) }
func (s *ServerSuite) TestServerAddBad(c *C) { e := testutils.NewResponder("Hi, I'm endpoint") defer e.Close() c.Assert(s.mux.Start(), IsNil) b := MakeBatch(Batch{Addr: "localhost:11500", Route: `Path("/")`, URL: e.URL}) c.Assert(s.mux.UpsertServer(b.BK, b.S), IsNil) c.Assert(s.mux.UpsertFrontend(b.F), IsNil) c.Assert(s.mux.UpsertListener(b.L), IsNil) c.Assert(GETResponse(c, b.FrontendURL("/")), Equals, "Hi, I'm endpoint") bad := engine.Server{Id: UID("srv"), URL: ""} c.Assert(s.mux.UpsertServer(b.BK, bad), NotNil) c.Assert(GETResponse(c, b.FrontendURL("/")), Equals, "Hi, I'm endpoint") c.Assert(GETResponse(c, b.FrontendURL("/")), Equals, "Hi, I'm endpoint") }
func (s *ServerSuite) TestListenerCRUD(c *C) { e := testutils.NewResponder("Hi, I'm endpoint") defer e.Close() c.Assert(s.mux.Start(), IsNil) b := MakeBatch(Batch{Addr: "localhost:41000", Route: `Host("localhost") && Path("/")`, URL: e.URL}) c.Assert(s.mux.UpsertServer(b.BK, b.S), IsNil) c.Assert(s.mux.UpsertFrontend(b.F), IsNil) c.Assert(s.mux.UpsertListener(b.L), IsNil) c.Assert(GETResponse(c, b.FrontendURL("/")), Equals, "Hi, I'm endpoint") l2 := MakeListener("localhost:41001", engine.HTTP) c.Assert(s.mux.UpsertListener(l2), IsNil) c.Assert(GETResponse(c, MakeURL(l2, "/")), Equals, "Hi, I'm endpoint") c.Assert(s.mux.DeleteListener(engine.ListenerKey{Id: l2.Id}), IsNil) _, _, err := testutils.Get(MakeURL(l2, "/")) c.Assert(err, NotNil) }
func (s *ServerSuite) TestFrontendOptionsCRUD(c *C) { e := testutils.NewResponder("Hi, I'm endpoint 1") defer e.Close() c.Assert(s.mux.Start(), IsNil) b := MakeBatch(Batch{ Addr: "localhost:31000", Route: `Path("/")`, URL: e.URL, }) c.Assert(s.mux.UpsertServer(b.BK, b.S), IsNil) c.Assert(s.mux.UpsertFrontend(b.F), IsNil) c.Assert(s.mux.UpsertListener(b.L), IsNil) body := "Hello, this request is longer than 8 bytes" response, bodyBytes, err := testutils.MakeRequest(MakeURL(b.L, "/"), testutils.Body(body)) c.Assert(err, IsNil) c.Assert(string(bodyBytes), Equals, "Hi, I'm endpoint 1") c.Assert(response.StatusCode, Equals, http.StatusOK) settings := engine.HTTPFrontendSettings{ Limits: engine.HTTPFrontendLimits{ MaxBodyBytes: 8, }, FailoverPredicate: "IsNetworkError()", } b.F.Settings = settings c.Assert(s.mux.UpsertFrontend(b.F), IsNil) response, _, err = testutils.MakeRequest(MakeURL(b.L, "/"), testutils.Body(body)) c.Assert(err, IsNil) c.Assert(response.StatusCode, Equals, http.StatusRequestEntityTooLarge) }