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  }