Project

General

Profile

Download (13.8 KB) Statistics
| Branch: | Tag: | Revision:
require 'test_helper'
require 'json'
require 'dhcp_common/dhcp_common'
require 'dhcp_common/subnet'
require 'dhcp_common/record/lease'
require 'dhcp_common/record/reservation'
require 'dhcp/dhcp'
require 'dhcp/dependency_injection'
require 'dhcp/dhcp_api'
require 'dhcp/sparc_attrs'

ENV['RACK_ENV'] = 'test'

class DhcpApiTest < Test::Unit::TestCase
include Rack::Test::Methods
include SparcAttrs

def app
app = Proxy::DhcpApi.new
app.helpers.server = @server
app
end

def setup
@server = Object.new

@subnets = [Proxy::DHCP::Subnet.new("192.168.122.0", "255.255.255.0", "routers" => ["192.168.122.250"]),
Proxy::DHCP::Subnet.new("192.168.123.0", "255.255.255.192",
"routers" => ["192.168.123.1"], "domain_name_servers" => ["192.168.123.1"],
"range" => ["192.168.123.2", "192.168.123.62"]),
Proxy::DHCP::Subnet.new("192.168.124.0", "255.255.255.0",
"routers" => ["192.168.124.1", "192.168.124.2"],
"domain_name_servers" => ["192.168.123.1", "192.168.122.250"])
]

@subnet = @subnets.first

@reservations = [Proxy::DHCP::Reservation.new("test.example.com",
"192.168.122.1",
"00:11:bb:cc:dd:ee",
@subnet,
:hostname => "test.example.com"),
Proxy::DHCP::Reservation.new("ten.example.com",
"192.168.122.10",
"10:10:10:10:10:10",
@subnet,
:hostname => "ten.example.com")]

@leases = [
Proxy::DHCP::Lease.new(nil, "192.168.122.2", "00:aa:bb:cc:dd:ee", @subnet, date_format("Sat Jul 12 10:08:29 UTC 2014"), nil, "active"),
Proxy::DHCP::Lease.new(nil, "192.168.122.89", "ec:f4:bb:c6:ca:fe", @subnet, date_format("2014-10-16 12:59:40 UTC"), date_format("2199-01-01 00:00:01 UTC"), "active"),
Proxy::DHCP::Lease.new(nil, "192.168.122.5", "80:00:02:08:fe:80:00:00:00:00:00:00:00:02:aa:bb:cc:dd:ee:ff", @subnet, date_format("Sat Jul 12 10:08:29 UTC 2015"), nil, "active"),
]
end

# Date formats change between Ruby versions and JSON libraries & versions
def date_format(date)
JSON.load([Time.parse(date)].to_json).first
end

def test_get_subnets
@server.expects(:subnets).returns(@subnets)
get "/"
assert last_response.ok?, "Last response was not ok: #{last_response.status} #{last_response.body}"
assert_equal([{"network" => "192.168.122.0", "netmask" => "255.255.255.0", "options" => {}},
{"network" => "192.168.123.0", "netmask" => "255.255.255.192", "options" => {}},
{"network" => "192.168.124.0", "netmask" => "255.255.255.0", "options" => {}}].to_set, JSON.parse(last_response.body).to_set)
end

def test_get_network
@server.expects(:all_hosts).with(@subnet.network).returns(@reservations)
@server.expects(:all_leases).with(@subnet.network).returns(@leases)

get "/192.168.122.0"
assert last_response.ok?, "Last response was not ok: #{last_response.status} #{last_response.body}"


data = JSON.parse(last_response.body)
expected_reservations = JSON.parse(@reservations.to_json).to_set
expected_leases = JSON.parse(@leases.to_json).to_set

assert_equal expected_reservations, data['reservations'].to_set
assert_equal expected_leases, data['leases'].to_set
end

def test_get_network_for_non_existent_network
@server.expects(:all_hosts).raises(::Proxy::DHCP::SubnetNotFound)
get "/192.168.122.0"
assert_equal 404, last_response.status
end

def test_get_network_unused_ip
@server.expects(:unused_ip).with('192.168.122.0', "01:02:03:04:05:06", "192.168.122.10", "192.168.122.20").returns("192.168.122.11")
get "/192.168.122.0/unused_ip?mac=01:02:03:04:05:06&from=192.168.122.10&to=192.168.122.20"

assert last_response.ok?, "Last response was not ok: #{last_response.status} #{last_response.body}"
assert_equal({"ip"=>"192.168.122.11"}, JSON.parse(last_response.body))
end

def test_get_unused_ip_for_nonexistent_network
@server.expects(:unused_ip).with('192.168.122.0', "01:02:03:04:05:06", "192.168.122.10", "192.168.122.20").raises(::Proxy::DHCP::SubnetNotFound)
get "/192.168.122.0/unused_ip?mac=01:02:03:04:05:06&from=192.168.122.10&to=192.168.122.20"
assert_equal 404, last_response.status
end

def test_get_unused_when_not_inmplemented
@server.expects(:unused_ip).raises(::Proxy::DHCP::NotImplemented)
get "/192.168.122.0/unused_ip?mac=01:02:03:04:05:06&from=192.168.122.10&to=192.168.122.20"
assert_equal 501, last_response.status
end

def test_get_record
@server.expects(:find_record).with("192.168.122.0", "192.168.122.1").returns(@reservations.first)

get "/192.168.122.0/192.168.122.1"

assert last_response.ok?, "Last response was not ok: #{last_response.status} #{last_response.body}"
expected = {
"hostname" =>"test.example.com",
"ip" =>"192.168.122.1",
"mac" =>"00:11:bb:cc:dd:ee"
}
assert_equal expected, JSON.parse(last_response.body)
end

def test_get_record_for_non_existent_record
@server.expects(:find_record).with("192.168.122.0", "192.168.122.1").returns(nil)
get "/192.168.122.0/192.168.122.1"
assert_equal 404, last_response.status
end

def test_get_record_for_nonexistent_network
@server.expects(:find_record).with("192.168.122.0", "192.168.122.1").raises(::Proxy::DHCP::SubnetNotFound)
get "/192.168.122.0/192.168.122.1"
assert_equal 404, last_response.status
end

def test_get_reservation_record_by_ip
@server.expects(:find_records_by_ip).with("192.168.122.0", "192.168.122.1").returns([@reservations.first])

get "/192.168.122.0/ip/192.168.122.1"

assert last_response.ok?, "Last response was not ok: #{last_response.status} #{last_response.body}"
expected = [{
"deleteable" => true,
"type" => "reservation",
"hostname" => "test.example.com",
"ip" => "192.168.122.1",
"mac" => "00:11:bb:cc:dd:ee",
"name" => 'test.example.com',
"subnet" => "192.168.122.0/255.255.255.0"
}]
assert_equal expected, JSON.parse(last_response.body)
end

def test_get_lease_record_by_ip
@server.expects(:find_records_by_ip).with("192.168.122.0", "192.168.122.1").returns([@leases.first])

get "/192.168.122.0/ip/192.168.122.1"

assert last_response.ok?, "Last response was not ok: #{last_response.status} #{last_response.body}"

expected = [{
"ends" => nil,
"ip" => "192.168.122.2",
"mac" => "00:aa:bb:cc:dd:ee",
"name" => "lease-00aabbccddee",
"starts" => "2014-07-12 10:08:29 UTC",
"state" => "active",
"subnet" => "192.168.122.0/255.255.255.0",
"type" => "lease"
}]
assert_equal expected, JSON.parse(last_response.body)
end

def test_get_record_by_ip_for_nonexistent_ip
@server.expects(:find_records_by_ip).with("192.168.122.0", "192.168.122.1").returns([])
get "/192.168.122.0/ip/192.168.122.1"
assert_equal 404, last_response.status
end

def test_get_record_by_ip_for_nonexistent_network
@server.expects(:find_records_by_ip).with("192.168.122.0", "192.168.122.1").raises(::Proxy::DHCP::SubnetNotFound)
get "/192.168.122.0/ip/192.168.122.1"
assert_equal 404, last_response.status
end

def test_get_record_by_mac
@server.expects(:find_record_by_mac).with("192.168.122.0", "00:11:bb:cc:dd:ee").returns(@reservations.first)

get "/192.168.122.0/mac/00:11:bb:cc:dd:ee"

assert last_response.ok?, "Last response was not ok: #{last_response.status} #{last_response.body}"
expected = {
"deleteable" => true,
"type" => "reservation",
"hostname" =>"test.example.com",
"ip" =>"192.168.122.1",
"mac" =>"00:11:bb:cc:dd:ee",
"name" => 'test.example.com',
"subnet" =>"192.168.122.0/255.255.255.0" # NOTE: 'subnet' attribute isn't being used by foreman, which adds a 'network' attribute instead
}
assert_equal expected, JSON.parse(last_response.body)
end

def test_get_record_by_mac_64
@server.expects(:find_record_by_mac).with("192.168.122.0", "80:00:02:08:fe:80:00:00:00:00:00:00:00:02:aa:bb:cc:dd:ee:ff").returns(@leases.last)

get "/192.168.122.0/mac/80:00:02:08:fe:80:00:00:00:00:00:00:00:02:aa:bb:cc:dd:ee:ff"

assert last_response.ok?, "Last response was not ok: #{last_response.status} #{last_response.body}"
expected = {
"ends"=>nil,
"ip"=>"192.168.122.5",
"mac"=>"80:00:02:08:fe:80:00:00:00:00:00:00:00:02:aa:bb:cc:dd:ee:ff",
"name"=>"lease-80000208fe800000000000000002aabbccddeeff",
"starts"=>"2015-07-12 10:08:29 UTC",
"state"=>"active",
"subnet"=>"192.168.122.0/255.255.255.0",
"type"=>"lease"
}
assert_equal expected, JSON.parse(last_response.body)
end

def test_get_record_by_mac_uppercase
@server.expects(:find_record_by_mac).with("192.168.122.0", "00:11:bb:cc:dd:ee").returns(@reservations.first)

get "/192.168.122.0/mac/00:11:BB:CC:DD:EE"

assert last_response.ok?, "Last response was not ok: #{last_response.status} #{last_response.body}"
expected = {
"deleteable" => true,
"type" => "reservation",
"hostname" =>"test.example.com",
"ip" =>"192.168.122.1",
"mac" =>"00:11:bb:cc:dd:ee",
"name" => 'test.example.com',
"subnet" =>"192.168.122.0/255.255.255.0" # NOTE: 'subnet' attribute isn't being used by foreman, which adds a 'network' attribute instead
}
assert_equal expected, JSON.parse(last_response.body)
end

def test_get_record_by_mac_for_nonexistent_mac
@server.expects(:find_record_by_mac).with("192.168.122.0", "00:11:bb:cc:dd:ee").returns(nil)
get "/192.168.122.0/mac/00:11:bb:cc:dd:ee"
assert_equal 404, last_response.status
end

def test_get_record_by_mac_for_nonexistent_network
@server.expects(:find_record_by_mac).with("192.168.122.0", "00:11:bb:cc:dd:ee").raises(::Proxy::DHCP::SubnetNotFound)
get "/192.168.122.0/mac/00:11:bb:cc:dd:ee"
assert_equal 404, last_response.status
end

# New record with identical duplicate contents should be a successful no-op
def test_create_record_with_a_collision
params = {
"hostname" => "test.example.com",
"ip" => "192.168.122.1",
"mac" => "00:11:bb:cc:dd:ee",
"network" => "192.168.122.0",
}
@server.expects(:add_record).raises(Proxy::DHCP::Collision)

post "/192.168.122.0", params

assert_equal 409, last_response.status
end

def test_create_duplicate_record
params = {
"hostname" => "test.example.com",
"ip" => "192.168.122.1",
"mac" => "00:11:bb:cc:dd:ee",
"network" => "192.168.122.0",
}
@server.expects(:add_record).raises(Proxy::DHCP::AlreadyExists)

post "/192.168.122.0", params

assert last_response.ok?, "Last response was not ok: #{last_response.status} #{last_response.body}"
end

def test_create_record_new
record = {
"hostname" => "ten.example.com",
"ip" => "192.168.122.10",
"mac" => "10:10:10:10:10:10",
"network" => "192.168.122.0",
}
@server.expects(:add_record).with {|params| record.all? {|k_v| params[k_v[0]] == k_v[1]} }

post "/192.168.122.0", record

assert last_response.ok?, "Last response was not ok: #{last_response.status} #{last_response.body}"
end

def test_sparc_host_creation
@server.expects(:add_record).with() {|params| sparc_attrs.all? {|k_v| params[k_v[0]] == k_v[1]} }

post '/192.168.122.0', sparc_attrs
assert last_response.ok?, "Last response was not ok: #{last_response.body}"
end

def test_delete_record
@server.expects(:find_record).with("192.168.122.0", "192.168.122.1").returns(@reservations.first)
@server.expects(:del_record).with(@reservations.first).returns(nil)

delete "/192.168.122.0/192.168.122.1"

assert_equal 200, last_response.status
assert_empty last_response.body
end

def test_delete_records_by_ip
@server.expects(:del_records_by_ip).with("192.168.122.0", "192.168.122.1")
delete "/192.168.122.0/ip/192.168.122.1"
assert_equal 200, last_response.status
assert_empty last_response.body
end

def test_delete_records_by_ip_for_nonexistent_subnet
@server.expects(:del_records_by_ip).with("192.168.122.0", "192.168.122.1").raises(::Proxy::DHCP::SubnetNotFound)
delete "/192.168.122.0/ip/192.168.122.1"
assert_equal 200, last_response.status
assert_empty last_response.body
end

def test_delete_records_by_mac
@server.expects(:del_record_by_mac).with("192.168.122.0", "00:11:bb:cc:dd:ee")
delete "/192.168.122.0/mac/00:11:bb:cc:dd:ee"
assert_equal 200, last_response.status
assert_empty last_response.body
end

def test_delete_records_by_mac_uppercase
@server.expects(:del_record_by_mac).with("192.168.122.0", "00:11:bb:cc:dd:ee")
delete "/192.168.122.0/mac/00:11:BB:CC:DD:EE"
assert_equal 200, last_response.status
assert_empty last_response.body
end

def test_delete_records_by_mac_for_nonexistent_subnet
@server.expects(:del_record_by_mac).with("192.168.122.0", "00:11:bb:cc:dd:ee").raises(::Proxy::DHCP::SubnetNotFound)
delete "/192.168.122.0/mac/00:11:bb:cc:dd:ee"
assert_equal 200, last_response.status
assert_empty last_response.body
end

def test_delete_non_existent_record
@server.expects(:find_record).with("192.168.122.0", "192.168.122.1").returns(nil)
delete "/192.168.122.0/192.168.122.1"
assert_equal 404, last_response.status
end
end
(2-2/15)