1# Copyright 2018 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"""Test to make sure stack trace is generated in case of test failures.""" 16 17from __future__ import absolute_import 18from __future__ import division 19from __future__ import print_function 20 21import argparse 22import os 23import signal 24import subprocess 25import sys 26 27from tensorflow.python.platform import test 28from tensorflow.python.platform import tf_logging as logging 29 30 31# FLAGS defined at the bottom: 32# child (bool) set to true if we are running in the child process. 33FLAGS = None 34 35_CHILD_FLAG_HELP = 'Boolean. Set to true if this is the child process.' 36 37 38class StacktraceHandlerTest(test.TestCase): 39 40 def testChildProcessKillsItself(self): 41 if FLAGS.child: 42 os.kill(os.getpid(), signal.SIGABRT) 43 44 def testGeneratesStacktrace(self): 45 if FLAGS.child: 46 return 47 48 # Subprocess sys.argv[0] with --child=True 49 if sys.executable: 50 child_process = subprocess.Popen( 51 [sys.executable, sys.argv[0], '--child=True'], cwd=os.getcwd(), 52 stdout=subprocess.PIPE, stderr=subprocess.PIPE) 53 else: 54 child_process = subprocess.Popen( 55 [sys.argv[0], '--child=True'], cwd=os.getcwd(), 56 stdout=subprocess.PIPE, stderr=subprocess.PIPE) 57 58 # Capture its output. capture both stdout and stderr and append them. 59 # We are not worried about timing or order of messages in this test. 60 child_stdout, child_stderr = child_process.communicate() 61 child_output = child_stdout + child_stderr 62 63 # Make sure the child process is dead before we proceed. 64 child_process.wait() 65 66 logging.info('Output from the child process:') 67 logging.info(child_output) 68 69 # Verify a stack trace is printed. 70 self.assertIn(b'PyEval_EvalFrame', child_output) 71 72 73if __name__ == '__main__': 74 parser = argparse.ArgumentParser() 75 parser.add_argument( 76 '--child', type=bool, default=False, help=_CHILD_FLAG_HELP) 77 FLAGS, unparsed = parser.parse_known_args() 78 79 # Now update argv, so that unittest library does not get confused. 80 sys.argv = [sys.argv[0]] + unparsed 81 test.main() 82