Home | History | Annotate | Download | only in init
      1 /*
      2  * Copyright (C) 2015 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 "util.h"
     18 
     19 #include <errno.h>
     20 #include <fcntl.h>
     21 #include <sys/stat.h>
     22 
     23 #include <android-base/stringprintf.h>
     24 #include <android-base/test_utils.h>
     25 #include <gtest/gtest.h>
     26 
     27 using namespace std::literals::string_literals;
     28 
     29 namespace android {
     30 namespace init {
     31 
     32 TEST(util, ReadFile_ENOENT) {
     33     errno = 0;
     34     auto file_contents = ReadFile("/proc/does-not-exist");
     35     EXPECT_EQ(ENOENT, errno);
     36     ASSERT_FALSE(file_contents);
     37     EXPECT_EQ("open() failed: No such file or directory", file_contents.error_string());
     38 }
     39 
     40 TEST(util, ReadFileGroupWriteable) {
     41     std::string s("hello");
     42     TemporaryFile tf;
     43     ASSERT_TRUE(tf.fd != -1);
     44     EXPECT_TRUE(WriteFile(tf.path, s)) << strerror(errno);
     45     EXPECT_NE(-1, fchmodat(AT_FDCWD, tf.path, 0620, AT_SYMLINK_NOFOLLOW)) << strerror(errno);
     46     auto file_contents = ReadFile(tf.path);
     47     ASSERT_FALSE(file_contents) << strerror(errno);
     48     EXPECT_EQ("Skipping insecure file", file_contents.error_string());
     49 }
     50 
     51 TEST(util, ReadFileWorldWiteable) {
     52     std::string s("hello");
     53     TemporaryFile tf;
     54     ASSERT_TRUE(tf.fd != -1);
     55     EXPECT_TRUE(WriteFile(tf.path, s)) << strerror(errno);
     56     EXPECT_NE(-1, fchmodat(AT_FDCWD, tf.path, 0602, AT_SYMLINK_NOFOLLOW)) << strerror(errno);
     57     auto file_contents = ReadFile(tf.path);
     58     ASSERT_FALSE(file_contents) << strerror(errno);
     59     EXPECT_EQ("Skipping insecure file", file_contents.error_string());
     60 }
     61 
     62 TEST(util, ReadFileSymbolicLink) {
     63     errno = 0;
     64     // lrwxrwxrwx 1 root root 13 1970-01-01 00:00 charger -> /sbin/healthd
     65     auto file_contents = ReadFile("/charger");
     66     EXPECT_EQ(ELOOP, errno);
     67     ASSERT_FALSE(file_contents);
     68     EXPECT_EQ("open() failed: Too many symbolic links encountered", file_contents.error_string());
     69 }
     70 
     71 TEST(util, ReadFileSuccess) {
     72     auto file_contents = ReadFile("/proc/version");
     73     ASSERT_TRUE(file_contents);
     74     EXPECT_GT(file_contents->length(), 6U);
     75     EXPECT_EQ('\n', file_contents->at(file_contents->length() - 1));
     76     (*file_contents)[5] = 0;
     77     EXPECT_STREQ("Linux", file_contents->c_str());
     78 }
     79 
     80 TEST(util, WriteFileBinary) {
     81     std::string contents("abcd");
     82     contents.push_back('\0');
     83     contents.push_back('\0');
     84     contents.append("dcba");
     85     ASSERT_EQ(10u, contents.size());
     86 
     87     TemporaryFile tf;
     88     ASSERT_TRUE(tf.fd != -1);
     89     EXPECT_TRUE(WriteFile(tf.path, contents)) << strerror(errno);
     90 
     91     auto read_back_contents = ReadFile(tf.path);
     92     ASSERT_TRUE(read_back_contents) << strerror(errno);
     93     EXPECT_EQ(contents, *read_back_contents);
     94     EXPECT_EQ(10u, read_back_contents->size());
     95 }
     96 
     97 TEST(util, WriteFileNotExist) {
     98     std::string s("hello");
     99     TemporaryDir test_dir;
    100     std::string path = android::base::StringPrintf("%s/does-not-exist", test_dir.path);
    101     EXPECT_TRUE(WriteFile(path, s));
    102     auto file_contents = ReadFile(path);
    103     ASSERT_TRUE(file_contents);
    104     EXPECT_EQ(s, *file_contents);
    105     struct stat sb;
    106     int fd = open(path.c_str(), O_RDONLY | O_NOFOLLOW | O_CLOEXEC);
    107     EXPECT_NE(-1, fd);
    108     EXPECT_EQ(0, fstat(fd, &sb));
    109     EXPECT_EQ((const unsigned int)(S_IRUSR | S_IWUSR), sb.st_mode & 0777);
    110     EXPECT_EQ(0, unlink(path.c_str()));
    111 }
    112 
    113 TEST(util, WriteFileExist) {
    114     TemporaryFile tf;
    115     ASSERT_TRUE(tf.fd != -1);
    116     EXPECT_TRUE(WriteFile(tf.path, "1hello1")) << strerror(errno);
    117     auto file_contents = ReadFile(tf.path);
    118     ASSERT_TRUE(file_contents);
    119     EXPECT_EQ("1hello1", *file_contents);
    120     EXPECT_TRUE(WriteFile(tf.path, "2ll2"));
    121     file_contents = ReadFile(tf.path);
    122     ASSERT_TRUE(file_contents);
    123     EXPECT_EQ("2ll2", *file_contents);
    124 }
    125 
    126 TEST(util, DecodeUid) {
    127     auto decoded_uid = DecodeUid("root");
    128     EXPECT_TRUE(decoded_uid);
    129     EXPECT_EQ(0U, *decoded_uid);
    130 
    131     decoded_uid = DecodeUid("toot");
    132     EXPECT_FALSE(decoded_uid);
    133     EXPECT_EQ("getpwnam failed: No such file or directory", decoded_uid.error_string());
    134 
    135     decoded_uid = DecodeUid("123");
    136     EXPECT_TRUE(decoded_uid);
    137     EXPECT_EQ(123U, *decoded_uid);
    138 }
    139 
    140 TEST(util, is_dir) {
    141     TemporaryDir test_dir;
    142     EXPECT_TRUE(is_dir(test_dir.path));
    143     TemporaryFile tf;
    144     EXPECT_FALSE(is_dir(tf.path));
    145 }
    146 
    147 TEST(util, mkdir_recursive) {
    148     TemporaryDir test_dir;
    149     std::string path = android::base::StringPrintf("%s/three/directories/deep", test_dir.path);
    150     EXPECT_TRUE(mkdir_recursive(path, 0755));
    151     std::string path1 = android::base::StringPrintf("%s/three", test_dir.path);
    152     EXPECT_TRUE(is_dir(path1.c_str()));
    153     std::string path2 = android::base::StringPrintf("%s/three/directories", test_dir.path);
    154     EXPECT_TRUE(is_dir(path1.c_str()));
    155     std::string path3 = android::base::StringPrintf("%s/three/directories/deep", test_dir.path);
    156     EXPECT_TRUE(is_dir(path1.c_str()));
    157 }
    158 
    159 TEST(util, mkdir_recursive_extra_slashes) {
    160     TemporaryDir test_dir;
    161     std::string path = android::base::StringPrintf("%s/three////directories/deep//", test_dir.path);
    162     EXPECT_TRUE(mkdir_recursive(path, 0755));
    163     std::string path1 = android::base::StringPrintf("%s/three", test_dir.path);
    164     EXPECT_TRUE(is_dir(path1.c_str()));
    165     std::string path2 = android::base::StringPrintf("%s/three/directories", test_dir.path);
    166     EXPECT_TRUE(is_dir(path1.c_str()));
    167     std::string path3 = android::base::StringPrintf("%s/three/directories/deep", test_dir.path);
    168     EXPECT_TRUE(is_dir(path1.c_str()));
    169 }
    170 
    171 }  // namespace init
    172 }  // namespace android
    173