| // Copyright 2019 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 "src/developer/debug/zxdb/expr/pretty_rust_tuple.h" | |
| #include <gtest/gtest.h> | |
| #include "src/developer/debug/shared/message_loop.h" | |
| #include "src/developer/debug/zxdb/common/test_with_loop.h" | |
| #include "src/developer/debug/zxdb/expr/expr_value.h" | |
| #include "src/developer/debug/zxdb/expr/format_node.h" | |
| #include "src/developer/debug/zxdb/expr/format_options.h" | |
| #include "src/developer/debug/zxdb/expr/format_test_support.h" | |
| #include "src/developer/debug/zxdb/expr/mock_eval_context.h" | |
| #include "src/developer/debug/zxdb/symbols/symbol_utils.h" | |
| #include "src/developer/debug/zxdb/symbols/type_test_support.h" | |
| namespace zxdb { | |
| namespace { | |
| class PrettyRustTupleTest : public TestWithLoop { | |
| public: | |
| PrettyRustTupleTest() { context_ = fxl::MakeRefCounted<MockEvalContext>(); } | |
| // Evaluates the given member, promotes the result to 64-bit and expects that it's equal to the | |
| // given value. | |
| void ExpectMemberValue(const ExprValue& input, const std::string& member_name, int64_t expected) { | |
| PrettyRustTuple pretty; | |
| auto getter = pretty.GetMember(member_name); | |
| ASSERT_TRUE(getter); | |
| bool should_quit = false; | |
| bool called = false; | |
| getter(context(), input, [&called, &should_quit, expected](ErrOrValue v) { | |
| called = true; | |
| ASSERT_TRUE(v.ok()) << v.err().msg(); | |
| int64_t actual = 0; | |
| Err err = v.value().PromoteTo64(&actual); | |
| ASSERT_TRUE(err.ok()); | |
| EXPECT_EQ(expected, actual); | |
| if (should_quit) | |
| debug_ipc::MessageLoop::Current()->QuitNow(); | |
| }); | |
| if (!called) { | |
| should_quit = true; | |
| debug_ipc::MessageLoop::Current()->Run(); | |
| } | |
| EXPECT_TRUE(called); | |
| } | |
| fxl::RefPtr<MockEvalContext> context() { return context_; } | |
| private: | |
| fxl::RefPtr<MockEvalContext> context_; | |
| }; | |
| } // namespace | |
| TEST_F(PrettyRustTupleTest, Tuple) { | |
| const char kMyStructName[] = "(i32)"; | |
| // Encodes 13 as a 32-bit integer. | |
| uint8_t kMem[4] = { | |
| 0x0d, | |
| 0x00, | |
| 0x00, | |
| 0x00, | |
| }; | |
| auto int32_type = MakeInt32Type(); | |
| auto type = MakeRustTuple(kMyStructName, {int32_type}); | |
| ExprValue value(type, std::vector<uint8_t>(std::begin(kMem), std::end(kMem))); | |
| FormatNode node("value", value); | |
| PrettyRustTuple pretty; | |
| // Expect synchronous completion for the inline value case. | |
| bool completed = false; | |
| pretty.Format(&node, FormatOptions(), context(), | |
| fit::defer_callback([&completed]() { completed = true; })); | |
| EXPECT_TRUE(completed); | |
| SyncFillAndDescribeFormatTree(context(), &node, FormatOptions()); | |
| EXPECT_EQ("value = (i32), \n 0 = int32_t, 13\n", GetDebugTreeForFormatNode(&node)); | |
| ExpectMemberValue(value, "0", 13); | |
| } | |
| TEST_F(PrettyRustTupleTest, TupleStruct) { | |
| const char kMyStructName[] = "MyStruct"; | |
| // Encodes 13 as a 32-bit integer. | |
| uint8_t kMem[4] = { | |
| 0x0d, | |
| 0x00, | |
| 0x00, | |
| 0x00, | |
| }; | |
| auto int32_type = MakeInt32Type(); | |
| auto type = MakeRustTuple(kMyStructName, {int32_type}); | |
| ExprValue value(type, std::vector<uint8_t>(std::begin(kMem), std::end(kMem))); | |
| FormatNode node("value", value); | |
| PrettyRustTuple pretty; | |
| // Expect synchronous completion for the inline value case. | |
| bool completed = false; | |
| pretty.Format(&node, FormatOptions(), context(), | |
| fit::defer_callback([&completed]() { completed = true; })); | |
| EXPECT_TRUE(completed); | |
| SyncFillAndDescribeFormatTree(context(), &node, FormatOptions()); | |
| EXPECT_EQ("value = MyStruct, \n 0 = int32_t, 13\n", GetDebugTreeForFormatNode(&node)); | |
| ExpectMemberValue(value, "0", 13); | |
| } | |
| TEST_F(PrettyRustTupleTest, Status) { | |
| const char kRustStatusName[] = "fuchsia_zircon_status::Status"; | |
| // Encodes -6 as a 32-bit integer. | |
| uint8_t kMem[4] = { | |
| 0xfa, | |
| 0xff, | |
| 0xff, | |
| 0xff, | |
| }; | |
| auto int32_type = MakeInt32Type(); | |
| auto type = MakeRustTuple(kRustStatusName, {int32_type}); | |
| ExprValue value(type, std::vector<uint8_t>(std::begin(kMem), std::end(kMem))); | |
| FormatNode node("value", value); | |
| PrettyRustZirconStatus pretty; | |
| // Expect synchronous completion for the inline value case. | |
| bool completed = false; | |
| pretty.Format(&node, FormatOptions(), context(), | |
| fit::defer_callback([&completed]() { completed = true; })); | |
| EXPECT_TRUE(completed); | |
| ASSERT_EQ(1u, node.children().size()); | |
| EXPECT_EQ("-6 (ZX_ERR_INTERNAL_INTR_RETRY)", node.children()[0]->description()); | |
| } | |
| } // namespace zxdb |