1// +build linux freebsd
2
3package operatingsystem
4
5import (
6	"io/ioutil"
7	"os"
8	"path/filepath"
9	"testing"
10)
11
12func TestGetOperatingSystem(t *testing.T) {
13	var backup = etcOsRelease
14
15	invalids := []struct {
16		content       string
17		errorExpected string
18	}{
19		{
20			`PRETTY_NAME=Source Mage GNU/Linux
21PRETTY_NAME=Ubuntu 14.04.LTS`,
22			"PRETTY_NAME needs to be enclosed by quotes if they have spaces: Source Mage GNU/Linux",
23		},
24		{
25			`PRETTY_NAME="Ubuntu Linux
26PRETTY_NAME=Ubuntu 14.04.LTS`,
27			"PRETTY_NAME is invalid: invalid command line string",
28		},
29		{
30			`PRETTY_NAME=Ubuntu'
31PRETTY_NAME=Ubuntu 14.04.LTS`,
32			"PRETTY_NAME is invalid: invalid command line string",
33		},
34		{
35			`PRETTY_NAME'
36PRETTY_NAME=Ubuntu 14.04.LTS`,
37			"PRETTY_NAME needs to be enclosed by quotes if they have spaces: Ubuntu 14.04.LTS",
38		},
39	}
40
41	valids := []struct {
42		content  string
43		expected string
44	}{
45		{
46			`NAME="Ubuntu"
47PRETTY_NAME_AGAIN="Ubuntu 14.04.LTS"
48VERSION="14.04, Trusty Tahr"
49ID=ubuntu
50ID_LIKE=debian
51VERSION_ID="14.04"
52HOME_URL="http://www.ubuntu.com/"
53SUPPORT_URL="http://help.ubuntu.com/"
54BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"`,
55			"Linux",
56		},
57		{
58			`NAME="Ubuntu"
59VERSION="14.04, Trusty Tahr"
60ID=ubuntu
61ID_LIKE=debian
62VERSION_ID="14.04"
63HOME_URL="http://www.ubuntu.com/"
64SUPPORT_URL="http://help.ubuntu.com/"
65BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"`,
66			"Linux",
67		},
68		{
69			`NAME=Gentoo
70ID=gentoo
71PRETTY_NAME="Gentoo/Linux"
72ANSI_COLOR="1;32"
73HOME_URL="http://www.gentoo.org/"
74SUPPORT_URL="http://www.gentoo.org/main/en/support.xml"
75BUG_REPORT_URL="https://bugs.gentoo.org/"
76`,
77			"Gentoo/Linux",
78		},
79		{
80			`NAME="Ubuntu"
81VERSION="14.04, Trusty Tahr"
82ID=ubuntu
83ID_LIKE=debian
84PRETTY_NAME="Ubuntu 14.04 LTS"
85VERSION_ID="14.04"
86HOME_URL="http://www.ubuntu.com/"
87SUPPORT_URL="http://help.ubuntu.com/"
88BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"`,
89			"Ubuntu 14.04 LTS",
90		},
91		{
92			`NAME="Ubuntu"
93VERSION="14.04, Trusty Tahr"
94ID=ubuntu
95ID_LIKE=debian
96PRETTY_NAME='Ubuntu 14.04 LTS'`,
97			"Ubuntu 14.04 LTS",
98		},
99		{
100			`PRETTY_NAME=Source
101NAME="Source Mage"`,
102			"Source",
103		},
104		{
105			`PRETTY_NAME=Source
106PRETTY_NAME="Source Mage"`,
107			"Source Mage",
108		},
109	}
110
111	dir := os.TempDir()
112	etcOsRelease = filepath.Join(dir, "etcOsRelease")
113
114	defer func() {
115		os.Remove(etcOsRelease)
116		etcOsRelease = backup
117	}()
118
119	for _, elt := range invalids {
120		if err := ioutil.WriteFile(etcOsRelease, []byte(elt.content), 0600); err != nil {
121			t.Fatalf("failed to write to %s: %v", etcOsRelease, err)
122		}
123		s, err := GetOperatingSystem()
124		if err == nil || err.Error() != elt.errorExpected {
125			t.Fatalf("Expected an error %q, got %q (err: %v)", elt.errorExpected, s, err)
126		}
127	}
128
129	for _, elt := range valids {
130		if err := ioutil.WriteFile(etcOsRelease, []byte(elt.content), 0600); err != nil {
131			t.Fatalf("failed to write to %s: %v", etcOsRelease, err)
132		}
133		s, err := GetOperatingSystem()
134		if err != nil || s != elt.expected {
135			t.Fatalf("Expected %q, got %q (err: %v)", elt.expected, s, err)
136		}
137	}
138}
139
140func TestIsContainerized(t *testing.T) {
141	var (
142		backup                                = proc1Cgroup
143		nonContainerizedProc1Cgroupsystemd226 = []byte(`9:memory:/init.scope
1448:net_cls,net_prio:/
1457:cpuset:/
1466:freezer:/
1475:devices:/init.scope
1484:blkio:/init.scope
1493:cpu,cpuacct:/init.scope
1502:perf_event:/
1511:name=systemd:/init.scope
152`)
153		nonContainerizedProc1Cgroup = []byte(`14:name=systemd:/
15413:hugetlb:/
15512:net_prio:/
15611:perf_event:/
15710:bfqio:/
1589:blkio:/
1598:net_cls:/
1607:freezer:/
1616:devices:/
1625:memory:/
1634:cpuacct:/
1643:cpu:/
1652:cpuset:/
166`)
167		containerizedProc1Cgroup = []byte(`9:perf_event:/docker/3cef1b53c50b0fa357d994f8a1a8cd783c76bbf4f5dd08b226e38a8bd331338d
1688:blkio:/docker/3cef1b53c50b0fa357d994f8a1a8cd783c76bbf4f5dd08b226e38a8bd331338d
1697:net_cls:/
1706:freezer:/docker/3cef1b53c50b0fa357d994f8a1a8cd783c76bbf4f5dd08b226e38a8bd331338d
1715:devices:/docker/3cef1b53c50b0fa357d994f8a1a8cd783c76bbf4f5dd08b226e38a8bd331338d
1724:memory:/docker/3cef1b53c50b0fa357d994f8a1a8cd783c76bbf4f5dd08b226e38a8bd331338d
1733:cpuacct:/docker/3cef1b53c50b0fa357d994f8a1a8cd783c76bbf4f5dd08b226e38a8bd331338d
1742:cpu:/docker/3cef1b53c50b0fa357d994f8a1a8cd783c76bbf4f5dd08b226e38a8bd331338d
1751:cpuset:/`)
176	)
177
178	dir := os.TempDir()
179	proc1Cgroup = filepath.Join(dir, "proc1Cgroup")
180
181	defer func() {
182		os.Remove(proc1Cgroup)
183		proc1Cgroup = backup
184	}()
185
186	if err := ioutil.WriteFile(proc1Cgroup, nonContainerizedProc1Cgroup, 0600); err != nil {
187		t.Fatalf("failed to write to %s: %v", proc1Cgroup, err)
188	}
189	inContainer, err := IsContainerized()
190	if err != nil {
191		t.Fatal(err)
192	}
193	if inContainer {
194		t.Fatal("Wrongly assuming containerized")
195	}
196
197	if err := ioutil.WriteFile(proc1Cgroup, nonContainerizedProc1Cgroupsystemd226, 0600); err != nil {
198		t.Fatalf("failed to write to %s: %v", proc1Cgroup, err)
199	}
200	inContainer, err = IsContainerized()
201	if err != nil {
202		t.Fatal(err)
203	}
204	if inContainer {
205		t.Fatal("Wrongly assuming containerized for systemd /init.scope cgroup layout")
206	}
207
208	if err := ioutil.WriteFile(proc1Cgroup, containerizedProc1Cgroup, 0600); err != nil {
209		t.Fatalf("failed to write to %s: %v", proc1Cgroup, err)
210	}
211	inContainer, err = IsContainerized()
212	if err != nil {
213		t.Fatal(err)
214	}
215	if !inContainer {
216		t.Fatal("Wrongly assuming non-containerized")
217	}
218}
219
220func TestOsReleaseFallback(t *testing.T) {
221	var backup = etcOsRelease
222	var altBackup = altOsRelease
223	dir := os.TempDir()
224	etcOsRelease = filepath.Join(dir, "etcOsRelease")
225	altOsRelease = filepath.Join(dir, "altOsRelease")
226
227	defer func() {
228		os.Remove(dir)
229		etcOsRelease = backup
230		altOsRelease = altBackup
231	}()
232	content := `NAME=Gentoo
233ID=gentoo
234PRETTY_NAME="Gentoo/Linux"
235ANSI_COLOR="1;32"
236HOME_URL="http://www.gentoo.org/"
237SUPPORT_URL="http://www.gentoo.org/main/en/support.xml"
238BUG_REPORT_URL="https://bugs.gentoo.org/"
239`
240	if err := ioutil.WriteFile(altOsRelease, []byte(content), 0600); err != nil {
241		t.Fatalf("failed to write to %s: %v", etcOsRelease, err)
242	}
243	s, err := GetOperatingSystem()
244	if err != nil || s != "Gentoo/Linux" {
245		t.Fatalf("Expected %q, got %q (err: %v)", "Gentoo/Linux", s, err)
246	}
247}
248