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