func TestLBUtilsCallSvc(t *testing.T) { serverResp := "Hello, client" var server1Called, server2Called bool server1 := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { server1Called = true w.Write([]byte(serverResp)) })) defer server1.Close() server2 := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { server2Called = true w.Write([]byte(serverResp)) })) defer server2.Close() kvs := buildTestConfigForLBCall(t, server1.URL, server2.URL) sc, err := config.ReadServiceConfig("lbclistener", kvs) assert.Nil(t, err) assert.NotNil(t, sc) config.RecordActiveConfig(sc) lb, err := NewBackendLoadBalancer("lbcbackend") assert.Nil(t, err) req, err := http.NewRequest("GET", "/foo", nil) assert.Nil(t, err) //Call 1 resp, err := lb.DoWithLoadBalancer(req, false) if assert.Nil(t, err) { defer resp.Body.Close() b, err := ioutil.ReadAll(resp.Body) assert.Nil(t, err) assert.Equal(t, serverResp, string(b)) } //Call 2 resp, err = lb.DoWithLoadBalancer(req, false) if assert.Nil(t, err) { defer resp.Body.Close() b, err := ioutil.ReadAll(resp.Body) assert.Nil(t, err) assert.Equal(t, serverResp, string(b)) } //Make sure both servers were called assert.True(t, server1Called, "Expected server 1 to be called") assert.True(t, server2Called, "Expected server 2 to be called") }
func TestLBUtilsNoSuchBackend(t *testing.T) { kvs := config.BuildKVStoreTestConfig(t) assert.NotNil(t, kvs) sc, err := config.ReadServiceConfig("listener", kvs) assert.Nil(t, err) assert.NotNil(t, sc) config.RecordActiveConfig(sc) lb, err := NewBackendLoadBalancer("no-such-backed") assert.Nil(t, lb) assert.NotNil(t, err) assert.Equal(t, ErrBackendNotFound, err) }
func main() { //Allow expvar monitoring go http.ListenAndServe(":1234", nil) //Initialize the KVStore from the local file store established by running //the set up script endpoint := os.Getenv(env.KVStoreURL) if endpoint == "" { log.Fatal(fmt.Sprintf("Required environment variable %s for configuration KV store must be specified", env.KVStoreURL)) } kvs, err := kvstore.NewKVStore(endpoint) fatal(err) //Since no listener is in context in this sample process, register //the configuration so NewBackendLoadBalancer has it in context. sc, err := config.ReadServiceConfig("quote-listener", kvs) fatal(err) config.RecordActiveConfig(sc) //Instantiate the load balancer for the quote-backend lb, err := loadbalancer.NewBackendLoadBalancer("quote-backend") fatal(err) for i := 1; i < 10000; i++ { req, err := http.NewRequest("GET", "https://hostname:4443", nil) fatal(err) resp, err := lb.DoWithLoadBalancer(req, true) fatal(err) _, err = ioutil.ReadAll(resp.Body) fatal(err) resp.Body.Close() if i%100 == 0 { fmt.Printf("Done %d calls...\n", i) } } time.Sleep(300 * time.Second) }
func TestLBUtilsBuildFromConfig(t *testing.T) { kvs := config.BuildKVStoreTestConfig(t) assert.NotNil(t, kvs) sc, err := config.ReadServiceConfig("listener", kvs) assert.Nil(t, err) assert.NotNil(t, sc) config.RecordActiveConfig(sc) lb, err := NewBackendLoadBalancer("hello-backend") assert.Nil(t, err) assert.NotNil(t, lb) assert.Equal(t, "hello-backend", lb.BackendConfig.Name) assert.Equal(t, "", lb.BackendConfig.CACertPath) assert.Equal(t, 2, len(lb.BackendConfig.ServerNames)) h, _ := lb.LoadBalancer.GetEndpoints() if assert.True(t, len(h) == 2) { assert.Equal(t, "localhost:3000", h[0]) assert.Equal(t, "localhost:3100", h[1]) } }
//Run executes the Listen command with the supplied arguments func (l *Listen) Run(args []string) int { config.ListenContext = true var listener, address, cpuprofile string cmdFlags := flag.NewFlagSet("listen", flag.ContinueOnError) cmdFlags.Usage = func() { l.UI.Error(l.Help()) } cmdFlags.StringVar(&listener, "ln", "", "") cmdFlags.StringVar(&address, "address", "", "") cmdFlags.StringVar(&cpuprofile, "cpuprofile", "", "write cpu profile to file") if err := cmdFlags.Parse(args); err != nil { return 1 } argErr := false //Check listener if listener == "" { l.UI.Error("Listener name must be specified") argErr = true } //Check address if address == "" { l.UI.Error("Address must be specified") argErr = true } if argErr { l.UI.Error("") l.UI.Error(l.Help()) return 1 } if cpuprofile != "" { f, err := os.Create(cpuprofile) if err != nil { l.UI.Error(err.Error()) return 1 } pprof.StartCPUProfile(f) defer pprof.StopCPUProfile() } //Read and record the listener config so it is available to the plugin chain serviceConfig, err := config.ReadServiceConfig(listener, l.KVStore) if err != nil { l.UI.Error(err.Error()) return 1 } config.RecordActiveConfig(serviceConfig) //Build the service for the named listener s, err := service.BuildServiceForListener(listener, address, l.KVStore) if err != nil { l.UI.Error(err.Error()) return 1 } l.UI.Info(fmt.Sprintf("***Service:\n%s", s)) exitChannel := make(chan int) signalChannel := make(chan os.Signal, 1) signal.Notify(signalChannel, os.Interrupt) go func() { for _ = range signalChannel { exitChannel <- 0 } }() go func(service service.Service) { service.Run() //Run can return if it can't open ports, etc. exitChannel <- 1 }(s) exitStatus := <-exitChannel fmt.Printf("exiting with status %d\n", exitStatus) return exitStatus }