func TestChainedSolicitWorks(t *testing.T) { s1, opts := runSeedServer(t) defer s1.Shutdown() // Create the routes string for others to connect to the seed. routesStr := fmt.Sprintf("nats-route://%s:%d/", opts.ClusterHost, opts.ClusterPort) // Run Server #2 s2Opts := nextServerOpts(opts) s2Opts.Routes = server.RoutesFromStr(routesStr) s2 := RunServer(s2Opts) defer s2.Shutdown() // Run Server #3 s3Opts := nextServerOpts(s2Opts) // We will have s3 connect to s2, not the seed. routesStr = fmt.Sprintf("nats-route://%s:%d/", s2Opts.ClusterHost, s2Opts.ClusterPort) s3Opts.Routes = server.RoutesFromStr(routesStr) s3 := RunServer(s3Opts) defer s3.Shutdown() // Wait for a bit for graph to connect time.Sleep(500 * time.Millisecond) // Grab Routez from monitor ports, make sure we are fully connected url := fmt.Sprintf("http://%s:%d/", opts.Host, opts.HTTPPort) rz := readHttpRoutez(t, url) ris := expectRids(t, rz, []string{s2.Id(), s3.Id()}) if ris[s2.Id()].IsConfigured == true { t.Fatalf("Expected server not to be configured\n") } if ris[s3.Id()].IsConfigured == true { t.Fatalf("Expected server not to be configured\n") } url = fmt.Sprintf("http://%s:%d/", s2Opts.Host, s2Opts.HTTPPort) rz = readHttpRoutez(t, url) ris = expectRids(t, rz, []string{s1.Id(), s3.Id()}) if ris[s1.Id()].IsConfigured != true { t.Fatalf("Expected seed server to be configured\n") } if ris[s3.Id()].IsConfigured == true { t.Fatalf("Expected server not to be configured\n") } url = fmt.Sprintf("http://%s:%d/", s3Opts.Host, s3Opts.HTTPPort) rz = readHttpRoutez(t, url) ris = expectRids(t, rz, []string{s1.Id(), s2.Id()}) if ris[s2.Id()].IsConfigured != true { t.Fatalf("Expected s2 server to be configured\n") } if ris[s1.Id()].IsConfigured == true { t.Fatalf("Expected seed server not to be configured\n") } }
func configureClusterOpts(opts *server.Options) error { // If we don't have cluster defined in the configuration // file and no cluster listen string override, but we do // have a routes override, we need to report misconfiguration. if opts.Cluster.ListenStr == "" && opts.Cluster.Host == "" && opts.Cluster.Port == 0 { if opts.RoutesStr != "" { server.PrintAndDie("Solicited routes require cluster capabilities, e.g. --cluster.") } return nil } // If cluster flag override, process it if opts.Cluster.ListenStr != "" { clusterURL, err := url.Parse(opts.Cluster.ListenStr) h, p, err := net.SplitHostPort(clusterURL.Host) if err != nil { return err } opts.Cluster.Host = h _, err = fmt.Sscan(p, &opts.Cluster.Port) if err != nil { return err } if clusterURL.User != nil { pass, hasPassword := clusterURL.User.Password() if !hasPassword { return fmt.Errorf("Expected cluster password to be set.") } opts.Cluster.Password = pass user := clusterURL.User.Username() opts.Cluster.Username = user } else { // Since we override from flag and there is no user/pwd, make // sure we clear what we may have gotten from config file. opts.Cluster.Username = "" opts.Cluster.Password = "" } } // If we have routes but no config file, fill in here. if opts.RoutesStr != "" && opts.Routes == nil { opts.Routes = server.RoutesFromStr(opts.RoutesStr) } return nil }
func configureClusterOpts(opts *server.Options) error { if opts.ClusterListenStr == "" { if opts.RoutesStr != "" { server.PrintAndDie("Solicited routes require cluster capabilities, e.g. --cluster.") } return nil } clusterURL, err := url.Parse(opts.ClusterListenStr) h, p, err := net.SplitHostPort(clusterURL.Host) if err != nil { return err } opts.ClusterHost = h _, err = fmt.Sscan(p, &opts.ClusterPort) if err != nil { return err } if clusterURL.User != nil { pass, hasPassword := clusterURL.User.Password() if !hasPassword { return fmt.Errorf("Expected cluster password to be set.") } opts.ClusterPassword = pass user := clusterURL.User.Username() opts.ClusterUsername = user } // If we have routes but no config file, fill in here. if opts.RoutesStr != "" && opts.Routes == nil { opts.Routes = server.RoutesFromStr(opts.RoutesStr) } return nil }
func TestStressChainedSolicitWorks(t *testing.T) { s1, opts := runSeedServer(t) defer s1.Shutdown() // Create the routes string for s2 to connect to the seed routesStr := fmt.Sprintf("nats-route://%s:%d/", opts.Cluster.Host, opts.Cluster.Port) s2Opts := nextServerOpts(opts) s2Opts.Routes = server.RoutesFromStr(routesStr) s3Opts := nextServerOpts(s2Opts) // Create the routes string for s3 to connect to s2 routesStr = fmt.Sprintf("nats-route://%s:%d/", s2Opts.Cluster.Host, s2Opts.Cluster.Port) s3Opts.Routes = server.RoutesFromStr(routesStr) s4Opts := nextServerOpts(s3Opts) // Create the routes string for s4 to connect to s3 routesStr = fmt.Sprintf("nats-route://%s:%d/", s3Opts.Cluster.Host, s3Opts.Cluster.Port) s4Opts.Routes = server.RoutesFromStr(routesStr) for i := 0; i < 10; i++ { func() { // Run these servers manually, because we want them to start and // connect to s1 as fast as possible. s2 := server.New(s2Opts) if s2 == nil { panic("No NATS Server object returned.") } defer s2.Shutdown() go s2.Start() s3 := server.New(s3Opts) if s3 == nil { panic("No NATS Server object returned.") } defer s3.Shutdown() go s3.Start() s4 := server.New(s4Opts) if s4 == nil { panic("No NATS Server object returned.") } defer s4.Shutdown() go s4.Start() serversInfo := []serverInfo{{s1, opts}, {s2, s2Opts}, {s3, s3Opts}, {s4, s4Opts}} var err error maxTime := time.Now().Add(5 * time.Second) for time.Now().Before(maxTime) { resetPreviousHTTPConnections() for j := 0; j < len(serversInfo); j++ { err = checkConnected(t, serversInfo, j, false) // If error, start this for loop from beginning if err != nil { // Sleep a bit before the next attempt time.Sleep(100 * time.Millisecond) break } } // All servers checked ok, we are done, otherwise, try again // until time is up if err == nil { break } } // Report error if err != nil { t.Fatalf("Error: %v", err) } }() maxTime := time.Now().Add(2 * time.Second) for time.Now().Before(maxTime) { if s1.NumRoutes() > 0 { time.Sleep(10 * time.Millisecond) } else { break } } } }