...

Source file src/github.com/opencontainers/runc/libcontainer/system/proc_test.go

Documentation: github.com/opencontainers/runc/libcontainer/system

     1  package system
     2  
     3  import (
     4  	"errors"
     5  	"math/bits"
     6  	"os"
     7  	"reflect"
     8  	"strconv"
     9  	"testing"
    10  )
    11  
    12  var procdata = map[string]Stat_t{
    13  	"4902 (gunicorn: maste) S 4885 4902 4902 0 -1 4194560 29683 29929 61 83 78 16 96 17 20 0 1 0 9126532 52965376 1903 18446744073709551615 4194304 7461796 140733928751520 140733928698072 139816984959091 0 0 16781312 137447943 1 0 0 17 3 0 0 9 0 0 9559488 10071156 33050624 140733928758775 140733928758945 140733928758945 140733928759264 0": {
    14  		Name:      "gunicorn: maste",
    15  		State:     'S',
    16  		StartTime: 9126532,
    17  	},
    18  	"9534 (cat) R 9323 9534 9323 34828 9534 4194304 95 0 0 0 0 0 0 0 20 0 1 0 9214966 7626752 168 18446744073709551615 4194304 4240332 140732237651568 140732237650920 140570710391216 0 0 0 0 0 0 0 17 1 0 0 0 0 0 6340112 6341364 21553152 140732237653865 140732237653885 140732237653885 140732237656047 0": {
    19  		Name:      "cat",
    20  		State:     'R',
    21  		StartTime: 9214966,
    22  	},
    23  	"12345 ((ugly )pr()cess() R 9323 9534 9323 34828 9534 4194304 95 0 0 0 0 0 0 0 20 0 1 0 9214966 7626752 168 18446744073709551615 4194304 4240332 140732237651568 140732237650920 140570710391216 0 0 0 0 0 0 0 17 1 0 0 0 0 0 6340112 6341364 21553152 140732237653865 140732237653885 140732237653885 140732237656047 0": {
    24  		Name:      "(ugly )pr()cess(",
    25  		State:     'R',
    26  		StartTime: 9214966,
    27  	},
    28  	"24767 (irq/44-mei_me) S 2 0 0 0 -1 2129984 0 0 0 0 0 0 0 0 -51 0 1 0 8722075 0 0 18446744073709551615 0 0 0 0 0 0 0 2147483647 0 0 0 0 17 1 50 1 0 0 0 0 0 0 0 0 0 0 0": {
    29  		Name:      "irq/44-mei_me",
    30  		State:     'S',
    31  		StartTime: 8722075,
    32  	},
    33  	"0 () I 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0": {
    34  		Name:      "",
    35  		State:     'I',
    36  		StartTime: 0,
    37  	},
    38  	// Not entirely correct, but minimally viable input (StartTime and a space after).
    39  	"1 (woo hoo) S 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 ": {
    40  		Name:      "woo hoo",
    41  		State:     'S',
    42  		StartTime: 4,
    43  	},
    44  }
    45  
    46  func TestParseStat(t *testing.T) {
    47  	for line, exp := range procdata {
    48  		st, err := parseStat(line)
    49  		if err != nil {
    50  			t.Errorf("input %q, unexpected error %v", line, err)
    51  		} else if !reflect.DeepEqual(st, exp) {
    52  			t.Errorf("input %q, expected %+v, got %+v", line, exp, st)
    53  		}
    54  	}
    55  }
    56  
    57  func TestParseStatBadInput(t *testing.T) {
    58  	cases := []struct {
    59  		desc, input string
    60  	}{
    61  		{
    62  			"no (",
    63  			"123 ) S 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0",
    64  		},
    65  		{
    66  			"no )",
    67  			"123 ( S 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0",
    68  		},
    69  		{
    70  			") at end",
    71  			"123 (cmd) S 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)",
    72  		},
    73  		{
    74  			"misplaced ()",
    75  			"123 )one( S 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0",
    76  		},
    77  		{
    78  			"misplaced empty ()",
    79  			"123 )( S 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0",
    80  		},
    81  		{
    82  			"empty line",
    83  			"",
    84  		},
    85  		{
    86  			"short line",
    87  			"123 (cmd) S 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0",
    88  		},
    89  		{
    90  			"short line (no space after stime)",
    91  			"123 (cmd) S 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 42",
    92  		},
    93  		{
    94  			"bad stime",
    95  			"123 (cmd) S 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 ",
    96  		},
    97  		{
    98  			"bad stime 2", // would be valid if not -1
    99  			"123 (cmd) S                   -1 ",
   100  		},
   101  		{
   102  			"a tad short",
   103  			"1234 (cmd) ",
   104  		},
   105  		{
   106  			"bad stime",
   107  			"123 (cmd) S 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1",
   108  		},
   109  	}
   110  	for _, c := range cases {
   111  		st, err := parseStat(c.input)
   112  		if err == nil {
   113  			t.Errorf("case %q, expected error, got nil, %+v", c.desc, st)
   114  		}
   115  	}
   116  }
   117  
   118  func BenchmarkParseStat(b *testing.B) {
   119  	var (
   120  		st, exp Stat_t
   121  		line    string
   122  		err     error
   123  	)
   124  
   125  	for i := 0; i != b.N; i++ {
   126  		for line, exp = range procdata {
   127  			st, err = parseStat(line)
   128  		}
   129  	}
   130  	if err != nil {
   131  		b.Fatal(err)
   132  	}
   133  	if !reflect.DeepEqual(st, exp) {
   134  		b.Fatal("wrong result")
   135  	}
   136  }
   137  
   138  func BenchmarkParseRealStat(b *testing.B) {
   139  	var (
   140  		st    Stat_t
   141  		err   error
   142  		total int
   143  	)
   144  	b.StopTimer()
   145  	fd, err := os.Open("/proc")
   146  	if err != nil {
   147  		b.Fatal(err)
   148  	}
   149  	defer fd.Close()
   150  
   151  	for i := 0; i != b.N; i++ {
   152  		count := 0
   153  		if _, err := fd.Seek(0, 0); err != nil {
   154  			b.Fatal(err)
   155  		}
   156  		names, err := fd.Readdirnames(-1)
   157  		if err != nil {
   158  			b.Fatal(err)
   159  		}
   160  		for _, n := range names {
   161  			pid, err := strconv.ParseUint(n, 10, bits.UintSize)
   162  			if err != nil {
   163  				continue
   164  			}
   165  			b.StartTimer()
   166  			st, err = Stat(int(pid))
   167  			b.StopTimer()
   168  			if err != nil {
   169  				// Ignore a process that just finished.
   170  				if errors.Is(err, os.ErrNotExist) {
   171  					continue
   172  				}
   173  				b.Fatal(err)
   174  			}
   175  			count++
   176  		}
   177  		total += count
   178  	}
   179  	b.Logf("N: %d, parsed %d pids, last stat: %+v, err: %v", b.N, total, st, err)
   180  }
   181  

View as plain text