| // Licensed to the Apache Software Foundation (ASF) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The ASF licenses this file |
| // to you under the Apache License, Version 2.0 (the |
| // "License"); you may not use this file except in compliance |
| // with the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, |
| // software distributed under the License is distributed on an |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| |
| #include <string> |
| |
| #include "common/thread-debug-info.h" |
| #include "testutil/gtest-util.h" |
| #include "util/container-util.h" |
| #include "util/thread.h" |
| |
| #include "common/names.h" |
| |
| namespace impala { |
| |
| TEST(ThreadDebugInfo, Ids) { |
| // This test checks if SetInstanceId() stores the |
| // string representation of a TUniqueId correctly. |
| ThreadDebugInfo thread_debug_info; |
| TUniqueId instance_id; |
| instance_id.hi = 123; |
| instance_id.lo = 456; |
| thread_debug_info.SetInstanceId(instance_id); |
| string instance_id_str = PrintId(instance_id); |
| |
| EXPECT_EQ(instance_id, thread_debug_info.GetInstanceId()); |
| EXPECT_EQ(instance_id_str, PrintId(thread_debug_info.GetInstanceId())); |
| |
| TUniqueId query_id; |
| query_id.hi = 1234; |
| query_id.lo = 4567; |
| thread_debug_info.SetQueryId(query_id); |
| string query_id_str = PrintId(query_id); |
| |
| EXPECT_EQ(query_id, thread_debug_info.GetQueryId()); |
| EXPECT_EQ(query_id_str, PrintId(thread_debug_info.GetQueryId())); |
| } |
| |
| TEST(ThreadDebugInfo, ThreadName) { |
| // Checks if we can store the thread name. |
| // If thread name is too long, the prefix of the thread name is stored. |
| ThreadDebugInfo thread_debug_info; |
| string thread_name = "thread-1"; |
| thread_debug_info.SetThreadName(thread_name); |
| |
| EXPECT_EQ(thread_name, thread_debug_info.GetThreadName()); |
| |
| string a_255(255, 'a'); |
| string b_255(255, 'b'); |
| string a_b = a_255 + b_255; |
| thread_debug_info.SetThreadName(a_b); |
| string stored_name = thread_debug_info.GetThreadName(); |
| |
| // Let's check if we stored the corrects parts of thread name |
| string expected = a_255.substr(0, 244) + "..." + b_255.substr(0, 8); |
| EXPECT_EQ(expected, stored_name); |
| } |
| |
| TEST(ThreadDebugInfo, Global) { |
| // Checks if the constructor of the local ThreadDebugInfo object set the |
| // global pointer to itself. |
| ThreadDebugInfo thread_debug_info; |
| ThreadDebugInfo* global_thread_debug_info = GetThreadDebugInfo(); |
| |
| EXPECT_EQ(&thread_debug_info, global_thread_debug_info); |
| } |
| |
| TEST(ThreadDebugInfo, ThreadCreateRelationships) { |
| // Checks if child thread extracts debug info from parent automatically. |
| // Child's thread name is given in Thread::Create |
| // Child's instance_id_ should be the same as parent's instance_id_ |
| // Child should store a copy of its parent's thread name. |
| // Child should store its parent's system thread id. |
| string parent_name = "Parent"; |
| string child_name = "Child"; |
| |
| ThreadDebugInfo parent_tdi; |
| parent_tdi.SetThreadName(parent_name); |
| TUniqueId instance_id; |
| instance_id.hi = 123; |
| instance_id.lo = 456; |
| parent_tdi.SetInstanceId(instance_id); |
| |
| TUniqueId query_id; |
| query_id.hi = 123; |
| query_id.lo = 456; |
| parent_tdi.SetQueryId(query_id); |
| |
| std::unique_ptr<Thread> child_thread; |
| auto f = [instance_id, query_id, child_name, parent_name, &parent_tdi]() { |
| // In child's thread the global ThreadDebugInfo object points to the child's own |
| // ThreadDebugInfo object which was automatically created in Thread::SuperviseThread |
| ThreadDebugInfo* child_tdi = GetThreadDebugInfo(); |
| EXPECT_EQ(child_name, child_tdi->GetThreadName()); |
| EXPECT_EQ(instance_id, child_tdi->GetInstanceId()); |
| EXPECT_EQ(query_id, child_tdi->GetQueryId()); |
| EXPECT_EQ(parent_name, child_tdi->GetParentThreadName()); |
| EXPECT_EQ(parent_tdi.GetSystemThreadId(), child_tdi->GetParentSystemThreadId()); |
| }; |
| ASSERT_OK(Thread::Create("Test", child_name, f, &child_thread)); |
| child_thread->Join(); |
| } |
| |
| TEST(ThreadDebugInfo, Scoping) { |
| TUniqueId id; |
| id.hi = 123; |
| id.lo = 456; |
| TUniqueId id2; |
| id.hi = 234; |
| id.lo = 345; |
| |
| ThreadDebugInfo tdi; |
| ASSERT_EQ(ThreadDebugInfo::ZERO_THREAD_ID, tdi.GetQueryId()); |
| ASSERT_EQ(ThreadDebugInfo::ZERO_THREAD_ID, tdi.GetInstanceId()); |
| { |
| ScopedThreadContext s(&tdi, id); |
| ASSERT_EQ(id, tdi.GetQueryId()); |
| ASSERT_EQ(ThreadDebugInfo::ZERO_THREAD_ID, tdi.GetInstanceId()); |
| } |
| ASSERT_EQ(ThreadDebugInfo::ZERO_THREAD_ID, tdi.GetQueryId()); |
| ASSERT_EQ(ThreadDebugInfo::ZERO_THREAD_ID, tdi.GetInstanceId()); |
| { |
| ScopedThreadContext s(&tdi, id, id2); |
| ASSERT_EQ(id, tdi.GetQueryId()); |
| ASSERT_EQ(id2, tdi.GetInstanceId()); |
| } |
| ASSERT_EQ(ThreadDebugInfo::ZERO_THREAD_ID, tdi.GetQueryId()); |
| ASSERT_EQ(ThreadDebugInfo::ZERO_THREAD_ID, tdi.GetInstanceId()); |
| } |
| |
| } |