diff options
author | John Hood <cgull@glup.org> | 2015-10-19 18:37:39 -0400 |
---|---|---|
committer | John Hood <cgull@glup.org> | 2015-12-06 17:42:34 -0500 |
commit | e0f6eb78eff8628067c2fa2827ea7b17ad13e160 (patch) | |
tree | f361652f638f790145216c56fbb5a0bfec2ea51c | |
parent | 66634eb97ccc71f435b486c6f317279698d30051 (diff) |
Improve roundtrip verification tests and debug dump.
Add another round-trip verification. For both original and generated
state, generate a diff from an initial, empty state. Verify that
these two diffs are the same.
-rw-r--r-- | src/network/transportsender.cc | 6 | ||||
-rw-r--r-- | src/statesync/completeterminal.cc | 32 | ||||
-rw-r--r-- | src/statesync/completeterminal.h | 1 | ||||
-rw-r--r-- | src/statesync/user.h | 1 | ||||
-rw-r--r-- | src/terminal/terminalframebuffer.cc | 47 | ||||
-rw-r--r-- | src/terminal/terminalframebuffer.h | 10 |
6 files changed, 73 insertions, 24 deletions
diff --git a/src/network/transportsender.cc b/src/network/transportsender.cc index 5f2ea4d..01f3105 100644 --- a/src/network/transportsender.cc +++ b/src/network/transportsender.cc @@ -176,6 +176,12 @@ void TransportSender<MyState>::tick( void ) if ( current_state.compare( newstate ) ) { fprintf( stderr, "Warning, round-trip Instruction verification failed!\n" ); } + /* Also verify that both the original frame and generated frame have the same initial diff. */ + std::string current_diff( current_state.init_diff() ); + std::string new_diff( newstate.init_diff() ); + if ( current_diff != new_diff ) { + fprintf( stderr, "Warning, target state Instruction verification failed!\n" ); + } } if ( diff.empty() && (now >= next_ack_time) ) { diff --git a/src/statesync/completeterminal.cc b/src/statesync/completeterminal.cc index 07e76bd..d65ff9d 100644 --- a/src/statesync/completeterminal.cc +++ b/src/statesync/completeterminal.cc @@ -94,6 +94,11 @@ string Complete::diff_from( const Complete &existing ) const return output.SerializeAsString(); } +string Complete::init_diff( void ) const +{ + return diff_from( Complete( get_fb().ds.get_width(), get_fb().ds.get_height() )); +} + void Complete::apply_string( string diff ) { HostBuffers::HostMessage input; @@ -174,22 +179,35 @@ int Complete::wait_time( uint64_t now ) const bool Complete::compare( const Complete &other ) const { bool ret = false; - for ( int y = 0; y < terminal.get_fb().ds.get_height(); y++ ) { - for ( int x = 0; x < terminal.get_fb().ds.get_width(); x++ ) { - if ( terminal.get_fb().get_cell( y, x )->compare( *other.terminal.get_fb().get_cell( y, x ) ) ) { + const Framebuffer &fb = terminal.get_fb(); + const Framebuffer &other_fb = other.terminal.get_fb(); + const int height = fb.ds.get_height(); + const int other_height = other_fb.ds.get_height(); + const int width = fb.ds.get_width(); + const int other_width = other_fb.ds.get_width(); + + if ( height != other_height || width != other_width ) { + fprintf( stderr, "Framebuffer size (%dx%d, %dx%d) differs.\n", width, height, other_width, other_height ); + return true; + } + + for ( int y = 0; y < height; y++ ) { + for ( int x = 0; x < width; x++ ) { + if ( fb.get_cell( y, x )->compare( *other_fb.get_cell( y, x ) ) ) { fprintf( stderr, "Cell (%d, %d) differs.\n", y, x ); ret = true; } } } - if ( (terminal.get_fb().ds.get_cursor_row() != other.terminal.get_fb().ds.get_cursor_row()) - || (terminal.get_fb().ds.get_cursor_col() != other.terminal.get_fb().ds.get_cursor_col()) ) { + if ( (fb.ds.get_cursor_row() != other_fb.ds.get_cursor_row()) + || (fb.ds.get_cursor_col() != other_fb.ds.get_cursor_col()) ) { fprintf( stderr, "Cursor mismatch: (%d, %d) vs. (%d, %d).\n", - terminal.get_fb().ds.get_cursor_row(), terminal.get_fb().ds.get_cursor_col(), - other.terminal.get_fb().ds.get_cursor_row(), other.terminal.get_fb().ds.get_cursor_col() ); + fb.ds.get_cursor_row(), fb.ds.get_cursor_col(), + other_fb.ds.get_cursor_row(), other_fb.ds.get_cursor_col() ); ret = true; } + /* XXX should compare other terminal state too (mouse mode, bell. etc.) */ return ret; } diff --git a/src/statesync/completeterminal.h b/src/statesync/completeterminal.h index 13bdf56..cbcaa12 100644 --- a/src/statesync/completeterminal.h +++ b/src/statesync/completeterminal.h @@ -76,6 +76,7 @@ namespace Terminal { /* interface for Network::Transport */ void subtract( const Complete * ) const {} std::string diff_from( const Complete &existing ) const; + std::string init_diff( void ) const; void apply_string( std::string diff ); bool operator==( const Complete &x ) const; diff --git a/src/statesync/user.h b/src/statesync/user.h index dbbaf8f..5c5a295 100644 --- a/src/statesync/user.h +++ b/src/statesync/user.h @@ -89,6 +89,7 @@ namespace Network { /* interface for Network::Transport */ void subtract( const UserStream *prefix ); string diff_from( const UserStream &existing ) const; + string init_diff( void ) const { assert( false ); return string(); }; void apply_string( string diff ); bool operator==( const UserStream &x ) const { return actions == x.actions; } diff --git a/src/terminal/terminalframebuffer.cc b/src/terminal/terminalframebuffer.cc index 0a36744..9f6c4cd 100644 --- a/src/terminal/terminalframebuffer.cc +++ b/src/terminal/terminalframebuffer.cc @@ -643,16 +643,26 @@ void Framebuffer::prefix_window_title( const title_type &s ) window_title.insert(window_title.begin(), s.begin(), s.end() ); } -wint_t Cell::debug_contents( void ) const +std::string Cell::debug_contents( void ) const { if ( contents.empty() ) { - return '_'; + return "'_' ()"; } else { - /* very, very cheesy */ - wchar_t ch[2]; - const std::string chars( contents.begin(), contents.end() ); - mbstowcs(ch, chars.c_str(), 1); - return ch[0]; + std::string chars( 1, '\'' ); + print_grapheme( chars ); + chars.append( "' [" ); + const char *lazycomma = ""; + char buf[64]; + for ( content_type::const_iterator i = contents.begin(); + i < contents.end(); + i++ ) { + + sprintf( buf, "%s0x%02x", lazycomma, static_cast<uint8_t>(*i) ); + chars.append( buf ); + lazycomma = ", "; + } + chars.append( "]" ); + return chars; } } @@ -660,15 +670,28 @@ bool Cell::compare( const Cell &other ) const { bool ret = false; - if ( !contents_match( other ) ) { + std::string grapheme, other_grapheme; + + print_grapheme( grapheme ); + other.print_grapheme( other_grapheme ); + + if ( grapheme != other_grapheme ) { ret = true; - fprintf( stderr, "Contents: %lc (%ld) vs. %lc (%ld)\n", - debug_contents(), contents.size(), - other.debug_contents(), other.contents.size() ); + fprintf( stderr, "Graphemes: '%s' vs. '%s'\n", + grapheme.c_str(), other_grapheme.c_str() ); + } + + if ( !contents_match( other ) ) { + // ret = true; + fprintf( stderr, "Contents: %s (%ld) vs. %s (%ld)\n", + debug_contents().c_str(), + static_cast<long int>( contents.size() ), + other.debug_contents().c_str(), + static_cast<long int>( other.contents.size() ) ); } if ( fallback != other.fallback ) { - ret = true; + // ret = true; fprintf( stderr, "fallback: %d vs. %d\n", fallback, other.fallback ); } diff --git a/src/terminal/terminalframebuffer.h b/src/terminal/terminalframebuffer.h index 3ec29b5..37367c0 100644 --- a/src/terminal/terminalframebuffer.h +++ b/src/terminal/terminalframebuffer.h @@ -109,7 +109,7 @@ namespace Terminal { bool operator!=( const Cell &x ) const { return !operator==( x ); } - wint_t debug_contents( void ) const; + std::string debug_contents( void ) const; bool is_blank( void ) const { @@ -165,18 +165,18 @@ namespace Terminal { void print_grapheme( std::string &output ) const { - if ( cell.contents.empty() ) { - output.append( ' ' ); + if ( contents.empty() ) { + output.append( 1, ' ' ); return; } /* * cells that begin with combining character get combiner * attached to no-break space */ - if ( cell.fallback ) { + if ( fallback ) { output.append( "\xC2\xA0" ); } - output.append( cell.contents ); + output.append( contents ); } }; |