1// Copyright 2016 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <unittest/unittest.h>
6#include <sched.h>
7#include <threads.h>
8
9#include "dso-ctor/dso-ctor.h"
10
11namespace {
12
13bool global_ctor_ran;
14
15static struct Global {
16    Global() { global_ctor_ran = true; }
17    ~Global() {
18        // This is just some random nonempty thing that the compiler
19        // can definitely never decide to optimize away.  We can't
20        // easily test that the destructor got run, but we can ensure
21        // that using a static destructor compiles and links correctly.
22        sched_yield();
23    }
24} global;
25
26bool check_ctor() {
27    BEGIN_TEST;
28    EXPECT_TRUE(global_ctor_ran, "global constuctor didn't run!");
29    END_TEST;
30}
31
32int my_static = 23;
33
34bool check_initializer() {
35    BEGIN_TEST;
36    EXPECT_EQ(my_static, 23, "static initializer didn't run!");
37    END_TEST;
38}
39
40bool tlocal_ctor_ran, tlocal_dtor_ran;
41thread_local ThreadLocal<&tlocal_ctor_ran, &tlocal_dtor_ran> tlocal;
42
43int do_thread_local_dtor_test(void*) {
44    BEGIN_HELPER;
45    EXPECT_TRUE(decltype(tlocal)::check_before_reference());
46    tlocal.flag = true;
47    EXPECT_TRUE(decltype(tlocal)::check_after_reference());
48    EXPECT_TRUE(check_dso_tlocal_in_thread());
49    END_HELPER;
50}
51
52bool check_thread_local_ctor_dtor() {
53    BEGIN_TEST;
54    thrd_t th;
55    ASSERT_EQ(thrd_create(&th, &do_thread_local_dtor_test, nullptr),
56              thrd_success);
57    int retval = -1;
58    EXPECT_EQ(thrd_join(th, &retval), thrd_success);
59    EXPECT_TRUE(static_cast<bool>(retval));
60    EXPECT_TRUE(decltype(tlocal)::check_after_join());
61    EXPECT_TRUE(check_dso_tlocal_after_join());
62    END_TEST;
63}
64
65}  // namespace
66
67BEGIN_TEST_CASE(ctors)
68RUN_TEST(check_ctor)
69RUN_TEST(check_initializer)
70RUN_TEST(check_dso_ctor)
71RUN_TEST(check_thread_local_ctor_dtor)
72END_TEST_CASE(ctors)
73
74int main(int argc, char** argv) {
75    return unittest_run_all_tests(argc, argv) ? 0 : -1;
76}
77