1 // Copyright (c) 2014 The Chromium 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 "base/trace_event/trace_event_argument.h" 6 7 #include <stddef.h> 8 9 #include <utility> 10 11 #include "base/memory/ptr_util.h" 12 #include "base/values.h" 13 #include "testing/gtest/include/gtest/gtest.h" 14 15 namespace base { 16 namespace trace_event { 17 18 TEST(TraceEventArgumentTest, FlatDictionary) { 19 std::unique_ptr<TracedValue> value(new TracedValue()); 20 value->SetInteger("int", 2014); 21 value->SetDouble("double", 0.0); 22 value->SetBoolean("bool", true); 23 value->SetString("string", "string"); 24 std::string json = "PREFIX"; 25 value->AppendAsTraceFormat(&json); 26 EXPECT_EQ( 27 "PREFIX{\"bool\":true,\"double\":0.0,\"int\":2014,\"string\":\"string\"}", 28 json); 29 } 30 31 TEST(TraceEventArgumentTest, NoDotPathExpansion) { 32 std::unique_ptr<TracedValue> value(new TracedValue()); 33 value->SetInteger("in.t", 2014); 34 value->SetDouble("doub.le", 0.0); 35 value->SetBoolean("bo.ol", true); 36 value->SetString("str.ing", "str.ing"); 37 std::string json; 38 value->AppendAsTraceFormat(&json); 39 EXPECT_EQ( 40 "{\"bo.ol\":true,\"doub.le\":0.0,\"in.t\":2014,\"str.ing\":\"str.ing\"}", 41 json); 42 } 43 44 TEST(TraceEventArgumentTest, Hierarchy) { 45 std::unique_ptr<TracedValue> value(new TracedValue()); 46 value->SetInteger("i0", 2014); 47 value->BeginDictionary("dict1"); 48 value->SetInteger("i1", 2014); 49 value->BeginDictionary("dict2"); 50 value->SetBoolean("b2", false); 51 value->EndDictionary(); 52 value->SetString("s1", "foo"); 53 value->EndDictionary(); 54 value->SetDouble("d0", 0.0); 55 value->SetBoolean("b0", true); 56 value->BeginArray("a1"); 57 value->AppendInteger(1); 58 value->AppendBoolean(true); 59 value->BeginDictionary(); 60 value->SetInteger("i2", 3); 61 value->EndDictionary(); 62 value->EndArray(); 63 value->SetString("s0", "foo"); 64 std::string json; 65 value->AppendAsTraceFormat(&json); 66 EXPECT_EQ( 67 "{\"a1\":[1,true,{\"i2\":3}],\"b0\":true,\"d0\":0.0,\"dict1\":{\"dict2\":" 68 "{\"b2\":false},\"i1\":2014,\"s1\":\"foo\"},\"i0\":2014,\"s0\":" 69 "\"foo\"}", 70 json); 71 } 72 73 TEST(TraceEventArgumentTest, LongStrings) { 74 std::string kLongString = "supercalifragilisticexpialidocious"; 75 std::string kLongString2 = "0123456789012345678901234567890123456789"; 76 char kLongString3[4096]; 77 for (size_t i = 0; i < sizeof(kLongString3); ++i) 78 kLongString3[i] = 'a' + (i % 25); 79 kLongString3[sizeof(kLongString3) - 1] = '\0'; 80 81 std::unique_ptr<TracedValue> value(new TracedValue()); 82 value->SetString("a", "short"); 83 value->SetString("b", kLongString); 84 value->BeginArray("c"); 85 value->AppendString(kLongString2); 86 value->AppendString(""); 87 value->BeginDictionary(); 88 value->SetString("a", kLongString3); 89 value->EndDictionary(); 90 value->EndArray(); 91 92 std::string json; 93 value->AppendAsTraceFormat(&json); 94 EXPECT_EQ("{\"a\":\"short\",\"b\":\"" + kLongString + "\",\"c\":[\"" + 95 kLongString2 + "\",\"\",{\"a\":\"" + kLongString3 + "\"}]}", 96 json); 97 } 98 99 TEST(TraceEventArgumentTest, PassBaseValue) { 100 FundamentalValue int_value(42); 101 FundamentalValue bool_value(true); 102 FundamentalValue double_value(42.0f); 103 104 auto dict_value = WrapUnique(new DictionaryValue); 105 dict_value->SetBoolean("bool", true); 106 dict_value->SetInteger("int", 42); 107 dict_value->SetDouble("double", 42.0f); 108 dict_value->SetString("string", std::string("a") + "b"); 109 dict_value->SetString("string", std::string("a") + "b"); 110 111 auto list_value = WrapUnique(new ListValue); 112 list_value->AppendBoolean(false); 113 list_value->AppendInteger(1); 114 list_value->AppendString("in_list"); 115 list_value->Append(std::move(dict_value)); 116 117 std::unique_ptr<TracedValue> value(new TracedValue()); 118 value->BeginDictionary("outer_dict"); 119 value->SetValue("inner_list", std::move(list_value)); 120 value->EndDictionary(); 121 122 dict_value.reset(); 123 list_value.reset(); 124 125 std::string json; 126 value->AppendAsTraceFormat(&json); 127 EXPECT_EQ( 128 "{\"outer_dict\":{\"inner_list\":[false,1,\"in_list\",{\"bool\":true," 129 "\"double\":42.0,\"int\":42,\"string\":\"ab\"}]}}", 130 json); 131 } 132 133 TEST(TraceEventArgumentTest, PassTracedValue) { 134 auto dict_value = WrapUnique(new TracedValue()); 135 dict_value->SetInteger("a", 1); 136 137 auto nested_dict_value = WrapUnique(new TracedValue()); 138 nested_dict_value->SetInteger("b", 2); 139 nested_dict_value->BeginArray("c"); 140 nested_dict_value->AppendString("foo"); 141 nested_dict_value->EndArray(); 142 143 dict_value->SetValue("e", *nested_dict_value); 144 145 // Check the merged result. 146 std::string json; 147 dict_value->AppendAsTraceFormat(&json); 148 EXPECT_EQ("{\"a\":1,\"e\":{\"b\":2,\"c\":[\"foo\"]}}", json); 149 150 // Check that the passed nestd dict was left unouthced. 151 json = ""; 152 nested_dict_value->AppendAsTraceFormat(&json); 153 EXPECT_EQ("{\"b\":2,\"c\":[\"foo\"]}", json); 154 155 // And that it is still usable. 156 nested_dict_value->SetInteger("f", 3); 157 nested_dict_value->BeginDictionary("g"); 158 nested_dict_value->EndDictionary(); 159 json = ""; 160 nested_dict_value->AppendAsTraceFormat(&json); 161 EXPECT_EQ("{\"b\":2,\"c\":[\"foo\"],\"f\":3,\"g\":{}}", json); 162 } 163 164 } // namespace trace_event 165 } // namespace base 166