get.pme.sh/pnats@v0.0.0-20240304004023-26bb5a137ed0/test/test_test.go (about) 1 // Copyright 2016-2020 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 "context" 18 "fmt" 19 "net" 20 "strconv" 21 "strings" 22 "sync" 23 "testing" 24 "time" 25 26 "get.pme.sh/pnats/server" 27 "golang.org/x/time/rate" 28 ) 29 30 func checkFor(t testing.TB, totalWait, sleepDur time.Duration, f func() error) { 31 t.Helper() 32 timeout := time.Now().Add(totalWait) 33 var err error 34 for time.Now().Before(timeout) { 35 err = f() 36 if err == nil { 37 return 38 } 39 time.Sleep(sleepDur) 40 } 41 if err != nil { 42 t.Fatal(err.Error()) 43 } 44 } 45 46 // Slow Proxy - For introducing RTT and BW constraints. 47 type slowProxy struct { 48 listener net.Listener 49 conns []net.Conn 50 o *server.Options 51 u string 52 } 53 54 func newSlowProxy(rtt time.Duration, up, down int, opts *server.Options) *slowProxy { 55 saddr := net.JoinHostPort(opts.Host, strconv.Itoa(opts.Port)) 56 hp := net.JoinHostPort("127.0.0.1", "0") 57 l, e := net.Listen("tcp", hp) 58 if e != nil { 59 panic(fmt.Sprintf("Error listening on port: %s, %q", hp, e)) 60 } 61 port := l.Addr().(*net.TCPAddr).Port 62 sp := &slowProxy{listener: l} 63 go func() { 64 client, err := l.Accept() 65 if err != nil { 66 return 67 } 68 server, err := net.DialTimeout("tcp", saddr, time.Second) 69 if err != nil { 70 panic("Can't connect to server") 71 } 72 sp.conns = append(sp.conns, client, server) 73 go sp.loop(rtt, up, client, server) 74 go sp.loop(rtt, down, server, client) 75 }() 76 sp.o = &server.Options{Host: "127.0.0.1", Port: port} 77 sp.u = fmt.Sprintf("nats://%s:%d", sp.o.Host, sp.o.Port) 78 return sp 79 } 80 81 func (sp *slowProxy) opts() *server.Options { 82 return sp.o 83 } 84 85 //lint:ignore U1000 Referenced in norace_test.go 86 func (sp *slowProxy) clientURL() string { 87 return sp.u 88 } 89 90 func (sp *slowProxy) loop(rtt time.Duration, tbw int, r, w net.Conn) { 91 delay := rtt / 2 92 const rbl = 1024 93 var buf [rbl]byte 94 ctx := context.Background() 95 96 rl := rate.NewLimiter(rate.Limit(tbw), rbl) 97 98 for fr := true; ; { 99 sr := time.Now() 100 n, err := r.Read(buf[:]) 101 if err != nil { 102 return 103 } 104 // RTT delays 105 if fr || time.Since(sr) > 2*time.Millisecond { 106 fr = false 107 time.Sleep(delay) 108 } 109 if err := rl.WaitN(ctx, n); err != nil { 110 return 111 } 112 if _, err = w.Write(buf[:n]); err != nil { 113 return 114 } 115 } 116 } 117 118 func (sp *slowProxy) stop() { 119 if sp.listener != nil { 120 sp.listener.Close() 121 sp.listener = nil 122 for _, c := range sp.conns { 123 c.Close() 124 } 125 } 126 } 127 128 // Dummy Logger 129 type dummyLogger struct { 130 sync.Mutex 131 msg string 132 } 133 134 func (d *dummyLogger) Fatalf(format string, args ...interface{}) { 135 d.Lock() 136 d.msg = fmt.Sprintf(format, args...) 137 d.Unlock() 138 } 139 140 func (d *dummyLogger) Errorf(format string, args ...interface{}) { 141 } 142 143 func (d *dummyLogger) Debugf(format string, args ...interface{}) { 144 } 145 146 func (d *dummyLogger) Tracef(format string, args ...interface{}) { 147 } 148 149 func (d *dummyLogger) Noticef(format string, args ...interface{}) { 150 } 151 152 func (d *dummyLogger) Warnf(format string, args ...interface{}) { 153 } 154 155 func TestStackFatal(t *testing.T) { 156 d := &dummyLogger{} 157 stackFatalf(d, "test stack %d", 1) 158 if !strings.HasPrefix(d.msg, "test stack 1") { 159 t.Fatalf("Unexpected start of stack: %v", d.msg) 160 } 161 if !strings.Contains(d.msg, "test_test.go") { 162 t.Fatalf("Unexpected stack: %v", d.msg) 163 } 164 }