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  }