saucelabs-adapter 0.8.4 → 0.8.5
Sign up to get free protection for your applications and to get access to all the features.
data/README.markdown
CHANGED
@@ -123,6 +123,12 @@ Resources
|
|
123
123
|
|
124
124
|
NOTABLE CHANGES
|
125
125
|
===============
|
126
|
+
|
127
|
+
0.8.5
|
128
|
+
-----
|
129
|
+
- Allow application_port to be a range of form: XXXX-YYYY, e.g. 4000-5000. The SaucelabsAdapter will find an unused port in that range.
|
130
|
+
- Allow specification of the test framework in use. If test_framework == :webrat and tunnel_mode == :sshtunnel, the generated unused port will also be written to tunnel_to_localhost_port
|
131
|
+
|
126
132
|
0.8
|
127
133
|
---
|
128
134
|
- Added new tunnel type SshTunnel (a generic reverse SSH tunnel), see selenium.yml for now to configure.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.8.
|
1
|
+
0.8.5
|
@@ -21,6 +21,7 @@ local_jsunit:
|
|
21
21
|
# "googlechrome" ""
|
22
22
|
# "Linux" "firefox" "3."
|
23
23
|
saucelabs: &saucelabs
|
24
|
+
test_framework: webrat
|
24
25
|
# URL of Selenium RC server:
|
25
26
|
selenium_server_address: "saucelabs.com"
|
26
27
|
selenium_server_port: "4444"
|
@@ -43,7 +44,7 @@ saucelabs: &saucelabs
|
|
43
44
|
#
|
44
45
|
# tunnel_method: :sshtunnel
|
45
46
|
# application_address: proxy.mycompany.com
|
46
|
-
# application_port: 12345
|
47
|
+
# application_port: 12345 # or can be a range XXXX-YYYY
|
47
48
|
# tunnel_to_localhost_port: 4000 # Warning: application_port and tunnel_to_localhost_port must be identical if you are using Webrat
|
48
49
|
# tunnel_username: fred
|
49
50
|
# tunnel_keyfile: "/path/to/keyfile" # or tunnel_password: "password"
|
@@ -15,7 +15,8 @@ module SaucelabsAdapter
|
|
15
15
|
@configuration[attribute.to_s] = value
|
16
16
|
end
|
17
17
|
|
18
|
-
[ :
|
18
|
+
[ :test_framework,
|
19
|
+
:selenium_server_address, :selenium_server_port,
|
19
20
|
:application_address, :application_port,
|
20
21
|
:saucelabs_username, :saucelabs_access_key,
|
21
22
|
:saucelabs_browser_os, :saucelabs_browser, :saucelabs_browser_version,
|
@@ -106,6 +107,11 @@ module SaucelabsAdapter
|
|
106
107
|
def build_configuration(configuration_name)
|
107
108
|
@configuration = @@selenium_configs[configuration_name]
|
108
109
|
raise "[saucelabs-adapter] stanza '#{configuration_name}' not found in #{@selenium_yml}" unless @configuration
|
110
|
+
# If the Saucelabs-Adapter picked a port out of a range during this session, use it.
|
111
|
+
if ENV['SAUCELABS_ADAPTER_APPLICATION_PORT']
|
112
|
+
@configuration['application_port'] = ENV['SAUCELABS_ADAPTER_APPLICATION_PORT'].to_i
|
113
|
+
debug("Using application port #{application_port} from environment variable SAUCELABS_ADAPTER_APPLICATION_PORT", 2)
|
114
|
+
end
|
109
115
|
check_configuration(configuration_name)
|
110
116
|
end
|
111
117
|
|
@@ -129,6 +135,14 @@ module SaucelabsAdapter
|
|
129
135
|
errors << require_attributes([:tunnel_password, :tunnel_keyfile],
|
130
136
|
:when => "when tunnel_method is :sshtunnel",
|
131
137
|
:any_or_all => :any)
|
138
|
+
if application_address && application_port.is_a?(String) && application_port =~ /(\d+)-(\d+)/
|
139
|
+
# We have been given a port range. Find an unused one.
|
140
|
+
port = find_unused_port(application_address, ($1.to_i)..($2.to_i))
|
141
|
+
@configuration['application_port'] = port
|
142
|
+
@configuration['tunnel_to_localhost_port'] = port if test_framework == :webrat
|
143
|
+
# Pass this calculated value on to any other instances of SeleniumConfig created
|
144
|
+
ENV['SAUCELABS_ADAPTER_APPLICATION_PORT'] = port.to_s
|
145
|
+
end
|
132
146
|
if tunnel_keyfile && !File.exist?(File.expand_path(tunnel_keyfile))
|
133
147
|
errors << "tunnel_keyfile '#{tunnel_keyfile}' does not exist"
|
134
148
|
end
|
@@ -10,18 +10,25 @@ module SaucelabsAdapter
|
|
10
10
|
say "Setting up SSH reverse tunnel from #{@se_config.application_address}:#{@se_config.application_port} to localhost:#{@se_config.tunnel_to_localhost_port}"
|
11
11
|
options = @se_config.tunnel_password ? { :password => @se_config.tunnel_password } : { :keys => @se_config.tunnel_keyfile }
|
12
12
|
@gateway = Net::SSH::Gateway.new(@se_config.application_address, @se_config.tunnel_username, options)
|
13
|
-
@
|
13
|
+
@host_and_port = @gateway.open_remote(@se_config.tunnel_to_localhost_port.to_i, "127.0.0.1", @se_config.application_port.to_i, "0.0.0.0")
|
14
14
|
end
|
15
15
|
|
16
16
|
def shutdown
|
17
|
-
|
18
|
-
#
|
19
|
-
#
|
20
|
-
#
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
17
|
+
# We have experienced problems with the tunnel shutdown hanging.
|
18
|
+
# Previously the method was a no-op and we just exited the process which had the effect of closing the tunnel.
|
19
|
+
# However we are now running multiple tunnels in one process (sequentially), so we need to actually do a shutdown.
|
20
|
+
# So let's add a timeout.
|
21
|
+
if @gateway
|
22
|
+
begin
|
23
|
+
Timeout::timeout(15) do
|
24
|
+
say "Shutting down ssh reverse tunnel"
|
25
|
+
@gateway.close_remote(*@host_and_port) if @host_and_port
|
26
|
+
@gateway.shutdown! if @gateway
|
27
|
+
end
|
28
|
+
rescue Timeout::Error
|
29
|
+
say "tunnel shutdown timed out"
|
30
|
+
end
|
31
|
+
end
|
25
32
|
end
|
26
33
|
end
|
27
34
|
end
|
@@ -19,5 +19,20 @@ module SaucelabsAdapter
|
|
19
19
|
def raise_with_message(message)
|
20
20
|
raise "#{diagnostics_prefix} #{message}"
|
21
21
|
end
|
22
|
+
|
23
|
+
def find_unused_port(hostname, range = (3000..5000))
|
24
|
+
debug 'searching for unused port', 2
|
25
|
+
range.each do |port|
|
26
|
+
debug "trying #{hostname}:#{port}", 2
|
27
|
+
begin
|
28
|
+
socket = TCPSocket.new(hostname, port)
|
29
|
+
rescue Errno::ECONNREFUSED
|
30
|
+
debug "it's good, returning #{port}", 2
|
31
|
+
return port
|
32
|
+
ensure
|
33
|
+
socket.close if socket
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
22
37
|
end
|
23
38
|
end
|