// Copyright 2015-2016 Apcera Inc. All rights reserved. package server import ( "net" "strings" "testing" "time" ) var DefaultOptions = Options{ Host: "localhost", Port: 11222, HTTPPort: 11333, ClusterPort: 11444, ProfPort: 11280, NoLog: true, NoSigs: true, } // New Go Routine based server func RunServer(opts *Options) *Server { if opts == nil { opts = &DefaultOptions } s := New(opts) if s == nil { panic("No NATS Server object returned.") } // Run server in Go routine. go s.Start() end := time.Now().Add(10 * time.Second) for time.Now().Before(end) { addr := s.GetListenEndpoint() if addr == "" { time.Sleep(10 * time.Millisecond) // Retry. We might take a little while to open a connection. continue } conn, err := net.Dial("tcp", addr) if err != nil { // Retry after 50ms time.Sleep(50 * time.Millisecond) continue } conn.Close() // Wait a bit to give a chance to the server to remove this // "client" from its state, which may otherwise interfere with // some tests. time.Sleep(25 * time.Millisecond) return s } panic("Unable to start NATS Server in Go Routine") } func TestStartupAndShutdown(t *testing.T) { s := RunServer(&DefaultOptions) defer s.Shutdown() if !s.isRunning() { t.Fatal("Could not run server") } // Debug stuff. numRoutes := s.NumRoutes() if numRoutes != 0 { t.Fatalf("Expected numRoutes to be 0 vs %d\n", numRoutes) } numRemotes := s.NumRemotes() if numRemotes != 0 { t.Fatalf("Expected numRemotes to be 0 vs %d\n", numRemotes) } numClients := s.NumClients() if numClients != 0 && numClients != 1 { t.Fatalf("Expected numClients to be 1 or 0 vs %d\n", numClients) } numSubscriptions := s.NumSubscriptions() if numSubscriptions != 0 { t.Fatalf("Expected numSubscriptions to be 0 vs %d\n", numSubscriptions) } } func TestTlsCipher(t *testing.T) { if strings.Compare(tlsCipher(0x0005), "TLS_RSA_WITH_RC4_128_SHA") != 0 { t.Fatalf("Invalid tls cipher") } if strings.Compare(tlsCipher(0x000a), "TLS_RSA_WITH_3DES_EDE_CBC_SHA") != 0 { t.Fatalf("Invalid tls cipher") } if strings.Compare(tlsCipher(0x002f), "TLS_RSA_WITH_AES_128_CBC_SHA") != 0 { t.Fatalf("Invalid tls cipher") } if strings.Compare(tlsCipher(0x0035), "TLS_RSA_WITH_AES_256_CBC_SHA") != 0 { t.Fatalf("Invalid tls cipher") } if strings.Compare(tlsCipher(0xc007), "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA") != 0 { t.Fatalf("Invalid tls cipher") } if strings.Compare(tlsCipher(0xc009), "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA") != 0 { t.Fatalf("Invalid tls cipher") } if strings.Compare(tlsCipher(0xc00a), "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA") != 0 { t.Fatalf("Invalid tls cipher") } if strings.Compare(tlsCipher(0xc011), "TLS_ECDHE_RSA_WITH_RC4_128_SHA") != 0 { t.Fatalf("Invalid tls cipher") } if strings.Compare(tlsCipher(0xc012), "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA") != 0 { t.Fatalf("Invalid tls cipher") } if strings.Compare(tlsCipher(0xc013), "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA") != 0 { t.Fatalf("Invalid tls cipher") } if strings.Compare(tlsCipher(0xc014), "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA") != 0 { t.Fatalf("IUnknownnvalid tls cipher") } if strings.Compare(tlsCipher(0xc02f), "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256") != 0 { t.Fatalf("Invalid tls cipher") } if strings.Compare(tlsCipher(0xc02b), "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256") != 0 { t.Fatalf("Invalid tls cipher") } if strings.Compare(tlsCipher(0xc030), "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384") != 0 { t.Fatalf("Invalid tls cipher") } if strings.Compare(tlsCipher(0xc02c), "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384") != 0 { t.Fatalf("Invalid tls cipher") } if !strings.Contains(tlsCipher(0x9999), "Unknown") { t.Fatalf("Expected an unknown cipher.") } } func TestGetConnectURLs(t *testing.T) { opts := DefaultOptions opts.Port = 4222 var globalIP net.IP checkGlobalConnectURLs := func() { s := New(&opts) defer s.Shutdown() urls := s.getClientConnectURLs() if len(urls) == 0 { t.Fatalf("Expected to get a list of urls, got none for listen addr: %v", opts.Host) } for _, u := range urls { tcpaddr, err := net.ResolveTCPAddr("tcp", u) if err != nil { t.Fatalf("Error resolving: %v", err) } ip := tcpaddr.IP if !ip.IsGlobalUnicast() { t.Fatalf("IP %v is not global", ip.String()) } if ip.IsUnspecified() { t.Fatalf("IP %v is unspecified", ip.String()) } addr := strings.TrimSuffix(u, ":4222") if addr == opts.Host { t.Fatalf("Returned url is not right: %v", u) } if globalIP == nil { globalIP = ip } } } listenAddrs := []string{"0.0.0.0", "::"} for _, listenAddr := range listenAddrs { opts.Host = listenAddr checkGlobalConnectURLs() } checkConnectURLsHasOnlyOne := func() { s := New(&opts) defer s.Shutdown() urls := s.getClientConnectURLs() if len(urls) != 1 { t.Fatalf("Expected one URL, got %v", urls) } tcpaddr, err := net.ResolveTCPAddr("tcp", urls[0]) if err != nil { t.Fatalf("Error resolving: %v", err) } ip := tcpaddr.IP if ip.String() != opts.Host { t.Fatalf("Expected connect URL to be %v, got %v", opts.Host, ip.String()) } } singleConnectReturned := []string{"127.0.0.1", "::1"} if globalIP != nil { singleConnectReturned = append(singleConnectReturned, globalIP.String()) } for _, listenAddr := range singleConnectReturned { opts.Host = listenAddr checkConnectURLsHasOnlyOne() } } func TestNoDeadlockOnStartFailure(t *testing.T) { opts := DefaultOptions opts.Host = "x.x.x.x" // bad host opts.Port = 4222 opts.ClusterHost = "localhost" opts.ClusterPort = 6222 s := New(&opts) // This should return since it should fail to start a listener // on x.x.x.x:4222 s.Start() // We should be able to shutdown s.Shutdown() }