1 /*
2  * Copyright (c) 2020, Red Hat Inc.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 
25 import static org.junit.Assert.assertEquals;
26 import static org.junit.Assert.assertNull;
27 import static org.junit.Assert.assertTrue;
28 
29 import java.io.IOException;
30 import java.nio.charset.StandardCharsets;
31 import java.nio.file.Files;
32 import java.nio.file.Path;
33 import java.nio.file.Paths;
34 import java.util.Arrays;
35 
36 import org.junit.After;
37 import org.junit.Before;
main(String[] args)38 import org.junit.Test;
39 
40 import jdk.internal.platform.CgroupSubsystemController;
41 import jdk.test.lib.Utils;
42 import jdk.test.lib.util.FileUtils;
43 
44 /*
45  * @test
46  * @key cgroups
47  * @requires os.family == "linux"
48  * @modules java.base/jdk.internal.platform
49  * @library /test/lib
50  * @run junit/othervm TestCgroupSubsystemController
51  */
52 
53 /**
54  *
55  * Basic unit test for CgroupSubsystemController
56  *
57  */
58 public class TestCgroupSubsystemController {
59 
60     private static final double DELTA = 0.01;
61     private Path existingDirectory;
62     private Path existingFile;
63     private String existingFileName = "test-controller-file";
64     private String existingFileContents = "foobar";
65     private String doubleValueContents = "1.5";
66     private String longValueContents = "3000000000";
67     private String longValueMatchingLineContents = "testme\n" +
68                                                    "itemfoo 25";
69     private String longEntryContents = "s 1\n" +
70                                        "t 2";
71     private String longEntryName = "longEntry";
72     private String longEntryMatchingLineName = "longMatchingLine";
73     private String doubleValueName = "doubleValue";
74     private String longValueName = "longValue";
75     private CgroupSubsystemController mockController;
76 
77     @Before
78     public void setup() {
79         try {
80             existingDirectory = Utils.createTempDirectory(TestCgroupSubsystemController.class.getSimpleName());
81             existingFile = Paths.get(existingDirectory.toString(), existingFileName);
82             Files.writeString(existingFile, existingFileContents, StandardCharsets.UTF_8);
83             Path longFile = Paths.get(existingDirectory.toString(), longValueName);
84             Files.writeString(longFile, longValueContents);
85             Path doubleFile = Paths.get(existingDirectory.toString(), doubleValueName);
86             Files.writeString(doubleFile, doubleValueContents);
87             Path longEntryFile = Paths.get(existingDirectory.toString(), longEntryName);
88             Files.writeString(longEntryFile, longEntryContents);
89             Path longMatchingLine = Paths.get(existingDirectory.toString(), longEntryMatchingLineName);
90             Files.writeString(longMatchingLine, longValueMatchingLineContents);
91             mockController = new MockCgroupSubsystemController(existingDirectory.toString());
92         } catch (IOException e) {
93             throw new RuntimeException(e);
94         }
95     }
96 
97     @After
98     public void teardown() {
99         try {
100             FileUtils.deleteFileTreeWithRetry(existingDirectory);
101         } catch (IOException e) {
102             System.err.println("Teardown failed. " + e.getMessage());
103         }
104     }
105 
106     @Test
107     public void getStringValueNullController() {
108         String val = CgroupSubsystemController.getStringValue(null, "ignore");
109         assertNull(val);
110     }
111 
112     @Test
113     public void getStringValueIOException() throws IOException {
114         String val = CgroupSubsystemController.getStringValue(mockController, "don-t-exist.txt");
115         assertNull(val);
116     }
117 
118     @Test
119     public void getStringValueSuccess() {
120         String actual = CgroupSubsystemController.getStringValue(mockController, existingFileName);
121         assertEquals(existingFileContents, actual);
122     }
123 
124     @Test
125     public void convertStringToLong() {
126         String strVal = "1230";
127         long longVal = Long.parseLong(strVal);
128         long actual = CgroupSubsystemController.convertStringToLong(strVal, -1L, 0);
129         assertEquals(longVal, actual);
130 
131         String overflowVal = "9223372036854775808"; // Long.MAX_VALUE + 1
132         long overflowDefault = -1;
133         actual = CgroupSubsystemController.convertStringToLong(overflowVal, overflowDefault, 0);
134         assertEquals(overflowDefault, actual);
135         overflowDefault = Long.MAX_VALUE;
136         actual = CgroupSubsystemController.convertStringToLong(overflowVal, overflowDefault, 0);
137         assertEquals(overflowDefault, actual);
138     }
139 
140     @Test
141     public void convertStringRangeToIntArray() {
142         assertNull(CgroupSubsystemController.stringRangeToIntArray(null));
143         assertNull(CgroupSubsystemController.stringRangeToIntArray(""));
144         String strRange = "2,4,6";
145         int[] actual = CgroupSubsystemController.stringRangeToIntArray(strRange);
146         int[] expected = new int[] { 2, 4, 6 };
147         assertTrue(Arrays.equals(expected, actual));
148         strRange = "6,1-3";
149         actual = CgroupSubsystemController.stringRangeToIntArray(strRange);
150         expected = new int[] { 1, 2, 3, 6 };
151         assertTrue(Arrays.equals(expected, actual));
152     }
153 
154     @Test
155     public void getDoubleValue() {
156         double defaultValue = -3;
157         double actual = CgroupSubsystemController.getDoubleValue(null, null, defaultValue);
158         assertEquals(defaultValue, actual, DELTA);
159         double expected = Double.parseDouble(doubleValueContents);
160         actual = CgroupSubsystemController.getDoubleValue(mockController, doubleValueName, defaultValue);
161         assertEquals(expected, actual, DELTA);
162         actual = CgroupSubsystemController.getDoubleValue(mockController, "don't-exist", defaultValue);
163         assertEquals(defaultValue, actual, DELTA);
164     }
165 
166     @Test
167     public void getLongValue() {
168         long defaultValue = -4;
169         long actual = CgroupSubsystemController.getLongValue(null, null, Long::parseLong, defaultValue);
170         assertEquals(defaultValue, actual);
171         actual = CgroupSubsystemController.getLongValue(mockController, "dont-exist", Long::parseLong, defaultValue);
172         assertEquals(defaultValue, actual);
173         long expected = Long.parseLong(longValueContents);
174         actual = CgroupSubsystemController.getLongValue(mockController, longValueName, Long::parseLong, defaultValue);
175         assertEquals(expected, actual);
176     }
177 
178     @Test
179     public void getLongEntry() {
180         long defaultValue = -5;
181         long actual = CgroupSubsystemController.getLongEntry(null, null, "no-matter", defaultValue);
182         assertEquals(defaultValue, actual);
183         actual = CgroupSubsystemController.getLongEntry(mockController, "dont-exist", "foo-bar", defaultValue);
184         assertEquals(defaultValue, actual);
185         actual = CgroupSubsystemController.getLongEntry(mockController, longEntryName, "t", defaultValue);
186         assertEquals(2, actual);
187     }
188 
189     @Test
190     public void getLongMatchingLine() {
191         long defaultValue = -6;
192         long actual = CgroupSubsystemController.getLongValueMatchingLine(null, null, "no-matter", Long::parseLong, defaultValue);
193         assertEquals(defaultValue, actual);
194         actual = CgroupSubsystemController.getLongValueMatchingLine(mockController, "dont-exist", "no-matter", Long::parseLong, defaultValue);
195         assertEquals(defaultValue, actual);
196         actual = CgroupSubsystemController.getLongValueMatchingLine(mockController, longEntryMatchingLineName, "item", TestCgroupSubsystemController::convertLong, defaultValue);
197         assertEquals(25, actual);
198     }
199 
200     public static long convertLong(String line) {
201         return Long.parseLong(line.split("\\s+")[1]);
202     }
203 
204     static class MockCgroupSubsystemController implements CgroupSubsystemController {
205 
206         private final String path;
207 
208         public MockCgroupSubsystemController(String path) {
209             this.path = path;
210         }
211 
212         @Override
213         public String path() {
214             return path;
215         }
216 
217     }
218 
219 }
220