...

Source file src/github.com/prometheus/procfs/net_sockstat_test.go

Documentation: github.com/prometheus/procfs

     1  // Copyright 2019 The Prometheus Authors
     2  // Licensed under the Apache License, Version 2.0 (the "License");
     3  // you may not use this file except in compliance with the License.
     4  // You may obtain a copy of the License at
     5  //
     6  // http://www.apache.org/licenses/LICENSE-2.0
     7  //
     8  // Unless required by applicable law or agreed to in writing, software
     9  // distributed under the License is distributed on an "AS IS" BASIS,
    10  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package procfs
    15  
    16  import (
    17  	"os"
    18  	"strings"
    19  	"testing"
    20  
    21  	"github.com/google/go-cmp/cmp"
    22  )
    23  
    24  // The majority of test cases are covered in Test_parseSockstat. The top level
    25  // tests just check the basics for integration test purposes.
    26  
    27  func TestNetSockstat(t *testing.T) {
    28  	fs, err := NewFS(procTestFixtures)
    29  	if err != nil {
    30  		t.Fatalf("failed to open procfs: %v", err)
    31  	}
    32  
    33  	stat, err := fs.NetSockstat()
    34  	if err != nil {
    35  		t.Fatalf("failed to get sockstat: %v", err)
    36  	}
    37  
    38  	// IPv4 stats should include Used.
    39  	if stat.Used == nil {
    40  		t.Fatalf("IPv4 sockstat used value was nil")
    41  	}
    42  	if diff := cmp.Diff(1602, *stat.Used); diff != "" {
    43  		t.Fatalf("unexpected IPv4 used sockets (-want +got):\n%s", diff)
    44  	}
    45  
    46  	// TCP occurs first; do a basic sanity check.
    47  	if diff := cmp.Diff("TCP", stat.Protocols[0].Protocol); diff != "" {
    48  		t.Fatalf("unexpected socket protocol (-want +got):\n%s", diff)
    49  	}
    50  	if diff := cmp.Diff(35, stat.Protocols[0].InUse); diff != "" {
    51  		t.Fatalf("unexpected number of TCP sockets (-want +got):\n%s", diff)
    52  	}
    53  }
    54  
    55  func TestNetSockstat6(t *testing.T) {
    56  	fs, err := NewFS(procTestFixtures)
    57  	if err != nil {
    58  		t.Fatalf("failed to open procfs: %v", err)
    59  	}
    60  
    61  	stat, err := fs.NetSockstat6()
    62  	if err != nil {
    63  		t.Fatalf("failed to get sockstat: %v", err)
    64  	}
    65  
    66  	// IPv6 stats should not include Used.
    67  	if stat.Used != nil {
    68  		t.Fatalf("IPv6 sockstat used value was not nil")
    69  	}
    70  
    71  	// TCP6 occurs first; do a basic sanity check.
    72  	if diff := cmp.Diff("TCP6", stat.Protocols[0].Protocol); diff != "" {
    73  		t.Fatalf("unexpected socket protocol (-want +got):\n%s", diff)
    74  	}
    75  	if diff := cmp.Diff(17, stat.Protocols[0].InUse); diff != "" {
    76  		t.Fatalf("unexpected number of TCP sockets (-want +got):\n%s", diff)
    77  	}
    78  }
    79  
    80  func Test_readSockstatIsNotExist(t *testing.T) {
    81  	// On a machine with IPv6 disabled for example, we want to ensure that
    82  	// readSockstat returns an error that is compatible with os.IsNotExist.
    83  	//
    84  	// We can use a synthetic file path here to verify this behavior.
    85  	_, err := readSockstat("/does/not/exist")
    86  	if err == nil || !os.IsNotExist(err) {
    87  		t.Fatalf("error is not compatible with os.IsNotExist: %#v", err)
    88  	}
    89  }
    90  
    91  func Test_parseSockstat(t *testing.T) {
    92  	tests := []struct {
    93  		name string
    94  		s    string
    95  		ok   bool
    96  		stat *NetSockstat
    97  	}{
    98  		{
    99  			name: "empty",
   100  			ok:   true,
   101  			stat: &NetSockstat{},
   102  		},
   103  		{
   104  			name: "bad line",
   105  			s: `
   106  sockets: used
   107  `,
   108  		},
   109  		{
   110  			name: "bad key/value pairs",
   111  			s: `
   112  TCP: inuse 32 orphan
   113  `,
   114  		},
   115  		{
   116  			name: "IPv4",
   117  			s: `
   118  sockets: used 1591
   119  TCP: inuse 32 orphan 0 tw 0 alloc 58 mem 13
   120  UDP: inuse 8 mem 115
   121  UDPLITE: inuse 0
   122  RAW: inuse 0
   123  FRAG: inuse 0 memory 0
   124  			`,
   125  			ok: true,
   126  			stat: &NetSockstat{
   127  				Used: intp(1591),
   128  				Protocols: []NetSockstatProtocol{
   129  					{
   130  						Protocol: "TCP",
   131  						InUse:    32,
   132  						Orphan:   intp(0),
   133  						TW:       intp(0),
   134  						Alloc:    intp(58),
   135  						Mem:      intp(13),
   136  					},
   137  					{
   138  						Protocol: "UDP",
   139  						InUse:    8,
   140  						Mem:      intp(115),
   141  					},
   142  					{
   143  						Protocol: "UDPLITE",
   144  					},
   145  					{
   146  						Protocol: "RAW",
   147  					},
   148  					{
   149  						Protocol: "FRAG",
   150  						Memory:   intp(0),
   151  					},
   152  				},
   153  			},
   154  		},
   155  		{
   156  			name: "IPv6",
   157  			s: `
   158  TCP6: inuse 24
   159  UDP6: inuse 9
   160  UDPLITE6: inuse 0
   161  RAW6: inuse 1
   162  FRAG6: inuse 0 memory 0
   163  			`,
   164  			ok: true,
   165  			stat: &NetSockstat{
   166  				Protocols: []NetSockstatProtocol{
   167  					{
   168  						Protocol: "TCP6",
   169  						InUse:    24,
   170  					},
   171  					{
   172  						Protocol: "UDP6",
   173  						InUse:    9,
   174  					},
   175  					{
   176  						Protocol: "UDPLITE6",
   177  					},
   178  					{
   179  						Protocol: "RAW6",
   180  						InUse:    1,
   181  					},
   182  					{
   183  						Protocol: "FRAG6",
   184  						Memory:   intp(0),
   185  					},
   186  				},
   187  			},
   188  		},
   189  	}
   190  
   191  	for _, tt := range tests {
   192  		t.Run(tt.name, func(t *testing.T) {
   193  			stat, err := parseSockstat(strings.NewReader(strings.TrimSpace(tt.s)))
   194  			if err != nil {
   195  				if tt.ok {
   196  					t.Fatalf("failed to parse sockstats: %v", err)
   197  				}
   198  
   199  				t.Logf("OK error: %v", err)
   200  				return
   201  			}
   202  			if !tt.ok {
   203  				t.Fatal("expected an error, but none occurred")
   204  			}
   205  
   206  			if diff := cmp.Diff(tt.stat, stat); diff != "" {
   207  				t.Errorf("unexpected sockstats (-want +got):\n%s", diff)
   208  			}
   209  		})
   210  	}
   211  }
   212  
   213  func intp(i int) *int { return &i }
   214  

View as plain text