testability-driver-qt-sut-plugin 1.2.1 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|