1 /* Copyright 2017 The TensorFlow Authors. All Rights Reserved. 2 3 Licensed under the Apache License, Version 2.0 (the "License"); 4 you may not use this file except in compliance with the License. 5 You may obtain a copy of the License at 6 7 http://www.apache.org/licenses/LICENSE-2.0 8 9 Unless required by applicable law or agreed to in writing, software 10 distributed under the License is distributed on an "AS IS" BASIS, 11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 See the License for the specific language governing permissions and 13 limitations under the License. 14 ==============================================================================*/ 15 16 #include "tensorflow/core/debug/debug_graph_utils.h" 17 18 #include "tensorflow/core/framework/tensor_testutil.h" 19 #include "tensorflow/core/lib/core/status_test_util.h" 20 #include "tensorflow/core/lib/strings/str_util.h" 21 22 namespace tensorflow { 23 24 class DebugGraphUtilsTest : public ::testing::Test { 25 protected: 26 Status ParseDebugOpName(const string& debug_op_name, 27 string* debug_op_name_proper, 28 std::unordered_map<string, string>* attributes) { 29 return DebugNodeInserter::ParseDebugOpName( 30 debug_op_name, debug_op_name_proper, attributes); 31 } 32 }; 33 34 TEST_F(DebugGraphUtilsTest, TestParseNoAttributeDebugOpName) { 35 string debug_op_name_proper; 36 std::unordered_map<string, string> attributes; 37 TF_ASSERT_OK( 38 ParseDebugOpName("DebugIdentity", &debug_op_name_proper, &attributes)); 39 ASSERT_EQ("DebugIdentity", debug_op_name_proper); 40 ASSERT_EQ(0, attributes.size()); 41 } 42 43 TEST_F(DebugGraphUtilsTest, TestMalformedDebugOpName) { 44 string debug_op_name_proper; 45 std::unordered_map<string, string> attributes; 46 47 Status s = ParseDebugOpName("(mute_if_healthy=true)", &debug_op_name_proper, 48 &attributes); 49 ASSERT_EQ(errors::Code::INVALID_ARGUMENT, s.code()); 50 51 s = ParseDebugOpName("DebugNumericSummary(", &debug_op_name_proper, 52 &attributes); 53 ASSERT_EQ(errors::Code::INVALID_ARGUMENT, s.code()); 54 55 s = ParseDebugOpName("DebugNumericSummary)", &debug_op_name_proper, 56 &attributes); 57 ASSERT_EQ(errors::Code::INVALID_ARGUMENT, s.code()); 58 } 59 60 TEST_F(DebugGraphUtilsTest, TestDebugOpNameWithMalformedAttributes) { 61 string debug_op_name_proper; 62 std::unordered_map<string, string> attributes; 63 64 Status s = ParseDebugOpName("DebugNumericSummary(=)", &debug_op_name_proper, 65 &attributes); 66 ASSERT_EQ(errors::Code::INVALID_ARGUMENT, s.code()); 67 68 s = ParseDebugOpName("DebugNumericSummary(mute_if_healthy=)", 69 &debug_op_name_proper, &attributes); 70 ASSERT_EQ(errors::Code::INVALID_ARGUMENT, s.code()); 71 72 s = ParseDebugOpName("DebugNumericSummary(=true)", &debug_op_name_proper, 73 &attributes); 74 ASSERT_EQ(errors::Code::INVALID_ARGUMENT, s.code()); 75 76 s = ParseDebugOpName("DebugNumericSummary(mute_if_healthy:true)", 77 &debug_op_name_proper, &attributes); 78 ASSERT_EQ(errors::Code::INVALID_ARGUMENT, s.code()); 79 80 s = ParseDebugOpName("DebugNumericSummary(mute_if_healthy=true;threshold=)", 81 &debug_op_name_proper, &attributes); 82 ASSERT_EQ(errors::Code::INVALID_ARGUMENT, s.code()); 83 84 s = ParseDebugOpName( 85 "DebugNumericSummary(mute_if_healthy=true;threshold:300.0)", 86 &debug_op_name_proper, &attributes); 87 ASSERT_EQ(errors::Code::INVALID_ARGUMENT, s.code()); 88 } 89 90 TEST_F(DebugGraphUtilsTest, TestValidDebugOpNameWithSingleAttribute) { 91 string debug_op_name_proper; 92 std::unordered_map<string, string> attributes; 93 94 TF_ASSERT_OK(ParseDebugOpName("DebugNumericSummary()", &debug_op_name_proper, 95 &attributes)); 96 ASSERT_EQ("DebugNumericSummary", debug_op_name_proper); 97 ASSERT_EQ(0, attributes.size()); 98 99 attributes.clear(); 100 TF_ASSERT_OK(ParseDebugOpName("DebugNumericSummary(mute_if_healthy=true)", 101 &debug_op_name_proper, &attributes)); 102 ASSERT_EQ("DebugNumericSummary", debug_op_name_proper); 103 ASSERT_EQ(1, attributes.size()); 104 ASSERT_EQ("true", attributes["mute_if_healthy"]); 105 } 106 107 TEST_F(DebugGraphUtilsTest, TestValidDebugOpNameWithMoreThanOneAttributes) { 108 string debug_op_name_proper; 109 std::unordered_map<string, string> attributes; 110 TF_ASSERT_OK(ParseDebugOpName( 111 "DebugNumericSummary(mute_if_healthy=true; threshold=300.0)", 112 &debug_op_name_proper, &attributes)); 113 ASSERT_EQ("DebugNumericSummary", debug_op_name_proper); 114 ASSERT_EQ(2, attributes.size()); 115 ASSERT_EQ("true", attributes["mute_if_healthy"]); 116 ASSERT_EQ("300.0", attributes["threshold"]); 117 118 attributes.clear(); 119 TF_ASSERT_OK(ParseDebugOpName( 120 "DebugNumericSummary(mute_if_healthy=true;threshold=300.0;first_n=100)", 121 &debug_op_name_proper, &attributes)); 122 ASSERT_EQ("DebugNumericSummary", debug_op_name_proper); 123 ASSERT_EQ(3, attributes.size()); 124 ASSERT_EQ("true", attributes["mute_if_healthy"]); 125 ASSERT_EQ("300.0", attributes["threshold"]); 126 ASSERT_EQ("100", attributes["first_n"]); 127 } 128 129 TEST_F(DebugGraphUtilsTest, TestValidDebugOpNameWithMoreDuplicatettributes) { 130 string debug_op_name_proper; 131 std::unordered_map<string, string> attributes; 132 Status s = ParseDebugOpName( 133 "DebugNumericSummary(mute_if_healthy=true; lower_bound=3; " 134 "mute_if_healthy=false;)", 135 &debug_op_name_proper, &attributes); 136 ASSERT_EQ(errors::Code::INVALID_ARGUMENT, s.code()); 137 } 138 139 TEST_F(DebugGraphUtilsTest, TestValidDebugOpNameWithWhitespaceInAttributes) { 140 string debug_op_name_proper; 141 std::unordered_map<string, string> attributes; 142 143 TF_ASSERT_OK(ParseDebugOpName( 144 "DebugNumericSummary( mute_if_healthy=true; threshold=300.0 )", 145 &debug_op_name_proper, &attributes)); 146 ASSERT_EQ("DebugNumericSummary", debug_op_name_proper); 147 ASSERT_EQ(2, attributes.size()); 148 ASSERT_EQ("true", attributes["mute_if_healthy"]); 149 ASSERT_EQ("300.0", attributes["threshold"]); 150 151 attributes.clear(); 152 TF_ASSERT_OK(ParseDebugOpName( 153 "DebugNumericSummary(;;mute_if_healthy=true; threshold=300.0;;)", 154 &debug_op_name_proper, &attributes)); 155 ASSERT_EQ("DebugNumericSummary", debug_op_name_proper); 156 ASSERT_EQ(2, attributes.size()); 157 ASSERT_EQ("true", attributes["mute_if_healthy"]); 158 ASSERT_EQ("300.0", attributes["threshold"]); 159 } 160 161 } // namespace tensorflow 162