get.pme.sh/pnats@v0.0.0-20240304004023-26bb5a137ed0/test/ping_test.go (about)

     1  // Copyright 2012-2019 The NATS Authors
     2  // Licensed under the Apache License, Version 2.0 (the "License");
     3  // you may not use this file except in compliance with the License.
     4  // You may obtain a copy of the License at
     5  //
     6  // http://www.apache.org/licenses/LICENSE-2.0
     7  //
     8  // Unless required by applicable law or agreed to in writing, software
     9  // distributed under the License is distributed on an "AS IS" BASIS,
    10  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package test
    15  
    16  import (
    17  	"crypto/tls"
    18  	"fmt"
    19  	"net"
    20  	"testing"
    21  	"time"
    22  
    23  	"get.pme.sh/pnats/server"
    24  )
    25  
    26  const (
    27  	PING_TEST_PORT = 9972
    28  	PING_INTERVAL  = 50 * time.Millisecond
    29  	PING_MAX       = 2
    30  )
    31  
    32  func runPingServer() *server.Server {
    33  	opts := DefaultTestOptions
    34  	opts.Port = PING_TEST_PORT
    35  	opts.PingInterval = PING_INTERVAL
    36  	opts.MaxPingsOut = PING_MAX
    37  	return RunServer(&opts)
    38  }
    39  
    40  func TestPingSentToTLSConnection(t *testing.T) {
    41  	opts := DefaultTestOptions
    42  	opts.Port = PING_TEST_PORT
    43  	opts.PingInterval = PING_INTERVAL
    44  	opts.MaxPingsOut = PING_MAX
    45  	opts.TLSCert = "configs/certs/server-cert.pem"
    46  	opts.TLSKey = "configs/certs/server-key.pem"
    47  	opts.TLSCaCert = "configs/certs/ca.pem"
    48  
    49  	tc := server.TLSConfigOpts{}
    50  	tc.CertFile = opts.TLSCert
    51  	tc.KeyFile = opts.TLSKey
    52  	tc.CaFile = opts.TLSCaCert
    53  
    54  	opts.TLSConfig, _ = server.GenTLSConfig(&tc)
    55  	opts.TLSTimeout = 5
    56  	s := RunServer(&opts)
    57  	defer s.Shutdown()
    58  
    59  	c := createClientConn(t, "127.0.0.1", PING_TEST_PORT)
    60  	defer c.Close()
    61  
    62  	checkInfoMsg(t, c)
    63  	c = tls.Client(c, &tls.Config{InsecureSkipVerify: true})
    64  	tlsConn := c.(*tls.Conn)
    65  	tlsConn.Handshake()
    66  
    67  	cs := fmt.Sprintf("CONNECT {\"verbose\":%v,\"pedantic\":%v,\"tls_required\":%v}\r\n", false, false, true)
    68  	sendProto(t, c, cs)
    69  
    70  	expect := expectCommand(t, c)
    71  
    72  	// Expect the max to be delivered correctly..
    73  	for i := 0; i < PING_MAX; i++ {
    74  		time.Sleep(PING_INTERVAL / 2)
    75  		expect(pingRe)
    76  	}
    77  
    78  	// We should get an error from the server
    79  	time.Sleep(PING_INTERVAL)
    80  	expect(errRe)
    81  
    82  	// Server should close the connection at this point..
    83  	time.Sleep(PING_INTERVAL)
    84  	c.SetWriteDeadline(time.Now().Add(PING_INTERVAL))
    85  
    86  	var err error
    87  	for {
    88  		_, err = c.Write([]byte("PING\r\n"))
    89  		if err != nil {
    90  			break
    91  		}
    92  	}
    93  	c.SetWriteDeadline(time.Time{})
    94  
    95  	if err == nil {
    96  		t.Fatal("No error: Expected to have connection closed")
    97  	}
    98  	if ne, ok := err.(net.Error); ok && ne.Timeout() {
    99  		t.Fatal("timeout: Expected to have connection closed")
   100  	}
   101  }
   102  
   103  func TestPingInterval(t *testing.T) {
   104  	s := runPingServer()
   105  	defer s.Shutdown()
   106  
   107  	c := createClientConn(t, "127.0.0.1", PING_TEST_PORT)
   108  	defer c.Close()
   109  
   110  	doConnect(t, c, false, false, false)
   111  
   112  	expect := expectCommand(t, c)
   113  
   114  	// Expect the max to be delivered correctly..
   115  	for i := 0; i < PING_MAX; i++ {
   116  		time.Sleep(PING_INTERVAL / 2)
   117  		expect(pingRe)
   118  	}
   119  
   120  	// We should get an error from the server
   121  	time.Sleep(PING_INTERVAL)
   122  	expect(errRe)
   123  
   124  	// Server should close the connection at this point..
   125  	time.Sleep(PING_INTERVAL)
   126  	c.SetWriteDeadline(time.Now().Add(PING_INTERVAL))
   127  
   128  	var err error
   129  	for {
   130  		_, err = c.Write([]byte("PING\r\n"))
   131  		if err != nil {
   132  			break
   133  		}
   134  	}
   135  	c.SetWriteDeadline(time.Time{})
   136  
   137  	if err == nil {
   138  		t.Fatal("No error: Expected to have connection closed")
   139  	}
   140  	if ne, ok := err.(net.Error); ok && ne.Timeout() {
   141  		t.Fatal("timeout: Expected to have connection closed")
   142  	}
   143  }
   144  
   145  func TestUnpromptedPong(t *testing.T) {
   146  	s := runPingServer()
   147  	defer s.Shutdown()
   148  
   149  	c := createClientConn(t, "127.0.0.1", PING_TEST_PORT)
   150  	defer c.Close()
   151  
   152  	doConnect(t, c, false, false, false)
   153  
   154  	expect := expectCommand(t, c)
   155  
   156  	// Send lots of PONGs in a row...
   157  	for i := 0; i < 100; i++ {
   158  		c.Write([]byte("PONG\r\n"))
   159  	}
   160  
   161  	// The server should still send the max number of PINGs and then
   162  	// close the connection.
   163  	for i := 0; i < PING_MAX; i++ {
   164  		time.Sleep(PING_INTERVAL / 2)
   165  		expect(pingRe)
   166  	}
   167  
   168  	// We should get an error from the server
   169  	time.Sleep(PING_INTERVAL)
   170  	expect(errRe)
   171  
   172  	// Server should close the connection at this point..
   173  	c.SetWriteDeadline(time.Now().Add(PING_INTERVAL))
   174  	var err error
   175  	for {
   176  		_, err = c.Write([]byte("PING\r\n"))
   177  		if err != nil {
   178  			break
   179  		}
   180  	}
   181  	c.SetWriteDeadline(time.Time{})
   182  
   183  	if err == nil {
   184  		t.Fatal("No error: Expected to have connection closed")
   185  	}
   186  	if ne, ok := err.(net.Error); ok && ne.Timeout() {
   187  		t.Fatal("timeout: Expected to have connection closed")
   188  	}
   189  }
   190  
   191  func TestPingSuppresion(t *testing.T) {
   192  	pingInterval := 100 * time.Millisecond
   193  	highWater := 130 * time.Millisecond
   194  	opts := DefaultTestOptions
   195  	opts.Port = PING_TEST_PORT
   196  	opts.PingInterval = pingInterval
   197  	opts.DisableShortFirstPing = true
   198  
   199  	s := RunServer(&opts)
   200  	defer s.Shutdown()
   201  
   202  	c := createClientConn(t, "127.0.0.1", PING_TEST_PORT)
   203  	defer c.Close()
   204  
   205  	connectTime := time.Now()
   206  
   207  	send, expect := setupConn(t, c)
   208  
   209  	expect(pingRe)
   210  	pingTime := time.Since(connectTime)
   211  	send("PONG\r\n")
   212  
   213  	// Should be > 100 but less then 120(ish)
   214  	if pingTime < pingInterval {
   215  		t.Fatalf("pingTime too low: %v", pingTime)
   216  	}
   217  	// +5 is just for fudging in case things are slow in the testing system.
   218  	if pingTime > highWater {
   219  		t.Fatalf("pingTime too high: %v", pingTime)
   220  	}
   221  
   222  	time.Sleep(pingInterval / 2)
   223  
   224  	// Sending a PING should suppress.
   225  	send("PING\r\n")
   226  	expect(pongRe)
   227  
   228  	// This will wait for the time period where a PING should have fired
   229  	// and been delivered. We expect nothing here since it should be suppressed.
   230  	expectNothingTimeout(t, c, time.Now().Add(100*time.Millisecond))
   231  }