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