Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright (C) 2012 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 <gtest/gtest.h>
     18 #include "TemporaryFile.h"
     19 
     20 #include <errno.h>
     21 #include <libgen.h>
     22 #include <limits.h>
     23 #include <pthread.h>
     24 #include <stdint.h>
     25 #include <stdlib.h>
     26 #include <fcntl.h>
     27 #include <sys/types.h>
     28 #include <sys/wait.h>
     29 
     30 TEST(stdlib, drand48) {
     31   srand48(0x01020304);
     32   EXPECT_DOUBLE_EQ(0.65619299195623526, drand48());
     33   EXPECT_DOUBLE_EQ(0.18522597229772941, drand48());
     34   EXPECT_DOUBLE_EQ(0.42015087072844537, drand48());
     35   EXPECT_DOUBLE_EQ(0.061637783047395089, drand48());
     36 }
     37 
     38 TEST(stdlib, lrand48) {
     39   srand48(0x01020304);
     40   EXPECT_EQ(1409163720, lrand48());
     41   EXPECT_EQ(397769746, lrand48());
     42   EXPECT_EQ(902267124, lrand48());
     43   EXPECT_EQ(132366131, lrand48());
     44 }
     45 
     46 TEST(stdlib, random) {
     47   srandom(0x01020304);
     48   EXPECT_EQ(55436735, random());
     49   EXPECT_EQ(1399865117, random());
     50   EXPECT_EQ(2032643283, random());
     51   EXPECT_EQ(571329216, random());
     52 }
     53 
     54 TEST(stdlib, rand) {
     55   srand(0x01020304);
     56   EXPECT_EQ(55436735, rand());
     57   EXPECT_EQ(1399865117, rand());
     58   EXPECT_EQ(2032643283, rand());
     59   EXPECT_EQ(571329216, rand());
     60 }
     61 
     62 TEST(stdlib, mrand48) {
     63   srand48(0x01020304);
     64   EXPECT_EQ(-1476639856, mrand48());
     65   EXPECT_EQ(795539493, mrand48());
     66   EXPECT_EQ(1804534249, mrand48());
     67   EXPECT_EQ(264732262, mrand48());
     68 }
     69 
     70 TEST(stdlib, posix_memalign) {
     71   void* p;
     72 
     73   ASSERT_EQ(0, posix_memalign(&p, 512, 128));
     74   ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(p) % 512);
     75   free(p);
     76 
     77   // Can't align to a non-power of 2.
     78   ASSERT_EQ(EINVAL, posix_memalign(&p, 81, 128));
     79 }
     80 
     81 TEST(stdlib, realpath__NULL_filename) {
     82   errno = 0;
     83   char* p = realpath(NULL, NULL);
     84   ASSERT_TRUE(p == NULL);
     85   ASSERT_EQ(EINVAL, errno);
     86 }
     87 
     88 TEST(stdlib, realpath__empty_filename) {
     89   errno = 0;
     90   char* p = realpath("", NULL);
     91   ASSERT_TRUE(p == NULL);
     92   ASSERT_EQ(ENOENT, errno);
     93 }
     94 
     95 TEST(stdlib, realpath__ENOENT) {
     96   errno = 0;
     97   char* p = realpath("/this/directory/path/almost/certainly/does/not/exist", NULL);
     98   ASSERT_TRUE(p == NULL);
     99   ASSERT_EQ(ENOENT, errno);
    100 }
    101 
    102 TEST(stdlib, realpath) {
    103   // Get the name of this executable.
    104   char executable_path[PATH_MAX];
    105   int rc = readlink("/proc/self/exe", executable_path, sizeof(executable_path));
    106   ASSERT_NE(rc, -1);
    107   executable_path[rc] = '\0';
    108 
    109   char buf[PATH_MAX + 1];
    110   char* p = realpath("/proc/self/exe", buf);
    111   ASSERT_STREQ(executable_path, p);
    112 
    113   p = realpath("/proc/self/exe", NULL);
    114   ASSERT_STREQ(executable_path, p);
    115   free(p);
    116 }
    117 
    118 TEST(stdlib, qsort) {
    119   struct s {
    120     char name[16];
    121     static int comparator(const void* lhs, const void* rhs) {
    122       return strcmp(reinterpret_cast<const s*>(lhs)->name, reinterpret_cast<const s*>(rhs)->name);
    123     }
    124   };
    125   s entries[3];
    126   strcpy(entries[0].name, "charlie");
    127   strcpy(entries[1].name, "bravo");
    128   strcpy(entries[2].name, "alpha");
    129 
    130   qsort(entries, 3, sizeof(s), s::comparator);
    131   ASSERT_STREQ("alpha", entries[0].name);
    132   ASSERT_STREQ("bravo", entries[1].name);
    133   ASSERT_STREQ("charlie", entries[2].name);
    134 
    135   qsort(entries, 3, sizeof(s), s::comparator);
    136   ASSERT_STREQ("alpha", entries[0].name);
    137   ASSERT_STREQ("bravo", entries[1].name);
    138   ASSERT_STREQ("charlie", entries[2].name);
    139 }
    140 
    141 static void* TestBug57421_child(void* arg) {
    142   pthread_t main_thread = reinterpret_cast<pthread_t>(arg);
    143   pthread_join(main_thread, NULL);
    144   char* value = getenv("ENVIRONMENT_VARIABLE");
    145   if (value == NULL) {
    146     setenv("ENVIRONMENT_VARIABLE", "value", 1);
    147   }
    148   return NULL;
    149 }
    150 
    151 static void TestBug57421_main() {
    152   pthread_t t;
    153   ASSERT_EQ(0, pthread_create(&t, NULL, TestBug57421_child, reinterpret_cast<void*>(pthread_self())));
    154   pthread_exit(NULL);
    155 }
    156 
    157 // Even though this isn't really a death test, we have to say "DeathTest" here so gtest knows to
    158 // run this test (which exits normally) in its own process.
    159 TEST(stdlib_DeathTest, getenv_after_main_thread_exits) {
    160   // https://code.google.com/p/android/issues/detail?id=57421
    161   ::testing::FLAGS_gtest_death_test_style = "threadsafe";
    162   ASSERT_EXIT(TestBug57421_main(), ::testing::ExitedWithCode(0), "");
    163 }
    164 
    165 TEST(stdlib, mkstemp) {
    166   TemporaryFile tf;
    167   struct stat sb;
    168   ASSERT_EQ(0, fstat(tf.fd, &sb));
    169 }
    170 
    171 TEST(stdlib, mkstemp64) {
    172   GenericTemporaryFile<mkstemp64> tf;
    173   struct stat64 sb;
    174   ASSERT_EQ(0, fstat64(tf.fd, &sb));
    175   ASSERT_EQ(O_LARGEFILE, fcntl(tf.fd, F_GETFL) & O_LARGEFILE);
    176 }
    177 
    178 TEST(stdlib, system) {
    179   int status;
    180 
    181   status = system("exit 0");
    182   ASSERT_TRUE(WIFEXITED(status));
    183   ASSERT_EQ(0, WEXITSTATUS(status));
    184 
    185   status = system("exit 1");
    186   ASSERT_TRUE(WIFEXITED(status));
    187   ASSERT_EQ(1, WEXITSTATUS(status));
    188 }
    189 
    190 TEST(stdlib, atof) {
    191   ASSERT_DOUBLE_EQ(1.23, atof("1.23"));
    192 }
    193 
    194 TEST(stdlib, strtod) {
    195   ASSERT_DOUBLE_EQ(1.23, strtod("1.23", NULL));
    196 }
    197 
    198 TEST(stdlib, strtof) {
    199   ASSERT_FLOAT_EQ(1.23, strtof("1.23", NULL));
    200 }
    201 
    202 TEST(stdlib, strtold) {
    203   ASSERT_DOUBLE_EQ(1.23, strtold("1.23", NULL));
    204 }
    205 
    206 TEST(stdlib, quick_exit) {
    207   pid_t pid = fork();
    208   ASSERT_NE(-1, pid) << strerror(errno);
    209 
    210   if (pid == 0) {
    211     quick_exit(99);
    212   }
    213 
    214   int status;
    215   ASSERT_EQ(pid, waitpid(pid, &status, 0));
    216   ASSERT_TRUE(WIFEXITED(status));
    217   ASSERT_EQ(99, WEXITSTATUS(status));
    218 }
    219 
    220 static int quick_exit_status = 0;
    221 
    222 static void quick_exit_1(void) {
    223   ASSERT_EQ(quick_exit_status, 0);
    224   quick_exit_status = 1;
    225 }
    226 
    227 static void quick_exit_2(void) {
    228   ASSERT_EQ(quick_exit_status, 1);
    229 }
    230 
    231 static void not_run(void) {
    232   FAIL();
    233 }
    234 
    235 TEST(stdlib, at_quick_exit) {
    236   pid_t pid = fork();
    237   ASSERT_NE(-1, pid) << strerror(errno);
    238 
    239   if (pid == 0) {
    240     ASSERT_EQ(at_quick_exit(quick_exit_2), 0);
    241     ASSERT_EQ(at_quick_exit(quick_exit_1), 0);
    242     atexit(not_run);
    243     quick_exit(99);
    244   }
    245 
    246   int status;
    247   ASSERT_EQ(pid, waitpid(pid, &status, 0));
    248   ASSERT_TRUE(WIFEXITED(status));
    249   ASSERT_EQ(99, WEXITSTATUS(status));
    250 }
    251 
    252 TEST(unistd, _Exit) {
    253   int pid = fork();
    254   ASSERT_NE(-1, pid) << strerror(errno);
    255 
    256   if (pid == 0) {
    257     _Exit(99);
    258   }
    259 
    260   int status;
    261   ASSERT_EQ(pid, waitpid(pid, &status, 0));
    262   ASSERT_TRUE(WIFEXITED(status));
    263   ASSERT_EQ(99, WEXITSTATUS(status));
    264 }
    265 
    266 TEST(stdlib, pty_smoke) {
    267   // getpt returns a pty with O_RDWR|O_NOCTTY.
    268   int fd = getpt();
    269   ASSERT_NE(-1, fd);
    270 
    271   // grantpt is a no-op.
    272   ASSERT_EQ(0, grantpt(fd));
    273 
    274   // ptsname_r should start "/dev/pts/".
    275   char name_r[128];
    276   ASSERT_EQ(0, ptsname_r(fd, name_r, sizeof(name_r)));
    277   name_r[9] = 0;
    278   ASSERT_STREQ("/dev/pts/", name_r);
    279 
    280   close(fd);
    281 }
    282 
    283 TEST(stdlib, posix_openpt) {
    284   int fd = posix_openpt(O_RDWR|O_NOCTTY|O_CLOEXEC);
    285   ASSERT_NE(-1, fd);
    286   close(fd);
    287 }
    288 
    289 TEST(stdlib, ptsname_r_ENOTTY) {
    290   errno = 0;
    291   char buf[128];
    292   ASSERT_EQ(ENOTTY, ptsname_r(STDOUT_FILENO, buf, sizeof(buf)));
    293   ASSERT_EQ(ENOTTY, errno);
    294 }
    295 
    296 TEST(stdlib, ptsname_r_EINVAL) {
    297   int fd = getpt();
    298   ASSERT_NE(-1, fd);
    299   errno = 0;
    300   char* buf = NULL;
    301   ASSERT_EQ(EINVAL, ptsname_r(fd, buf, 128));
    302   ASSERT_EQ(EINVAL, errno);
    303   close(fd);
    304 }
    305 
    306 TEST(stdlib, ptsname_r_ERANGE) {
    307   int fd = getpt();
    308   ASSERT_NE(-1, fd);
    309   errno = 0;
    310   char buf[1];
    311   ASSERT_EQ(ERANGE, ptsname_r(fd, buf, sizeof(buf)));
    312   ASSERT_EQ(ERANGE, errno);
    313   close(fd);
    314 }
    315 
    316 TEST(stdlib, ttyname_r) {
    317   int fd = getpt();
    318   ASSERT_NE(-1, fd);
    319 
    320   // ttyname_r returns "/dev/ptmx" for a pty.
    321   char name_r[128];
    322   ASSERT_EQ(0, ttyname_r(fd, name_r, sizeof(name_r)));
    323   ASSERT_STREQ("/dev/ptmx", name_r);
    324 
    325   close(fd);
    326 }
    327 
    328 TEST(stdlib, ttyname_r_ENOTTY) {
    329   int fd = open("/dev/null", O_WRONLY);
    330   errno = 0;
    331   char buf[128];
    332   ASSERT_EQ(ENOTTY, ttyname_r(fd, buf, sizeof(buf)));
    333   ASSERT_EQ(ENOTTY, errno);
    334   close(fd);
    335 }
    336 
    337 TEST(stdlib, ttyname_r_EINVAL) {
    338   int fd = getpt();
    339   ASSERT_NE(-1, fd);
    340   errno = 0;
    341   char* buf = NULL;
    342   ASSERT_EQ(EINVAL, ttyname_r(fd, buf, 128));
    343   ASSERT_EQ(EINVAL, errno);
    344   close(fd);
    345 }
    346 
    347 TEST(stdlib, ttyname_r_ERANGE) {
    348   int fd = getpt();
    349   ASSERT_NE(-1, fd);
    350   errno = 0;
    351   char buf[1];
    352   ASSERT_EQ(ERANGE, ttyname_r(fd, buf, sizeof(buf)));
    353   ASSERT_EQ(ERANGE, errno);
    354   close(fd);
    355 }
    356 
    357 TEST(stdlib, unlockpt_ENOTTY) {
    358   int fd = open("/dev/null", O_WRONLY);
    359   errno = 0;
    360   ASSERT_EQ(-1, unlockpt(fd));
    361   ASSERT_EQ(ENOTTY, errno);
    362   close(fd);
    363 }
    364