operatingsystem_linux_test.go 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. // +build linux freebsd
  2. package operatingsystem // import "github.com/docker/docker/pkg/parsers/operatingsystem"
  3. import (
  4. "io/ioutil"
  5. "os"
  6. "path/filepath"
  7. "testing"
  8. "gotest.tools/assert"
  9. )
  10. type EtcReleaseParsingTest struct {
  11. name string
  12. content string
  13. expected string
  14. expectedErr string
  15. }
  16. func TestGetOperatingSystem(t *testing.T) {
  17. tests := []EtcReleaseParsingTest{
  18. {
  19. content: `PRETTY_NAME=Source Mage GNU/Linux
  20. PRETTY_NAME=Ubuntu 14.04.LTS`,
  21. expectedErr: "PRETTY_NAME needs to be enclosed by quotes if they have spaces: Source Mage GNU/Linux",
  22. },
  23. {
  24. content: `PRETTY_NAME="Ubuntu Linux
  25. PRETTY_NAME=Ubuntu 14.04.LTS`,
  26. expectedErr: "PRETTY_NAME is invalid: invalid command line string",
  27. },
  28. {
  29. content: `PRETTY_NAME=Ubuntu'
  30. PRETTY_NAME=Ubuntu 14.04.LTS`,
  31. expectedErr: "PRETTY_NAME is invalid: invalid command line string",
  32. },
  33. {
  34. content: `PRETTY_NAME'
  35. PRETTY_NAME=Ubuntu 14.04.LTS`,
  36. expectedErr: "PRETTY_NAME needs to be enclosed by quotes if they have spaces: Ubuntu 14.04.LTS",
  37. },
  38. {
  39. content: `NAME="Ubuntu"
  40. PRETTY_NAME_AGAIN="Ubuntu 14.04.LTS"
  41. VERSION="14.04, Trusty Tahr"
  42. ID=ubuntu
  43. ID_LIKE=debian
  44. VERSION_ID="14.04"
  45. HOME_URL="http://www.ubuntu.com/"
  46. SUPPORT_URL="http://help.ubuntu.com/"
  47. BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"`,
  48. expected: "Linux",
  49. },
  50. {
  51. content: `NAME="Ubuntu"
  52. VERSION="14.04, Trusty Tahr"
  53. ID=ubuntu
  54. ID_LIKE=debian
  55. VERSION_ID="14.04"
  56. HOME_URL="http://www.ubuntu.com/"
  57. SUPPORT_URL="http://help.ubuntu.com/"
  58. BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"`,
  59. expected: "Linux",
  60. },
  61. {
  62. content: `NAME=Gentoo
  63. ID=gentoo
  64. PRETTY_NAME="Gentoo/Linux"
  65. ANSI_COLOR="1;32"
  66. HOME_URL="http://www.gentoo.org/"
  67. SUPPORT_URL="http://www.gentoo.org/main/en/support.xml"
  68. BUG_REPORT_URL="https://bugs.gentoo.org/"
  69. `,
  70. expected: "Gentoo/Linux",
  71. },
  72. {
  73. content: `NAME="Ubuntu"
  74. VERSION="14.04, Trusty Tahr"
  75. ID=ubuntu
  76. ID_LIKE=debian
  77. PRETTY_NAME="Ubuntu 14.04 LTS"
  78. VERSION_ID="14.04"
  79. HOME_URL="http://www.ubuntu.com/"
  80. SUPPORT_URL="http://help.ubuntu.com/"
  81. BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"`,
  82. expected: "Ubuntu 14.04 LTS",
  83. },
  84. {
  85. content: `NAME="Ubuntu"
  86. VERSION="14.04, Trusty Tahr"
  87. ID=ubuntu
  88. ID_LIKE=debian
  89. PRETTY_NAME='Ubuntu 14.04 LTS'`,
  90. expected: "Ubuntu 14.04 LTS",
  91. },
  92. {
  93. content: `PRETTY_NAME=Source
  94. NAME="Source Mage"`,
  95. expected: "Source",
  96. },
  97. {
  98. content: `PRETTY_NAME=Source
  99. PRETTY_NAME="Source Mage"`,
  100. expected: "Source Mage",
  101. },
  102. }
  103. runEtcReleaseParsingTests(t, tests, GetOperatingSystem)
  104. }
  105. func TestGetOperatingSystemVersion(t *testing.T) {
  106. tests := []EtcReleaseParsingTest{
  107. {
  108. name: "invalid version id",
  109. content: `VERSION_ID="18.04
  110. VERSION_ID=18.04`,
  111. expectedErr: "VERSION_ID is invalid: invalid command line string",
  112. },
  113. {
  114. name: "ubuntu 14.04",
  115. content: `NAME="Ubuntu"
  116. PRETTY_NAME="Ubuntu 14.04.LTS"
  117. VERSION="14.04, Trusty Tahr"
  118. ID=ubuntu
  119. ID_LIKE=debian
  120. VERSION_ID="14.04"
  121. HOME_URL="http://www.ubuntu.com/"
  122. SUPPORT_URL="http://help.ubuntu.com/"
  123. BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"`,
  124. expected: "14.04",
  125. },
  126. {
  127. name: "gentoo",
  128. content: `NAME=Gentoo
  129. ID=gentoo
  130. PRETTY_NAME="Gentoo/Linux"
  131. ANSI_COLOR="1;32"
  132. HOME_URL="http://www.gentoo.org/"
  133. SUPPORT_URL="http://www.gentoo.org/main/en/support.xml"
  134. BUG_REPORT_URL="https://bugs.gentoo.org/"
  135. `,
  136. },
  137. {
  138. name: "dual version id",
  139. content: `VERSION_ID="14.04"
  140. VERSION_ID=18.04`,
  141. expected: "18.04",
  142. },
  143. }
  144. runEtcReleaseParsingTests(t, tests, GetOperatingSystemVersion)
  145. }
  146. func runEtcReleaseParsingTests(t *testing.T, tests []EtcReleaseParsingTest, parsingFunc func() (string, error)) {
  147. var backup = etcOsRelease
  148. dir := os.TempDir()
  149. etcOsRelease = filepath.Join(dir, "etcOsRelease")
  150. defer func() {
  151. os.Remove(etcOsRelease)
  152. etcOsRelease = backup
  153. }()
  154. for _, test := range tests {
  155. t.Run(test.name, func(t *testing.T) {
  156. if err := ioutil.WriteFile(etcOsRelease, []byte(test.content), 0600); err != nil {
  157. t.Fatalf("failed to write to %s: %v", etcOsRelease, err)
  158. }
  159. s, err := parsingFunc()
  160. if test.expectedErr == "" {
  161. assert.NilError(t, err)
  162. } else {
  163. assert.Error(t, err, test.expectedErr)
  164. }
  165. assert.Equal(t, s, test.expected)
  166. })
  167. }
  168. }
  169. func TestIsContainerized(t *testing.T) {
  170. var (
  171. backup = proc1Cgroup
  172. nonContainerizedProc1Cgroupsystemd226 = []byte(`9:memory:/init.scope
  173. 8:net_cls,net_prio:/
  174. 7:cpuset:/
  175. 6:freezer:/
  176. 5:devices:/init.scope
  177. 4:blkio:/init.scope
  178. 3:cpu,cpuacct:/init.scope
  179. 2:perf_event:/
  180. 1:name=systemd:/init.scope
  181. `)
  182. nonContainerizedProc1Cgroup = []byte(`14:name=systemd:/
  183. 13:hugetlb:/
  184. 12:net_prio:/
  185. 11:perf_event:/
  186. 10:bfqio:/
  187. 9:blkio:/
  188. 8:net_cls:/
  189. 7:freezer:/
  190. 6:devices:/
  191. 5:memory:/
  192. 4:cpuacct:/
  193. 3:cpu:/
  194. 2:cpuset:/
  195. `)
  196. containerizedProc1Cgroup = []byte(`9:perf_event:/docker/3cef1b53c50b0fa357d994f8a1a8cd783c76bbf4f5dd08b226e38a8bd331338d
  197. 8:blkio:/docker/3cef1b53c50b0fa357d994f8a1a8cd783c76bbf4f5dd08b226e38a8bd331338d
  198. 7:net_cls:/
  199. 6:freezer:/docker/3cef1b53c50b0fa357d994f8a1a8cd783c76bbf4f5dd08b226e38a8bd331338d
  200. 5:devices:/docker/3cef1b53c50b0fa357d994f8a1a8cd783c76bbf4f5dd08b226e38a8bd331338d
  201. 4:memory:/docker/3cef1b53c50b0fa357d994f8a1a8cd783c76bbf4f5dd08b226e38a8bd331338d
  202. 3:cpuacct:/docker/3cef1b53c50b0fa357d994f8a1a8cd783c76bbf4f5dd08b226e38a8bd331338d
  203. 2:cpu:/docker/3cef1b53c50b0fa357d994f8a1a8cd783c76bbf4f5dd08b226e38a8bd331338d
  204. 1:cpuset:/`)
  205. )
  206. dir := os.TempDir()
  207. proc1Cgroup = filepath.Join(dir, "proc1Cgroup")
  208. defer func() {
  209. os.Remove(proc1Cgroup)
  210. proc1Cgroup = backup
  211. }()
  212. if err := ioutil.WriteFile(proc1Cgroup, nonContainerizedProc1Cgroup, 0600); err != nil {
  213. t.Fatalf("failed to write to %s: %v", proc1Cgroup, err)
  214. }
  215. inContainer, err := IsContainerized()
  216. if err != nil {
  217. t.Fatal(err)
  218. }
  219. if inContainer {
  220. t.Fatal("Wrongly assuming containerized")
  221. }
  222. if err := ioutil.WriteFile(proc1Cgroup, nonContainerizedProc1Cgroupsystemd226, 0600); err != nil {
  223. t.Fatalf("failed to write to %s: %v", proc1Cgroup, err)
  224. }
  225. inContainer, err = IsContainerized()
  226. if err != nil {
  227. t.Fatal(err)
  228. }
  229. if inContainer {
  230. t.Fatal("Wrongly assuming containerized for systemd /init.scope cgroup layout")
  231. }
  232. if err := ioutil.WriteFile(proc1Cgroup, containerizedProc1Cgroup, 0600); err != nil {
  233. t.Fatalf("failed to write to %s: %v", proc1Cgroup, err)
  234. }
  235. inContainer, err = IsContainerized()
  236. if err != nil {
  237. t.Fatal(err)
  238. }
  239. if !inContainer {
  240. t.Fatal("Wrongly assuming non-containerized")
  241. }
  242. }
  243. func TestOsReleaseFallback(t *testing.T) {
  244. var backup = etcOsRelease
  245. var altBackup = altOsRelease
  246. dir := os.TempDir()
  247. etcOsRelease = filepath.Join(dir, "etcOsRelease")
  248. altOsRelease = filepath.Join(dir, "altOsRelease")
  249. defer func() {
  250. os.Remove(dir)
  251. etcOsRelease = backup
  252. altOsRelease = altBackup
  253. }()
  254. content := `NAME=Gentoo
  255. ID=gentoo
  256. PRETTY_NAME="Gentoo/Linux"
  257. ANSI_COLOR="1;32"
  258. HOME_URL="http://www.gentoo.org/"
  259. SUPPORT_URL="http://www.gentoo.org/main/en/support.xml"
  260. BUG_REPORT_URL="https://bugs.gentoo.org/"
  261. `
  262. if err := ioutil.WriteFile(altOsRelease, []byte(content), 0600); err != nil {
  263. t.Fatalf("failed to write to %s: %v", etcOsRelease, err)
  264. }
  265. s, err := GetOperatingSystem()
  266. if err != nil || s != "Gentoo/Linux" {
  267. t.Fatalf("Expected %q, got %q (err: %v)", "Gentoo/Linux", s, err)
  268. }
  269. }