go.nanomsg.org/mangos/v3@v3.4.3-0.20240217232803-46464076f1f5/internal/test/ttl.go (about) 1 // Copyright 2019 The Mangos Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use file except in compliance with the License. 5 // You may obtain a copy of the license at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package test 16 17 import ( 18 "bytes" 19 "testing" 20 "time" 21 22 "go.nanomsg.org/mangos/v3" 23 ) 24 25 // SetTTLZero tests that a given socket fails to set a TTL of zero. 26 func SetTTLZero(t *testing.T, f func() (mangos.Socket, error)) { 27 s, err := f() 28 if err != nil { 29 t.Errorf("Failed to make socket: %v", err) 30 return 31 } 32 defer s.Close() 33 err = s.SetOption(mangos.OptionTTL, 0) 34 switch err { 35 case mangos.ErrBadValue: // expected result 36 case nil: 37 t.Errorf("Negative test fail, permitted zero TTL") 38 default: 39 t.Errorf("Negative test fail (0), wrong error %v", err) 40 } 41 } 42 43 // SetTTLNegative tests that a given socket fails to set a negative TTL. 44 func SetTTLNegative(t *testing.T, f func() (mangos.Socket, error)) { 45 s, err := f() 46 if err != nil { 47 t.Errorf("Failed to make socket: %v", err) 48 return 49 } 50 defer s.Close() 51 err = s.SetOption(mangos.OptionTTL, -1) 52 switch err { 53 case mangos.ErrBadValue: // expected result 54 case nil: 55 t.Errorf("Negative test fail, permitted negative TTL") 56 default: 57 t.Errorf("Negative test fail (-1), wrong error %v", err) 58 } 59 } 60 61 // SetTTLTooBig tests that a given socket fails to set a very large TTL. 62 func SetTTLTooBig(t *testing.T, f func() (mangos.Socket, error)) { 63 s, err := f() 64 if err != nil { 65 t.Errorf("Failed to make socket: %v", err) 66 return 67 } 68 defer s.Close() 69 err = s.SetOption(mangos.OptionTTL, 256) 70 switch err { 71 case mangos.ErrBadValue: // expected result 72 case nil: 73 t.Errorf("Negative test fail, permitted too large TTL") 74 default: 75 t.Errorf("Negative test fail (256), wrong error %v", err) 76 } 77 } 78 79 // SetTTLNotInt tests that a given socket fails to set a non-integer TTL. 80 func SetTTLNotInt(t *testing.T, f func() (mangos.Socket, error)) { 81 s, err := f() 82 if err != nil { 83 t.Errorf("Failed to make socket: %v", err) 84 return 85 } 86 defer s.Close() 87 err = s.SetOption(mangos.OptionTTL, "garbage") 88 switch err { 89 case mangos.ErrBadValue: // expected result 90 case nil: 91 t.Errorf("Negative test fail, permitted non-int value") 92 default: 93 t.Errorf("Negative test fail (garbage), wrong error %v", err) 94 } 95 } 96 97 // SetTTL tests that we can set a valid TTL, and get the same value back. 98 func SetTTL(t *testing.T, f func() (mangos.Socket, error)) { 99 s, err := f() 100 if err != nil { 101 t.Errorf("Failed to make socket: %v", err) 102 return 103 } 104 defer s.Close() 105 106 err = s.SetOption(mangos.OptionTTL, 2) 107 if err != nil { 108 t.Errorf("Failed SetOption: %v", err) 109 return 110 } 111 112 v, err := s.GetOption(mangos.OptionTTL) 113 if err != nil { 114 t.Errorf("Failed GetOption: %v", err) 115 return 116 } 117 if val, ok := v.(int); !ok { 118 t.Errorf("Returned value not type int") 119 } else if val != 2 { 120 t.Errorf("Returned value %d not %d", val, 2) 121 } 122 } 123 124 // TTLDropTest is a generic test for dropping based on TTL expiration. 125 // F1 makes the Client socket, f2 makes the Server socket. 126 func TTLDropTest(t *testing.T, 127 cli func() (mangos.Socket, error), 128 srv func() (mangos.Socket, error), 129 rawcli func() (mangos.Socket, error), 130 rawsrv func() (mangos.Socket, error)) { 131 132 nhop := 3 133 clis := make([]mangos.Socket, 0, nhop) 134 srvs := make([]mangos.Socket, 0, nhop) 135 var addrs []string 136 for i := 0; i < nhop; i++ { 137 addrs = append(addrs, AddrTestInp()) 138 } 139 140 for i := 0; i < nhop; i++ { 141 var fn func() (mangos.Socket, error) 142 if i == nhop-1 { 143 fn = srv 144 } else { 145 fn = rawsrv 146 } 147 s, err := fn() 148 MustSucceed(t, err) 149 MustNotBeNil(t, s) 150 defer s.Close() 151 152 MustSucceed(t, s.Listen(addrs[i])) 153 srvs = append(srvs, s) 154 } 155 156 for i := 0; i < nhop; i++ { 157 var fn func() (mangos.Socket, error) 158 if i == 0 { 159 fn = cli 160 } else { 161 fn = rawcli 162 } 163 s, err := fn() 164 MustSucceed(t, err) 165 MustNotBeNil(t, s) 166 defer s.Close() 167 168 MustSucceed(t, s.Dial(addrs[i])) 169 170 clis = append(clis, s) 171 } 172 173 // Now make the device chain 174 for i := 0; i < nhop-1; i++ { 175 MustSucceed(t, mangos.Device(srvs[i], clis[i+1])) 176 } 177 178 // Wait for the various connections to plumb up 179 time.Sleep(time.Millisecond * 100) 180 181 // At this point, we can issue requests on clis[0], and read them from 182 // srvs[nhop-1]. 183 184 rq := clis[0] 185 rp := srvs[nhop-1] 186 187 MustSucceed(t, rp.SetOption(mangos.OptionRecvDeadline, time.Millisecond*100)) 188 MustSucceed(t, rq.Send([]byte("GOOD"))) 189 v, err := rp.Recv() 190 MustSucceed(t, err) 191 MustBeTrue(t, bytes.Equal(v, []byte("GOOD"))) 192 193 // Now try setting the option. 194 MustSucceed(t, rp.SetOption(mangos.OptionTTL, nhop-1)) 195 196 MustSucceed(t, rq.Send([]byte("DROP"))) 197 198 _, err = rp.Recv() 199 MustBeError(t, err, mangos.ErrRecvTimeout) 200 }