test/encoding_test.rb in ruby-ldapserver-0.5.3 vs test/encoding_test.rb in ruby-ldapserver-0.7.0
- old
+ new
@@ -10,26 +10,26 @@
# independent source of LDAP packets to try.
require 'ldap/server/operation'
require 'ldap/server/server'
-require 'ldap'
+require 'net/ldap'
# We subclass the Operation class, overriding the methods to do what we need
class MockOperation < LDAP::Server::Operation
def initialize(connection, messageId)
super(connection, messageId)
@@lastop = [:connect]
end
def simple_bind(version, user, pass)
- @@lastop = [:simple_bind, version, user, pass]
+ @@lastop = [:simple_bind, version.to_i, user, pass]
end
def search(basedn, scope, deref, filter)
- @@lastop = [:search, basedn, scope, deref, filter, @attributes]
+ @@lastop = [:search, basedn, scope.to_i, deref.to_i, filter, @attributes]
send_SearchResultEntry("cn=foo", {"a"=>["1","2"], "b"=>"boing"})
send_SearchResultEntry("cn=bar", {"a"=>["3","4","5"], "b"=>"wibble"})
end
def add(dn, av)
@@ -60,267 +60,230 @@
class TestLdap < Test::Unit::TestCase
HOST = '127.0.0.1'
PORT = 1389
- def open_child_posix
- IO.popen("-","w+").tap do |io|
- unless io
- do_child Kernel, Kernel
- exit!
- end
- end
- end
-
- class DoubleIO < IO
- def initialize out, inio
- @out_io = out
- @in_io = inio
- end
-
- def read *a
- @out_io.read *a
- end
-
- def write *a
- @in_io.write *a
- end
-
- def gets
- @out_io.gets
- end
-
- def close
- @in_io.close
- @out_io.close
- end
- end
-
- def open_child_java
- in_rd, in_wr = IO.pipe
- out_rd, out_wr = IO.pipe
+ def start_client
+ in_ = Queue.new
+ out = Queue.new
Thread.new do
- do_child in_rd, out_wr
+ do_child(in_, out)
end
- DoubleIO.new(out_rd, in_wr)
+ return in_, out
end
- def open_child
- case RUBY_PLATFORM
- when 'java'
- open_child_java
- else
- open_child_posix
- end
+ def ensure_server_started
+ @serv || start_server
end
- def setup
- @ppid = $$
- @io = open_child
-
+ def start_server(opts={})
# back to a single process (the parent). Now we start our
# listener thread
- @serv = LDAP::Server.new(
- :bindaddr => '127.0.0.1',
- :port => PORT,
- :nodelay => true,
- :operation_class => MockOperation
- )
+ @serv = LDAP::Server.new({
+ :bindaddr => '127.0.0.1',
+ :port => PORT,
+ :nodelay => true,
+ :operation_class => MockOperation,
+ }.merge(opts))
+
@serv.run_tcpserver
end
+ def setup
+ @client = nil
+ @serv = nil
+ end
+
def teardown
if @serv
@serv.stop
@serv = nil
end
- if @io
- @io.puts "quit"
- @io.gets
- @io.close
- @io = nil
+ if @client
+ # @client.close
+ @client = nil
end
end
- # Process commands on stdin in child
-
- def do_child in_, out
- while true
- begin
- a = in_.gets.chomp
- conn ||= LDAP::Conn.new(HOST,PORT)
- case a
- when "bind2"
- conn.set_option(LDAP::LDAP_OPT_PROTOCOL_VERSION, 2)
- conn.bind("foo","bar")
- when "bind3"
- conn.set_option(LDAP::LDAP_OPT_PROTOCOL_VERSION, 3)
- conn.bind("foo","bar")
- # these examples taken from the ruby-ldap examples
- when "add1"
- entry1 = [
- LDAP.mod(LDAP::LDAP_MOD_ADD, 'objectclass', ['top', 'domain']),
- LDAP.mod(LDAP::LDAP_MOD_ADD, 'o', ['TTSKY.NET']),
- LDAP.mod(LDAP::LDAP_MOD_ADD, 'dc', ['localhost']),
- ]
- conn.add("dc=localhost, dc=domain", entry1)
- when "add2"
- entry2 = [
- LDAP.mod(LDAP::LDAP_MOD_ADD, 'objectclass', ['top', 'person']),
- LDAP.mod(LDAP::LDAP_MOD_ADD, 'cn', ['Takaaki Tateishi']),
- LDAP.mod(LDAP::LDAP_MOD_ADD | LDAP::LDAP_MOD_BVALUES, 'sn', ['ttate','Tateishi', "zero\000zero"]),
- ]
- conn.add("cn=Takaaki Tateishi, dc=localhost, dc=localdomain", entry2)
- when "del"
- conn.delete("cn=Takaaki-Tateishi, dc=localhost, dc=localdomain")
- when /^compare (.*)/
- begin
- case conn.compare("cn=Takaaki Tateishi, dc=localhost, dc=localdomain",
- "cn", $1)
- when true; out.puts "OK true"; next
- when false; out.puts "OK false"; next
- end
- rescue LDAP::ResultError => e
- # For older versions of ruby-ldap
- case e.message
- when /Compare True/i; out.puts "OK true"; next
- when /Compare False/i; out.puts "OK false"; next
- end
- raise
- end
- when "modrdn"
- conn.modrdn("cn=Takaaki Tateishi, dc=localhost, dc=localdomain",
- "cn=Takaaki-Tateishi",
- true)
- when "modify"
- entry = [
- LDAP.mod(LDAP::LDAP_MOD_ADD, 'objectclass', ['top', 'domain']),
- LDAP.mod(LDAP::LDAP_MOD_DELETE, 'o', []),
- LDAP.mod(LDAP::LDAP_MOD_REPLACE, 'dc', ['localhost']),
- ]
- conn.modify("dc=localhost, dc=domain", entry)
- when "search"
- res = {}
- conn.search("dc=localhost, dc=localdomain",
- LDAP::LDAP_SCOPE_SUBTREE,
- "(objectclass=*)") do |e|
- entry = e.to_hash
- dn = entry.delete("dn").first
- res[dn] = entry
- end
- exp = {
- "cn=foo" => {"a"=>["1","2"], "b"=>["boing"]},
- "cn=bar" => {"a"=>["3","4","5"], "b"=>["wibble"]},
- }
- if res != exp
- raise "Bad Search Result, expected\n#{exp.inspect}\ngot\n#{res.inspect}"
- end
- when "search2"
- # FIXME: ruby-ldap doesn't seem to allow DEREF options to be set
- conn.search("dc=localhost, dc=localdomain",
- LDAP::LDAP_SCOPE_BASE,
- "(&(cn=foo)(objectclass=*)(|(!(sn=*))(ou>=baz)(o<=z)(cn~=brian)(cn=*and*er)))",
- ["a","b"]) do |e|
- entry = e.to_hash
- dn = entry.delete("dn").first
- res[dn] = entry
- end
- when "quit"
- out.puts "OK"
- break
- else
- raise "Bad command! #{a.inspect}"
- end
- out.puts "OK"
- rescue Exception => e
- $stderr.puts "Child exception: #{e}\n\t#{e.backtrace.join("\n\t")}"
- out.puts "ERR #{e}"
- end
- end
+ def conn
+ ensure_server_started
+ @client ||= Net::LDAP.new(host: HOST, port: PORT)
end
- def req(cmd)
- @io.puts cmd
- res = @io.gets.chomp
- assert_match(/^OK/, res)
- res
- end
-
def test_bind2
- req("bind2")
+ pend("net-ldap gem doesn't support protocol 2")
+
+ # TODO: Net::LDAP only supports protocol 3
+ conn.set_option(LDAP::LDAP_OPT_PROTOCOL_VERSION, 2)
+ conn.auth("foo","bar")
+ conn.bind
+
assert_equal([:simple_bind, 2, "foo", "bar"], MockOperation.lastop)
# cannot bind any more; ldap client library says "already binded." (sic)
end
def test_bind3
- req("bind3")
+ conn.auth("foo","bar")
+ conn.bind
+
assert_equal([:simple_bind, 3, "foo", "bar"], MockOperation.lastop)
# cannot bind any more; ldap client library says "already binded." (sic)
end
def test_add
- req("add1")
+ entry1 = {
+ objectclass: ['top', 'domain'],
+ o: ['TTSKY.NET'],
+ dc: ['localhost'],
+ }
+ conn.add(dn: "dc=localhost, dc=domain", attributes: entry1)
+
assert_equal([:add, "dc=localhost, dc=domain", {
'objectclass'=>['top', 'domain'],
'o'=>['TTSKY.NET'],
'dc'=>['localhost'],
}], MockOperation.lastop)
- req("add2")
+
+ entry2 = {
+ objectclass: ['top', 'person'],
+ cn: ['Takaaki Tateishi'],
+ sn: ['ttate','Tateishi', "zero\000zero"],
+ }
+ conn.add(dn: "cn=Takaaki Tateishi, dc=localhost, dc=localdomain", attributes: entry2)
+
assert_equal([:add, "cn=Takaaki Tateishi, dc=localhost, dc=localdomain", {
'objectclass'=>['top', 'person'],
'cn'=>['Takaaki Tateishi'],
'sn'=>['ttate','Tateishi',"zero\000zero"],
}], MockOperation.lastop)
end
def test_del
- req("del")
+ conn.delete(dn: "cn=Takaaki-Tateishi, dc=localhost, dc=localdomain")
assert_equal([:del, "cn=Takaaki-Tateishi, dc=localhost, dc=localdomain"], MockOperation.lastop)
end
def test_compare
- r = req("compare Takaaki Tateishi")
- assert_match(/OK true/, r)
+ pend("net-ldap gem doesn't support compare requests")
+ res = conn.compare("cn=Takaaki Tateishi, dc=localhost, dc=localdomain",
+ "cn", "Takaaki Tateishi")
+
assert_equal([:compare, "cn=Takaaki Tateishi, dc=localhost, dc=localdomain",
"cn", "Takaaki Tateishi"], MockOperation.lastop)
- r = req("compare false")
- assert_match(/OK false/, r)
+ assert res
+
+ res = conn.compare("cn=Takaaki Tateishi, dc=localhost, dc=localdomain",
+ "cn", "false")
assert_equal([:compare, "cn=Takaaki Tateishi, dc=localhost, dc=localdomain",
"cn", "false"], MockOperation.lastop)
+ refute res
end
def test_modrdn
- req("modrdn")
+ conn.modify_rdn(olddn: "cn=Takaaki Tateishi, dc=localhost, dc=localdomain",
+ newrdn: "cn=Takaaki-Tateishi",
+ delete_attributes: true)
+
assert_equal([:modifydn, "cn=Takaaki Tateishi, dc=localhost, dc=localdomain",
"cn=Takaaki-Tateishi", true, nil], MockOperation.lastop)
# FIXME: ruby-ldap doesn't support the four-argument form
end
def test_modify
- req("modify")
+ entry = [
+ [:add, :objectclass, ['top', 'domain']],
+ [:delete, :o, []],
+ [:replace, :dc, ['localhost']],
+ ]
+ conn.modify(dn: "dc=localhost, dc=domain", operations: entry)
+
assert_equal([:modify, "dc=localhost, dc=domain", {
'objectclass' => [:add, 'top', 'domain'],
'o' => [:delete],
'dc' => [:replace, 'localhost'],
}], MockOperation.lastop)
end
def test_search
- req("search")
+ res = []
+ conn.search(base: "dc=localhost, dc=localdomain",
+ scope: Net::LDAP::SearchScope_WholeSubtree,
+ filter: "(objectclass=*)") do |e|
+ res << e.to_h
+ end
+
assert_equal([:search, "dc=localhost, dc=localdomain",
LDAP::Server::WholeSubtree,
LDAP::Server::NeverDerefAliases,
[:true], []], MockOperation.lastop)
- req("search2")
+
+ exp = [
+ {a: ["1","2"], b: ["boing"], dn: ["cn=foo"]},
+ {a: ["3","4","5"], b: ["wibble"], dn: ["cn=bar"]},
+ ]
+ assert_equal exp, res
+
+ res = []
+ # FIXME: ruby-ldap doesn't seem to allow DEREF options to be set
+ conn.search(base: "dc=localhost, dc=localdomain",
+ scope: Net::LDAP::SearchScope_BaseObject,
+ filter: "(&(cn=foo)(objectclass=*)(|(!(sn=*))(ou>=baz)(o<=z)(cn=*and*er)))",
+ attributes: [:a, :b]) do |e|
+ res << e.to_h
+ end
+
assert_equal([:search, "dc=localhost, dc=localdomain",
LDAP::Server::BaseObject,
LDAP::Server::NeverDerefAliases,
[:and, [:eq, "cn", nil, "foo"],
[:or, [:not, [:present, "sn"]],
[:ge, "ou", nil, "baz"],
[:le, "o", nil, "z"],
- [:approx, "cn", nil, "brian"],
[:substrings, "cn", nil, nil, "and", "er"],
],
], ["a","b"]], MockOperation.lastop)
+
+ assert_equal exp, res
+ end
+
+ def test_search_with_range
+ res = []
+ conn.search(base: "dc=localhost, dc=localdomain",
+ scope: Net::LDAP::SearchScope_BaseObject,
+ attributes: ["a;range=1-2", "b"]) do |e|
+ res << e.to_h
+ end
+
+ assert_equal([:search, "dc=localhost, dc=localdomain",
+ LDAP::Server::BaseObject,
+ LDAP::Server::NeverDerefAliases,
+ [:true], ["a","b"]], MockOperation.lastop)
+
+ exp = [
+ {a: [], "a;range=1-*": ["2"], b: ["boing"], dn: ["cn=foo"]},
+ {a: [], "a;range=1-2": ["4","5"], b: ["wibble"], dn: ["cn=bar"]},
+ ]
+ assert_equal exp, res
+ end
+
+ def test_search_with_range_limit
+ start_server(attribute_range_limit: 2)
+
+ res = []
+ conn.search(base: "dc=localhost, dc=localdomain",
+ scope: Net::LDAP::SearchScope_WholeSubtree,
+ filter: "(objectclass=*)") do |e|
+ res << e.to_h
+ end
+
+ assert_equal([:search, "dc=localhost, dc=localdomain",
+ LDAP::Server::WholeSubtree,
+ LDAP::Server::NeverDerefAliases,
+ [:true], []], MockOperation.lastop)
+
+ exp = [
+ {a: ["1","2"], b: ["boing"], dn: ["cn=foo"]},
+ {a: [], "a;range=0-1": ["3","4"], b: ["wibble"], dn: ["cn=bar"]},
+ ]
+ assert_equal exp, res
end
end