util_test.go 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. package cgroup
  2. import (
  3. "archive/zip"
  4. "fmt"
  5. "io"
  6. "os"
  7. "path/filepath"
  8. "testing"
  9. "github.com/stretchr/testify/assert"
  10. )
  11. const dockerTestData = "testdata/docker.zip"
  12. func TestMain(m *testing.M) {
  13. err := extractTestData(dockerTestData)
  14. if err != nil {
  15. fmt.Println(err)
  16. os.Exit(1)
  17. }
  18. os.Exit(m.Run())
  19. }
  20. // extractTestData from zip file and write it in the same dir as the zip file.
  21. func extractTestData(path string) error {
  22. r, err := zip.OpenReader(path)
  23. if err != nil {
  24. return err
  25. }
  26. defer r.Close()
  27. dest := filepath.Dir(path)
  28. extractAndWriteFile := func(f *zip.File) error {
  29. rc, err := f.Open()
  30. if err != nil {
  31. return err
  32. }
  33. defer rc.Close()
  34. path := filepath.Join(dest, f.Name)
  35. if found, err := exists(path); err != nil || found {
  36. return err
  37. }
  38. if f.FileInfo().IsDir() {
  39. os.MkdirAll(path, f.Mode())
  40. } else {
  41. destFile, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, os.FileMode(0700))
  42. if err != nil {
  43. return err
  44. }
  45. defer destFile.Close()
  46. _, err = io.Copy(destFile, rc)
  47. if err != nil {
  48. return err
  49. }
  50. os.Chmod(path, f.Mode())
  51. }
  52. return nil
  53. }
  54. for _, f := range r.File {
  55. err := extractAndWriteFile(f)
  56. if err != nil {
  57. return err
  58. }
  59. }
  60. return nil
  61. }
  62. // exists returns whether the given file or directory exists or not
  63. func exists(path string) (bool, error) {
  64. _, err := os.Stat(path)
  65. if err == nil {
  66. return true, nil
  67. }
  68. if os.IsNotExist(err) {
  69. return false, nil
  70. }
  71. return true, err
  72. }
  73. func TestSupportedSubsystems(t *testing.T) {
  74. subsystems, err := SupportedSubsystems("testdata/docker")
  75. if err != nil {
  76. t.Fatal(err)
  77. }
  78. assert.Len(t, subsystems, 11)
  79. assertContains(t, subsystems, "cpuset")
  80. assertContains(t, subsystems, "cpu")
  81. assertContains(t, subsystems, "cpuacct")
  82. assertContains(t, subsystems, "blkio")
  83. assertContains(t, subsystems, "memory")
  84. assertContains(t, subsystems, "devices")
  85. assertContains(t, subsystems, "freezer")
  86. assertContains(t, subsystems, "net_cls")
  87. assertContains(t, subsystems, "perf_event")
  88. assertContains(t, subsystems, "net_prio")
  89. assertContains(t, subsystems, "pids")
  90. _, found := subsystems["hugetlb"]
  91. assert.False(t, found, "hugetlb should be missing because it's disabled")
  92. }
  93. func TestSupportedSubsystemsErrCgroupsMissing(t *testing.T) {
  94. _, err := SupportedSubsystems("testdata/doesnotexist")
  95. if err != ErrCgroupsMissing {
  96. t.Fatalf("expected ErrCgroupsMissing, but got %v", err)
  97. }
  98. }
  99. func TestSubsystemMountpoints(t *testing.T) {
  100. subsystems := map[string]struct{}{}
  101. subsystems["blkio"] = struct{}{}
  102. subsystems["cpu"] = struct{}{}
  103. subsystems["cpuacct"] = struct{}{}
  104. subsystems["cpuset"] = struct{}{}
  105. subsystems["devices"] = struct{}{}
  106. subsystems["freezer"] = struct{}{}
  107. subsystems["hugetlb"] = struct{}{}
  108. subsystems["memory"] = struct{}{}
  109. subsystems["perf_event"] = struct{}{}
  110. mountpoints, err := SubsystemMountpoints("testdata/docker", subsystems)
  111. if err != nil {
  112. t.Fatal(err)
  113. }
  114. assert.Equal(t, "testdata/docker/sys/fs/cgroup/blkio", mountpoints["blkio"])
  115. assert.Equal(t, "testdata/docker/sys/fs/cgroup/cpu", mountpoints["cpu"])
  116. assert.Equal(t, "testdata/docker/sys/fs/cgroup/cpuacct", mountpoints["cpuacct"])
  117. assert.Equal(t, "testdata/docker/sys/fs/cgroup/cpuset", mountpoints["cpuset"])
  118. assert.Equal(t, "testdata/docker/sys/fs/cgroup/devices", mountpoints["devices"])
  119. assert.Equal(t, "testdata/docker/sys/fs/cgroup/freezer", mountpoints["freezer"])
  120. assert.Equal(t, "testdata/docker/sys/fs/cgroup/hugetlb", mountpoints["hugetlb"])
  121. assert.Equal(t, "testdata/docker/sys/fs/cgroup/memory", mountpoints["memory"])
  122. assert.Equal(t, "testdata/docker/sys/fs/cgroup/perf_event", mountpoints["perf_event"])
  123. }
  124. func TestProcessCgroupPaths(t *testing.T) {
  125. paths, err := ProcessCgroupPaths("testdata/docker", 985)
  126. if err != nil {
  127. t.Fatal(err)
  128. }
  129. path := "/docker/b29faf21b7eff959f64b4192c34d5d67a707fe8561e9eaa608cb27693fba4242"
  130. assert.Equal(t, path, paths["blkio"])
  131. assert.Equal(t, path, paths["cpu"])
  132. assert.Equal(t, path, paths["cpuacct"])
  133. assert.Equal(t, path, paths["cpuset"])
  134. assert.Equal(t, path, paths["devices"])
  135. assert.Equal(t, path, paths["freezer"])
  136. assert.Equal(t, path, paths["memory"])
  137. assert.Equal(t, path, paths["net_cls"])
  138. assert.Equal(t, path, paths["net_prio"])
  139. assert.Equal(t, path, paths["perf_event"])
  140. assert.Len(t, paths, 10)
  141. }
  142. func assertContains(t testing.TB, m map[string]struct{}, key string) {
  143. _, contains := m[key]
  144. if !contains {
  145. t.Errorf("map is missing key %v, map=%+v", key, m)
  146. }
  147. }
  148. func TestParseMountinfoLine(t *testing.T) {
  149. lines := []string{
  150. "30 24 0:25 / /sys/fs/cgroup/blkio rw,nosuid,nodev,noexec,relatime - cgroup cgroup rw,blkio",
  151. "30 24 0:25 / /sys/fs/cgroup/blkio rw,nosuid,nodev,noexec,relatime shared:13 - cgroup cgroup rw,blkio",
  152. "30 24 0:25 / /sys/fs/cgroup/blkio rw,nosuid,nodev,noexec,relatime shared:13 master:1 - cgroup cgroup rw,blkio",
  153. "30 24 0:25 / /sys/fs/cgroup/blkio rw,nosuid,nodev,noexec,relatime shared:13 - cgroup cgroup rw,name=blkio",
  154. }
  155. for _, line := range lines {
  156. mount, err := parseMountinfoLine(line)
  157. if err != nil {
  158. t.Fatal(err)
  159. }
  160. assert.Equal(t, "/sys/fs/cgroup/blkio", mount.mountpoint)
  161. assert.Equal(t, "cgroup", mount.filesystemType)
  162. assert.Len(t, mount.superOptions, 2)
  163. }
  164. }