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