blob: 6946f715d7415e23646873dbb53c57861f0d0c97 [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <inttypes.h>
#include <time.h>
#include <ostream>
#include "garnet/bin/zxdb/common/string_util.h"
#include "garnet/bin/zxdb/symbols/module_symbol_index.h"
#include "garnet/bin/zxdb/symbols/test_symbol_module.h"
#include "gtest/gtest.h"
namespace zxdb {
TEST(ModuleSymbolIndex, FindExact) {
TestSymbolModule module;
std::string err;
ASSERT_TRUE(module.Load(&err)) << err;
ModuleSymbolIndex index;
index.CreateIndex(module.object_file());
#if 0
// Enable to dump the found index for debugging purposes.
std::cout << "Index dump:\n";
index.root().Dump(std::cout, 1);
index.DumpFileIndex(std::cout);
#endif
// Standalone function search.
auto result = index.FindExact(TestSymbolModule::kMyFunctionName);
EXPECT_EQ(1u, result.size()) << "Symbol not found.";
// Standalone function inside a namespace.
result = index.FindExact(TestSymbolModule::kNamespaceFunctionName);
EXPECT_EQ(1u, result.size()) << "Symbol not found.";
// Namespace + class member function search.
result = index.FindExact(TestSymbolModule::kMyMemberOneName);
EXPECT_EQ(1u, result.size()) << "Symbol not found.";
// Same but in the 2nd compilation unit (tests unit-relative addressing).
result = index.FindExact(TestSymbolModule::kFunctionInTest2Name);
EXPECT_EQ(1u, result.size()) << "Symbol not found.";
// Namespace + class + struct with static member function search.
result = index.FindExact(TestSymbolModule::kMyMemberTwoName);
EXPECT_EQ(1u, result.size()) << "Symbol not found.";
// Global variable.
result = index.FindExact(TestSymbolModule::kGlobalName);
EXPECT_EQ(1u, result.size()) << "Symbol not found.";
// Class static variable.
result = index.FindExact(TestSymbolModule::kClassStaticName);
EXPECT_EQ(1u, result.size()) << "Symbol not found.";
}
TEST(ModuleSymbolIndex, FindFileMatches) {
TestSymbolModule module;
std::string err;
ASSERT_TRUE(module.Load(&err)) << err;
ModuleSymbolIndex index;
index.CreateIndex(module.object_file());
// Simple filename-only query that succeeds.
std::vector<std::string> result =
index.FindFileMatches("zxdb_symbol_test.cc");
ASSERT_EQ(1u, result.size());
EXPECT_TRUE(
StringEndsWith(result[0], "symbols/test_data/zxdb_symbol_test.cc"));
// Save the full path for later.
std::string full_path = result[0];
// Simple filename-only query that fails.
result = index.FindFileMatches("nonexistant.cc");
EXPECT_EQ(0u, result.size());
// Multiple path components.
result = index.FindFileMatches("symbols/test_data/zxdb_symbol_test.cc");
EXPECT_EQ(1u, result.size());
// Ends-with match but doesn't start on a slash boundary.
result = index.FindFileMatches("nt/test_data/zxdb_symbol_test.cc");
EXPECT_EQ(0u, result.size());
// Full path match.
result = index.FindFileMatches(full_path);
EXPECT_EQ(1u, result.size());
// More-than-full path match.
result = index.FindFileMatches("/a" + full_path);
EXPECT_EQ(0u, result.size());
}
// Enable and substitute a path on your system for kFilename to run the
// indexing benchmark.
#if 0
static int64_t GetTickMicroseconds() {
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
constexpr int64_t kMicrosecondsPerSecond = 1000000;
constexpr int64_t kNanosecondsPerMicrosecond = 1000;
int64_t result = ts.tv_sec * kMicrosecondsPerSecond;
result += (ts.tv_nsec / kNanosecondsPerMicrosecond);
return result;
}
TEST(ModuleSymbolIndex, BenchmarkIndexing) {
const char kFilename[] =
"/usr/local/google/home/brettw/prj/src/out/release/chrome";
int64_t begin_us = GetTickMicroseconds();
TestSymbolModule module;
std::string err;
ASSERT_TRUE(module.LoadSpecific(kFilename, &err)) << err;
int64_t load_complete_us = GetTickMicroseconds();
ModuleSymbolIndex index;
index.CreateIndex(module.object_file());
int64_t index_complete_us = GetTickMicroseconds();
printf("\nIndexing results for %s:\n Load: %" PRId64
" µs\n Index: %" PRId64 " µs\n\n",
kFilename, load_complete_us - begin_us,
index_complete_us - load_complete_us);
sleep(10);
}
#endif // End indexing benchmark.
} // namespace zxdb