1# Copyright 2015 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"""Tests for tensorflow.python.framework.traceable_stack.""" 16 17from tensorflow.python.framework import test_util 18from tensorflow.python.framework import traceable_stack 19from tensorflow.python.platform import googletest 20from tensorflow.python.util import tf_inspect as inspect 21 22_LOCAL_OBJECT = lambda x: x 23_THIS_FILENAME = inspect.getsourcefile(_LOCAL_OBJECT) 24 25 26class TraceableObjectTest(test_util.TensorFlowTestCase): 27 28 def testSetFilenameAndLineFromCallerUsesCallersStack(self): 29 t_obj = traceable_stack.TraceableObject(17) 30 31 # Do not separate placeholder from the set_filename_and_line_from_caller() 32 # call one line below it as it is used to calculate the latter's line 33 # number. 34 placeholder = lambda x: x 35 result = t_obj.set_filename_and_line_from_caller() 36 37 expected_lineno = inspect.getsourcelines(placeholder)[1] + 1 38 self.assertEqual(expected_lineno, t_obj.lineno) 39 self.assertEqual(_THIS_FILENAME, t_obj.filename) 40 self.assertEqual(t_obj.SUCCESS, result) 41 42 def testSetFilenameAndLineFromCallerRespectsOffset(self): 43 44 def call_set_filename_and_line_from_caller(t_obj): 45 # We expect to retrieve the line number from _our_ caller. 46 return t_obj.set_filename_and_line_from_caller(offset=1) 47 48 t_obj = traceable_stack.TraceableObject(None) 49 # Do not separate placeholder from the 50 # call_set_filename_and_line_from_caller() call one line below it as it is 51 # used to calculate the latter's line number. 52 placeholder = lambda x: x 53 result = call_set_filename_and_line_from_caller(t_obj) 54 55 expected_lineno = inspect.getsourcelines(placeholder)[1] + 1 56 self.assertEqual(expected_lineno, t_obj.lineno) 57 self.assertEqual(t_obj.SUCCESS, result) 58 59 def testSetFilenameAndLineFromCallerHandlesRidiculousOffset(self): 60 t_obj = traceable_stack.TraceableObject('The quick brown fox.') 61 # This line shouldn't die. 62 result = t_obj.set_filename_and_line_from_caller(offset=300) 63 64 # We expect a heuristic to be used because we are not currently 300 frames 65 # down on the stack. The filename and lineno of the outermost frame are not 66 # predictable -- in some environments the filename is this test file, but in 67 # other environments it is not (e.g. due to a test runner calling this 68 # file). Therefore we only test that the called function knows it applied a 69 # heuristic for the ridiculous stack offset. 70 self.assertEqual(t_obj.HEURISTIC_USED, result) 71 72 73class TraceableStackTest(test_util.TensorFlowTestCase): 74 75 def testPushPeekPopObj(self): 76 t_stack = traceable_stack.TraceableStack() 77 t_stack.push_obj(42.0) 78 t_stack.push_obj('hope') 79 80 expected_lifo_peek = ['hope', 42.0] 81 self.assertEqual(expected_lifo_peek, list(t_stack.peek_objs())) 82 83 self.assertEqual('hope', t_stack.pop_obj()) 84 self.assertEqual(42.0, t_stack.pop_obj()) 85 86 def testPushPeekTopObj(self): 87 t_stack = traceable_stack.TraceableStack() 88 t_stack.push_obj(42.0) 89 t_stack.push_obj('hope') 90 self.assertEqual('hope', t_stack.peek_top_obj()) 91 92 def testPushPopPreserveLifoOrdering(self): 93 t_stack = traceable_stack.TraceableStack() 94 t_stack.push_obj(0) 95 t_stack.push_obj(1) 96 t_stack.push_obj(2) 97 t_stack.push_obj(3) 98 99 obj_3 = t_stack.pop_obj() 100 obj_2 = t_stack.pop_obj() 101 obj_1 = t_stack.pop_obj() 102 obj_0 = t_stack.pop_obj() 103 104 self.assertEqual(3, obj_3) 105 self.assertEqual(2, obj_2) 106 self.assertEqual(1, obj_1) 107 self.assertEqual(0, obj_0) 108 109 def testPushObjSetsFilenameAndLineInfoForCaller(self): 110 t_stack = traceable_stack.TraceableStack() 111 112 # We expect that the line number recorded for the 1-object will come from 113 # the call to t_stack.push_obj(1). Do not separate the next two lines! 114 placeholder_1 = lambda x: x 115 t_stack.push_obj(1) 116 117 # We expect that the line number recorded for the 2-object will come from 118 # the call to call_push_obj() and _not_ the call to t_stack.push_obj(). 119 def call_push_obj(obj): 120 t_stack.push_obj(obj, offset=1) 121 122 # Do not separate the next two lines! 123 placeholder_2 = lambda x: x 124 call_push_obj(2) 125 126 expected_lineno_1 = inspect.getsourcelines(placeholder_1)[1] + 1 127 expected_lineno_2 = inspect.getsourcelines(placeholder_2)[1] + 1 128 129 t_obj_2, t_obj_1 = t_stack.peek_traceable_objs() 130 self.assertEqual(expected_lineno_2, t_obj_2.lineno) 131 self.assertEqual(expected_lineno_1, t_obj_1.lineno) 132 133 134if __name__ == '__main__': 135 googletest.main() 136