1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
|
# Copyright (C) 2021-2023 Free Software Foundation, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Create a TUI window in Python that responds to GDB event. Each
# event will trigger the TUI window to redraw itself.
#
# This test is checking how GDB behaves if the user first displays a
# Python based tui window, and then does 'tui disable'. At one point
# it was possible that GDB would try to redraw the tui window even
# though the tui should be disabled.
load_lib gdb-python.exp
tuiterm_env
standard_testfile
if {[build_executable "failed to prepare" ${testfile} ${srcfile}] == -1} {
return -1
}
clean_restart
if {[skip_tui_tests]} {
return
}
# Copy the Python script to where the tests are being run.
set remote_python_file [gdb_remote_download host \
${srcdir}/${subdir}/${testfile}.py]
proc clean_restart_and_setup { prefix } {
global testfile
global remote_python_file
with_test_prefix $prefix {
Term::clean_restart 24 80 $testfile
# Skip all tests if Python scripting is not enabled.
if { [skip_python_tests] } { return 0 }
# Now source the python script.
gdb_test_no_output "source ${remote_python_file}" \
"source ${testfile}.py"
# Create a new layout making use of our new event window.
gdb_test_no_output "tui new-layout test events 1 cmd 1"
# Disable source code highlighting.
gdb_test_no_output "set style sources off"
if {![runto_main]} {
perror "test suppressed"
return
}
}
return 1
}
# Run the test. CLEANUP_PROPERLY is either true or false. This is
# used to set a flag in the Python code which controls whether the
# Python TUI window cleans up properly or not.
#
# When the Python window does not cleanup properly then it retains a
# cyclic reference to itself, this means that it is still possible for
# the object to try and redraw itself even when the tui is disabled.
proc run_test { cleanup_properly } {
if { ![clean_restart_and_setup "initial restart"] } {
unsupported "couldn't restart GDB"
return
}
if { $cleanup_properly } {
gdb_test_no_output "python cleanup_properly = True"
} else {
gdb_test_no_output "python cleanup_properly = False"
}
if {![Term::enter_tui]} {
unsupported "TUI not supported"
return
}
Term::command "layout test"
# Confirm that the events box is initially empty, then perform two
# actions that will add two events to the window.
Term::check_box_contents "no events yet" 0 0 80 16 ""
Term::command "next"
Term::check_box_contents "single stop event" 0 0 80 16 "stop"
Term::command "next"
Term::check_box_contents "two stop events" 0 0 80 16 \
"stop\[^\n\]+\nstop"
# Now disable the tui, we should end up back at a standard GDB prompt.
Term::command "tui disable"
# Do something just so we know that the CLI is working.
gdb_test "print 1 + 1 + 1" " = 3"
# Now perform an action that would trigger an event. At one point
# there was a bug where the TUI window might try to redraw itself.
# This is why we use GDB_TEST_MULTIPLE here, so we can spot the tui
# window title and know that things have gone wrong.
gdb_test_multiple "next" "next at cli" {
-re -wrap "func \\(3\\);" {
pass $gdb_test_name
}
-re "This Is The Event Window" {
fail $gdb_test_name
}
}
# Do something just so we know that the CLI is still working. This
# also serves to drain the expect buffer if the above test failed.
gdb_test "print 2 + 2 + 2" " = 6"
# Now tell the Python code not to check the window is valid before
# calling rerended. The result is the Python code will try to draw to
# the screen. This should throw a Python exception.
gdb_test_no_output "python perform_valid_check = False"
set exception_pattern "\r\nPython Exception\[^\n\r\]+TUI window is invalid\[^\n\r\]+"
gdb_test_multiple "next" "next at cli, with an exception" {
-re -wrap "func \\(4\\);${exception_pattern}" {
pass $gdb_test_name
}
-re "This Is The Event Window" {
fail $gdb_test_name
}
}
# Do something just so we know that the CLI is still working. This
# also serves to drain the expect buffer if the above test failed.
gdb_test "print 3 + 3 + 3" " = 9"
# Set 'update_title' to True. The Python script will now try to set
# the window title when an event occurs (instead of trying to redraw
# the window). As the window is still not displayed this will again
# through an exception.
gdb_test_no_output "python update_title = True"
gdb_test_multiple "next" "next at cli, with an exception for setting the title" {
-re -wrap "func \\(5\\);${exception_pattern}" {
pass $gdb_test_name
}
-re "This Is The Event Window" {
fail $gdb_test_name
}
}
# We need to perform a restart here as the TUI library we use for
# testing doesn't seem to handle output in the command window
# correctly, and gets really upset as we approach the bottom of
# the screen.
#
# Restart GDB, enable tui mode, select the new layout. Then
# disable tui and re-enable again.
if { ![clean_restart_and_setup "second restart"] } {
unsupported "couldn't restart GDB"
return
}
with_test_prefix "enter tui again" {
if {![Term::enter_tui]} {
unsupported "TUI not supported"
return
}
}
Term::command "layout test"
Term::command "tui disable"
send_gdb "tui enable\n"
Term::check_box "check for python window" 0 0 80 16
}
# Run the tests in both cleanup modes.
foreach_with_prefix cleanup_properly { True False } {
run_test $cleanup_properly
}
|