Skip to content

Commit 63829d0

Browse files
labathTeemperor
authored andcommitted
[lldb/Test] Introduce "assertSuccess"
Summary: A lot of our tests do 'self.assertTrue(error.Success()'. The problem with that is that when this fails, it produces a completely useless error message (False is not True) and the most important piece of information -- the actual error message -- is completely hidden. Sometimes we mitigate that by including the error message in the "msg" argument, but this has two additional problems: - as the msg argument is evaluated unconditionally, one needs to be careful to not trigger an exception when the operation was actually successful. - it requires more typing, which means we often don't do it assertSuccess solves these problems by taking the entire SBError object as an argument. If the operation was unsuccessful, it can format a reasonable error message itself. The function still accepts a "msg" argument, which can include any additional context, but this context now does not need to include the error message. To demonstrate usage, I replace a number of existing assertTrue assertions with the new function. As this process is not easily automatable, I have just manually updated a representative sample. In some cases, I did not update the code to use assertSuccess, but I went for even higher-level assertion apis (runCmd, expect_expr), as these are even shorter, and can produce even better failure messages. Reviewers: teemperor, JDevlieghere Subscribers: arphaman, lldb-commits Tags: #lldb Differential Revision: https://reviews.llvm.org/D82759 (cherry picked from commit 3567497)
1 parent 893c4d2 commit 63829d0

File tree

13 files changed

+47
-74
lines changed

13 files changed

+47
-74
lines changed

lldb/packages/Python/lldbsuite/test/lldbtest.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2394,9 +2394,7 @@ def expect_expr(
23942394
self.assertEqual(error_msg, eval_result.GetError().GetCString())
23952395
return
23962396

2397-
if not eval_result.GetError().Success():
2398-
self.assertTrue(eval_result.GetError().Success(),
2399-
"Unexpected failure with msg: " + eval_result.GetError().GetCString())
2397+
self.assertSuccess(eval_result.GetError())
24002398

24012399
if result_type:
24022400
self.assertEqual(result_type, eval_result.GetDisplayTypeName())
@@ -2448,6 +2446,13 @@ def run_platform_command(self, cmd):
24482446
err = platform.Run(shell_command)
24492447
return (err, shell_command.GetStatus(), shell_command.GetOutput())
24502448

2449+
"""Assert that an lldb.SBError is in the "success" state."""
2450+
def assertSuccess(self, obj, msg=None):
2451+
if not obj.Success():
2452+
error = obj.GetCString()
2453+
self.fail(self._formatMessage(msg,
2454+
"'{}' is not success".format(error)))
2455+
24512456
# =================================================
24522457
# Misc. helper methods for debugging test execution
24532458
# =================================================

lldb/test/API/commands/expression/call-restarts/TestCallThatRestarts.py

Lines changed: 7 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,7 @@ def call_function(self):
5252
'Stop here in main.', self.main_source_spec)
5353

5454
# Make sure the SIGCHLD behavior is pass/no-stop/no-notify:
55-
return_obj = lldb.SBCommandReturnObject()
56-
self.dbg.GetCommandInterpreter().HandleCommand(
57-
"process handle SIGCHLD -s 0 -p 1 -n 0", return_obj)
58-
self.assertTrue(return_obj.Succeeded(), "Set SIGCHLD to pass, no-stop")
55+
self.runCmd("process handle SIGCHLD -s 0 -p 1 -n 0")
5956

6057
# The sigchld_no variable should be 0 at this point.
6158
self.sigchld_no = target.FindFirstGlobalVariable("sigchld_no")
@@ -107,11 +104,7 @@ def call_function(self):
107104

108105
# Now set the signal to print but not stop and make sure that calling
109106
# still works:
110-
self.dbg.GetCommandInterpreter().HandleCommand(
111-
"process handle SIGCHLD -s 0 -p 1 -n 1", return_obj)
112-
self.assertTrue(
113-
return_obj.Succeeded(),
114-
"Set SIGCHLD to pass, no-stop, notify")
107+
self.runCmd("process handle SIGCHLD -s 0 -p 1 -n 1")
115108

116109
value = frame.EvaluateExpression(
117110
"call_me (%d)" %
@@ -135,29 +128,20 @@ def call_function(self):
135128
# Okay, now set UnwindOnError to true, and then make the signal behavior to stop
136129
# and see that now we do stop at the signal point:
137130

138-
self.dbg.GetCommandInterpreter().HandleCommand(
139-
"process handle SIGCHLD -s 1 -p 1 -n 1", return_obj)
140-
self.assertTrue(
141-
return_obj.Succeeded(),
142-
"Set SIGCHLD to pass, stop, notify")
131+
self.runCmd("process handle SIGCHLD -s 1 -p 1 -n 1")
143132

144133
value = frame.EvaluateExpression(
145134
"call_me (%d)" %
146135
(num_sigchld), options)
147-
self.assertTrue(
148-
value.IsValid() and value.GetError().Success() == False)
136+
self.assertTrue(value.IsValid())
137+
self.assertFalse(value.GetError().Success())
149138

150139
# Set signal handling back to no-stop, and continue and we should end
151140
# up back in out starting frame:
152-
self.dbg.GetCommandInterpreter().HandleCommand(
153-
"process handle SIGCHLD -s 0 -p 1 -n 1", return_obj)
154-
self.assertTrue(
155-
return_obj.Succeeded(),
156-
"Set SIGCHLD to pass, no-stop, notify")
141+
self.runCmd("process handle SIGCHLD -s 0 -p 1 -n 1")
157142

158143
error = process.Continue()
159-
self.assertTrue(
160-
error.Success(),
144+
self.assertSuccess(error,
161145
"Continuing after stopping for signal succeeds.")
162146

163147
frame = self.thread.GetFrameAtIndex(0)

lldb/test/API/commands/expression/context-object-objc/TestContextObjectObjc.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,13 @@ def test_context_object_objc(self):
4444
# Test retrieving of an objcClass's property through the self pointer
4545
value = obj_val.EvaluateExpression("self.property")
4646
self.assertTrue(value.IsValid())
47-
self.assertTrue(value.GetError().Success())
47+
self.assertSuccess(value.GetError())
4848
self.assertEqual(value.GetValueAsSigned(), 2222)
4949

5050
# Test objcClass's methods evaluation through the self pointer
5151
value = obj_val.EvaluateExpression("[self method]")
5252
self.assertTrue(value.IsValid())
53-
self.assertTrue(value.GetError().Success())
53+
self.assertSuccess(value.GetError())
5454
self.assertEqual(value.GetValueAsSigned(), 3333)
5555

5656
# Test if we can use a computation result reference object correctly
@@ -63,12 +63,12 @@ def test_context_object_objc(self):
6363
# Test an expression evaluation on it
6464
value = obj_val.EvaluateExpression("1")
6565
self.assertTrue(value.IsValid())
66-
self.assertTrue(value.GetError().Success())
66+
self.assertSuccess(value.GetError())
6767

6868
# Test retrieving of a field on it
6969
value = obj_val.EvaluateExpression("field")
7070
self.assertTrue(value.IsValid())
71-
self.assertTrue(value.GetError().Success())
71+
self.assertSuccess(value.GetError())
7272
self.assertEqual(value.GetValueAsSigned(), 1111)
7373

7474
def setUp(self):

lldb/test/API/commands/expression/context-object/TestContextObject.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,19 +32,19 @@ def test_context_object(self):
3232
# Test retrieveing of a field (not a local with the same name)
3333
value = obj_val.EvaluateExpression("field")
3434
self.assertTrue(value.IsValid())
35-
self.assertTrue(value.GetError().Success())
35+
self.assertSuccess(value.GetError())
3636
self.assertEqual(value.GetValueAsSigned(), 1111)
3737

3838
# Test functions evaluation
3939
value = obj_val.EvaluateExpression("function()")
4040
self.assertTrue(value.IsValid())
41-
self.assertTrue(value.GetError().Success())
41+
self.assertSuccess(value.GetError())
4242
self.assertEqual(value.GetValueAsSigned(), 2222)
4343

4444
# Test that we retrieve the right global
4545
value = obj_val.EvaluateExpression("global.field")
4646
self.assertTrue(value.IsValid())
47-
self.assertTrue(value.GetError().Success())
47+
self.assertSuccess(value.GetError())
4848
self.assertEqual(value.GetValueAsSigned(), 1111)
4949

5050
#
@@ -57,7 +57,7 @@ def test_context_object(self):
5757
# Test retrieveing of a field
5858
value = obj_val.EvaluateExpression("field_int")
5959
self.assertTrue(value.IsValid())
60-
self.assertTrue(value.GetError().Success())
60+
self.assertSuccess(value.GetError())
6161
self.assertEqual(value.GetValueAsSigned(), 5555)
6262

6363
#
@@ -87,7 +87,7 @@ def test_context_object(self):
8787
# Test retrieveing of an element's field
8888
value = obj_val.GetValueForExpressionPath("[7]").EvaluateExpression("field")
8989
self.assertTrue(value.IsValid())
90-
self.assertTrue(value.GetError().Success())
90+
self.assertSuccess(value.GetError())
9191
self.assertEqual(value.GetValueAsSigned(), 1111)
9292

9393
#
@@ -105,7 +105,7 @@ def test_context_object(self):
105105
# Test retrieveing of a dereferenced object's field
106106
value = obj_val.Dereference().EvaluateExpression("field")
107107
self.assertTrue(value.IsValid())
108-
self.assertTrue(value.GetError().Success())
108+
self.assertSuccess(value.GetError())
109109
self.assertEqual(value.GetValueAsSigned(), 1111)
110110

111111
#
@@ -135,7 +135,7 @@ def test_context_object(self):
135135
# Test retrieveing of a dereferenced object's field
136136
value = obj_val.Dereference().EvaluateExpression("field")
137137
self.assertTrue(value.IsValid())
138-
self.assertTrue(value.GetError().Success())
138+
self.assertSuccess(value.GetError())
139139
self.assertEqual(value.GetValueAsSigned(), 1111)
140140

141141
def setUp(self):

lldb/test/API/commands/expression/dont_allow_jit/TestAllowJIT.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ def expr_options_test(self):
5858

5959
# Now use the options:
6060
result = frame.EvaluateExpression("call_me(10)", options)
61-
self.assertTrue(result.GetError().Success(), "expression succeeded")
61+
self.assertSuccess(result.GetError())
6262
self.assertEqual(result.GetValueAsSigned(), 18, "got the right value.")
6363

6464
# Now disallow JIT and make sure it fails:
@@ -77,6 +77,6 @@ def expr_options_test(self):
7777

7878
# And again, make sure this works:
7979
result = frame.EvaluateExpression("call_me(10)", options)
80-
self.assertTrue(result.GetError().Success(), "expression succeeded")
80+
self.assertSuccess(result.GetError())
8181
self.assertEqual(result.GetValueAsSigned(), 18, "got the right value.")
8282

lldb/test/API/commands/expression/options/TestExprOptions.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,14 @@ def test_expr_options(self):
4646
# Make sure we can evaluate a C++11 expression.
4747
val = frame.EvaluateExpression('foo != nullptr')
4848
self.assertTrue(val.IsValid())
49-
self.assertTrue(val.GetError().Success())
49+
self.assertSuccess(val.GetError())
5050
self.DebugSBValue(val)
5151

5252
# Make sure it still works if language is set to C++11:
5353
options.SetLanguage(lldb.eLanguageTypeC_plus_plus_11)
5454
val = frame.EvaluateExpression('foo != nullptr', options)
5555
self.assertTrue(val.IsValid())
56-
self.assertTrue(val.GetError().Success())
56+
self.assertSuccess(val.GetError())
5757
self.DebugSBValue(val)
5858

5959
# Make sure it fails if language is set to C:
@@ -80,7 +80,7 @@ def test_expr_options_lang(self):
8080
options.SetLanguage(lldb.eLanguageTypeC_plus_plus_11)
8181
val = frame.EvaluateExpression('id == 0', options)
8282
self.assertTrue(val.IsValid())
83-
self.assertTrue(val.GetError().Success())
83+
self.assertSuccess(val.GetError())
8484
self.DebugSBValue(val)
8585

8686
# Make sure we can't retrieve `id` variable if language is set to ObjC:

lldb/test/API/commands/expression/pr35310/TestExprsBug35310.py

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,8 @@ def test_issue35310(self):
2323
"""
2424
self.build()
2525

26-
(target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self,
26+
lldbutil.run_to_source_breakpoint(self,
2727
'// Break here', self.main_source_spec)
28-
frame = thread.GetFrameAtIndex(0)
2928

30-
value = frame.EvaluateExpression("a.test_abi_tag()")
31-
self.assertTrue(value.IsValid())
32-
self.assertTrue(value.GetError().Success())
33-
self.assertEqual(value.GetValueAsSigned(0), 1)
34-
35-
value = frame.EvaluateExpression("a.test_asm_name()")
36-
self.assertTrue(value.IsValid())
37-
self.assertTrue(value.GetError().Success())
38-
self.assertEqual(value.GetValueAsSigned(0), 2)
29+
self.expect_expr("a.test_abi_tag()", result_value='1')
30+
self.expect_expr("a.test_asm_name()", result_value='2')

lldb/test/API/commands/expression/scoped_enums/TestScopedEnumType.py

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,8 @@ def test(self):
2323
self.expect("expr f == Foo::FooBar",
2424
substrs=['(bool) $0 = true'])
2525

26-
value = frame.EvaluateExpression("f == Foo::FooBar")
27-
self.assertTrue(value.IsValid())
28-
self.assertTrue(value.GetError().Success())
29-
self.assertEqual(value.GetValueAsUnsigned(), 1)
30-
31-
value = frame.EvaluateExpression("b == BarBar")
32-
self.assertTrue(value.IsValid())
33-
self.assertTrue(value.GetError().Success())
34-
self.assertEqual(value.GetValueAsUnsigned(), 1)
26+
self.expect_expr("f == Foo::FooBar", result_value='true')
27+
self.expect_expr("b == BarBar", result_value='true')
3528

3629
## b is not a Foo
3730
value = frame.EvaluateExpression("b == Foo::FooBar")

lldb/test/API/commands/expression/timeout/TestCallWithTimeout.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ def test(self):
5858
options.SetTimeoutInMicroSeconds(1000000)
5959
value = frame.EvaluateExpression("wait_a_while (1000)", options)
6060
self.assertTrue(value.IsValid())
61-
self.assertTrue(value.GetError().Success())
61+
self.assertSuccess(value.GetError())
6262

6363
# Now do the same thingwith the command line command, and make sure it
6464
# works too.
@@ -76,4 +76,4 @@ def test(self):
7676
options.SetOneThreadTimeoutInMicroSeconds(500000)
7777
value = frame.EvaluateExpression("wait_a_while (1000)", options)
7878
self.assertTrue(value.IsValid())
79-
self.assertTrue(value.GetError().Success())
79+
self.assertSuccess(value.GetError())

lldb/test/API/commands/expression/unwind_expression/TestUnwindExpression.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,7 @@ def test_conditional_bktp(self):
4545

4646
main_frame = self.thread.GetFrameAtIndex(0)
4747
val = main_frame.EvaluateExpression("second_function(47)", options)
48-
self.assertTrue(
49-
val.GetError().Success(),
50-
"We did complete the execution.")
48+
self.assertSuccess(val.GetError(), "We did complete the execution.")
5149
self.assertEquals(47, val.GetValueAsSigned())
5250

5351

@@ -91,8 +89,8 @@ def do_unwind_test(self, thread, bkpt, timeout):
9189

9290
# Now unwind the expression, and make sure we got back to where we
9391
# started.
94-
error = thread.UnwindInnermostExpression()
95-
self.assertTrue(error.Success(), "We succeeded in unwinding")
92+
self.assertSuccess(thread.UnwindInnermostExpression(),
93+
"We succeeded in unwinding")
9694

9795
cur_frame = thread.GetFrameAtIndex(0)
9896
self.assertTrue(

lldb/test/API/commands/expression/weak_symbols/TestWeakSymbols.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ def run_weak_var_check (self, weak_varname, present):
3939
# the bug that expressions with no result currently return False for Success()...
4040
expr = "if (&" + weak_varname + " != NULL) { present_weak_int = 10; } else { present_weak_int = 20;}; 10"
4141
result = self.frame.EvaluateExpression(expr)
42-
self.assertTrue(result.GetError().Success(), "absent_weak_int expr failed: %s"%(result.GetError().GetCString()))
42+
self.assertSuccess(result.GetError(), "absent_weak_int expr failed")
4343
self.assertEqual(value.GetValueAsSigned(), correct_value, "Didn't change present_weak_int correctly.")
4444

4545
def do_test(self):

lldb/test/API/commands/register/register/register_command/TestRegisters.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -235,12 +235,12 @@ def fp_special_purpose_register_read(self):
235235
error = lldb.SBError()
236236
reg_value_fstat_initial = value.GetValueAsUnsigned(error, 0)
237237

238-
self.assertTrue(error.Success(), "reading a value for fstat")
238+
self.assertSuccess(error, "reading a value for fstat")
239239
value = currentFrame.FindValue("ftag", lldb.eValueTypeRegister)
240240
error = lldb.SBError()
241241
reg_value_ftag_initial = value.GetValueAsUnsigned(error, 0)
242242

243-
self.assertTrue(error.Success(), "reading a value for ftag")
243+
self.assertSuccess(error, "reading a value for ftag")
244244
fstat_top_pointer_initial = (reg_value_fstat_initial & 0x3800) >> 11
245245

246246
# Execute 'si' aka 'thread step-inst' instruction 5 times and with
@@ -292,7 +292,7 @@ def fp_register_write(self):
292292
0, # launch flags
293293
True, # stop at entry
294294
error)
295-
self.assertTrue(error.Success(), "Launch succeeds. Error is :" + str(error))
295+
self.assertSuccess(error, "Launch succeeds")
296296

297297
self.assertTrue(
298298
process.GetState() == lldb.eStateStopped,

lldb/test/API/python_api/hello_world/TestHelloWorld.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,8 @@ def test_with_attach_to_process_with_name_api(self):
140140
target.ConnectRemote(listener, None, None, error)
141141

142142
process = target.AttachToProcessWithName(listener, name, False, error)
143-
self.assertTrue(error.Success() and process, PROCESS_IS_VALID)
143+
self.assertSuccess(error)
144+
self.assertTrue(process, PROCESS_IS_VALID)
144145

145146
# Verify that after attach, our selected target indeed matches name.
146147
self.expect(

0 commit comments

Comments
 (0)