...

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

Documentation: github.com/prometheus/procfs

     1  // Copyright 2022 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  	"reflect"
    18  	"sort"
    19  	"strconv"
    20  	"testing"
    21  )
    22  
    23  var (
    24  	testPID  = int(27079)
    25  	testTIDS = [...]int{27079, 27080, 27081, 27082, 27083}
    26  )
    27  
    28  func TestAllThreads(t *testing.T) {
    29  	fixFS := getProcFixtures(t)
    30  	threads, err := fixFS.AllThreads(testPID)
    31  	if err != nil {
    32  		t.Fatal(err)
    33  	}
    34  	sort.Sort(threads)
    35  	for i, tid := range testTIDS {
    36  		if wantTID, haveTID := tid, threads[i].PID; wantTID != haveTID {
    37  			t.Errorf("want TID %d, have %d", wantTID, haveTID)
    38  		}
    39  		wantFS := fixFS.proc.Path(strconv.Itoa(testPID), "task")
    40  		haveFS := string(threads[i].fs.proc)
    41  		if wantFS != haveFS {
    42  			t.Errorf("want fs %q, have %q", wantFS, haveFS)
    43  		}
    44  	}
    45  }
    46  
    47  func TestThreadStat(t *testing.T) {
    48  	// Pull process and thread stats.
    49  	proc, err := getProcFixtures(t).Proc(testPID)
    50  	if err != nil {
    51  		t.Fatal(err)
    52  	}
    53  	procStat, err := proc.Stat()
    54  	if err != nil {
    55  		t.Fatal(err)
    56  	}
    57  
    58  	threads, err := getProcFixtures(t).AllThreads(testPID)
    59  	if err != nil {
    60  		t.Fatal(err)
    61  	}
    62  	sort.Sort(threads)
    63  	threadStats := make([]*ProcStat, len(threads))
    64  	for i, thread := range threads {
    65  		threadStat, err := thread.Stat()
    66  		if err != nil {
    67  			t.Fatal(err)
    68  		}
    69  		threadStats[i] = &threadStat
    70  	}
    71  
    72  	// The following fields should be shared between the process and its thread:
    73  	procStatValue := reflect.ValueOf(procStat)
    74  	sharedFields := [...]string{
    75  		"PPID",
    76  		"PGRP",
    77  		"Session",
    78  		"TTY",
    79  		"TPGID",
    80  		"VSize",
    81  		"RSS",
    82  	}
    83  
    84  	for i, thread := range threads {
    85  		threadStatValue := reflect.ValueOf(threadStats[i]).Elem()
    86  		for _, f := range sharedFields {
    87  			if want, have := procStatValue.FieldByName(f), threadStatValue.FieldByName(f); want.Interface() != have.Interface() {
    88  				t.Errorf("TID %d, want %s %#v, have %#v", thread.PID, f, want, have)
    89  			}
    90  		}
    91  	}
    92  
    93  	// Thread specific fields:
    94  	for i, thread := range threads {
    95  		if want, have := thread.PID, threadStats[i].PID; want != have {
    96  			t.Errorf("TID %d, want PID %d, have %d", thread.PID, want, have)
    97  		}
    98  	}
    99  
   100  	// Finally exemplify the relationship between process and constituent
   101  	// threads CPU times: each the former  ~ the sum of the corresponding
   102  	// latter. Require -v flag.
   103  	totalUTime, totalSTime := uint(0), uint(0)
   104  	for _, thread := range threads {
   105  		threadStat, err := thread.Stat()
   106  		if err != nil {
   107  			t.Fatal(err)
   108  		}
   109  		t.Logf("TID %d, UTime %d, STime %d", thread.PID, threadStat.UTime, threadStat.STime)
   110  		totalUTime += threadStat.UTime
   111  		totalSTime += threadStat.STime
   112  	}
   113  	t.Logf("PID %d, UTime %d, STime %d, total threads UTime %d, STime %d", proc.PID, procStat.UTime, procStat.STime, totalUTime, totalSTime)
   114  }
   115  

View as plain text