Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,7 @@ group :development do
gem "yard-thor"
gem "yard"
gem "pry"
# this is required to avoid `undefined method last_comment`
# until jeweler is upgraded
gem "rake", "< 11.0"
end
2 changes: 2 additions & 0 deletions lib/jenkins_api_client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,12 @@
require 'jenkins_api_client/version'
require 'jenkins_api_client/exceptions'
require 'jenkins_api_client/client'
require 'jenkins_api_client/job_build'
require 'jenkins_api_client/job'
require 'jenkins_api_client/node'
require 'jenkins_api_client/system'
require 'jenkins_api_client/view'
require 'jenkins_api_client/queue_item'
require 'jenkins_api_client/build_queue'
require 'jenkins_api_client/plugin_manager'
require 'jenkins_api_client/user'
Expand Down
10 changes: 10 additions & 0 deletions lib/jenkins_api_client/build_queue.rb
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,16 @@ def list
tasks
end

# Lists all tasks currently in the build queue as [QueueItem] objects
#
def list_tasks
@logger.info "Obtaining the tasks currently in the build queue"
response_json = @client.api_get_request("/queue")
tasks = response_json["items"].map do |item|
QueueItem.new(@client, item)
end
end

# Gets the time number of seconds the task is in the queue
#
# @param [String] task_name Name of the task/job
Expand Down
11 changes: 11 additions & 0 deletions lib/jenkins_api_client/job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -665,6 +665,17 @@ def list(filter, ignorecase = true)
jobs
end

# List all builds for a given job
#
# @return an array of [JobBuild] items
def list_builds(job_name)
@logger.info "Obtaining the builds of #{job_name}"
response_json = @client.api_get_request("/job/#{path_encode job_name}", "tree=builds[number]")
tasks = response_json["builds"].map do |item|
JobBuild.new(@client, :id => item['number'],:name => job_name)
end
end

# List all jobs on the Jenkins CI server along with their details
#
# @return [Array<Hash>] the details of all jobs in jenkins
Expand Down
66 changes: 66 additions & 0 deletions lib/jenkins_api_client/job_build.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
module JenkinsApi
class Client

#
# This class represents a build with an assingned id. This includes
# jobs already built or that are currently active.
#
class JobBuild
VALID_PARAMS = ['id', 'name', 'params'].freeze
attr_accessor :id, :name

# Initializes a new [JobBuild]
#
# @param client [Client] the api client object
# @param attr Hash with attributes containing at least name and id, the information not provided
# can be latter retrieved through the json api using the given client
#
# @return [JobBuild] the build item object
def initialize(client, attr = {})
@client = client
attr.each do |name, value|
name = name.to_s
if VALID_PARAMS.include?(name)
instance_variable_set("@#{name.to_s}", value)
end
end
end

# @return Hash with build parameters
#
def params
load_attributes
@params
end

private

# Queries the server for the missing information
#
def load_attributes
if @params.nil?
json = @client.api_get_request("/job/#{@name}/#{@id}", "depth=2")
if json.member?('actions')
@params = json['actions'].find do |action|
if action.is_a?(Hash)
action.member?('parameters')
elsif action.is_a?(Array)
action.first.is_a?(Hash) and action.first.member?('value')
end
end
if @params.nil?
@params = {}
else
@params = @params['parameters'] if @params.is_a?(Hash)
@params = @params.map do |param|
[param['name'], param['value']]
end
@params = Hash[@params]
end

end
end
end
end
end
end
51 changes: 51 additions & 0 deletions lib/jenkins_api_client/queue_item.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
module JenkinsApi
class Client

#
# This class represents an item in the building queue and allows interaction
# with an identified queue item.
#
class QueueItem
VALID_PARAMS = ['id', 'params'].freeze
attr_accessor *VALID_PARAMS.each {|attr| attr.to_sym}
attr_accessor :name

# Initializes a new QueueItem
#
# @param client [Cliente] the api client object
# @param json the json object with all the information of the queue item (as returned by api call "/queue")
#
# @return [QueueItem] the queue item object
#
def initialize(client, json)
@client = client
json.each do |key, value|
if VALID_PARAMS.include?(key)
instance_variable_set("@#{key}", value)
end
end if json.is_a? Hash
@name = json['task']['name']

# parseamos los parametros
@params = @params.split("\n").map do |p|
p.split('=')
end.select do |p|
not p.empty?
end
@params = Hash[@params]
end

# String representation of the queue item object
#
def to_s
self.name
end

# Removes the item from the building queue
#
def cancel
@client.api_post_request("/queue/cancelItem?id=#{self.id}")
end
end
end
end
27 changes: 27 additions & 0 deletions spec/func_tests/job_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,33 @@ def test_and_validate(name, params, config_line = nil)
end
end

describe "#list_builds" do
it "Should get builds of a specified job, and query their parameters" do
job = 'dummy_with_params'
begin
tries ||= 1
xml = @helper.create_job_with_params_xml
@client.job.create(job, xml).to_i.should == 200
rescue JenkinsApi::Exceptions::JobAlreadyExists
@client.job.delete(job)
tries -= 1
retry if tries >= 0
end

2.times do |num|
@client.job.build(job, {"PARAM1" => num})
sleep 10
while @client.job.get_current_build_status(job) == "running" do
sleep 2
end
end
builds = @client.job.list_builds(job)
builds.class.should == Array
builds.map {|b| b.id }.sort.should == [1, 2]
builds.map {|b| b.params['PARAM1']}.sort.should == ['0', '1']
end
end

describe "#get_current_build_status" do
it "Should obtain the current build status for the specified job" do
build_status = @client.job.get_current_build_status(@job_name)
Expand Down
106 changes: 106 additions & 0 deletions spec/func_tests/queue_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
#
# Specifying JenkinsApi::Client::Job class capabilities
# Author: Kannan Manickam <[email protected]>
#

require File.expand_path('../spec_helper', __FILE__)
require 'yaml'

describe JenkinsApi::Client::BuildQueue do
context "With properly initialized client" do
before(:each) do
@helper = JenkinsApiSpecHelper::Helper.new
@creds_file = '~/.jenkins_api_client/spec.yml'
@creds = YAML.load_file(File.expand_path(@creds_file, __FILE__))
@job_name_prefix = 'awesome_rspec_test_job'
@filter = "^#{@job_name_prefix}.*"
@job_name = ''
@valid_post_responses = [200, 201, 302]
begin
@client = JenkinsApi::Client.new(@creds)
rescue Exception => e
puts "WARNING: Credentials are not set properly."
puts e.message
end
# Creating 10 jobs to run the spec tests on
begin
@client.node.create_dumb_slave(:name => 'none', :slave_host => '10.10.10.10', :private_key_file => '')
10.times do |num|
xml = @helper.create_job_with_params_xml
job = "#{@job_name_prefix}_#{num}"
@job_name = job if num == 0
@client.job.create(job, xml).to_i.should == 200
end
rescue Exception => e
puts "WARNING: Can't create jobs for preparing to spec tests"
puts e.message
end
end

describe "InstanceMethods" do

describe "#initialize" do
it "Initializes without any exception" do
expect(
lambda { job = JenkinsApi::Client::BuildQueue.new(@client) }
).not_to raise_error
end
it "Raises an error if a reference of client is not passed" do
expect(
lambda { job = JenkinsApi::Client::BuildQueue.new() }
).to raise_error
end
end

describe "#list_tasks" do
it "Gets all queued tasks as QueueItem objects" do
10.times do |num|
job = "#{@job_name_prefix}_#{num}"
@job_name = job if num == 0
@client.job.build(job, {"PARAM1" => num})
end

tasks = @client.queue.list_tasks
expect(tasks).to be_a_kind_of(Array)
tasks.each do |task|
expect(task).to be_a_kind_of(JenkinsApi::Client::QueueItem)
expect(task.params).to include("PARAM1")
expect(task.name).to eq("#{@job_name_prefix}_#{task.params['PARAM1']}")
end
tasks.size.should == 10
end
end

end

describe "QueueItem" do
describe "#cancel" do
it "Cancels an item in the queue" do
5.times do |num|
job = "#{@job_name_prefix}_3"
@client.job.build(job, {"PARAM1" => num})
end

tasks = @client.queue.list_tasks
tasks.size.should == 5

tasks.each do |task|
task.cancel if task.params['PARAM1'].to_i.even?
end

tasks = @client.queue.list_tasks
tasks.map {|t| t.params['PARAM1']}.sort.should == ['1', '3']
end
end
end

after(:each) do
job_names = @client.job.list(@filter)
job_names.each { |job_name|
@client.job.delete(job_name)
}
@client.node.delete_all!
end

end
end
35 changes: 35 additions & 0 deletions spec/func_tests/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,40 @@ def create_job_xml
}
builder.to_xml
end

def create_job_with_params_xml
builder = Nokogiri::XML::Builder.new(:encoding => 'UTF-8') { |xml|
xml.project {
xml.actions
xml.description
xml.keepDependencies "false"
xml.properties {
xml.send("hudson.model.ParametersDefinitionProperty") {
xml.parameterDefinitions {
xml.send("hudson.model.StringParameterDefinition") {
xml.name "PARAM1"
}
}
}
}
xml.scm(:class => "hudson.scm.NullSCM")
xml.canRoam "true"
xml.disabled "false"
xml.assignedNode "none"
xml.blockBuildWhenDownstreamBuilding "false"
xml.blockBuildWhenUpstreamBuilding "false"
xml.triggers.vector
xml.concurrentBuild "false"
xml.builders {
xml.send("hudson.tasks.Shell") {
xml.command "\necho 'going to take a nice nap'\nsleep 15\necho 'took a nice nap'"
}
}
xml.publishers
xml.buildWrappers
}
}
builder.to_xml
end
end
end
13 changes: 13 additions & 0 deletions spec/unit_tests/build_queue_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,19 @@
end
end

describe "#list_tasks" do
it "returns the list of tasks in the queue as QueueItems" do
@client.should_receive(:api_get_request).with("/queue").and_return(
@sample_queue_json
)
tasks = @queue.list_tasks
tasks.class.should == Array
tasks.each do |t|
t.class.should == JenkinsApi::Client::QueueItem
end
end
end

describe "#get_age" do
it "returns the age of a task" do
@client.should_receive(:api_get_request).with("/queue").and_return(
Expand Down
Loading