sauce 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.0
1
+ 0.4.0
data/lib/job.rb CHANGED
@@ -7,21 +7,19 @@ module Sauce
7
7
  # Interact with a Sauce Labs selenium jobs as if it were a ruby object
8
8
  class Job
9
9
 
10
- #{"BrowserVersion": "3.", "Name": "prsel_./spec/integration/people_a_1_spec.rb", "_rev": "5-228269313", "CreationTime": 1266698090, "AssignmentTime": 1266698097, "Server": "10.212.146.145:4443", "AssignedTo": "f663372ba04444ce8cb3e6f61503f304", "ChefStartTime": 1266698101, "EndTime": 1266698139, "Type": "job", "Interactive": "true", "Status": "complete", "SeleniumServerLogUploadRequest": {"bucket": "sauce-userdata", "key": "sgrove/6337fe576deba0ba278dc1b5dfceac5f/selenium-server.log"}, "Tags": [], "ResultId": "6337fe576deba0ba278dc1b5dfceac5f", "AttachmentRequests": {}, "ModificationTime": 1266698139, "Browser": "firefox", "StartTime": 1266698101, "Owner": "sgrove", "_id": "01fc48caba6d15b46fad79e1b0562bbe", "OS": "Linux", "VideoUploadRequest": {"bucket": "sauce-userdata", "key": "sgrove/6337fe576deba0ba278dc1b5dfceac5f/video.flv"}}
10
+ class CannotDeleteJobError < StandardError; end #:nodoc
11
11
 
12
- attr_accessor :owner, :id, :name, :_rev, :server, :assigned_to, :sauce_type, :interactive, :status,:tags, :result_id
13
- attr_accessor :selenium_server_log_upload_request, :attachment_requests, :videoupload_request
14
- attr_accessor :creation_time, :assignment_time, :chef_start_time, :end_time, :modification_time, :start_time
15
- attr_accessor :os, :browser, :browser_version
12
+ attr_accessor :id, :owner, :status, :error
13
+ attr_accessor :name, :browser, :browser_version, :os
14
+ attr_accessor :creation_time, :start_time, :end_time
15
+ attr_accessor :public, :video_url, :log_url, :tags
16
16
 
17
- # TODO: Buckets for logs and videos
18
-
19
17
  # Get the class @@client.
20
18
  # TODO: Consider metaprogramming this away
21
19
  def self.client
22
20
  @@client
23
21
  end
24
-
22
+
25
23
  # Set the class @@client.
26
24
  # TODO: Consider metaprogramming this away
27
25
  def self.client=(client)
@@ -48,42 +46,28 @@ module Sauce
48
46
  self.all.last
49
47
  end
50
48
 
51
- def self.all
52
- =begin
53
- responses = JSON.parse @@client["jobs/recent"].get
49
+ # Misnomer: Gets the most recent 100 jobs
50
+ # TODO: Allow/automate paging
51
+ def self.all(options={})
52
+ responses = JSON.parse @@client["jobs/full"].get
54
53
  return responses.collect{|response| Sauce::Job.new(response)}
55
- =end
56
- return self.complete_jobs + self.in_progress_jobs
57
54
  end
58
55
 
59
56
  def self.destroy
60
57
  self.all.each { |tunnel| tunnel.destroy }
61
58
  end
62
59
 
63
- def self.find id
60
+ def self.find(options={})
61
+ if options.class == String
62
+ id = options
63
+ elsif options.class == Hash
64
+ id = options[:id]
65
+ end
66
+
64
67
  #puts "GET-URL: #{@@client.url}jobs/#{id}"
65
68
  Sauce::Job.new JSON.parse(@@client["jobs/#{id}"].get)
66
69
  end
67
70
 
68
- def self.complete_jobs
69
- responses = JSON.parse @@client["complete-jobs"].get
70
- start = Time.now
71
- jobs = responses["jobs"].collect{|response| Sauce::Job.find(response["id"])}
72
- lapsed = Time.now - start
73
- puts "Took #{lapsed} seconds"
74
- return jobs
75
- end
76
-
77
- def self.in_progress_jobs
78
- responses = JSON.parse @@client["in-progress-jobs"].get
79
- return [] if responses == []
80
- start = Time.now
81
- jobs = responses["jobs"].collect{|response| Sauce::Job.find(response["id"])}
82
- lapsed = Time.now - start
83
- puts "Took #{lapsed} seconds"
84
- return jobs
85
- end
86
-
87
71
  # Creates an instance representing a job.
88
72
  def initialize(options)
89
73
  build!(options)
@@ -92,42 +76,64 @@ module Sauce
92
76
  # Retrieves the latest information on this job from the Sauce Labs' server
93
77
  def refresh!
94
78
  response = JSON.parse @@client["jobs/#{@id}"].get
95
- puts "\tjob refresh with: #{response.inspect}"
79
+ #puts "\tjob refresh with: #{response}"
96
80
  build! response
97
81
  self
98
82
  end
99
83
 
100
- protected
84
+ # Save/update the current information for the job
85
+ def save
86
+ response = JSON.parse(@@client["jobs/#{@id}"]. self.to_json, :content_type => :json, :accept => :json)
87
+ end
88
+
89
+ def self.to_json(options={})
90
+ json = {
91
+ :id => @id,
92
+ :owner => @owner,
93
+ :status => @status,
94
+ :error => @error,
95
+ :name => @name,
96
+ :browser => @browser,
97
+ :browser_version => @browser_version,
98
+ :os => @os,
99
+ :creation_time => @creation_time,
100
+ :start_time => @start_time,
101
+ :end_time => @end_time,
102
+ :video_url => @video_url,
103
+ :log_url => @log_url,
104
+ :public => @public,
105
+ :tags => @tags
106
+ }
107
+
108
+ options[:except].each { |key| json.delete(key) } if options[:except]
109
+ json = json.select { |key,value| options[:only].include? key } if options[:only]
110
+
111
+ return json
112
+ end
113
+
114
+ def delete
115
+ raise CannonDeleteJobError("Cannot delete jobs via Sauce Labs' REST API currently")
116
+ end
117
+
118
+ protected
101
119
 
102
120
  # Sets all internal variables from a hash
103
121
  def build!(options)
104
- #puts "\tBuild with #{options.inspect}"
105
-
106
- @owner = options["Owner"]
107
- @id = options["_id"]
108
- @id = options["id"] if @id.nil? or @id.empty?
109
- @name = options["Name"]
110
- @_rev = options["_rev"]
111
- @server = options["Server"]
112
- @assigned_to = options["AssignedTo"]
113
-
114
- @sauce_type = options["Type"]
115
- @interactive = options["Interactive"]
116
- @status = options["Status"]
117
- @tags = options["Tags"]
118
- @result_id = options["ResultId"]
119
-
120
- @os = options["OS"]
121
- @browser = options["Browser"]
122
- @browser_version = options["BrowserVersion"]
123
-
124
- # TODO: Should this be created_at and updated_at? Probably.
125
- @creation_time = options["CreationTime"]
126
- @assignment_time = options["AssignmentTime"]
127
- @chef_start_time = options["ChefStartTime"]
128
- @end_time = options["EndTime"]
129
- @modification_time = options["ModificationTime"]
130
- @start_time = options["StartTime"]
122
+ @id = options["id"]
123
+ @owner = options["owner"]
124
+ @status = options["status"]
125
+ @error = options["error"]
126
+ @name = options["name"]
127
+ @browser = options["browser"]
128
+ @browser_version = options["browser_version"]
129
+ @os = options["os"]
130
+ @creation_time = options["creation_time"].to_i
131
+ @start_time = options["start_time"].to_i
132
+ @end_time = options["end_time"].to_i
133
+ @video_url = options["video_url"]
134
+ @log_url = options["log_url"]
135
+ @public = options["public"]
136
+ @tags = options["tags"]
131
137
 
132
138
  raise NoIDError if @id.nil? or @id.empty?
133
139
  end
data/lib/rest.rb CHANGED
@@ -4,8 +4,8 @@ require 'json'
4
4
  module Sauce
5
5
  # The module that brokers most communication with Sauce Labs' REST API
6
6
  class Client
7
- class BadAccessError < StandardError; end #nodoc
8
- class MisconfiguredError < StandardError; end #nodoc
7
+ class BadAccessError < StandardError; end #:nodoc
8
+ class MisconfiguredError < StandardError; end #:nodoc
9
9
 
10
10
  attr_accessor :username, :access_key, :client, :ip, :api_url
11
11
  attr_accessor :tunnels, :jobs
@@ -16,20 +16,23 @@ module Sauce
16
16
  @ip = options[:ip]
17
17
 
18
18
  raise MisconfiguredError if @username.nil? or @access_key.nil?
19
- @api_url = "https://#{@username}:#{@access_key}@saucelabs.com/rest/#{@username}/"
19
+ @api_url = "https://#{@username}:#{@access_key}@saucelabs.com/api/v1/#{@username}/"
20
20
  @client = RestClient::Resource.new @api_url
21
21
 
22
22
  @tunnels = Sauce::Tunnel
23
23
  @tunnels.client = @client
24
- @tunnels.account = {:username => @username,
24
+ @tunnels.account = {
25
+ :username => @username,
25
26
  :access_key => @access_key,
26
27
  :ip => @ip}
27
28
 
28
29
  @jobs = Sauce::Job
29
30
  @jobs.client = @client
30
- @jobs.account = {:username => @username,
31
+ @jobs.account = {
32
+ :username => @username,
31
33
  :access_key => @access_key,
32
- :ip => @ip}
34
+ :ip => @ip
35
+ }
33
36
  end
34
37
  end
35
38
  end
data/test/test_jobs.rb CHANGED
@@ -2,7 +2,7 @@ require 'helper'
2
2
  require 'json'
3
3
 
4
4
  class TestSauce < Test::Unit::TestCase
5
- context "A jobs instance" do
5
+ context "A V1 jobs instance" do
6
6
  setup do
7
7
  # Create this file and put in your details to run the tests
8
8
  account = YAML.load_file "live_account.yml"
@@ -11,44 +11,124 @@ class TestSauce < Test::Unit::TestCase
11
11
  @ip = account["ip"]
12
12
  @client = Sauce::Client.new(:username => @username,
13
13
  :access_key => @access_key)
14
+
15
+ @example_data = YAML.load_file('example_data.yml')
14
16
  end
15
17
 
16
18
  should "initialize with passed variables" do
17
- job_json = JSON.parse '{"BrowserVersion": "3.", "Name": "example_job/name.rb", "_rev": "5-228269313", "CreationTime": 1266698090, "AssignmentTime": 1266698097, "Server": "192.168.0.1:4443", "AssignedTo": "f663372ba04444ce8cb3e6f61503f304", "ChefStartTime": 1266698101, "EndTime": 1266698139, "Type": "job", "Interactive": "true", "Status": "complete", "SeleniumServerLogUploadRequest": {"bucket": "sauce-userdata", "key": "sgrove/6337fe576deba0ba278dc1b5dfceac5f/selenium-server.log"}, "Tags": ["tag_1", "tag_2"], "ResultId": "6337fe576deba0ba278dc1b5dfceac5f", "AttachmentRequests": {}, "ModificationTime": 1266698139, "Browser": "firefox", "StartTime": 1266698101, "Owner": "sgrove", "_id": "01fc48caba6d15b46fad79e1b0562bbe", "OS": "Linux", "VideoUploadRequest": {"bucket": "sauce-userdata", "key": "sgrove/6337fe576deba0ba278dc1b5dfceac5f/video.flv"}}'
18
-
19
19
  client = Sauce::Client.new(:username => "test_user",
20
20
  :access_key => "abc123")
21
21
 
22
- job = client.jobs.new(job_json)
22
+ job = client.jobs.new(JSON.parse(@example_data["example_job"]))
23
+
24
+ assert_equal "501aca56282545a9a21ad2fc592b03fa", job.id
25
+ assert_equal "joe", job.owner
26
+ assert_equal "complete", job.status
27
+ assert_equal "job-name", job.name
28
+
29
+ assert_equal "firefox", job.browser
30
+ assert_equal "3.5.", job.browser_version
31
+ assert_equal "Windows 2003", job.os
32
+
33
+ assert_equal 1253856281, job.creation_time
34
+ assert_equal 1253856366, job.start_time
35
+ assert_equal 1253856465, job.end_time
36
+
37
+ assert_equal "http://saucelabs.com/video/8b6bf8d360cc338cc7cf7f6e093264d0/video.flv", job.video_url
38
+ assert_equal "http://saucelabs.com/video/8b6bf8d360cc338cc7cf7f6e093264d0/selenium-server.log", job.log_url
39
+
40
+ assert_equal false, job.public
41
+ assert_equal ["test", "example", "python_is_fun"], job.tags
42
+ end
23
43
 
24
- assert_equal "sgrove", job.owner
25
- assert_equal "01fc48caba6d15b46fad79e1b0562bbe", job.id
26
- assert_equal "example_job/name.rb", job.name
27
- assert_equal "5-228269313", job._rev
28
- assert_equal "192.168.0.1:4443", job.server
29
- assert_equal "f663372ba04444ce8cb3e6f61503f304", job.assigned_to
44
+ # Note: This won't pass until we have a canonical "test job" and its data
45
+ should "retrieve and parse a job via the api" do
46
+ job = @client.jobs.find("501aca56282545a9a21ad2fc592b03fa")
30
47
 
31
- assert_equal "job", job.sauce_type
32
- assert_equal "true", job.interactive
48
+ assert_equal "501aca56282545a9a21ad2fc592b03fa", job.id
49
+ assert_equal "joe", job.owner
33
50
  assert_equal "complete", job.status
34
- assert_equal ["tag_1", "tag_2"], job.tags
35
- assert_equal "6337fe576deba0ba278dc1b5dfceac5f", job.result_id
51
+ assert_equal "job-name", job.name
52
+
53
+ assert_equal "firefox", job.browser
54
+ assert_equal "3.5.", job.browser_version
55
+ assert_equal "Windows 2003", job.os
56
+
57
+ assert_equal 1253856281, job.creation_time
58
+ assert_equal 1253856366, job.start_time
59
+ assert_equal 1253856465, job.end_time
60
+
61
+ assert_equal "http://saucelabs.com/video/8b6bf8d360cc338cc7cf7f6e093264d0/video.flv", job.video_url
62
+ assert_equal "http://saucelabs.com/video/8b6bf8d360cc338cc7cf7f6e093264d0/selenium-server.log", job.log_url
63
+
64
+ assert_equal false, job.public
65
+ assert_equal ["test", "example", "python_is_fun"], job.tags
66
+ end
67
+
68
+ should "update writable properties" do
69
+ job = @client.jobs.find("501aca56282545a9a21ad2fc592b03fa")
70
+
71
+ # Make sure it's in the expected condition before changing
72
+ assert_equal false, job.public
73
+ assert_equal ["test", "example", "python_is_fun"], job.tags
74
+ assert_equal "job-name", job.name
36
75
 
37
- # TODO: Buckets
38
- #assert_equal , job.selenium_server_log_upload_request
39
- #assert_equal , job.attachment_requests
40
- #assert_equal , job.videoupload_request
76
+ job.public = true
77
+ job.tags = ["changed", "updated", "ruby_is_also_fun"]
78
+ job.name = "changed-job-name", job.name
79
+ job.save
41
80
 
81
+ # Fresh copy of the same job
82
+ job2 = @client.jobs.find("501aca56282545a9a21ad2fc592b03fa")
83
+
84
+ assert_equal true, job.public
85
+ assert_equal ["changed", "updated", "ruby_is_also_fun"], job.tags
86
+ assert_equal "changed-job-name", job.name
87
+
88
+ # Return the job to its original state and check it out
89
+ job.public = false
90
+ job.tags = ["test", "example", "python_is_fun"]
91
+ job.name = "job-name", job.name
92
+ job.save
93
+
94
+ # Check to see if the change took
95
+ job2.refresh!
96
+ assert_equal job.public, job2.public
97
+ assert_equal job.tags, job2.tags
98
+ assert_equal job.name, job2.name
99
+ end
100
+
101
+ should "not update read-only properties" do
102
+ job = @client.jobs.find("501aca56282545a9a21ad2fc592b03fa")
103
+
104
+ # Make sure it's in the expected condition before changing
105
+ assert_equal "complete", job.status
106
+ assert_equal "joe", job.owner
42
107
  assert_equal "Linux", job.os
43
- assert_equal "firefox", job.browser
44
- assert_equal "3.", job.browser_version
45
-
46
- assert_equal 1266698090, job.creation_time
47
- assert_equal 1266698097, job.assignment_time
48
- assert_equal 1266698101, job.chef_start_time
49
- assert_equal 1266698139, job.end_time
50
- assert_equal 1266698139, job.modification_time
51
- assert_equal 1266698101, job.start_time
108
+
109
+ job.status = "groggy"
110
+ job.owner = "sjobs"
111
+ job.os = "darwin" # In a perfect world...
112
+ assert_equal "groggy", job.status
113
+ assert_equal "joe", job.owner
114
+ assert_equal "darwin", job.os
115
+ job.save
116
+
117
+ # Changes should go away when refreshed
118
+ job.refresh!
119
+ assert_equal "complete", job.status
120
+ assert_equal "joe", job.owner
121
+ assert_equal "Linux", job.os
122
+ end
123
+
124
+ should "list the 100 most recent jobs" do
125
+ jobs = @client.jobs.all
126
+
127
+ assert_equal 5, jobs.count
128
+ end
129
+
130
+ should "show the full job information on index if requested" do
131
+ flunk "TODO: implement this"
52
132
  end
53
133
 
54
134
  def teardown
@@ -0,0 +1,58 @@
1
+ require 'helper'
2
+ require 'json'
3
+
4
+ class TestSauce < Test::Unit::TestCase
5
+ context "A jobs instance" do
6
+ setup do
7
+ # Create this file and put in your details to run the tests
8
+ account = YAML.load_file "live_account.yml"
9
+ @username = account["username"]
10
+ @access_key = account["access_key"]
11
+ @ip = account["ip"]
12
+ @client = Sauce::Client.new(:username => @username,
13
+ :access_key => @access_key)
14
+ end
15
+
16
+ should "initialize with passed variables" do
17
+ job_json = JSON.parse '{"BrowserVersion": "3.", "Name": "example_job/name.rb", "_rev": "5-228269313", "CreationTime": 1266698090, "AssignmentTime": 1266698097, "Server": "192.168.0.1:4443", "AssignedTo": "f663372ba04444ce8cb3e6f61503f304", "ChefStartTime": 1266698101, "EndTime": 1266698139, "Type": "job", "Interactive": "true", "Status": "complete", "SeleniumServerLogUploadRequest": {"bucket": "sauce-userdata", "key": "sgrove/6337fe576deba0ba278dc1b5dfceac5f/selenium-server.log"}, "Tags": ["tag_1", "tag_2"], "ResultId": "6337fe576deba0ba278dc1b5dfceac5f", "AttachmentRequests": {}, "ModificationTime": 1266698139, "Browser": "firefox", "StartTime": 1266698101, "Owner": "sgrove", "_id": "01fc48caba6d15b46fad79e1b0562bbe", "OS": "Linux", "VideoUploadRequest": {"bucket": "sauce-userdata", "key": "sgrove/6337fe576deba0ba278dc1b5dfceac5f/video.flv"}}'
18
+
19
+ client = Sauce::Client.new(:username => "test_user",
20
+ :access_key => "abc123")
21
+
22
+ job = client.jobs.new(job_json)
23
+
24
+ assert_equal "sgrove", job.owner
25
+ assert_equal "01fc48caba6d15b46fad79e1b0562bbe", job.id
26
+ assert_equal "example_job/name.rb", job.name
27
+ assert_equal "5-228269313", job._rev
28
+ assert_equal "192.168.0.1:4443", job.server
29
+ assert_equal "f663372ba04444ce8cb3e6f61503f304", job.assigned_to
30
+
31
+ assert_equal "job", job.sauce_type
32
+ assert_equal "true", job.interactive
33
+ assert_equal "complete", job.status
34
+ assert_equal ["tag_1", "tag_2"], job.tags
35
+ assert_equal "6337fe576deba0ba278dc1b5dfceac5f", job.result_id
36
+
37
+ # TODO: Buckets
38
+ #assert_equal , job.selenium_server_log_upload_request
39
+ #assert_equal , job.attachment_requests
40
+ #assert_equal , job.videoupload_request
41
+
42
+ assert_equal "Linux", job.os
43
+ assert_equal "firefox", job.browser
44
+ assert_equal "3.", job.browser_version
45
+
46
+ assert_equal 1266698090, job.creation_time
47
+ assert_equal 1266698097, job.assignment_time
48
+ assert_equal 1266698101, job.chef_start_time
49
+ assert_equal 1266698139, job.end_time
50
+ assert_equal 1266698139, job.modification_time
51
+ assert_equal 1266698101, job.start_time
52
+ end
53
+
54
+ def teardown
55
+ @client.tunnels.destroy
56
+ end
57
+ end
58
+ end
data/test/test_tunnels.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  require 'helper'
2
2
 
3
3
  class TestSauce < Test::Unit::TestCase
4
- context "A Client instance" do
4
+ context "A V1 tunnel instance" do
5
5
  setup do
6
6
  # Create this file and put in your details to run the tests
7
7
  account = YAML.load_file "live_account.yml"
@@ -16,7 +16,7 @@ class TestSauce < Test::Unit::TestCase
16
16
  should "initialize with passed variables" do
17
17
  client = Sauce::Client.new(:username => "test_user",
18
18
  :access_key => "abc123")
19
- assert_equal client.api_url, "https://test_user:abc123@saucelabs.com/rest/test_user/"
19
+ assert_equal "https://test_user:abc123@saucelabs.com/api/v1/test_user/", client.api_url
20
20
  end
21
21
 
22
22
  should "create a tunnel with the current user" do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sauce
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sean Grove
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-02-26 00:00:00 -08:00
12
+ date: 2010-03-02 00:00:00 -08:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -88,5 +88,6 @@ test_files:
88
88
  - test/helper.rb
89
89
  - test/irb_boot.rb
90
90
  - test/test_jobs.rb
91
+ - test/test_jobs_old.rb
91
92
  - test/test_tunnels.rb
92
93
  - test/test_videos.rb