...

Source file src/github.com/datawire/ambassador/v2/pkg/memory/memory_test.go

Documentation: github.com/datawire/ambassador/v2/pkg/memory

     1  package memory
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/stretchr/testify/assert"
     9  
    10  	"github.com/datawire/dlib/dlog"
    11  )
    12  
    13  // Test that we trigger "actions" (which we just use to log when interesting stuff happens) at the
    14  // right times.
    15  func TestMemoryUsage(t *testing.T) {
    16  	start := time.Now()
    17  	usage := &MemoryUsage{}
    18  
    19  	// nothing interesting has happened yet
    20  	usage.maybeDo(start, func() {
    21  		assert.Fail(t, "no action")
    22  	})
    23  
    24  	// memory jumped, but not enough to qualify as interesting
    25  	usage.usage = 1024 * 1024
    26  	usage.maybeDo(start, func() {
    27  		assert.Fail(t, "no action")
    28  	})
    29  
    30  	// memory jumped enough to qualify as interesting
    31  	usage.usage = 1024 * 1024 * 1024
    32  	did := false
    33  	usage.maybeDo(start, func() {
    34  		did = true
    35  	})
    36  	assert.True(t, did)
    37  
    38  	// nothing else interesting has happened
    39  	usage.maybeDo(start, func() {
    40  		assert.Fail(t, "no action")
    41  	})
    42  
    43  	// one minute passed, but we are don't have a limit, so we don't care
    44  	usage.maybeDo(start.Add(60*time.Second), func() {
    45  		assert.Fail(t, "no action")
    46  	})
    47  
    48  	// we are now over 50% capacity and one minute has passed, so this qualifies as interesting
    49  	usage.limit = usage.usage + 1
    50  	did = false
    51  	usage.maybeDo(start.Add(60*time.Second), func() {
    52  		did = true
    53  	})
    54  	assert.True(t, did)
    55  
    56  	// we are still over 50% capacity, but we just triggered an action, so this doesn't count as interesting
    57  	usage.maybeDo(start.Add(61*time.Second), func() {
    58  		assert.Fail(t, "no action")
    59  	})
    60  
    61  	// but in another 59 seconds, it counts as interesting
    62  	did = false
    63  	usage.maybeDo(start.Add(120*time.Second), func() {
    64  		did = true
    65  	})
    66  	assert.True(t, did)
    67  }
    68  
    69  // Make sure we clear out exited processes after 10 refreshes.
    70  func TestMemoryUsageGCExited(t *testing.T) {
    71  	ctx := dlog.NewTestContext(t, false)
    72  	count := 0
    73  	m := &MemoryUsage{
    74  		limit:      unlimited,
    75  		perProcess: map[int]*ProcessUsage{},
    76  		readUsage: func(_ context.Context) (memory, memory) {
    77  			return 0, unlimited
    78  		},
    79  		readPerProcess: func(_ context.Context) map[int]*ProcessUsage {
    80  			defer func() {
    81  				count = count + 1
    82  			}()
    83  			switch count {
    84  			case 0:
    85  				return map[int]*ProcessUsage{
    86  					1: {1, []string{"one"}, 1024, 0},
    87  					2: {2, []string{"two"}, 1024, 0},
    88  					3: {3, []string{"three"}, 1024, 0},
    89  					4: {4, []string{"four"}, 1024, 0},
    90  					5: {5, []string{"five"}, 1024, 0},
    91  				}
    92  			case 1:
    93  				return map[int]*ProcessUsage{
    94  					1: {1, []string{"one"}, 1024, 0},
    95  					2: {2, []string{"two"}, 1024, 0},
    96  					4: {4, []string{"four"}, 1024, 0},
    97  					5: {5, []string{"five"}, 1024, 0},
    98  				}
    99  			case 2:
   100  				return map[int]*ProcessUsage{
   101  					1: {1, []string{"one"}, 1024, 0},
   102  					2: {2, []string{"two"}, 1024, 0},
   103  					5: {5, []string{"five"}, 1024, 0},
   104  				}
   105  			case 3:
   106  				return map[int]*ProcessUsage{
   107  					1: {1, []string{"one"}, 1024, 0},
   108  					5: {5, []string{"five"}, 1024, 0},
   109  				}
   110  			default:
   111  				return map[int]*ProcessUsage{
   112  					1: {1, []string{"one"}, 1024, 0},
   113  					5: {5, []string{"five"}, 1024, 0},
   114  				}
   115  			}
   116  		},
   117  	}
   118  
   119  	t.Log(m.String())
   120  
   121  	assert.Equal(t, 0, len(m.perProcess))
   122  	m.Refresh(ctx)
   123  	t.Log(m.String())
   124  	assert.Equal(t, 5, len(m.perProcess))
   125  	m.Refresh(ctx)
   126  	t.Log(m.String())
   127  	for i := 0; i < 10; i++ {
   128  		assert.Equal(t, 5, len(m.perProcess))
   129  		m.Refresh(ctx)
   130  		t.Log(m.String())
   131  	}
   132  
   133  	m.Refresh(ctx)
   134  	assert.Equal(t, 4, len(m.perProcess))
   135  	t.Log(m.String())
   136  	assert.NotContains(t, m.perProcess, 3)
   137  
   138  	m.Refresh(ctx)
   139  	assert.Equal(t, 3, len(m.perProcess))
   140  	t.Log(m.String())
   141  	assert.NotContains(t, m.perProcess, 4)
   142  
   143  	m.Refresh(ctx)
   144  	assert.Equal(t, 2, len(m.perProcess))
   145  	t.Log(m.String())
   146  	assert.NotContains(t, m.perProcess, 2)
   147  
   148  	m.Refresh(ctx)
   149  	assert.Equal(t, 2, len(m.perProcess))
   150  	t.Log(m.String())
   151  	assert.Contains(t, m.perProcess, 1)
   152  	assert.Contains(t, m.perProcess, 5)
   153  
   154  }
   155  
   156  func TestParseMemoryStat(t *testing.T) {
   157  	assert := assert.New(t)
   158  	contents := `
   159  cache 175247360
   160  rss 403296256
   161  rss_huge 65011712
   162  shmem 0
   163  mapped_file 93401088
   164  dirty 0
   165  writeback 0
   166  swap 1
   167  pgpgin 5829351
   168  pgpgout 5726886
   169  pgfault 5848359
   170  pgmajfault 792
   171  inactive_anon 0
   172  active_anon 309968896
   173  inactive_file 222568448
   174  active_file 46092288
   175  unevictable 0
   176  hierarchical_memory_limit 2097152000
   177  hierarchical_memsw_limit 9223372036854771712
   178  total_cache 175247360
   179  total_rss 403296256
   180  total_rss_huge 65011712
   181  total_shmem 0
   182  total_mapped_file 93401088
   183  total_dirty 0
   184  total_writeback 0
   185  total_swap 0
   186  total_pgpgin 5829351
   187  total_pgpgout 5726886
   188  total_pgfault 5848359
   189  total_pgmajfault 792
   190  total_inactive_anon 0
   191  total_active_anon 309968896
   192  total_inactive_file 222568448
   193  total_active_file 46092288
   194  total_unevictable 0
   195  `
   196  	result, err := parseMemoryStat(contents)
   197  	assert.NoError(err)
   198  	assert.Equal(uint64(403296256), result.Rss)
   199  	assert.Equal(uint64(175247360), result.Cache)
   200  	assert.Equal(uint64(1), result.Swap)
   201  	assert.Equal(uint64(222568448), result.InactiveFile)
   202  }
   203  

View as plain text