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 }