testability-driver-qt-sut-plugin 1.2.1 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/behaviours/application.rb +16 -6
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/behaviours/behaviour.rb +86 -12
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/behaviours/configure_behaviour.rb +1 -1
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/behaviours/events.rb +5 -3
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/behaviours/file_transfer.rb +15 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/behaviours/fixture.rb +110 -76
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/behaviours/gesture.rb +125 -69
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/behaviours/sut.rb +28 -19
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/behaviours/synchronization.rb +143 -24
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/behaviours/widget.rb +25 -10
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/controllers/agent.rb +54 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/controllers/application.rb +1 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/controllers/configure_command.rb +32 -39
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/controllers/find_object.rb +8 -19
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/controllers/fixture.rb +35 -22
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/controllers/group.rb +31 -29
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/controllers/infologger_command.rb +23 -32
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/controllers/key_sequence.rb +44 -61
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/controllers/screen_capture.rb +22 -23
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/controllers/tap.rb +39 -28
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/controllers/version.rb +14 -24
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/controllers/widget.rb +39 -42
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/sut/adapter.rb +93 -120
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/sut/communication.rb +95 -75
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/util/find_object_generator.rb +6 -8
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/util/message_composer.rb +1 -1
- data/xml/behaviour/qt.xml +6 -0
- data/xml/keymap/win.xml +174 -0
- data/xml/template/qt.xml +128 -117
- metadata +60 -75
data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/controllers/key_sequence.rb
CHANGED
@@ -19,92 +19,75 @@
|
|
19
19
|
|
20
20
|
module MobyController
|
21
21
|
|
22
|
-
|
22
|
+
module QT
|
23
23
|
|
24
|
-
|
24
|
+
module KeySequence
|
25
25
|
|
26
|
-
|
26
|
+
include MobyController::Abstraction
|
27
27
|
|
28
|
-
|
28
|
+
# Creates service command message which will be sent to @sut_adapter by execute method
|
29
|
+
# == params
|
30
|
+
# == returns
|
31
|
+
# == raises
|
32
|
+
def make_message
|
29
33
|
|
30
|
-
|
34
|
+
press_types = { :KeyDown => 'KeyPress', :KeyUp => 'KeyRelease' }
|
31
35
|
|
32
|
-
|
33
|
-
# message to the device using the @sut_adapter (see base class)
|
34
|
-
# == params
|
35
|
-
# == returns
|
36
|
-
# == raises
|
37
|
-
# RuntimeError: No service request to be sent due to key sequence is empty
|
38
|
-
def execute
|
36
|
+
sut = @_sut
|
39
37
|
|
40
|
-
|
38
|
+
keymap = $parameters[ sut.id ][ :keymap ]
|
41
39
|
|
42
|
-
|
40
|
+
sequence = @sequence
|
41
|
+
|
42
|
+
message = Nokogiri::XML::Builder.new{
|
43
43
|
|
44
|
-
|
44
|
+
TasCommands( :id => sut.application.id, :transitions => 'true', :service => 'uiCommand' ){
|
45
45
|
|
46
|
-
|
46
|
+
Target( :TasId => 'FOCUSWIDGET', :type => 'Standard' ){
|
47
47
|
|
48
|
-
|
49
|
-
#
|
50
|
-
# Internal message generation method. Makes xml messages from the command_data
|
51
|
-
# == params
|
52
|
-
# none
|
53
|
-
def make_message
|
48
|
+
sequence.each{ | key_press |
|
54
49
|
|
55
|
-
|
50
|
+
key_press[ :value ].tap{ | key |
|
56
51
|
|
57
|
-
|
52
|
+
# raise exception if value type other than Fixnum or Symbol
|
53
|
+
raise ArgumentError, "Wrong argument type #{ key.class } for key (expected: Symbol or Fixnum)" unless [ Fixnum, Symbol ].include?( key.class )
|
58
54
|
|
59
|
-
|
60
|
-
|
61
|
-
message = Nokogiri::XML::Builder.new{
|
62
|
-
|
63
|
-
TasCommands( :id => sut.application.id, :transitions => 'true', :service => 'uiCommand' ){
|
64
|
-
|
65
|
-
Target( :TasId => 'FOCUSWIDGET', :type => 'Standard' ){
|
66
|
-
|
67
|
-
sequence.each{ | key_press |
|
68
|
-
|
69
|
-
key_press[ :value ].tap{ | key |
|
70
|
-
|
71
|
-
# raise exception if value type other than Fixnum or Symbol
|
72
|
-
Kernel::raise ArgumentError.new( "Wrong argument type %s for key (Expected: %s)" % [ key.class, "Symbol/Fixnum" ] ) unless [ Fixnum, Symbol ].include?( key.class )
|
73
|
-
|
74
|
-
# verify that keymap is defined for sut if symbol used.
|
75
|
-
Kernel::raise ArgumentError.new("Symbol #{ key.inspect } cannot be used due to no keymap defined for #{ sut.id } in TDriver configuration file.") if key.kind_of?( Symbol ) && $parameters[ sut.id ][ :keymap ].nil?
|
55
|
+
# verify that keymap is defined for sut if symbol used.
|
56
|
+
raise ArgumentError, "Symbol #{ key.inspect } cannot be used due to no keymap defined for #{ sut.id } in TDriver configuration file." if key.kind_of?( Symbol ) && keymap.nil?
|
76
57
|
|
77
58
|
# fetch keycode from keymap
|
78
|
-
|
59
|
+
key = TDriver::KeymapUtilities.fetch_keycode( key, keymap )
|
79
60
|
|
80
|
-
|
81
|
-
|
61
|
+
# retrieve corresponding scan code (type of string, convert to fixnum) for symbol from keymap if available
|
62
|
+
key = key.hex if key.kind_of?( String )
|
82
63
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
64
|
+
# raise exception if value is other than fixnum
|
65
|
+
raise ArgumentError, "Scan code for #{ key.inspect } not defined in keymap" unless key.kind_of?( Fixnum )
|
66
|
+
|
67
|
+
# determine keypress type
|
68
|
+
press_type = press_types.fetch( key_press[ :type ], 'KeyClick' )
|
88
69
|
|
89
|
-
|
70
|
+
Command( key.to_s, "name" => press_type.to_s, "modifiers" => "0", "delay" => "0")
|
90
71
|
|
91
|
-
|
72
|
+
}
|
92
73
|
|
93
|
-
|
74
|
+
}
|
94
75
|
|
95
|
-
|
96
|
-
|
97
|
-
|
76
|
+
}
|
77
|
+
|
78
|
+
}
|
79
|
+
|
80
|
+
}.to_xml
|
98
81
|
|
99
|
-
|
82
|
+
Comms::MessageGenerator.generate( message )
|
100
83
|
|
101
|
-
|
84
|
+
end
|
102
85
|
|
103
|
-
|
104
|
-
|
86
|
+
# enable hooking for performance measurement & debug logging
|
87
|
+
TDriver::Hooking.hook_methods( self ) if defined?( TDriver::Hooking )
|
105
88
|
|
106
|
-
|
89
|
+
end # KeySequence
|
107
90
|
|
108
|
-
|
91
|
+
end # QT
|
109
92
|
|
110
93
|
end # MobyController
|
data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/controllers/screen_capture.rb
CHANGED
@@ -19,36 +19,35 @@
|
|
19
19
|
|
20
20
|
module MobyController
|
21
21
|
|
22
|
-
|
22
|
+
module QT
|
23
23
|
|
24
|
-
|
24
|
+
module ScreenCapture
|
25
25
|
|
26
|
-
|
27
|
-
@sut_adapter = adapter
|
28
|
-
end
|
26
|
+
include MobyController::Abstraction
|
29
27
|
|
30
|
-
|
28
|
+
# Creates service command message which will be sent to @sut_adapter by execute method
|
29
|
+
# == params
|
30
|
+
# == returns
|
31
|
+
# == raises
|
32
|
+
def make_message
|
31
33
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
)
|
42
|
-
)
|
34
|
+
Comms::MessageGenerator.generate(
|
35
|
+
Nokogiri::XML::Builder.new{
|
36
|
+
TasCommands( :id=> 1, :service => "screenShot" ) {
|
37
|
+
Target( :TasId => 1, :type => "Application" ) {
|
38
|
+
Command( :name => "Screenshot", :format => @context.image_mime_type, :draw => @context.redraw.to_s )
|
39
|
+
}
|
40
|
+
}
|
41
|
+
}.to_xml
|
42
|
+
)
|
43
43
|
|
44
|
-
|
44
|
+
end
|
45
45
|
|
46
|
-
|
47
|
-
|
46
|
+
# enable hooking for performance measurement & debug logging
|
47
|
+
TDriver::Hooking.hook_methods( self ) if defined?( TDriver::Hooking )
|
48
48
|
|
49
|
+
end # ScreenCapture
|
49
50
|
|
50
|
-
|
51
|
-
|
52
|
-
end # QT
|
51
|
+
end # QT
|
53
52
|
|
54
53
|
end # MobyController
|
@@ -19,33 +19,44 @@
|
|
19
19
|
|
20
20
|
module MobyController
|
21
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
|
-
|
22
|
+
module QT
|
23
|
+
|
24
|
+
module Tap
|
25
|
+
|
26
|
+
include MobyController::Abstraction
|
27
|
+
|
28
|
+
# Creates service command message which will be sent to @sut_adapter by execute method
|
29
|
+
# == params
|
30
|
+
# == returns
|
31
|
+
# == raises
|
32
|
+
def make_message
|
33
|
+
|
34
|
+
Comms::MessageGenerator.generate(
|
35
|
+
Nokogiri::XML::Builder.new{
|
36
|
+
TasCommands( :service => "uiCommand" ) {
|
37
|
+
Target( :TasId => 1, :type => "Application" ) {
|
38
|
+
Command(
|
39
|
+
:name => "TapScreen",
|
40
|
+
:x => get_x,
|
41
|
+
:y => get_y,
|
42
|
+
:button => 1,
|
43
|
+
:count => 1,
|
44
|
+
:mouseMove => true,
|
45
|
+
:useCoordinates => true,
|
46
|
+
:time_to_hold => get_hold
|
47
|
+
)
|
48
|
+
}
|
49
|
+
}
|
50
|
+
}.to_xml
|
51
|
+
)
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
# enable hooking for performance measurement & debug logging
|
56
|
+
TDriver::Hooking.hook_methods( self ) if defined?( TDriver::Hooking )
|
57
|
+
|
58
|
+
end # Tap
|
59
|
+
|
60
|
+
end # QT
|
50
61
|
|
51
62
|
end # MobyController
|
@@ -21,36 +21,26 @@ module MobyController
|
|
21
21
|
|
22
22
|
module QT
|
23
23
|
|
24
|
-
|
24
|
+
module VersionCommand
|
25
25
|
|
26
|
-
|
27
|
-
# Sends the message to the device using the @sut_adapter (see base class)
|
28
|
-
# == params
|
29
|
-
# == returns
|
30
|
-
# == raises
|
31
|
-
# NotImplementedError: raised if unsupported command type
|
32
|
-
def execute
|
26
|
+
include MobyController::Abstraction
|
33
27
|
|
34
|
-
|
35
|
-
|
28
|
+
# Creates service command message which will be sent to @sut_adapter by execute method
|
29
|
+
# == params
|
30
|
+
# == returns
|
31
|
+
# == raises
|
32
|
+
def make_message
|
36
33
|
|
37
|
-
|
34
|
+
# *[ message, return_crc ]
|
35
|
+
[ Comms::MessageGenerator.generate( "<TasCommands service=\"versionService\" />" ), false ]
|
38
36
|
|
39
|
-
|
37
|
+
end
|
40
38
|
|
41
|
-
|
39
|
+
# enable hooking for performance measurement & debug logging
|
40
|
+
TDriver::Hooking.hook_methods( self ) if defined?( TDriver::Hooking )
|
42
41
|
|
43
|
-
|
44
|
-
|
45
|
-
@sut_adapter = adapter
|
46
|
-
|
47
|
-
end
|
48
|
-
|
49
|
-
# enable hooking for performance measurement & debug logging
|
50
|
-
TDriver::Hooking.hook_methods( self ) if defined?( TDriver::Hooking )
|
51
|
-
|
52
|
-
end # VersionCommand
|
53
|
-
|
42
|
+
end # VersionCommand
|
43
|
+
|
54
44
|
end # QT
|
55
45
|
|
56
46
|
end # MobyController
|
@@ -17,72 +17,69 @@
|
|
17
17
|
##
|
18
18
|
############################################################################
|
19
19
|
|
20
|
-
|
21
|
-
|
22
20
|
module MobyController
|
23
21
|
|
24
|
-
|
22
|
+
module QT
|
25
23
|
|
26
|
-
|
24
|
+
module WidgetCommand
|
27
25
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
26
|
+
# Execute the command).
|
27
|
+
# Sends the message to the device using the @sut_adapter (see base class)
|
28
|
+
# == params
|
29
|
+
# == returns
|
30
|
+
# == raises
|
31
|
+
# NotImplementedError: raised if unsupported command type
|
32
|
+
def execute
|
35
33
|
|
36
|
-
|
34
|
+
command_params = { :eventType => get_event_type, :name => get_command_name }
|
37
35
|
|
38
|
-
|
36
|
+
command_params.merge!( get_command_params ) if get_command_params
|
39
37
|
|
40
|
-
|
38
|
+
builder = Nokogiri::XML::Builder.new{
|
41
39
|
|
42
|
-
|
40
|
+
TasCommands( :id => get_application_id, :transitions => get_transitions, :service => get_service || 'uiCommand' ) {
|
43
41
|
|
44
|
-
|
42
|
+
Target( :TasId => get_object_id, :type => get_object_type ) {
|
45
43
|
|
46
|
-
|
44
|
+
if get_command_value.kind_of?( Array )
|
47
45
|
|
48
|
-
|
49
|
-
|
50
|
-
|
46
|
+
get_command_value.each do | command_part |
|
47
|
+
Command( command_part[ :value ], command_part[ :params ] )
|
48
|
+
end
|
51
49
|
|
52
50
|
elsif get_command_value
|
53
51
|
|
54
|
-
|
55
|
-
|
56
|
-
else
|
52
|
+
Command( get_command_value, command_params )
|
57
53
|
|
58
|
-
|
54
|
+
else
|
59
55
|
|
60
|
-
|
56
|
+
Command( command_params )
|
61
57
|
|
62
|
-
|
63
|
-
}
|
64
|
-
}
|
58
|
+
end
|
65
59
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
@sut_adapter.send_service_request( Comms::MessageGenerator.generate( builder.to_xml ) )
|
70
|
-
end
|
60
|
+
}
|
61
|
+
}
|
62
|
+
}
|
71
63
|
|
72
|
-
|
64
|
+
if @sut_adapter.group?
|
65
|
+
@sut_adapter.append_command( builder.doc.root.children )
|
66
|
+
else
|
67
|
+
@sut_adapter.send_service_request( Comms::MessageGenerator.generate( builder.to_xml ) )
|
68
|
+
end
|
73
69
|
|
74
|
-
|
70
|
+
end
|
75
71
|
|
76
|
-
|
72
|
+
def set_adapter( adapter )
|
77
73
|
|
78
|
-
|
74
|
+
@sut_adapter = adapter
|
79
75
|
|
80
|
-
|
81
|
-
TDriver::Hooking.hook_methods( self ) if defined?( TDriver::Hooking )
|
76
|
+
end
|
82
77
|
|
78
|
+
# enable hooking for performance measurement & debug logging
|
79
|
+
TDriver::Hooking.hook_methods( self ) if defined?( TDriver::Hooking )
|
83
80
|
|
84
|
-
|
81
|
+
end # WidgetCommand
|
85
82
|
|
86
|
-
|
83
|
+
end # QT
|
87
84
|
|
88
|
-
end #
|
85
|
+
end # MobyController
|
@@ -34,7 +34,9 @@ module MobyController
|
|
34
34
|
|
35
35
|
attr_accessor(
|
36
36
|
:socket_read_timeout,
|
37
|
-
:socket_write_timeout
|
37
|
+
:socket_write_timeout,
|
38
|
+
:deflate_service_request,
|
39
|
+
:defalte_minimum_size
|
38
40
|
)
|
39
41
|
|
40
42
|
# TODO: better way to set the host and port parameters
|
@@ -47,41 +49,70 @@ module MobyController
|
|
47
49
|
# sut_id id for the sut so that client details can be fetched from params
|
48
50
|
def initialize( sut_id, receive_timeout = 25, send_timeout = 25 )
|
49
51
|
|
52
|
+
# reset socket
|
50
53
|
@socket = nil
|
54
|
+
|
55
|
+
# connection state is false by default
|
51
56
|
@connected = false
|
52
57
|
|
58
|
+
# store sut id
|
59
|
+
@sut_id = sut_id
|
60
|
+
|
61
|
+
# reset hooks - no hooks by default
|
62
|
+
@hooks = {}
|
63
|
+
|
64
|
+
# reset sent/received bytes and packets counters
|
53
65
|
@socket_received_bytes = 0
|
54
66
|
@socket_sent_bytes = 0
|
55
67
|
|
56
68
|
@socket_received_packets = 0
|
57
69
|
@socket_sent_packets = 0
|
58
70
|
|
59
|
-
@sut_id = sut_id
|
60
|
-
|
61
71
|
# set timeouts
|
62
72
|
@socket_read_timeout = receive_timeout
|
63
73
|
@socket_write_timeout = send_timeout
|
64
74
|
|
75
|
+
# randomized value for initial message packet counter
|
65
76
|
@counter = rand( 1000 )
|
66
77
|
|
78
|
+
# optimization - use local variables for less AST lookups
|
79
|
+
@tcp_socket_select_method = TCPSocket.method( :select )
|
80
|
+
|
81
|
+
@tdriver_checksum_crc16_ibm_method = TDriver::Checksum.method( :crc16_ibm )
|
82
|
+
|
83
|
+
# retrieve sut configuration
|
84
|
+
_sut_parameters = $parameters[ @sut_id ]
|
85
|
+
|
67
86
|
# determine which inflate method to use
|
68
|
-
if
|
87
|
+
if _sut_parameters[ :win_native, false ].to_s.true?
|
88
|
+
|
89
|
+
@zlib_inflate_method = Zlib::Inflate.new( -Zlib::MAX_WBITS ).method( :inflate )
|
69
90
|
|
70
91
|
@inflate_method = method( :inflate_windows_native )
|
71
92
|
|
72
93
|
else
|
73
94
|
|
95
|
+
@zlib_inflate_method = Zlib::Inflate.method( :inflate )
|
96
|
+
|
74
97
|
@inflate_method = method( :inflate )
|
75
98
|
|
76
99
|
end
|
77
100
|
|
78
|
-
|
101
|
+
# default size 1kb
|
102
|
+
@deflate_minimum_size = _sut_parameters[ :io_deflate_minimum_size_in_bytes, 1024 ].to_i
|
103
|
+
|
104
|
+
# enabled by default - deflate outgoing service request if size > deflate_minimum_size
|
105
|
+
@deflate_service_request = _sut_parameters[ :io_deflate_service_request, true ].true?
|
106
|
+
|
107
|
+
# retrieve default compression level - best compression by default
|
108
|
+
@deflate_compression_level = _sut_parameters[ :io_deflate_compression_level, 9 ].to_i
|
79
109
|
|
80
110
|
end
|
81
111
|
|
82
112
|
# TODO: document me
|
83
113
|
def disconnect
|
84
114
|
|
115
|
+
# disconnect socket only if connected
|
85
116
|
@socket.close if @connected
|
86
117
|
|
87
118
|
@connected = false
|
@@ -144,11 +175,11 @@ module MobyController
|
|
144
175
|
end
|
145
176
|
|
146
177
|
# TODO: document me
|
147
|
-
def append_command(node_list)
|
178
|
+
def append_command( node_list )
|
148
179
|
|
149
|
-
node_list.each { |
|
180
|
+
node_list.each { | child |
|
150
181
|
|
151
|
-
@_builder.doc.root.add_child(
|
182
|
+
@_builder.doc.root.add_child( child )
|
152
183
|
|
153
184
|
}
|
154
185
|
|
@@ -188,7 +219,15 @@ module MobyController
|
|
188
219
|
# message:: message in qttas protocol format
|
189
220
|
# == returns
|
190
221
|
# the response body
|
191
|
-
def send_service_request( message,
|
222
|
+
def send_service_request( message, return_checksum = false )
|
223
|
+
|
224
|
+
read_message_id = 0
|
225
|
+
|
226
|
+
header = nil
|
227
|
+
|
228
|
+
body = nil
|
229
|
+
|
230
|
+
crc = nil
|
192
231
|
|
193
232
|
connect if !@connected
|
194
233
|
|
@@ -198,35 +237,35 @@ module MobyController
|
|
198
237
|
# set request message id
|
199
238
|
message.message_id = @counter
|
200
239
|
|
240
|
+
# deflate message body
|
241
|
+
if @deflate_service_request == true
|
242
|
+
|
243
|
+
# do not deflate messages below 1kb
|
244
|
+
message.deflate( @deflate_compression_level ) unless message.size < @deflate_minimum_size
|
245
|
+
|
246
|
+
end
|
247
|
+
|
201
248
|
# generate binary message to be sent to socket
|
202
249
|
binary_message = message.make_binary_message( @counter )
|
203
250
|
|
204
251
|
# write request message to socket
|
205
252
|
write_socket( binary_message )
|
206
253
|
|
207
|
-
# read response to determine was the message handled properly and parse the header
|
208
|
-
# header[ 0 ] = command_flag
|
209
|
-
# header[ 1 ] = body_size
|
210
|
-
# header[ 2 ] = crc
|
211
|
-
# header[ 3 ] = compression_flag
|
212
|
-
# header[ 4 ] = message_id
|
213
|
-
|
214
|
-
read_message_id = 0
|
215
|
-
|
216
|
-
header = nil
|
217
|
-
|
218
|
-
body = nil
|
219
|
-
|
220
254
|
until read_message_id == @counter
|
221
255
|
|
222
256
|
# read message header from socket, unpack string to array
|
257
|
+
# header[ 0 ] = command_flag
|
258
|
+
# header[ 1 ] = body_size
|
259
|
+
# header[ 2 ] = crc
|
260
|
+
# header[ 3 ] = compression_flag
|
261
|
+
# header[ 4 ] = message_id
|
223
262
|
header = read_socket( 12 ).unpack( 'CISCI' )
|
224
263
|
|
225
264
|
# read message body from socket
|
226
265
|
body = read_socket( header[ 1 ] )
|
227
266
|
|
228
267
|
# calculate body crc16 checksum
|
229
|
-
crc =
|
268
|
+
crc = @tdriver_checksum_crc16_ibm_method.call( body )
|
230
269
|
|
231
270
|
# read the message body and compare crc checksum
|
232
271
|
raise IOError, "CRC checksum did not match, response message body is corrupted! (#{ crc } != #{ header[ 2 ] })" if crc != header[ 2 ]
|
@@ -274,26 +313,44 @@ module MobyController
|
|
274
313
|
|
275
314
|
end
|
276
315
|
|
277
|
-
# return the body
|
278
|
-
|
316
|
+
# return the body and checksum if required
|
317
|
+
return_checksum ? [ body, body.hash ] : body
|
279
318
|
|
280
319
|
end
|
281
320
|
|
282
321
|
private
|
283
322
|
|
323
|
+
# TODO: document me
|
324
|
+
def wait_for_data_available( bytes_count )
|
325
|
+
|
326
|
+
# verify that there is data available to be read
|
327
|
+
raise IOError, "Socket reading timeout (#{ @socket_read_timeout.to_i }) exceeded for #{ bytes_count.to_i } bytes" if @tcp_socket_select_method.call( [ @socket ], nil, nil, @socket_read_timeout ).nil?
|
328
|
+
|
329
|
+
end
|
330
|
+
|
331
|
+
def wait_for_data_sent( bytes_count )
|
332
|
+
|
333
|
+
# verify that there is no data in writing buffer
|
334
|
+
raise IOError, "Socket writing timeout (#{ @socket_write_timeout.to_i }) exceeded for #{ bytes_count.to_i } bytes" if @tcp_socket_select_method.call( nil, [ @socket ], nil, @socket_write_timeout ).nil?
|
335
|
+
|
336
|
+
end
|
337
|
+
|
284
338
|
# TODO: document me
|
285
339
|
def read_socket( bytes_count )
|
286
340
|
|
341
|
+
# use local variables, performing less ATS (Abstract Syntax Tree) calls
|
342
|
+
_socket_read_timeout = @socket_read_timeout
|
343
|
+
|
287
344
|
# store time before start receving data
|
288
345
|
start_time = Time.now
|
289
346
|
|
290
347
|
# verify that there is data available to be read
|
291
|
-
|
348
|
+
wait_for_data_available( bytes_count )
|
292
349
|
|
293
350
|
# read data from socket
|
294
351
|
read_buffer = @socket.read( bytes_count ){
|
295
352
|
|
296
|
-
raise IOError, "Socket reading timeout (#{
|
353
|
+
raise IOError, "Socket reading timeout (#{ _socket_read_timeout.to_i }) exceeded for #{ bytes_count.to_i } bytes" if ( Time.now - start_time ) > _socket_read_timeout
|
297
354
|
|
298
355
|
}
|
299
356
|
|
@@ -305,106 +362,20 @@ module MobyController
|
|
305
362
|
@socket_received_packets += 1
|
306
363
|
|
307
364
|
read_buffer
|
308
|
-
|
309
|
-
=begin
|
310
|
-
begin
|
311
|
-
|
312
|
-
read_buffer = @socket.read_nonblock( bytes_count )
|
313
|
-
|
314
|
-
rescue Errno::EWOULDBLOCK
|
315
|
-
|
316
|
-
if TCPSocket.select( [ @socket ], nil, nil, @socket_read_timeout )
|
317
|
-
|
318
|
-
read_buffer = @socket.read_nonblock( bytes_count )
|
319
|
-
|
320
|
-
else
|
321
|
-
|
322
|
-
Kernel::raise IOError.new( "Socket reading timeout (%i) exceeded for %i bytes" % [ @socket_read_timeout, bytes_count ] )
|
323
|
-
|
324
|
-
end
|
325
|
-
|
326
|
-
end
|
327
|
-
|
328
|
-
read_buffer
|
329
|
-
=end
|
330
|
-
|
331
|
-
=begin
|
332
|
-
#Kernel::raise ThreadError, "Timeout within critical session" if Thread.critical
|
333
|
-
|
334
|
-
begin
|
335
|
-
|
336
|
-
# store current thread
|
337
|
-
main_thread = Thread.current
|
338
|
-
|
339
|
-
# create timeout thread
|
340
|
-
timeout_thread = Thread.new( @socket_read_timeout ){ | timeout, bytes_count |
|
341
|
-
|
342
|
-
# sleep the timeout
|
343
|
-
sleep time
|
344
|
-
|
345
|
-
# raise exception if timeout exceeds
|
346
|
-
main_thread.raise IOError.new( "Socket reading timeout (%i) exceeded for %i bytes" % [ timeout, bytes_count ] ) if main_thread.alive?
|
347
|
-
|
348
|
-
}
|
349
|
-
|
350
|
-
# read data from socket
|
351
|
-
@socket.read( bytes_count )
|
352
|
-
|
353
|
-
ensure
|
354
|
-
|
355
|
-
# ensure that timeout thread is terminated
|
356
|
-
timeout_thread.kill if timeout_thread && timeout_thread.alive?
|
357
|
-
|
358
|
-
@socket_received_bytes += bytes_count
|
359
|
-
|
360
|
-
end
|
361
|
-
=end
|
362
365
|
|
363
366
|
end
|
364
367
|
|
365
368
|
# TODO: document me
|
366
369
|
def write_socket( data )
|
367
370
|
|
368
|
-
@socket_sent_bytes += data.size
|
369
|
-
|
370
|
-
@socket_sent_packets += 1
|
371
|
-
|
372
371
|
@socket.write( data )
|
373
372
|
|
374
373
|
# verify that there is no data in writing buffer
|
375
|
-
|
374
|
+
wait_for_data_sent( data.length )
|
376
375
|
|
377
|
-
|
378
|
-
|
379
|
-
begin
|
380
|
-
|
381
|
-
# store current thread
|
382
|
-
main_thread = Thread.current
|
383
|
-
|
384
|
-
# create timeout thread
|
385
|
-
timeout_thread = Thread.new( @socket_write_timeout ){ | timeout, data.size |
|
386
|
-
|
387
|
-
# sleep the timeout
|
388
|
-
sleep time
|
389
|
-
|
390
|
-
# raise exception if timeout exceeds
|
391
|
-
main_thread.raise IOError.new( "Socket writing timeout (%i) exceeded for %i bytes" % [ timeout, bytes_count ] ) if main_thread.alive?
|
392
|
-
|
393
|
-
}
|
394
|
-
|
395
|
-
# read data from socket
|
396
|
-
@socket.write( data )
|
397
|
-
|
398
|
-
ensure
|
399
|
-
|
400
|
-
# ensure that timeout thread is terminated
|
401
|
-
timeout_thread.kill if timeout_thread and timeout_thread.alive?
|
402
|
-
|
403
|
-
@socket_sent_bytes += data.size
|
404
|
-
|
405
|
-
end
|
376
|
+
@socket_sent_bytes += data.size
|
406
377
|
|
407
|
-
|
378
|
+
@socket_sent_packets += 1
|
408
379
|
|
409
380
|
end
|
410
381
|
|
@@ -413,13 +384,15 @@ module MobyController
|
|
413
384
|
# inflate to be used in native windows env.
|
414
385
|
def inflate_windows_native( body )
|
415
386
|
|
416
|
-
|
387
|
+
tmp = body
|
417
388
|
|
418
|
-
|
389
|
+
unless tmp.empty?
|
390
|
+
|
391
|
+
@zlib_inflate_method.call( tmp )
|
419
392
|
|
420
393
|
else
|
421
394
|
|
422
|
-
|
395
|
+
tmp
|
423
396
|
|
424
397
|
end
|
425
398
|
|
@@ -433,7 +406,7 @@ module MobyController
|
|
433
406
|
|
434
407
|
unless tmp.empty?
|
435
408
|
|
436
|
-
|
409
|
+
@zlib_inflate_method.call( tmp )
|
437
410
|
|
438
411
|
else
|
439
412
|
|