github.com/hernad/nomad@v1.6.112/drivers/docker/stats_test.go (about) 1 // Copyright (c) HashiCorp, Inc. 2 // SPDX-License-Identifier: MPL-2.0 3 4 package docker 5 6 import ( 7 "runtime" 8 "sync" 9 "testing" 10 "time" 11 12 docker "github.com/fsouza/go-dockerclient" 13 "github.com/hernad/nomad/ci" 14 cstructs "github.com/hernad/nomad/client/structs" 15 "github.com/stretchr/testify/require" 16 ) 17 18 func TestDriver_DockerStatsCollector(t *testing.T) { 19 ci.Parallel(t) 20 require := require.New(t) 21 22 src := make(chan *docker.Stats) 23 defer close(src) 24 dst, recvCh := newStatsChanPipe() 25 defer dst.close() 26 stats := &docker.Stats{} 27 stats.CPUStats.ThrottlingData.Periods = 10 28 stats.CPUStats.ThrottlingData.ThrottledPeriods = 10 29 stats.CPUStats.ThrottlingData.ThrottledTime = 10 30 31 stats.MemoryStats.Stats.Rss = 6537216 32 stats.MemoryStats.Stats.Cache = 1234 33 stats.MemoryStats.Stats.Swap = 0 34 stats.MemoryStats.Stats.MappedFile = 1024 35 stats.MemoryStats.Usage = 5651904 36 stats.MemoryStats.MaxUsage = 6651904 37 stats.MemoryStats.Commit = 123231 38 stats.MemoryStats.CommitPeak = 321323 39 stats.MemoryStats.PrivateWorkingSet = 62222 40 41 go dockerStatsCollector(dst, src, time.Second) 42 43 select { 44 case src <- stats: 45 case <-time.After(time.Second): 46 require.Fail("sending stats should not block here") 47 } 48 49 select { 50 case ru := <-recvCh: 51 if runtime.GOOS != "windows" { 52 require.Equal(stats.MemoryStats.Stats.Rss, ru.ResourceUsage.MemoryStats.RSS) 53 require.Equal(stats.MemoryStats.Stats.Cache, ru.ResourceUsage.MemoryStats.Cache) 54 require.Equal(stats.MemoryStats.Stats.Swap, ru.ResourceUsage.MemoryStats.Swap) 55 require.Equal(stats.MemoryStats.Stats.MappedFile, ru.ResourceUsage.MemoryStats.MappedFile) 56 require.Equal(stats.MemoryStats.Usage, ru.ResourceUsage.MemoryStats.Usage) 57 require.Equal(stats.MemoryStats.MaxUsage, ru.ResourceUsage.MemoryStats.MaxUsage) 58 require.Equal(stats.CPUStats.ThrottlingData.ThrottledPeriods, ru.ResourceUsage.CpuStats.ThrottledPeriods) 59 require.Equal(stats.CPUStats.ThrottlingData.ThrottledTime, ru.ResourceUsage.CpuStats.ThrottledTime) 60 } else { 61 require.Equal(stats.MemoryStats.PrivateWorkingSet, ru.ResourceUsage.MemoryStats.RSS) 62 require.Equal(stats.MemoryStats.Commit, ru.ResourceUsage.MemoryStats.Usage) 63 require.Equal(stats.MemoryStats.CommitPeak, ru.ResourceUsage.MemoryStats.MaxUsage) 64 require.Equal(stats.CPUStats.ThrottlingData.ThrottledPeriods, ru.ResourceUsage.CpuStats.ThrottledPeriods) 65 require.Equal(stats.CPUStats.ThrottlingData.ThrottledTime, ru.ResourceUsage.CpuStats.ThrottledTime) 66 67 } 68 case <-time.After(time.Second): 69 require.Fail("receiving stats should not block here") 70 } 71 } 72 73 // TestDriver_DockerUsageSender asserts that the TaskResourceUsage chan wrapper 74 // supports closing and sending on a chan from concurrent goroutines. 75 func TestDriver_DockerUsageSender(t *testing.T) { 76 ci.Parallel(t) 77 78 // sample payload 79 res := &cstructs.TaskResourceUsage{} 80 81 destCh, recvCh := newStatsChanPipe() 82 83 // Sending should never fail 84 destCh.send(res) 85 destCh.send(res) 86 destCh.send(res) 87 88 // Clear chan 89 <-recvCh 90 91 // Send and close concurrently to let the race detector help us out 92 wg := sync.WaitGroup{} 93 wg.Add(3) 94 95 // Sender 96 go func() { 97 destCh.send(res) 98 wg.Done() 99 }() 100 101 // Closer 102 go func() { 103 destCh.close() 104 wg.Done() 105 }() 106 107 // Clear recv chan 108 go func() { 109 for range recvCh { 110 } 111 wg.Done() 112 }() 113 114 wg.Wait() 115 116 // Assert closed 117 destCh.mu.Lock() 118 closed := destCh.closed 119 destCh.mu.Unlock() 120 require.True(t, closed) 121 122 select { 123 case _, ok := <-recvCh: 124 require.False(t, ok) 125 default: 126 require.Fail(t, "expect recvCh to be closed") 127 } 128 129 // Assert sending and closing never fails 130 destCh.send(res) 131 destCh.close() 132 destCh.close() 133 destCh.send(res) 134 }