1/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "rlimit_parser.h"
18
19#include <iostream>
20
21#include <gtest/gtest.h>
22
23namespace android {
24namespace init {
25
26void TestRlimitSuccess(std::vector<std::string> input,
27                       const std::pair<int, rlimit>& expected_result) {
28    input.emplace(input.begin(), "");
29    ASSERT_EQ(4U, input.size());
30    auto result = ParseRlimit(input);
31
32    ASSERT_TRUE(result) << "input: " << input[1];
33    const auto& [resource, rlimit] = *result;
34    const auto& [expected_resource, expected_rlimit] = expected_result;
35    EXPECT_EQ(expected_resource, resource);
36    EXPECT_EQ(expected_rlimit.rlim_cur, rlimit.rlim_cur);
37    EXPECT_EQ(expected_rlimit.rlim_max, rlimit.rlim_max);
38}
39
40void TestRlimitFailure(std::vector<std::string> input, const std::string& expected_result) {
41    input.emplace(input.begin(), "");
42    ASSERT_EQ(4U, input.size());
43    auto result = ParseRlimit(input);
44
45    ASSERT_FALSE(result) << "input: " << input[1];
46    EXPECT_EQ(expected_result, result.error_string());
47    EXPECT_EQ(0, result.error_errno());
48}
49
50TEST(rlimit, RlimitSuccess) {
51    const std::vector<std::pair<std::vector<std::string>, std::pair<int, rlimit>>>
52        inputs_and_results = {
53            {{"cpu", "10", "10"}, {0, {10, 10}}},
54            {{"fsize", "10", "10"}, {1, {10, 10}}},
55            {{"data", "10", "10"}, {2, {10, 10}}},
56            {{"stack", "10", "10"}, {3, {10, 10}}},
57            {{"core", "10", "10"}, {4, {10, 10}}},
58            {{"rss", "10", "10"}, {5, {10, 10}}},
59            {{"nproc", "10", "10"}, {6, {10, 10}}},
60            {{"nofile", "10", "10"}, {7, {10, 10}}},
61            {{"memlock", "10", "10"}, {8, {10, 10}}},
62            {{"as", "10", "10"}, {9, {10, 10}}},
63            {{"locks", "10", "10"}, {10, {10, 10}}},
64            {{"sigpending", "10", "10"}, {11, {10, 10}}},
65            {{"msgqueue", "10", "10"}, {12, {10, 10}}},
66            {{"nice", "10", "10"}, {13, {10, 10}}},
67            {{"rtprio", "10", "10"}, {14, {10, 10}}},
68            {{"rttime", "10", "10"}, {15, {10, 10}}},
69
70            {{"RLIM_CPU", "10", "10"}, {0, {10, 10}}},
71            {{"RLIM_FSIZE", "10", "10"}, {1, {10, 10}}},
72            {{"RLIM_DATA", "10", "10"}, {2, {10, 10}}},
73            {{"RLIM_STACK", "10", "10"}, {3, {10, 10}}},
74            {{"RLIM_CORE", "10", "10"}, {4, {10, 10}}},
75            {{"RLIM_RSS", "10", "10"}, {5, {10, 10}}},
76            {{"RLIM_NPROC", "10", "10"}, {6, {10, 10}}},
77            {{"RLIM_NOFILE", "10", "10"}, {7, {10, 10}}},
78            {{"RLIM_MEMLOCK", "10", "10"}, {8, {10, 10}}},
79            {{"RLIM_AS", "10", "10"}, {9, {10, 10}}},
80            {{"RLIM_LOCKS", "10", "10"}, {10, {10, 10}}},
81            {{"RLIM_SIGPENDING", "10", "10"}, {11, {10, 10}}},
82            {{"RLIM_MSGQUEUE", "10", "10"}, {12, {10, 10}}},
83            {{"RLIM_NICE", "10", "10"}, {13, {10, 10}}},
84            {{"RLIM_RTPRIO", "10", "10"}, {14, {10, 10}}},
85            {{"RLIM_RTTIME", "10", "10"}, {15, {10, 10}}},
86
87            {{"0", "10", "10"}, {0, {10, 10}}},
88            {{"1", "10", "10"}, {1, {10, 10}}},
89            {{"2", "10", "10"}, {2, {10, 10}}},
90            {{"3", "10", "10"}, {3, {10, 10}}},
91            {{"4", "10", "10"}, {4, {10, 10}}},
92            {{"5", "10", "10"}, {5, {10, 10}}},
93            {{"6", "10", "10"}, {6, {10, 10}}},
94            {{"7", "10", "10"}, {7, {10, 10}}},
95            {{"8", "10", "10"}, {8, {10, 10}}},
96            {{"9", "10", "10"}, {9, {10, 10}}},
97            {{"10", "10", "10"}, {10, {10, 10}}},
98            {{"11", "10", "10"}, {11, {10, 10}}},
99            {{"12", "10", "10"}, {12, {10, 10}}},
100            {{"13", "10", "10"}, {13, {10, 10}}},
101            {{"14", "10", "10"}, {14, {10, 10}}},
102            {{"15", "10", "10"}, {15, {10, 10}}},
103        };
104
105    for (const auto& [input, expected_result] : inputs_and_results) {
106        TestRlimitSuccess(input, expected_result);
107    }
108}
109
110TEST(rlimit, RlimitFailure) {
111    const std::vector<std::pair<std::vector<std::string>, std::string>> inputs_and_results = {
112        {{"-4", "10", "10"}, "Resource '-4' below the minimum resource value '0'"},
113        {{"100", "10", "10"}, "Resource '100' over the maximum resource value '16'"},
114        {{"bad_string", "10", "10"}, "Could not parse resource 'bad_string'"},
115        {{"RLIM_", "10", "10"}, "Could not parse resource 'RLIM_'"},
116        {{"cpu", "abc", "10"}, "Could not parse soft limit 'abc'"},
117        {{"cpu", "10", "abc"}, "Could not parse hard limit 'abc'"},
118    };
119
120    for (const auto& [input, expected_result] : inputs_and_results) {
121        TestRlimitFailure(input, expected_result);
122    }
123}
124
125}  // namespace init
126}  // namespace android
127