github.com/gdamore/mangos@v1.4.0/test/ttl_test.go (about) 1 // Copyright 2016 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 "fmt" 20 "testing" 21 "time" 22 23 "nanomsg.org/go-mangos" 24 "nanomsg.org/go-mangos/transport/inproc" 25 ) 26 27 // SetTTLZero tests that a given socket fails to set a TTL of zero. 28 func SetTTLZero(t *testing.T, f newSockFunc) { 29 s, err := f() 30 if err != nil { 31 t.Errorf("Failed to make socket: %v", err) 32 return 33 } 34 defer s.Close() 35 err = s.SetOption(mangos.OptionTTL, 0) 36 switch err { 37 case mangos.ErrBadValue: // expected result 38 case nil: 39 t.Errorf("Negative test fail, permitted zero TTL") 40 default: 41 t.Errorf("Negative test fail (0), wrong error %v", err) 42 } 43 } 44 45 // SetTTLNegative tests that a given socket fails to set a negative TTL. 46 func SetTTLNegative(t *testing.T, f newSockFunc) { 47 s, err := f() 48 if err != nil { 49 t.Errorf("Failed to make socket: %v", err) 50 return 51 } 52 defer s.Close() 53 err = s.SetOption(mangos.OptionTTL, -1) 54 switch err { 55 case mangos.ErrBadValue: // expected result 56 case nil: 57 t.Errorf("Negative test fail, permitted negative TTL") 58 default: 59 t.Errorf("Negative test fail (-1), wrong error %v", err) 60 } 61 } 62 63 // SetTTLTooBig tests that a given socket fails to set a very large TTL. 64 func SetTTLTooBig(t *testing.T, f newSockFunc) { 65 s, err := f() 66 if err != nil { 67 t.Errorf("Failed to make socket: %v", err) 68 return 69 } 70 defer s.Close() 71 err = s.SetOption(mangos.OptionTTL, 256) 72 switch err { 73 case mangos.ErrBadValue: // expected result 74 case nil: 75 t.Errorf("Negative test fail, permitted too large TTL") 76 default: 77 t.Errorf("Negative test fail (256), wrong error %v", err) 78 } 79 } 80 81 // SetTTLNotInt tests that a given socket fails to set a non-integer TTL. 82 func SetTTLNotInt(t *testing.T, f newSockFunc) { 83 s, err := f() 84 if err != nil { 85 t.Errorf("Failed to make socket: %v", err) 86 return 87 } 88 defer s.Close() 89 err = s.SetOption(mangos.OptionTTL, "garbage") 90 switch err { 91 case mangos.ErrBadValue: // expected result 92 case nil: 93 t.Errorf("Negative test fail, permitted non-int value") 94 default: 95 t.Errorf("Negative test fail (garbage), wrong error %v", err) 96 } 97 } 98 99 // SetTTL tests that we can set a valid TTL, and get the same value back. 100 func SetTTL(t *testing.T, f newSockFunc) { 101 s, err := f() 102 if err != nil { 103 t.Errorf("Failed to make socket: %v", err) 104 return 105 } 106 defer s.Close() 107 108 err = s.SetOption(mangos.OptionTTL, 2) 109 if err != nil { 110 t.Errorf("Failed SetOption: %v", err) 111 return 112 } 113 114 v, err := s.GetOption(mangos.OptionTTL) 115 if err != nil { 116 t.Errorf("Failed GetOption: %v", err) 117 return 118 } 119 if val, ok := v.(int); !ok { 120 t.Errorf("Returned value not type int") 121 } else if val != 2 { 122 t.Errorf("Returned value %d not %d", val, 2) 123 } 124 } 125 126 // TTLDropTest is a generic test for dropping based on TTL expiration. 127 // F1 makes the client socket, f2 makes the server socket. 128 func TTLDropTest(t *testing.T, cli newSockFunc, srv newSockFunc) { 129 nhop := 3 130 clis := make([]mangos.Socket, 0, nhop) 131 srvs := make([]mangos.Socket, 0, nhop) 132 inp := inproc.NewTransport() 133 134 for i := 0; i < nhop; i++ { 135 s, err := srv() 136 if err != nil { 137 t.Errorf("Failed to make server: %v", err) 138 return 139 } 140 defer s.Close() 141 142 s.AddTransport(inp) 143 144 err = s.Listen(AddrTestInp + fmt.Sprintf("HOP%d", i)) 145 if err != nil { 146 t.Errorf("Failed listen: %v", err) 147 return 148 } 149 150 err = s.SetOption(mangos.OptionRaw, true) 151 if err != nil { 152 t.Errorf("Failed set raw mode: %v", err) 153 return 154 } 155 156 srvs = append(srvs, s) 157 } 158 159 for i := 0; i < nhop; i++ { 160 s, err := cli() 161 if err != nil { 162 t.Errorf("Failed to make client: %v", err) 163 return 164 } 165 defer s.Close() 166 167 s.AddTransport(inp) 168 169 err = s.Dial(AddrTestInp + fmt.Sprintf("HOP%d", i)) 170 if err != nil { 171 t.Errorf("Failed dial: %v", err) 172 return 173 } 174 175 clis = append(clis, s) 176 } 177 178 // Now make the device chain 179 for i := 0; i < nhop-1; i++ { 180 err := mangos.Device(srvs[i], clis[i+1]) 181 if err != nil { 182 t.Errorf("Device failed: %v", err) 183 return 184 } 185 } 186 187 // Wait for the various connections to plumb up 188 time.Sleep(time.Millisecond * 100) 189 190 // At this point, we can issue requests on clis[0], and read them from 191 // srvs[nhop-1]. 192 193 rq := clis[0] 194 rp := srvs[nhop-1] 195 196 err := rp.SetOption(mangos.OptionRecvDeadline, time.Millisecond*20) 197 if err != nil { 198 t.Errorf("Failed set recv deadline") 199 return 200 } 201 202 t.Logf("Socket for sending is %s", rq.GetProtocol().Name()) 203 if err = rq.Send([]byte("GOOD")); err != nil { 204 t.Errorf("Failed first send: %v", err) 205 return 206 } 207 t.Logf("Socket for receiving is %s", rp.GetProtocol().Name()) 208 v, err := rp.Recv() 209 if err != nil { 210 t.Errorf("Failed first recv: %v", err) 211 return 212 } else if !bytes.Equal(v, []byte("GOOD")) { 213 t.Errorf("Got wrong message: %v", v) 214 return 215 } else { 216 t.Logf("Got good message: %v", v) 217 } 218 219 // Now try setting the option. 220 err = rp.SetOption(mangos.OptionTTL, nhop-1) 221 if err != nil { 222 t.Errorf("Failed set TTL: %v", err) 223 return 224 } 225 226 if err = rq.Send([]byte("DROP")); err != nil { 227 t.Errorf("Failed send drop: %v", err) 228 return 229 } 230 231 v, err = rp.Recv() 232 switch err { 233 case mangos.ErrRecvTimeout: // expected 234 t.Logf("TTL honored") 235 case nil: 236 t.Errorf("Message not dropped: %v", v) 237 default: 238 t.Errorf("Got unexpected error: %v", err) 239 } 240 }