cutedriver-qt-sut-plugin 2.0.0.20210120165900
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.
- checksums.yaml +7 -0
- data/env.rb +24 -0
- data/installer/extconf.rb +62 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin.rb +23 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/behaviours/action.rb +157 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/behaviours/application.rb +312 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/behaviours/attribute.rb +300 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/behaviours/behaviour.rb +214 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/behaviours/configure_behaviour.rb +317 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/behaviours/cute_cpu.rb +145 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/behaviours/cute_gpu.rb +147 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/behaviours/cute_mem.rb +142 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/behaviours/cute_pwr.rb +146 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/behaviours/events.rb +192 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/behaviours/file_transfer.rb +375 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/behaviours/find.rb +82 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/behaviours/fixture.rb +214 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/behaviours/fps.rb +189 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/behaviours/gesture.rb +1039 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/behaviours/infologger.rb +767 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/behaviours/key_press.rb +166 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/behaviours/locale_db.rb +157 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/behaviours/method.rb +112 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/behaviours/multitouch.rb +474 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/behaviours/os.rb +100 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/behaviours/qt_api_method.rb +148 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/behaviours/record.rb +134 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/behaviours/screen_capture.rb +279 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/behaviours/settings.rb +302 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/behaviours/sut.rb +840 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/behaviours/synchronization.rb +257 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/behaviours/treewidgetitemcolumn.rb +117 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/behaviours/type_text.rb +97 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/behaviours/view_item.rb +97 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/behaviours/webkit.rb +272 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/behaviours/widget.rb +877 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/commands/action.rb +30 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/commands/configure_command.rb +38 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/commands/drag.rb +44 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/commands/find_object.rb +67 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/commands/group.rb +44 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/commands/infologger_command.rb +38 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/commands/qt.rb +171 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/commands/tap.rb +54 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/commands/version.rb +34 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/commands/widget.rb +199 -0
- 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 +192 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/controllers/configure_command.rb +53 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/controllers/find_object.rb +48 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/controllers/fixture.rb +65 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/controllers/group.rb +57 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/controllers/infologger_command.rb +53 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/controllers/key_sequence.rb +93 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/controllers/screen_capture.rb +53 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/controllers/tap.rb +62 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/controllers/version.rb +46 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/controllers/widget.rb +98 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/plugin.rb +200 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/sut/adapter.rb +466 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/sut/communication.rb +185 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/sut/controller.rb +69 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/util/find_object_generator.rb +287 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/util/fixture_parameter.rb +77 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/util/message_composer.rb +370 -0
- data/lib/testability-driver-plugins/testability-driver-qt-sut-plugin/util/widget.rb +79 -0
- data/lib/testability-driver-qt-sut-plugin.rb +24 -0
- data/xml/behaviour/qt.xml +845 -0
- data/xml/defaults/sut_qt.xml +9 -0
- data/xml/keymap/qt.xml +321 -0
- data/xml/keymap/win.xml +174 -0
- data/xml/template/qt.xml +141 -0
- metadata +127 -0
@@ -0,0 +1,46 @@
|
|
1
|
+
############################################################################
|
2
|
+
##
|
3
|
+
## Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
4
|
+
## All rights reserved.
|
5
|
+
## Contact: Nokia Corporation (testabilitydriver@nokia.com)
|
6
|
+
##
|
7
|
+
## This file is part of TDriver.
|
8
|
+
##
|
9
|
+
## If you have questions regarding the use of this file, please contact
|
10
|
+
## Nokia at testabilitydriver@nokia.com .
|
11
|
+
##
|
12
|
+
## This library is free software; you can redistribute it and/or
|
13
|
+
## modify it under the terms of the GNU Lesser General Public
|
14
|
+
## License version 2.1 as published by the Free Software Foundation
|
15
|
+
## and appearing in the file LICENSE.LGPL included in the packaging
|
16
|
+
## of this file.
|
17
|
+
##
|
18
|
+
############################################################################
|
19
|
+
|
20
|
+
module MobyController
|
21
|
+
|
22
|
+
module QT
|
23
|
+
|
24
|
+
module VersionCommand
|
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
|
+
# *[ message, return_crc ]
|
35
|
+
[ Comms::MessageGenerator.generate( "<TasCommands service=\"versionService\" />" ), false ]
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
# enable hooking for performance measurement & debug logging
|
40
|
+
TDriver::Hooking.hook_methods( self ) if defined?( TDriver::Hooking )
|
41
|
+
|
42
|
+
end # VersionCommand
|
43
|
+
|
44
|
+
end # QT
|
45
|
+
|
46
|
+
end # MobyController
|
@@ -0,0 +1,98 @@
|
|
1
|
+
############################################################################
|
2
|
+
##
|
3
|
+
## Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
4
|
+
## All rights reserved.
|
5
|
+
## Contact: Nokia Corporation (testabilitydriver@nokia.com)
|
6
|
+
##
|
7
|
+
## This file is part of TDriver.
|
8
|
+
##
|
9
|
+
## If you have questions regarding the use of this file, please contact
|
10
|
+
## Nokia at testabilitydriver@nokia.com .
|
11
|
+
##
|
12
|
+
## This library is free software; you can redistribute it and/or
|
13
|
+
## modify it under the terms of the GNU Lesser General Public
|
14
|
+
## License version 2.1 as published by the Free Software Foundation
|
15
|
+
## and appearing in the file LICENSE.LGPL included in the packaging
|
16
|
+
## of this file.
|
17
|
+
##
|
18
|
+
############################################################################
|
19
|
+
|
20
|
+
module MobyController
|
21
|
+
|
22
|
+
module QT
|
23
|
+
|
24
|
+
module WidgetCommand
|
25
|
+
|
26
|
+
include MobyController::Abstraction
|
27
|
+
|
28
|
+
# generate service request
|
29
|
+
def make_message
|
30
|
+
|
31
|
+
# reduce AST calls
|
32
|
+
_application_id = @_application_id
|
33
|
+
_transitions = @_transitions
|
34
|
+
_service = @_service
|
35
|
+
|
36
|
+
_object_id = @_object_id
|
37
|
+
_object_type = @_object_type
|
38
|
+
_command_value = @_command_value
|
39
|
+
|
40
|
+
# Object#not_nil return self if value not nil
|
41
|
+
_command_params = { :eventType => @_event_type.not_nil('Assert: event_type must be set!'), :name => @_command_name }.merge!( @_command_params || {} )
|
42
|
+
|
43
|
+
builder = Nokogiri::XML::Builder.new{
|
44
|
+
|
45
|
+
TasCommands( :id => _application_id, :transitions => _transitions, :service => _service || 'uiCommand' ) {
|
46
|
+
|
47
|
+
Target( :TasId => _object_id, :type => _object_type ) {
|
48
|
+
|
49
|
+
if _command_value.kind_of?( Array )
|
50
|
+
|
51
|
+
_command_value.each do | command_part | Command( command_part[ :value ], command_part[ :params ] ); end
|
52
|
+
|
53
|
+
elsif _command_value
|
54
|
+
|
55
|
+
Command( _command_value, _command_params )
|
56
|
+
|
57
|
+
else
|
58
|
+
|
59
|
+
Command( _command_params )
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
}
|
64
|
+
}
|
65
|
+
}
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
# Execute the command).
|
70
|
+
# Sends the message to the device using the @sut_adapter (see base class)
|
71
|
+
# == params
|
72
|
+
# == returns
|
73
|
+
# == raises
|
74
|
+
# NotImplementedError: raised if unsupported command type
|
75
|
+
def execute
|
76
|
+
|
77
|
+
message = make_message
|
78
|
+
|
79
|
+
if @sut_adapter.group?
|
80
|
+
|
81
|
+
@sut_adapter.append_command( message.doc.root.children )
|
82
|
+
|
83
|
+
else
|
84
|
+
|
85
|
+
@sut_adapter.send_service_request( Comms::MessageGenerator.generate( message.to_xml ) )
|
86
|
+
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
|
91
|
+
# enable hooking for performance measurement & debug logging
|
92
|
+
TDriver::Hooking.hook_methods( self ) if defined?( TDriver::Hooking )
|
93
|
+
|
94
|
+
end # WidgetCommand
|
95
|
+
|
96
|
+
end # QT
|
97
|
+
|
98
|
+
end # MobyController
|
@@ -0,0 +1,200 @@
|
|
1
|
+
############################################################################
|
2
|
+
##
|
3
|
+
## Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
4
|
+
## All rights reserved.
|
5
|
+
## Contact: Nokia Corporation (testabilitydriver@nokia.com)
|
6
|
+
##
|
7
|
+
## This file is part of TDriver.
|
8
|
+
##
|
9
|
+
## If you have questions regarding the use of this file, please contact
|
10
|
+
## Nokia at testabilitydriver@nokia.com .
|
11
|
+
##
|
12
|
+
## This library is free software; you can redistribute it and/or
|
13
|
+
## modify it under the terms of the GNU Lesser General Public
|
14
|
+
## License version 2.1 as published by the Free Software Foundation
|
15
|
+
## and appearing in the file LICENSE.LGPL included in the packaging
|
16
|
+
## of this file.
|
17
|
+
##
|
18
|
+
############################################################################
|
19
|
+
|
20
|
+
# verify that TDriver is loaded
|
21
|
+
raise RuntimeError, 'This SUT plugin requires Testability Driver and cannot be launched in standalone mode' unless (defined?( MATTI ) || defined?( TDriver ))
|
22
|
+
|
23
|
+
raise RuntimeError, 'Installed Testability Driver is too old; please update to later version' unless defined?( TDriver::TestObjectFactory ) || defined?( TDriver::SUTFactory )
|
24
|
+
|
25
|
+
include TDriverVerify
|
26
|
+
|
27
|
+
require 'socket'
|
28
|
+
require 'zlib'
|
29
|
+
require 'json'
|
30
|
+
|
31
|
+
module MobyPlugin
|
32
|
+
|
33
|
+
module QT
|
34
|
+
|
35
|
+
class SUT < MobyUtil::Plugin
|
36
|
+
|
37
|
+
## plugin configuration, constructor and deconstructor methods
|
38
|
+
def self.plugin_name
|
39
|
+
|
40
|
+
#File.basename( __FILE__, '.rb' ).downcase # => "tdriver-qt-sut-plugin"
|
41
|
+
|
42
|
+
# return plugin name as string
|
43
|
+
"testability-driver-qt-sut-plugin"
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.plugin_type
|
48
|
+
|
49
|
+
# return plugin type as symbol
|
50
|
+
:sut
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.register_plugin
|
55
|
+
|
56
|
+
# load plugin specific implementation or other initialization etc.
|
57
|
+
MobyUtil::FileHelper.load_modules(
|
58
|
+
|
59
|
+
# load utility modules
|
60
|
+
'util/*.rb',
|
61
|
+
|
62
|
+
# sut communication class
|
63
|
+
'sut/communication.rb',
|
64
|
+
|
65
|
+
# sut adapter class
|
66
|
+
'sut/adapter.rb',
|
67
|
+
|
68
|
+
# sut controller
|
69
|
+
'sut/controller.rb',
|
70
|
+
|
71
|
+
# qt behaviour abstraction class
|
72
|
+
'behaviours/behaviour.rb',
|
73
|
+
|
74
|
+
# load behaviour(s)
|
75
|
+
'behaviours/*.rb',
|
76
|
+
|
77
|
+
# load command(s)
|
78
|
+
'commands/*.rb',
|
79
|
+
|
80
|
+
# load command controller(s)
|
81
|
+
'controllers/*.rb'
|
82
|
+
|
83
|
+
)
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
def self.unregister_plugin
|
88
|
+
|
89
|
+
# unregister plugin
|
90
|
+
|
91
|
+
end
|
92
|
+
|
93
|
+
## plugin specific methods
|
94
|
+
|
95
|
+
# return sut type that plugin implements
|
96
|
+
def self.sut_type
|
97
|
+
|
98
|
+
# return sut type as string
|
99
|
+
"QT"
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
# returns SUT object - this method will be called from TDriver::SUTFactory
|
104
|
+
def self.make_sut( sut_id )
|
105
|
+
|
106
|
+
# retrieve sut specific parameters
|
107
|
+
sut_parameters = $parameters[ sut_id ]
|
108
|
+
|
109
|
+
# create sut adapter
|
110
|
+
adapter = MobyController::QT::SutAdapter.new(
|
111
|
+
|
112
|
+
# sut id
|
113
|
+
sut_id,
|
114
|
+
|
115
|
+
# tcp/ip read timeouts, default: 15 (seconds)
|
116
|
+
$parameters[ sut_id ][ :socket_read_timeout, "15" ].to_i,
|
117
|
+
|
118
|
+
# tcp/ip write timeouts, default: 15 (seconds)
|
119
|
+
$parameters[ sut_id ][ :socket_write_timeout, "25" ].to_i,
|
120
|
+
|
121
|
+
# tcp/ip connection timeouts, default: 15 (seconds)
|
122
|
+
$parameters[ sut_id ][ :socket_connect_timeout, "15" ].to_i
|
123
|
+
|
124
|
+
|
125
|
+
)
|
126
|
+
|
127
|
+
# create controller for sut
|
128
|
+
sut_controller = MobyBase::SutController.new(
|
129
|
+
|
130
|
+
# controller id
|
131
|
+
"QT",
|
132
|
+
|
133
|
+
adapter
|
134
|
+
|
135
|
+
)
|
136
|
+
|
137
|
+
# create sut object
|
138
|
+
sut = MobyBase::SUT.new(
|
139
|
+
|
140
|
+
sut_controller,
|
141
|
+
|
142
|
+
# pass test object factory class
|
143
|
+
TDriver::TestObjectFactory,
|
144
|
+
|
145
|
+
# pass sut id
|
146
|
+
sut_id
|
147
|
+
)
|
148
|
+
|
149
|
+
# hook connect method
|
150
|
+
adapter.add_hook( 'before_connect' ){}
|
151
|
+
|
152
|
+
# hook connect method
|
153
|
+
adapter.add_hook( 'after_connect' ){
|
154
|
+
|
155
|
+
begin
|
156
|
+
|
157
|
+
# send service request for agent version number
|
158
|
+
agent_version = sut_controller.__send__( :execute_command, MobyCommand::VersionCommand.new )
|
159
|
+
|
160
|
+
# agent version 1.3 or later supports new smaller xml format
|
161
|
+
if agent_version >= "1.3"
|
162
|
+
|
163
|
+
# use optimized XML format; if adapter is not found we're going through rescue block
|
164
|
+
adapter = TDriver::OptimizedXML::TestObjectAdapter
|
165
|
+
|
166
|
+
else
|
167
|
+
|
168
|
+
# didn't recognize the version number use old TDriver::TestObjectAdapter
|
169
|
+
raise
|
170
|
+
|
171
|
+
end
|
172
|
+
|
173
|
+
rescue
|
174
|
+
|
175
|
+
# in case of any exceptions use TDriver::TestObjectAdapter with old XML format
|
176
|
+
adapter = TDriver::TestObjectAdapter
|
177
|
+
|
178
|
+
end
|
179
|
+
|
180
|
+
#sut_controller.test_object_adapter = adapter
|
181
|
+
sut.instance_variable_set( :@test_object_adapter, adapter )
|
182
|
+
|
183
|
+
}
|
184
|
+
|
185
|
+
# return sut object as result
|
186
|
+
sut
|
187
|
+
|
188
|
+
end
|
189
|
+
|
190
|
+
# enable hooking for performance measurement & debug logging
|
191
|
+
TDriver::Hooking.hook_methods( self ) if defined?( TDriver::Hooking )
|
192
|
+
|
193
|
+
# register plugin
|
194
|
+
TDriver::PluginService.register_plugin( self )
|
195
|
+
|
196
|
+
end # SUT
|
197
|
+
|
198
|
+
end # QT
|
199
|
+
|
200
|
+
end # MobyPlugin
|
@@ -0,0 +1,466 @@
|
|
1
|
+
############################################################################
|
2
|
+
##
|
3
|
+
## Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
4
|
+
## All rights reserved.
|
5
|
+
## Contact: Nokia Corporation (testabilitydriver@nokia.com)
|
6
|
+
##
|
7
|
+
## This file is part of TDriver.
|
8
|
+
##
|
9
|
+
## If you have questions regarding the use of this file, please contact
|
10
|
+
## Nokia at testabilitydriver@nokia.com .
|
11
|
+
##
|
12
|
+
## This library is free software; you can redistribute it and/or
|
13
|
+
## modify it under the terms of the GNU Lesser General Public
|
14
|
+
## License version 2.1 as published by the Free Software Foundation
|
15
|
+
## and appearing in the file LICENSE.LGPL included in the packaging
|
16
|
+
## of this file.
|
17
|
+
##
|
18
|
+
############################################################################
|
19
|
+
|
20
|
+
module MobyController
|
21
|
+
|
22
|
+
module QT
|
23
|
+
|
24
|
+
# Sut adapter that used TCP/IP connections to send and receive data from QT side.
|
25
|
+
class SutAdapter < MobyController::SutAdapter
|
26
|
+
|
27
|
+
attr_reader(
|
28
|
+
:sut_id,
|
29
|
+
:socket_received_bytes,
|
30
|
+
:socket_sent_bytes,
|
31
|
+
:socket_received_packets,
|
32
|
+
:socket_sent_packets
|
33
|
+
)
|
34
|
+
|
35
|
+
attr_accessor(
|
36
|
+
:socket_read_timeout,
|
37
|
+
:socket_write_timeout,
|
38
|
+
:socket_connect_timeout,
|
39
|
+
:deflate_service_request,
|
40
|
+
:deflate_minimum_size,
|
41
|
+
:deflate_compression_level
|
42
|
+
)
|
43
|
+
|
44
|
+
# TODO: better way to set the host and port parameters
|
45
|
+
# Initialize the tcp adapter for communicating with the device.
|
46
|
+
# Communication is done using two tcp channels one form commanding
|
47
|
+
# the device and one for receiving ui state data.
|
48
|
+
# UI state data receivin is done in a seprate thread so it is good
|
49
|
+
# once usage is complete the shutdown_comms is called
|
50
|
+
# == params
|
51
|
+
# sut_id id for the sut so that client details can be fetched from params
|
52
|
+
def initialize( sut_id, receive_timeout = 25, send_timeout = 25, connect_timeout = 25 )
|
53
|
+
|
54
|
+
# reset socket
|
55
|
+
@socket = nil
|
56
|
+
|
57
|
+
# connection state is false by default
|
58
|
+
@connected = false
|
59
|
+
|
60
|
+
# store sut id
|
61
|
+
@sut_id = sut_id
|
62
|
+
|
63
|
+
# reset hooks - no hooks by default
|
64
|
+
@hooks = {}
|
65
|
+
|
66
|
+
# reset sent/received bytes and packets counters
|
67
|
+
@socket_received_bytes = 0
|
68
|
+
@socket_sent_bytes = 0
|
69
|
+
|
70
|
+
@socket_received_packets = 0
|
71
|
+
@socket_sent_packets = 0
|
72
|
+
|
73
|
+
# set timeouts
|
74
|
+
@socket_read_timeout = receive_timeout
|
75
|
+
@socket_write_timeout = send_timeout
|
76
|
+
@socket_connect_timeout = connect_timeout
|
77
|
+
|
78
|
+
# randomized value for initial message packet counter
|
79
|
+
@counter = rand( 1000 )
|
80
|
+
|
81
|
+
# optimization - use local variables for less AST lookups
|
82
|
+
@tcp_socket_select_method = TCPSocket.method( :select )
|
83
|
+
|
84
|
+
@tdriver_checksum_crc16_ibm_method = TDriver::Checksum.method( :crc16_ibm )
|
85
|
+
|
86
|
+
# retrieve sut configuration
|
87
|
+
_sut_parameters = $parameters[ @sut_id ]
|
88
|
+
|
89
|
+
# determine which inflate method to use
|
90
|
+
if _sut_parameters[ :win_native, false ].to_s.true?
|
91
|
+
|
92
|
+
@inflate_method = method( :inflate_windows_native )
|
93
|
+
|
94
|
+
else
|
95
|
+
|
96
|
+
@inflate_method = method( :inflate )
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
# default size 1kb
|
101
|
+
@deflate_minimum_size = _sut_parameters[ :io_deflate_minimum_size_in_bytes, 1024 ].to_i
|
102
|
+
|
103
|
+
# enabled by default - deflate outgoing service request if size > deflate_minimum_size
|
104
|
+
@deflate_service_request = _sut_parameters[ :io_deflate_service_request, true ].true?
|
105
|
+
|
106
|
+
# retrieve default compression level - best compression by default
|
107
|
+
@deflate_compression_level = _sut_parameters[ :io_deflate_compression_level, 9 ].to_i
|
108
|
+
|
109
|
+
end
|
110
|
+
|
111
|
+
# TODO: document me
|
112
|
+
def disconnect
|
113
|
+
|
114
|
+
# disconnect socket only if connected
|
115
|
+
@socket.close if @connected
|
116
|
+
|
117
|
+
@connected = false
|
118
|
+
|
119
|
+
end
|
120
|
+
|
121
|
+
def timeout_capable_socket_opener(ip,port,timeout=nil)
|
122
|
+
addr = Socket.getaddrinfo(ip, nil)
|
123
|
+
sock = Socket.new(Socket.const_get(addr[0][0]), Socket::SOCK_STREAM, 0)
|
124
|
+
if timeout
|
125
|
+
secs = Integer(timeout)
|
126
|
+
usecs = Integer((timeout - secs) * 1_000_000)
|
127
|
+
optval = [secs, usecs].pack("l_2")
|
128
|
+
## actual timeout gets triggered after 2 times of "timeout" value, most likely because my patch applies timeout to read AND write ..
|
129
|
+
sock.setsockopt Socket::SOL_SOCKET, Socket::SO_RCVTIMEO, optval
|
130
|
+
sock.setsockopt Socket::SOL_SOCKET, Socket::SO_SNDTIMEO, optval
|
131
|
+
## also, worth checking if there's actually some Socket::SO_* that applies the timeout to connection forming ..
|
132
|
+
end
|
133
|
+
begin
|
134
|
+
sock.connect_nonblock(Socket.pack_sockaddr_in(port, addr[0][3]))
|
135
|
+
rescue Errno::EINPROGRESS
|
136
|
+
resp = IO.select([sock],nil, nil, timeout.to_i)
|
137
|
+
begin
|
138
|
+
sock.connect_nonblock(Socket.pack_sockaddr_in(port, addr[0][3]))
|
139
|
+
rescue Errno::EISCONN
|
140
|
+
end
|
141
|
+
end
|
142
|
+
sock ## Its also worth noting that if we set RCV AND SNDTIMEOT to some value when checking for established socket,
|
143
|
+
## it might make sense to set the defaults values back again so that only during the connection, timeout is
|
144
|
+
## different..
|
145
|
+
end
|
146
|
+
|
147
|
+
# TODO: document me
|
148
|
+
def connect( id = nil )
|
149
|
+
|
150
|
+
id ||= @sut_id
|
151
|
+
|
152
|
+
sut_parameters = $parameters[ id, {} ]
|
153
|
+
|
154
|
+
begin
|
155
|
+
|
156
|
+
# retrieve ip and verify that value is not empty or nil
|
157
|
+
ip = sut_parameters[ :qttas_server_ip, nil ].not_blank( 'Connection failure; QTTAS server IP not defined in SUT configuration' ).to_s
|
158
|
+
|
159
|
+
# retrieve port and verify that value is not empty or nil
|
160
|
+
port = sut_parameters[ :qttas_server_port, nil ].not_blank( 'Connection failure; QTTAS server port not defined in SUT configuration' ).to_i
|
161
|
+
|
162
|
+
# executes the code block before openning the connection
|
163
|
+
execute_hook( 'before_connect', id, ip, port ) if hooked?( 'before_connect' )
|
164
|
+
|
165
|
+
# open tcp/ip connection
|
166
|
+
# Using ruby TCPSocket this way will utilize the underlying kernel to do the timeout, which by default is too long (In my tests, on ubuntu 10.10, TCPSocket.open
|
167
|
+
# will wait for exactly 380 seconds before throwing exception which is *FAR* too long ..
|
168
|
+
@socket = TCPSocket.open( ip, port )
|
169
|
+
|
170
|
+
|
171
|
+
# open tcp/ip connectio
|
172
|
+
## The block will actually double the time, so halve it. Actual timeout will +1 if it's an odd number
|
173
|
+
# @socket = timeout_capable_socket_opener(ip,port,(@socket_connect_timeout.to_i / 2.0).ceil)
|
174
|
+
|
175
|
+
# set connected status to true
|
176
|
+
@connected = true
|
177
|
+
|
178
|
+
# communication authentication etc can be done here
|
179
|
+
execute_hook( 'after_connect', id, ip, port, @socket ) if hooked?( 'after_connect' )
|
180
|
+
|
181
|
+
rescue
|
182
|
+
|
183
|
+
execute_hook( 'connection_failed', id, ip, port, $! ) if hooked?( 'connection_failed' )
|
184
|
+
#If reporter active report connetion error
|
185
|
+
|
186
|
+
raise IOError, "Connection failure; verify that QTTAS server is up and running at #{ ip }:#{ port }.\n Nested exception: #{ $!.message }"
|
187
|
+
|
188
|
+
end
|
189
|
+
|
190
|
+
true
|
191
|
+
|
192
|
+
end
|
193
|
+
|
194
|
+
# TODO: document me
|
195
|
+
def group?
|
196
|
+
|
197
|
+
@_group
|
198
|
+
|
199
|
+
end
|
200
|
+
|
201
|
+
# Set the document builder for the grouped behaviour message.
|
202
|
+
def set_message_builder( builder )
|
203
|
+
|
204
|
+
@_group = true
|
205
|
+
|
206
|
+
@_builder = builder
|
207
|
+
|
208
|
+
end
|
209
|
+
|
210
|
+
# TODO: document me
|
211
|
+
def append_command( node_list )
|
212
|
+
|
213
|
+
node_list.each { | child |
|
214
|
+
|
215
|
+
@_builder.doc.root.add_child( child )
|
216
|
+
|
217
|
+
}
|
218
|
+
|
219
|
+
end
|
220
|
+
|
221
|
+
# Sends a grouped command message to the server. Sets group to false and nils the builder
|
222
|
+
# to prevent future behviours of being grouped (unless so wanted)
|
223
|
+
# == returns
|
224
|
+
# the amout of commands grouped (and send)
|
225
|
+
def send_grouped_request
|
226
|
+
|
227
|
+
@_group = false
|
228
|
+
|
229
|
+
size = @_builder.doc.root.children.size
|
230
|
+
|
231
|
+
send_service_request(
|
232
|
+
|
233
|
+
Comms::MessageGenerator.generate( @_builder.to_xml )
|
234
|
+
|
235
|
+
)
|
236
|
+
|
237
|
+
@_builder = nil
|
238
|
+
|
239
|
+
size
|
240
|
+
|
241
|
+
end
|
242
|
+
|
243
|
+
def connected?
|
244
|
+
|
245
|
+
@connected
|
246
|
+
|
247
|
+
end
|
248
|
+
|
249
|
+
# Send the message to the qt server
|
250
|
+
# If there is no exception propagated the send to the device was successful
|
251
|
+
# == params
|
252
|
+
# message:: message in qttas protocol format
|
253
|
+
# == returns
|
254
|
+
# the response body
|
255
|
+
def send_service_request( message, return_checksum = false )
|
256
|
+
|
257
|
+
read_message_id = 0
|
258
|
+
|
259
|
+
header = nil
|
260
|
+
|
261
|
+
body = nil
|
262
|
+
|
263
|
+
crc = nil
|
264
|
+
|
265
|
+
connect if !@connected
|
266
|
+
|
267
|
+
# increase message count
|
268
|
+
@counter += 1
|
269
|
+
|
270
|
+
# set request message id
|
271
|
+
message.message_id = @counter
|
272
|
+
|
273
|
+
# deflate message body
|
274
|
+
if @deflate_service_request == true
|
275
|
+
|
276
|
+
# do not deflate messages below 1kb
|
277
|
+
message.deflate( @deflate_compression_level ) unless message.size < @deflate_minimum_size
|
278
|
+
|
279
|
+
end
|
280
|
+
|
281
|
+
# generate binary message to be sent to socket
|
282
|
+
binary_message = message.make_binary_message( @counter )
|
283
|
+
|
284
|
+
# write request message to socket
|
285
|
+
write_socket( binary_message )
|
286
|
+
|
287
|
+
until read_message_id == @counter
|
288
|
+
|
289
|
+
# read message header from socket, unpack string to array
|
290
|
+
# header[ 0 ] = command_flag
|
291
|
+
# header[ 1 ] = body_size
|
292
|
+
# header[ 2 ] = crc
|
293
|
+
# header[ 3 ] = compression_flag
|
294
|
+
# header[ 4 ] = message_id
|
295
|
+
header = read_socket( 12 ).unpack( 'CISCI' )
|
296
|
+
|
297
|
+
# read message body from socket
|
298
|
+
body = read_socket( header[ 1 ] )
|
299
|
+
|
300
|
+
# calculate body crc16 checksum
|
301
|
+
crc = @tdriver_checksum_crc16_ibm_method.call( body )
|
302
|
+
|
303
|
+
# read the message body and compare crc checksum
|
304
|
+
raise IOError, "CRC checksum did not match, response message body is corrupted! (#{ crc } != #{ header[ 2 ] })" if crc != header[ 2 ]
|
305
|
+
|
306
|
+
# validate response message; check that response message id matches the request
|
307
|
+
# if smaller than expected try to read the next message but if bigger raise error
|
308
|
+
read_message_id = header[ 4 ]
|
309
|
+
|
310
|
+
if read_message_id < @counter
|
311
|
+
|
312
|
+
$logger.warning "Response to request did not match: \"#{ header[ 4 ].to_s }\"<\"#{ @counter.to_s }\""
|
313
|
+
|
314
|
+
elsif read_message_id > @counter
|
315
|
+
|
316
|
+
$logger.fatal "Response to request did not match: \"#{ header[ 4 ].to_s }\">\"#{ @counter.to_s }\""
|
317
|
+
|
318
|
+
# save to file?
|
319
|
+
$logger.fatal body
|
320
|
+
|
321
|
+
raise RuntimeError, "Response to request did not match: \"#{ header[ 4 ].to_s }\"!=\"#{ @counter.to_s }\""
|
322
|
+
|
323
|
+
end
|
324
|
+
|
325
|
+
end
|
326
|
+
|
327
|
+
# inflate the message body if compressed
|
328
|
+
body = @inflate_method.call( body ) if ( header[ 3 ] == 2 )
|
329
|
+
|
330
|
+
# raise exception if messages error flag is set
|
331
|
+
# Flag statuses:
|
332
|
+
# 0 -> ERROR_MSG
|
333
|
+
# 1 -> VALID_MSG
|
334
|
+
# 2 -> OK_MESSAGE
|
335
|
+
if header[ 0 ] == 0
|
336
|
+
|
337
|
+
if body =~ /The application with Id \d+ is no longer available/
|
338
|
+
|
339
|
+
raise MobyBase::ApplicationNotAvailableError, body
|
340
|
+
|
341
|
+
else
|
342
|
+
|
343
|
+
raise RuntimeError, body
|
344
|
+
|
345
|
+
end
|
346
|
+
|
347
|
+
end
|
348
|
+
|
349
|
+
# return the body and checksum if required
|
350
|
+
return_checksum ? [ body, body.hash ] : body
|
351
|
+
|
352
|
+
end
|
353
|
+
|
354
|
+
private
|
355
|
+
|
356
|
+
def wait_for_data_available( bytes_count )
|
357
|
+
# verify that there is data available to be read, timeout is not reliable on all platforms, loop instead
|
358
|
+
time = 0
|
359
|
+
readable = nil
|
360
|
+
while (!readable && time < @socket_read_timeout)
|
361
|
+
readable = IO.select([ @socket ], nil, nil, 0.25)
|
362
|
+
time = time + 0.25
|
363
|
+
end
|
364
|
+
|
365
|
+
raise IOError, "Socket reading timeout (#{ @socket_read_timeout.to_s }) exceeded for #{ bytes_count.to_i } bytes" if readable.nil?
|
366
|
+
end
|
367
|
+
|
368
|
+
def wait_for_data_sent( bytes_count )
|
369
|
+
# verify that there is no data in writing buffer, timeout is not reliable on all platforms, loop instead
|
370
|
+
time = 0
|
371
|
+
writable = nil
|
372
|
+
while (!writable && time < @socket_write_timeout)
|
373
|
+
writable = IO.select(nil,[ @socket ], nil, 0.25)
|
374
|
+
time = time + 0.25
|
375
|
+
end
|
376
|
+
|
377
|
+
raise IOError, "Socket writing timeout (#{ @socket_write_timeout.to_s }) exceeded for #{ bytes_count.to_i } bytes" if writable.nil?
|
378
|
+
end
|
379
|
+
|
380
|
+
|
381
|
+
# TODO: document me
|
382
|
+
def read_socket( bytes_count )
|
383
|
+
|
384
|
+
# use local variables, performing less ATS (Abstract Syntax Tree) calls
|
385
|
+
_socket_read_timeout = @socket_read_timeout
|
386
|
+
|
387
|
+
# store time before start receving data
|
388
|
+
start_time = Time.now
|
389
|
+
|
390
|
+
# verify that there is data available to be read
|
391
|
+
wait_for_data_available( bytes_count )
|
392
|
+
|
393
|
+
# read data from socket
|
394
|
+
read_buffer = @socket.read( bytes_count ){
|
395
|
+
|
396
|
+
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
|
397
|
+
|
398
|
+
}
|
399
|
+
|
400
|
+
# useless?
|
401
|
+
raise IOError, "Socket reading error for #{ bytes_count.to_i } bytes - No data retrieved" if read_buffer.nil?
|
402
|
+
|
403
|
+
@socket_received_bytes += read_buffer.size
|
404
|
+
|
405
|
+
@socket_received_packets += 1
|
406
|
+
|
407
|
+
read_buffer
|
408
|
+
|
409
|
+
end
|
410
|
+
|
411
|
+
# TODO: document me
|
412
|
+
def write_socket( data )
|
413
|
+
|
414
|
+
@socket.write( data )
|
415
|
+
|
416
|
+
# verify that there is no data in writing buffer
|
417
|
+
wait_for_data_sent( data.length )
|
418
|
+
|
419
|
+
@socket_sent_bytes += data.size
|
420
|
+
|
421
|
+
@socket_sent_packets += 1
|
422
|
+
|
423
|
+
end
|
424
|
+
|
425
|
+
private
|
426
|
+
|
427
|
+
# inflate to be used in native windows env.
|
428
|
+
def inflate_windows_native( body )
|
429
|
+
|
430
|
+
unless body.empty?
|
431
|
+
|
432
|
+
zstream = Zlib::Inflate.new( -Zlib::MAX_WBITS )
|
433
|
+
body = zstream.inflate( body )
|
434
|
+
zstream.finish
|
435
|
+
zstream.close
|
436
|
+
|
437
|
+
end
|
438
|
+
|
439
|
+
body
|
440
|
+
|
441
|
+
end
|
442
|
+
|
443
|
+
# inflate to be used by default
|
444
|
+
def inflate( body )
|
445
|
+
|
446
|
+
# remove leading 4 bytes
|
447
|
+
tmp = body[ 4 .. -1 ]
|
448
|
+
|
449
|
+
unless tmp.empty?
|
450
|
+
|
451
|
+
tmp = Zlib::Inflate.inflate( tmp )
|
452
|
+
|
453
|
+
end
|
454
|
+
|
455
|
+
tmp
|
456
|
+
|
457
|
+
end
|
458
|
+
|
459
|
+
# enable hooking for performance measurement & debug logging
|
460
|
+
TDriver::Hooking.hook_methods( self ) if defined?( TDriver::Hooking )
|
461
|
+
|
462
|
+
end # SutAdapter
|
463
|
+
|
464
|
+
end # QT
|
465
|
+
|
466
|
+
end # MobyController
|