Home | History | Annotate | Download | only in debug
      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