Test for new thread creation
- don't clear the stack trace on continue - track running status properly (ish) - mark threads (running) when the app is executing - indicate the "current" thread with a different icon TODO: - allow user to specify current thread? - track running status of threads individually? - allow to pause/continue specific threads?
This commit is contained in:
parent
e2ca9b5318
commit
e9e0e9e5b9
7 changed files with 495 additions and 110 deletions
|
|
@ -91,3 +91,31 @@ endfunc
|
|||
function! ThisTestIsFlaky()
|
||||
let g:test_is_flaky = v:true
|
||||
endfunction
|
||||
|
||||
function! AssertMatchist( expected, actual ) abort
|
||||
let ret = assert_equal( len( a:expected ), len( a:actual ) )
|
||||
let len = min( [ len( a:expected ), len( a:actual ) ] )
|
||||
let idx = 0
|
||||
while idx < len
|
||||
let ret += assert_match( a:expected[ idx ], a:actual[ idx ] )
|
||||
let idx += 1
|
||||
endwhile
|
||||
return ret
|
||||
endfunction
|
||||
|
||||
|
||||
function! GetBufLine( buf, start, end = '$' )
|
||||
if type( a:start ) != v:t_string && a:start < 0
|
||||
let start = getbufinfo( a:buf )[ 0 ].linecount + a:start
|
||||
else
|
||||
let start = a:start
|
||||
endif
|
||||
|
||||
if type( a:end ) != v:t_string && a:end < 0
|
||||
let end = getbufinfo( a:buf )[ 0 ].linecount + a:end
|
||||
else
|
||||
let end = a:end
|
||||
endif
|
||||
|
||||
return getbufline( a:buf, start, end )
|
||||
endfunction
|
||||
|
|
|
|||
|
|
@ -10,38 +10,338 @@ endfunction
|
|||
|
||||
function! s:StartDebugging()
|
||||
exe 'edit ' . s:fn
|
||||
call vimspector#SetLineBreakpoint( s:fn, 13 )
|
||||
call vimspector#SetLineBreakpoint( s:fn, 15 )
|
||||
call vimspector#Launch()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, 13, 1 )
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, 15, 1 )
|
||||
endfunction
|
||||
|
||||
function! Test_Multiple_Threads()
|
||||
call vimspector#SetLineBreakpoint( s:fn, 41 )
|
||||
call vimspector#SetLineBreakpoint( s:fn, 51 )
|
||||
function! Test_Multiple_Threads_Continue()
|
||||
|
||||
let thread_l = 67
|
||||
let notify_l = 74
|
||||
|
||||
call vimspector#SetLineBreakpoint( s:fn, thread_l )
|
||||
call vimspector#SetLineBreakpoint( s:fn, notify_l )
|
||||
call s:StartDebugging()
|
||||
|
||||
call vimspector#Continue()
|
||||
|
||||
" As we step through the thread creation we should get Thread events
|
||||
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, 41, 1 )
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, thread_l, 1 )
|
||||
call cursor( 1, 1 )
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchist(
|
||||
\ [
|
||||
\ '> Thread: Thread #1',
|
||||
\ ' .*: threads!main@threads.cpp:' . string( thread_l )
|
||||
\ ],
|
||||
\ GetBufLine( winbufnr( g:vimspector_session_windows.stack_trace ),
|
||||
\ 1,
|
||||
\ 2 )
|
||||
\ )
|
||||
\ } )
|
||||
call vimspector#Continue()
|
||||
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, 41, 1 )
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, thread_l, 1 )
|
||||
call cursor( 1, 1 )
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchist(
|
||||
\ [
|
||||
\ '> Thread: Thread #1',
|
||||
\ ' .*: threads!main@threads.cpp:' . string( thread_l )
|
||||
\ ],
|
||||
\ GetBufLine( winbufnr( g:vimspector_session_windows.stack_trace ),
|
||||
\ 1,
|
||||
\ 2 )
|
||||
\ )
|
||||
\ } )
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchist(
|
||||
\ [
|
||||
\ '+ Thread: Thread #2',
|
||||
\ ],
|
||||
\ GetBufLine( winbufnr( g:vimspector_session_windows.stack_trace ),
|
||||
\ '$',
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
call vimspector#Continue()
|
||||
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, 41, 1 )
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, thread_l, 1 )
|
||||
call cursor( 1, 1 )
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchist(
|
||||
\ [
|
||||
\ '> Thread: Thread #1',
|
||||
\ ' .*: threads!main@threads.cpp:' . string( thread_l )
|
||||
\ ],
|
||||
\ GetBufLine( winbufnr( g:vimspector_session_windows.stack_trace ),
|
||||
\ 1,
|
||||
\ 2 )
|
||||
\ )
|
||||
\ } )
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchist(
|
||||
\ [
|
||||
\ '+ Thread: Thread #3',
|
||||
\ ],
|
||||
\ GetBufLine( winbufnr( g:vimspector_session_windows.stack_trace ),
|
||||
\ '$',
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
call vimspector#Continue()
|
||||
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, 41, 1 )
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, thread_l, 1 )
|
||||
call cursor( 1, 1 )
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchist(
|
||||
\ [
|
||||
\ '> Thread: Thread #1',
|
||||
\ ' .*: threads!main@threads.cpp:' . string( thread_l )
|
||||
\ ],
|
||||
\ GetBufLine( winbufnr( g:vimspector_session_windows.stack_trace ),
|
||||
\ 1,
|
||||
\ 2 )
|
||||
\ )
|
||||
\ } )
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchist(
|
||||
\ [
|
||||
\ '+ Thread: Thread #4',
|
||||
\ ],
|
||||
\ GetBufLine( winbufnr( g:vimspector_session_windows.stack_trace ),
|
||||
\ '$',
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
call vimspector#Continue()
|
||||
|
||||
" This is the last one
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, 41, 1 )
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, thread_l, 1 )
|
||||
call cursor( 1, 1 )
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchist(
|
||||
\ [
|
||||
\ '> Thread: Thread #1',
|
||||
\ ' .*: threads!main@threads.cpp:' . string( thread_l )
|
||||
\ ],
|
||||
\ GetBufLine( winbufnr( g:vimspector_session_windows.stack_trace ),
|
||||
\ 1,
|
||||
\ 2 )
|
||||
\ )
|
||||
\ } )
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchist(
|
||||
\ [
|
||||
\ '+ Thread: Thread #5',
|
||||
\ ],
|
||||
\ GetBufLine( winbufnr( g:vimspector_session_windows.stack_trace ),
|
||||
\ '$',
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
call vimspector#Continue()
|
||||
|
||||
" So we break out of the loop
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, 51, 1 )
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, notify_l, 1 )
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchist(
|
||||
\ [
|
||||
\ '> Thread: Thread #1',
|
||||
\ ' .*: threads!main@threads.cpp:' . string( notify_l )
|
||||
\ ],
|
||||
\ GetBufLine( winbufnr( g:vimspector_session_windows.stack_trace ),
|
||||
\ 1,
|
||||
\ 2 )
|
||||
\ )
|
||||
\ } )
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchist(
|
||||
\ [
|
||||
\ '+ Thread: Thread #6',
|
||||
\ ],
|
||||
\ GetBufLine( winbufnr( g:vimspector_session_windows.stack_trace ),
|
||||
\ '$',
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
|
||||
call vimspector#ClearBreakpoints()
|
||||
call vimspector#test#setup#Reset()
|
||||
%bwipe!
|
||||
endfunction
|
||||
|
||||
function! Test_Multiple_Threads_Step()
|
||||
let thread_l = 67
|
||||
let thread_n = thread_l + 1
|
||||
let notify_l = 74
|
||||
|
||||
call vimspector#SetLineBreakpoint( s:fn, thread_l )
|
||||
call vimspector#SetLineBreakpoint( s:fn, notify_l )
|
||||
call s:StartDebugging()
|
||||
call vimspector#Continue()
|
||||
|
||||
" As we step through the thread creation we should get Thread events
|
||||
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, thread_l, 1 )
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchist(
|
||||
\ [
|
||||
\ '> Thread: Thread #1',
|
||||
\ ' .*: threads!main@threads.cpp:' . string( thread_l )
|
||||
\ ],
|
||||
\ GetBufLine( winbufnr( g:vimspector_session_windows.stack_trace ),
|
||||
\ 1,
|
||||
\ 2 )
|
||||
\ )
|
||||
\ } )
|
||||
call vimspector#StepOver()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, thread_n, 1 )
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchist(
|
||||
\ [
|
||||
\ '+ Thread: Thread #2',
|
||||
\ ],
|
||||
\ GetBufLine( winbufnr( g:vimspector_session_windows.stack_trace ),
|
||||
\ '$',
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
call vimspector#Continue()
|
||||
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, thread_l, 1 )
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchist(
|
||||
\ [
|
||||
\ '+ Thread: Thread #2',
|
||||
\ ],
|
||||
\ GetBufLine( winbufnr( g:vimspector_session_windows.stack_trace ),
|
||||
\ '$',
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
call vimspector#StepOver()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, thread_n, 1 )
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchist(
|
||||
\ [
|
||||
\ '+ Thread: Thread #2',
|
||||
\ '+ Thread: Thread #3',
|
||||
\ ],
|
||||
\ GetBufLine( winbufnr( g:vimspector_session_windows.stack_trace ),
|
||||
\ -1,
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
call vimspector#Continue()
|
||||
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, thread_l, 1 )
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchist(
|
||||
\ [
|
||||
\ '+ Thread: Thread #2',
|
||||
\ '+ Thread: Thread #3',
|
||||
\ ],
|
||||
\ GetBufLine( winbufnr( g:vimspector_session_windows.stack_trace ),
|
||||
\ -1,
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
call vimspector#StepOver()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, thread_n, 1 )
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchist(
|
||||
\ [
|
||||
\ '+ Thread: Thread #2',
|
||||
\ '+ Thread: Thread #3',
|
||||
\ '+ Thread: Thread #4',
|
||||
\ ],
|
||||
\ GetBufLine( winbufnr( g:vimspector_session_windows.stack_trace ),
|
||||
\ -2,
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
call vimspector#Continue()
|
||||
|
||||
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, thread_l, 1 )
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchist(
|
||||
\ [
|
||||
\ '+ Thread: Thread #2',
|
||||
\ '+ Thread: Thread #3',
|
||||
\ '+ Thread: Thread #4',
|
||||
\ ],
|
||||
\ GetBufLine( winbufnr( g:vimspector_session_windows.stack_trace ),
|
||||
\ -2,
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
call vimspector#StepOver()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, thread_n, 1 )
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchist(
|
||||
\ [
|
||||
\ '+ Thread: Thread #2',
|
||||
\ '+ Thread: Thread #3',
|
||||
\ '+ Thread: Thread #4',
|
||||
\ '+ Thread: Thread #5',
|
||||
\ ],
|
||||
\ GetBufLine( winbufnr( g:vimspector_session_windows.stack_trace ),
|
||||
\ -3,
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
call vimspector#Continue()
|
||||
|
||||
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, thread_l, 1 )
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchist(
|
||||
\ [
|
||||
\ '+ Thread: Thread #2',
|
||||
\ '+ Thread: Thread #3',
|
||||
\ '+ Thread: Thread #4',
|
||||
\ '+ Thread: Thread #5',
|
||||
\ ],
|
||||
\ GetBufLine( winbufnr( g:vimspector_session_windows.stack_trace ),
|
||||
\ -3,
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
call vimspector#StepOver()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, thread_n, 1 )
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchist(
|
||||
\ [
|
||||
\ '+ Thread: Thread #2',
|
||||
\ '+ Thread: Thread #3',
|
||||
\ '+ Thread: Thread #4',
|
||||
\ '+ Thread: Thread #5',
|
||||
\ '+ Thread: Thread #6',
|
||||
\ ],
|
||||
\ GetBufLine( winbufnr( g:vimspector_session_windows.stack_trace ),
|
||||
\ -4,
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
call vimspector#Continue()
|
||||
|
||||
|
||||
" So we break out of the loop
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, notify_l, 1 )
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchist(
|
||||
\ [
|
||||
\ '+ Thread: Thread #6',
|
||||
\ ],
|
||||
\ GetBufLine( winbufnr( g:vimspector_session_windows.stack_trace ),
|
||||
\ '$',
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
|
||||
call vimspector#ClearBreakpoints()
|
||||
call vimspector#test#setup#Reset()
|
||||
|
|
|
|||
41
tests/testdata/cpp/simple/threads.cpp
vendored
41
tests/testdata/cpp/simple/threads.cpp
vendored
|
|
@ -1,6 +1,8 @@
|
|||
#include <chrono>
|
||||
#include <condition_variable>
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <mutex>
|
||||
#include <string_view>
|
||||
#include <system_error>
|
||||
#include <thread>
|
||||
|
|
@ -36,17 +38,40 @@ int main( int argc, char ** argv )
|
|||
auto eng = std::default_random_engine() ;
|
||||
auto dist = std::uniform_int_distribution<int>( 250, 1000 );
|
||||
|
||||
for ( int i = 0; i < numThreads; ++i )
|
||||
std::mutex m;
|
||||
std::condition_variable v;
|
||||
bool ready = false;
|
||||
{
|
||||
using namespace std::chrono_literals;
|
||||
threads.emplace_back( [&,tnum=i]() {
|
||||
std::cout << "Started thread " << tnum << '\n';
|
||||
std::this_thread::sleep_for(
|
||||
5s + std::chrono::milliseconds( dist( eng ) ) );
|
||||
std::cout << "Completed thread " << tnum << '\n';
|
||||
});
|
||||
std::lock_guard l(m);
|
||||
|
||||
std::cout << "Preparing..." << '\n';
|
||||
|
||||
for ( int i = 0; i < numThreads; ++i )
|
||||
{
|
||||
using namespace std::chrono_literals;
|
||||
auto tp = [&,tnum=i]() {
|
||||
// Wait for the go-ahead
|
||||
{
|
||||
std::unique_lock l(m);
|
||||
while (!ready) {
|
||||
v.wait(l);
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "Started thread " << tnum << '\n';
|
||||
std::this_thread::sleep_for(
|
||||
5s + std::chrono::milliseconds( dist( eng ) ) );
|
||||
std::cout << "Completed thread " << tnum << '\n';
|
||||
};
|
||||
|
||||
threads.emplace_back( tp );
|
||||
}
|
||||
|
||||
std::cout << "Ready to go!" << '\n';
|
||||
ready = true;
|
||||
}
|
||||
|
||||
v.notify_all();
|
||||
|
||||
for ( int i = 0; i < numThreads; ++i )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -8,17 +8,6 @@ function! ClearDown()
|
|||
call vimspector#test#setup#ClearDown()
|
||||
endfunction
|
||||
|
||||
function! s:assert_match_list( expected, actual ) abort
|
||||
let ret = assert_equal( len( a:expected ), len( a:actual ) )
|
||||
let len = min( [ len( a:expected ), len( a:actual ) ] )
|
||||
let idx = 0
|
||||
while idx < len
|
||||
let ret += assert_match( a:expected[ idx ], a:actual[ idx ] )
|
||||
let idx += 1
|
||||
endwhile
|
||||
return ret
|
||||
endfunction
|
||||
|
||||
function! s:StartDebugging( ... )
|
||||
if a:0 == 0
|
||||
let config = #{
|
||||
|
|
@ -222,7 +211,7 @@ function! Test_ExpandVariables()
|
|||
call feedkeys( "\<CR>", 'xt' )
|
||||
|
||||
call WaitForAssert( {->
|
||||
\ s:assert_match_list(
|
||||
\ AssertMatchist(
|
||||
\ [
|
||||
\ '- Scope: Locals',
|
||||
\ ' \*- t (Test): {...}',
|
||||
|
|
@ -240,7 +229,7 @@ function! Test_ExpandVariables()
|
|||
" Step - stays expanded
|
||||
call vimspector#StepOver()
|
||||
call WaitForAssert( {->
|
||||
\ s:assert_match_list(
|
||||
\ AssertMatchist(
|
||||
\ [
|
||||
\ '- Scope: Locals',
|
||||
\ ' - t (Test): {...}',
|
||||
|
|
@ -289,7 +278,7 @@ function! Test_ExpandVariables()
|
|||
call setpos( '.', [ 0, 2, 1 ] )
|
||||
call feedkeys( "\<CR>", 'xt' )
|
||||
call WaitForAssert( {->
|
||||
\ s:assert_match_list(
|
||||
\ AssertMatchist(
|
||||
\ [
|
||||
\ '- Scope: Locals',
|
||||
\ ' - t (Test): {...}',
|
||||
|
|
@ -389,7 +378,7 @@ function! Test_ExpandWatch()
|
|||
call feedkeys( "\<CR>", 'xt' )
|
||||
|
||||
call WaitForAssert( {->
|
||||
\ s:assert_match_list(
|
||||
\ AssertMatchist(
|
||||
\ [
|
||||
\ 'Watches: ----',
|
||||
\ 'Expression: t',
|
||||
|
|
@ -408,7 +397,7 @@ function! Test_ExpandWatch()
|
|||
" Step - stays expanded
|
||||
call vimspector#StepOver()
|
||||
call WaitForAssert( {->
|
||||
\ s:assert_match_list(
|
||||
\ AssertMatchist(
|
||||
\ [
|
||||
\ 'Watches: ----',
|
||||
\ 'Expression: t',
|
||||
|
|
@ -460,7 +449,7 @@ function! Test_ExpandWatch()
|
|||
call setpos( '.', [ 0, 3, 1 ] )
|
||||
call feedkeys( "\<CR>", 'xt' )
|
||||
call WaitForAssert( {->
|
||||
\ s:assert_match_list(
|
||||
\ AssertMatchist(
|
||||
\ [
|
||||
\ 'Watches: ----',
|
||||
\ 'Expression: t',
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue