aboutsummaryrefslogtreecommitdiff
path: root/gdb/testsuite/gdb.python/tui-window-disabled.exp
blob: 6048654882580d7602bdf1990bf7a3dadc703f05 (plain)
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
}