stdlib_test.cpp revision fe317a3775e16d466bb884a8e054fd77f7087bb3
1774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes/*
2774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes * Copyright (C) 2012 The Android Open Source Project
3774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes *
4774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes * Licensed under the Apache License, Version 2.0 (the "License");
5774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes * you may not use this file except in compliance with the License.
6774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes * You may obtain a copy of the License at
7774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes *
8774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes *      http://www.apache.org/licenses/LICENSE-2.0
9774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes *
10774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes * Unless required by applicable law or agreed to in writing, software
11774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes * distributed under the License is distributed on an "AS IS" BASIS,
12774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes * See the License for the specific language governing permissions and
14774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes * limitations under the License.
15774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes */
16774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes
17774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes#include <gtest/gtest.h>
18fe317a3775e16d466bb884a8e054fd77f7087bb3Calin Juravle#include "TemporaryFile.h"
19774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes
20b16b72248bd109b6073df6a45aeffaa69e38cfc6Elliott Hughes#include <errno.h>
21f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes#include <libgen.h>
22f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes#include <limits.h>
23877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes#include <pthread.h>
24b16b72248bd109b6073df6a45aeffaa69e38cfc6Elliott Hughes#include <stdint.h>
25774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes#include <stdlib.h>
26fe317a3775e16d466bb884a8e054fd77f7087bb3Calin Juravle#include <fcntl.h>
27774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes
28774c7f54ff375d71106283d42779b0cc5f238f87Elliott HughesTEST(stdlib, drand48) {
29774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes  srand48(0x01020304);
30774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes  EXPECT_DOUBLE_EQ(0.65619299195623526, drand48());
31774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes  EXPECT_DOUBLE_EQ(0.18522597229772941, drand48());
32774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes  EXPECT_DOUBLE_EQ(0.42015087072844537, drand48());
33774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes  EXPECT_DOUBLE_EQ(0.061637783047395089, drand48());
34774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes}
35774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes
36774c7f54ff375d71106283d42779b0cc5f238f87Elliott HughesTEST(stdlib, lrand48_random_rand) {
37774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes  srand48(0x01020304);
38774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes  EXPECT_EQ(1409163720, lrand48());
39774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes  EXPECT_EQ(397769746, lrand48());
40774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes  EXPECT_EQ(902267124, lrand48());
41774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes  EXPECT_EQ(132366131, lrand48());
42774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes
43774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes#if __BIONIC__
44774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes  // On bionic, random(3) is equivalent to lrand48...
45774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes  srandom(0x01020304);
46774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes  EXPECT_EQ(1409163720, random());
47774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes  EXPECT_EQ(397769746, random());
48774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes  EXPECT_EQ(902267124, random());
49774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes  EXPECT_EQ(132366131, random());
50774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes
51774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes  // ...and rand(3) is the bottom 32 bits.
52774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes  srand(0x01020304);
53774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes  EXPECT_EQ(static_cast<int>(1409163720), rand());
54774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes  EXPECT_EQ(static_cast<int>(397769746), rand());
55774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes  EXPECT_EQ(static_cast<int>(902267124), rand());
56774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes  EXPECT_EQ(static_cast<int>(132366131), rand());
57774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes#endif
58774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes}
59774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes
60774c7f54ff375d71106283d42779b0cc5f238f87Elliott HughesTEST(stdlib, mrand48) {
61774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes  srand48(0x01020304);
62774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes  EXPECT_EQ(-1476639856, mrand48());
63774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes  EXPECT_EQ(795539493, mrand48());
64774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes  EXPECT_EQ(1804534249, mrand48());
65774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes  EXPECT_EQ(264732262, mrand48());
66774c7f54ff375d71106283d42779b0cc5f238f87Elliott Hughes}
67b16b72248bd109b6073df6a45aeffaa69e38cfc6Elliott Hughes
68b16b72248bd109b6073df6a45aeffaa69e38cfc6Elliott HughesTEST(stdlib, posix_memalign) {
69b16b72248bd109b6073df6a45aeffaa69e38cfc6Elliott Hughes  void* p;
70b16b72248bd109b6073df6a45aeffaa69e38cfc6Elliott Hughes
71b16b72248bd109b6073df6a45aeffaa69e38cfc6Elliott Hughes  ASSERT_EQ(0, posix_memalign(&p, 512, 128));
72b16b72248bd109b6073df6a45aeffaa69e38cfc6Elliott Hughes  ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(p) % 512);
73b16b72248bd109b6073df6a45aeffaa69e38cfc6Elliott Hughes  free(p);
74b16b72248bd109b6073df6a45aeffaa69e38cfc6Elliott Hughes
75b16b72248bd109b6073df6a45aeffaa69e38cfc6Elliott Hughes  // Can't align to a non-power of 2.
76b16b72248bd109b6073df6a45aeffaa69e38cfc6Elliott Hughes  ASSERT_EQ(EINVAL, posix_memalign(&p, 81, 128));
77b16b72248bd109b6073df6a45aeffaa69e38cfc6Elliott Hughes}
78f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes
79f0777843c03deb26b1f78c8edd17c557041696e9Elliott HughesTEST(stdlib, realpath__NULL_filename) {
80f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes  errno = 0;
81f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes  char* p = realpath(NULL, NULL);
82f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes  ASSERT_TRUE(p == NULL);
83f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes  ASSERT_EQ(EINVAL, errno);
84f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes}
85f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes
86f0777843c03deb26b1f78c8edd17c557041696e9Elliott HughesTEST(stdlib, realpath__empty_filename) {
87f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes  errno = 0;
88f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes  char* p = realpath("", NULL);
89f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes  ASSERT_TRUE(p == NULL);
90f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes  ASSERT_EQ(ENOENT, errno);
91f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes}
92f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes
93f0777843c03deb26b1f78c8edd17c557041696e9Elliott HughesTEST(stdlib, realpath__ENOENT) {
94f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes  errno = 0;
95f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes  char* p = realpath("/this/directory/path/almost/certainly/does/not/exist", NULL);
96f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes  ASSERT_TRUE(p == NULL);
97f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes  ASSERT_EQ(ENOENT, errno);
98f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes}
99f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes
100f0777843c03deb26b1f78c8edd17c557041696e9Elliott HughesTEST(stdlib, realpath) {
101f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes  // Get the name of this executable.
102f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes  char executable_path[PATH_MAX];
103f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes  int rc = readlink("/proc/self/exe", executable_path, sizeof(executable_path));
104f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes  ASSERT_NE(rc, -1);
105f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes  executable_path[rc] = '\0';
106f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes
107f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes  char buf[PATH_MAX + 1];
108f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes  char* p = realpath("/proc/self/exe", buf);
109f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes  ASSERT_STREQ(executable_path, p);
110f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes
111f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes  p = realpath("/proc/self/exe", NULL);
112f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes  ASSERT_STREQ(executable_path, p);
113f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes  free(p);
114f0777843c03deb26b1f78c8edd17c557041696e9Elliott Hughes}
1150b25f633a23e575c8a1f9547d1af5dc5b0157a1cElliott Hughes
1160b25f633a23e575c8a1f9547d1af5dc5b0157a1cElliott HughesTEST(stdlib, qsort) {
1170b25f633a23e575c8a1f9547d1af5dc5b0157a1cElliott Hughes  struct s {
1180b25f633a23e575c8a1f9547d1af5dc5b0157a1cElliott Hughes    char name[16];
1190b25f633a23e575c8a1f9547d1af5dc5b0157a1cElliott Hughes    static int comparator(const void* lhs, const void* rhs) {
1200b25f633a23e575c8a1f9547d1af5dc5b0157a1cElliott Hughes      return strcmp(reinterpret_cast<const s*>(lhs)->name, reinterpret_cast<const s*>(rhs)->name);
1210b25f633a23e575c8a1f9547d1af5dc5b0157a1cElliott Hughes    }
1220b25f633a23e575c8a1f9547d1af5dc5b0157a1cElliott Hughes  };
1230b25f633a23e575c8a1f9547d1af5dc5b0157a1cElliott Hughes  s entries[3];
1240b25f633a23e575c8a1f9547d1af5dc5b0157a1cElliott Hughes  strcpy(entries[0].name, "charlie");
1250b25f633a23e575c8a1f9547d1af5dc5b0157a1cElliott Hughes  strcpy(entries[1].name, "bravo");
1260b25f633a23e575c8a1f9547d1af5dc5b0157a1cElliott Hughes  strcpy(entries[2].name, "alpha");
1270b25f633a23e575c8a1f9547d1af5dc5b0157a1cElliott Hughes
1280b25f633a23e575c8a1f9547d1af5dc5b0157a1cElliott Hughes  qsort(entries, 3, sizeof(s), s::comparator);
1290b25f633a23e575c8a1f9547d1af5dc5b0157a1cElliott Hughes  ASSERT_STREQ("alpha", entries[0].name);
1300b25f633a23e575c8a1f9547d1af5dc5b0157a1cElliott Hughes  ASSERT_STREQ("bravo", entries[1].name);
1310b25f633a23e575c8a1f9547d1af5dc5b0157a1cElliott Hughes  ASSERT_STREQ("charlie", entries[2].name);
1320b25f633a23e575c8a1f9547d1af5dc5b0157a1cElliott Hughes
1330b25f633a23e575c8a1f9547d1af5dc5b0157a1cElliott Hughes  qsort(entries, 3, sizeof(s), s::comparator);
1340b25f633a23e575c8a1f9547d1af5dc5b0157a1cElliott Hughes  ASSERT_STREQ("alpha", entries[0].name);
1350b25f633a23e575c8a1f9547d1af5dc5b0157a1cElliott Hughes  ASSERT_STREQ("bravo", entries[1].name);
1360b25f633a23e575c8a1f9547d1af5dc5b0157a1cElliott Hughes  ASSERT_STREQ("charlie", entries[2].name);
1370b25f633a23e575c8a1f9547d1af5dc5b0157a1cElliott Hughes}
138877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes
139877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughesstatic void* TestBug57421_child(void* arg) {
140877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes  pthread_t main_thread = reinterpret_cast<pthread_t>(arg);
141877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes  pthread_join(main_thread, NULL);
142877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes  char* value = getenv("ENVIRONMENT_VARIABLE");
143877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes  if (value == NULL) {
144877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes    setenv("ENVIRONMENT_VARIABLE", "value", 1);
145877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes  }
146877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes  return NULL;
147877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes}
148877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes
149877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughesstatic void TestBug57421_main() {
150877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes  pthread_t t;
151877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes  ASSERT_EQ(0, pthread_create(&t, NULL, TestBug57421_child, reinterpret_cast<void*>(pthread_self())));
152877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes  pthread_exit(NULL);
153877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes}
154877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes
155877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes// Even though this isn't really a death test, we have to say "DeathTest" here so gtest knows to
156877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes// run this test (which exits normally) in its own process.
157877ec6d90418ff1d6597147d355a2229fdffae7eElliott HughesTEST(stdlib_DeathTest, getenv_after_main_thread_exits) {
158877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes  // https://code.google.com/p/android/issues/detail?id=57421
159877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
160877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes  ASSERT_EXIT(TestBug57421_main(), ::testing::ExitedWithCode(0), "");
161877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes}
162fe317a3775e16d466bb884a8e054fd77f7087bb3Calin Juravle
163fe317a3775e16d466bb884a8e054fd77f7087bb3Calin JuravleTEST(stdlib, mkstemp) {
164fe317a3775e16d466bb884a8e054fd77f7087bb3Calin Juravle  TemporaryFile tf;
165fe317a3775e16d466bb884a8e054fd77f7087bb3Calin Juravle  struct stat sb;
166fe317a3775e16d466bb884a8e054fd77f7087bb3Calin Juravle  ASSERT_EQ(0, fstat(tf.fd, &sb));
167fe317a3775e16d466bb884a8e054fd77f7087bb3Calin Juravle}
168fe317a3775e16d466bb884a8e054fd77f7087bb3Calin Juravle
169fe317a3775e16d466bb884a8e054fd77f7087bb3Calin JuravleTEST(stdlib, mkstemp64) {
170fe317a3775e16d466bb884a8e054fd77f7087bb3Calin Juravle  GenericTemporaryFile<mkstemp64> tf;
171fe317a3775e16d466bb884a8e054fd77f7087bb3Calin Juravle  struct stat64 sb;
172fe317a3775e16d466bb884a8e054fd77f7087bb3Calin Juravle  ASSERT_EQ(0, fstat64(tf.fd, &sb));
173fe317a3775e16d466bb884a8e054fd77f7087bb3Calin Juravle  ASSERT_EQ(O_LARGEFILE, fcntl(tf.fd, F_GETFL) & O_LARGEFILE);
174fe317a3775e16d466bb884a8e054fd77f7087bb3Calin Juravle}
175