1// Copyright 2020 The Prometheus Authors
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
14package procfs
15
16import (
17	"reflect"
18	"testing"
19)
20
21func TestParseCgroupString(t *testing.T) {
22	tests := []struct {
23		name      string
24		s         string
25		shouldErr bool
26		cgroup    *Cgroup
27	}{
28		{
29			name:      "cgroups-v1 simple line",
30			s:         "10:rdma:/",
31			shouldErr: false,
32			cgroup: &Cgroup{
33				HierarchyID: 10,
34				Controllers: []string{"rdma"},
35				Path:        "/",
36			},
37		},
38		{
39			name:      "cgroups-v1 multi-hier line",
40			s:         "3:cpu,cpuacct:/user.slice/user-1000.slice/session-10.scope",
41			shouldErr: false,
42			cgroup: &Cgroup{
43				HierarchyID: 3,
44				Controllers: []string{"cpu", "cpuacct"},
45				Path:        "/user.slice/user-1000.slice/session-10.scope",
46			},
47		},
48		{
49			name:      "cgroup-v2 line",
50			s:         "0::/user.slice/user-1000.slice/user@1000.service/gnome-terminal-server.service",
51			shouldErr: false,
52			cgroup: &Cgroup{
53				HierarchyID: 0,
54				Controllers: nil,
55				Path:        "/user.slice/user-1000.slice/user@1000.service/gnome-terminal-server.service",
56			},
57		},
58		{
59			name:      "path containing colons",
60			s:         "0::/some/long/path:foobar",
61			shouldErr: false,
62			cgroup: &Cgroup{
63				HierarchyID: 0,
64				Controllers: nil,
65				Path:        "/some/long/path:foobar",
66			},
67		},
68		{
69			name:      "bad hierarchy ID field",
70			s:         "a:cpu:/",
71			shouldErr: true,
72			cgroup:    nil,
73		},
74	}
75
76	for i, test := range tests {
77		t.Logf("[%02d] test %q", i, test.name)
78
79		cgroup, err := parseCgroupString(test.s)
80
81		if test.shouldErr && err == nil {
82			t.Errorf("%s: expected an error, but none occurred", test.name)
83		}
84		if !test.shouldErr && err != nil {
85			t.Errorf("%s: unexpected error: %v", test.name, err)
86		}
87
88		if want, have := test.cgroup, cgroup; !reflect.DeepEqual(want, have) {
89			t.Errorf("cgroup:\nwant:\n%+v\nhave:\n%+v", want, have)
90		}
91	}
92
93}
94