github.com/google/cloudprober@v0.11.3/probes/ping/pingutils_test.go (about)

     1  // Copyright 2017-2019 The Cloudprober Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this 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 ping
    16  
    17  import (
    18  	"bytes"
    19  	"testing"
    20  	"time"
    21  
    22  	"github.com/golang/protobuf/proto"
    23  	"github.com/google/cloudprober/probes/options"
    24  	configpb "github.com/google/cloudprober/probes/ping/proto"
    25  	"github.com/google/cloudprober/targets"
    26  	"golang.org/x/net/icmp"
    27  	"golang.org/x/net/ipv4"
    28  	"golang.org/x/net/ipv6"
    29  )
    30  
    31  func TestPreparePayload(t *testing.T) {
    32  	ti := time.Now().UnixNano()
    33  
    34  	timeBytes := make([]byte, 8)
    35  	prepareRequestPayload(timeBytes, ti)
    36  
    37  	// Verify that we send a payload that we can get the original time out of.
    38  	for _, size := range []int{256, 1999} {
    39  		payload := make([]byte, size)
    40  		prepareRequestPayload(payload, ti)
    41  
    42  		// Verify that time bytes are intact.
    43  		ts := bytesToTime(payload)
    44  		if ts != ti {
    45  			t.Errorf("Got incorrect timestamp: %d, expected: %d", ts, ti)
    46  		}
    47  	}
    48  }
    49  
    50  func testPrepareRequestPacket(t *testing.T, ver int32, size int) {
    51  	var runID, seq uint16
    52  	runID = 12 // some number
    53  	seq = 143  // some number
    54  	unixNano := time.Now().UnixNano()
    55  
    56  	// Get packet bytes using icmp.Marshal. We'll compare these bytes with the
    57  	// bytes generated by p.prepareRequestPacket below.
    58  	var typ icmp.Type
    59  	typ = ipv4.ICMPTypeEcho
    60  	if ver == 6 {
    61  		typ = ipv6.ICMPTypeEchoRequest
    62  	}
    63  
    64  	payload := make([]byte, size)
    65  	prepareRequestPayload(payload, unixNano)
    66  
    67  	expectedPacketBytes, _ := (&icmp.Message{
    68  		Type: typ, Code: 0,
    69  		Body: &icmp.Echo{
    70  			ID: int(runID), Seq: int(seq),
    71  			Data: payload,
    72  		},
    73  	}).Marshal(nil)
    74  
    75  	// Build a packet using p.prepareOutPacke
    76  	p := &Probe{
    77  		name: "ping_test",
    78  		opts: &options.Options{
    79  			ProbeConf: &configpb.ProbeConf{
    80  				UseDatagramSocket: proto.Bool(false),
    81  			},
    82  			Targets:   targets.StaticTargets("test.com"),
    83  			Interval:  2 * time.Second,
    84  			Timeout:   time.Second,
    85  			IPVersion: int(ver),
    86  		},
    87  	}
    88  	p.initInternal()
    89  
    90  	pktbuf := make([]byte, icmpHeaderSize+size)
    91  	p.prepareRequestPacket(pktbuf, runID, seq, unixNano)
    92  
    93  	if !bytes.Equal(pktbuf, expectedPacketBytes) {
    94  		t.Errorf("p.prepareRequestPacket doesn't generate the same packet (%v) as icmp.Marshal (%v)", pktbuf, expectedPacketBytes)
    95  	}
    96  }
    97  
    98  func TestPrepareRequestPacketIPv4(t *testing.T) {
    99  	for _, size := range []int{56, 512, 1500} {
   100  		testPrepareRequestPacket(t, 4, size)
   101  	}
   102  }
   103  
   104  func TestPrepareRequestPacketIPv6(t *testing.T) {
   105  	for _, size := range []int{56, 512, 1500} {
   106  		testPrepareRequestPacket(t, 6, size)
   107  	}
   108  }
   109  
   110  func TestPktString(t *testing.T) {
   111  	testPkt := &rcvdPkt{
   112  		id:     5,
   113  		seq:    456,
   114  		target: "test-target",
   115  	}
   116  	rtt := 5 * time.Millisecond
   117  	expectedString := "peer=test-target id=5 seq=456 rtt=5ms"
   118  	got := testPkt.String(rtt)
   119  	if got != expectedString {
   120  		t.Errorf("pktString(%q, %s): expected=%s wanted=%s", testPkt, rtt, got, expectedString)
   121  	}
   122  }