openldap 0.0.1pre11
Sign up to get free protection for your applications and to get access to all the features.
- data/.gemtest +0 -0
- data/History.md +4 -0
- data/Manifest.txt +20 -0
- data/README.md +100 -0
- data/Rakefile +152 -0
- data/Roadmap.md +55 -0
- data/ext/connection.c +1125 -0
- data/ext/extconf.rb +24 -0
- data/ext/openldap.c +558 -0
- data/ext/openldap.h +91 -0
- data/lib/openldap.rb +102 -0
- data/lib/openldap/connection.rb +179 -0
- data/lib/openldap/exceptions.rb +246 -0
- data/lib/openldap/mixins.rb +65 -0
- data/lib/openldap/utils.rb +123 -0
- data/spec/lib/constants.rb +29 -0
- data/spec/lib/helpers.rb +128 -0
- data/spec/openldap/connection_spec.rb +190 -0
- data/spec/openldap/exceptions_spec.rb +46 -0
- data/spec/openldap_spec.rb +83 -0
- data/test.conf-example +2 -0
- metadata +181 -0
@@ -0,0 +1,65 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
require 'rbconfig'
|
4
|
+
require 'erb'
|
5
|
+
require 'etc'
|
6
|
+
require 'logger'
|
7
|
+
|
8
|
+
require 'openldap'
|
9
|
+
|
10
|
+
|
11
|
+
#--
|
12
|
+
# A collection of mixins shared between OpenLDAP classes. Stolen mostly from ThingFish.
|
13
|
+
#
|
14
|
+
module OpenLDAP # :nodoc:
|
15
|
+
|
16
|
+
# Add logging to a OpenLDAP class. Including classes get #log and #log_debug methods.
|
17
|
+
module Loggable
|
18
|
+
|
19
|
+
LEVEL = {
|
20
|
+
:debug => Logger::DEBUG,
|
21
|
+
:info => Logger::INFO,
|
22
|
+
:warn => Logger::WARN,
|
23
|
+
:error => Logger::ERROR,
|
24
|
+
:fatal => Logger::FATAL,
|
25
|
+
}
|
26
|
+
|
27
|
+
### A logging proxy class that wraps calls to the logger into calls that include
|
28
|
+
### the name of the calling class.
|
29
|
+
class ClassNameProxy # :nodoc:
|
30
|
+
|
31
|
+
### Create a new proxy for the given +klass+.
|
32
|
+
def initialize( klass, force_debug=false )
|
33
|
+
@classname = klass.name
|
34
|
+
@force_debug = force_debug
|
35
|
+
end
|
36
|
+
|
37
|
+
### Delegate calls the global logger with the class name as the 'progname'
|
38
|
+
### argument.
|
39
|
+
def method_missing( sym, msg=nil, &block )
|
40
|
+
return super unless LEVEL.key?( sym )
|
41
|
+
sym = :debug if @force_debug
|
42
|
+
OpenLDAP.logger.add( LEVEL[sym], msg, @classname, &block )
|
43
|
+
end
|
44
|
+
end # ClassNameProxy
|
45
|
+
|
46
|
+
#########
|
47
|
+
protected
|
48
|
+
#########
|
49
|
+
|
50
|
+
### Return the proxied logger.
|
51
|
+
def log
|
52
|
+
@log_proxy ||= ClassNameProxy.new( self.class )
|
53
|
+
end
|
54
|
+
|
55
|
+
### Return a proxied "debug" logger that ignores other level specification.
|
56
|
+
def log_debug
|
57
|
+
@log_debug_proxy ||= ClassNameProxy.new( self.class, true )
|
58
|
+
end
|
59
|
+
end # module Loggable
|
60
|
+
|
61
|
+
|
62
|
+
end # module OpenLDAP
|
63
|
+
|
64
|
+
# vim: set nosta noet ts=4 sw=4:
|
65
|
+
|
@@ -0,0 +1,123 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'logger'
|
4
|
+
require 'erb'
|
5
|
+
|
6
|
+
require 'openldap' unless defined?( OpenLDAP )
|
7
|
+
|
8
|
+
module OpenLDAP # :nodoc:
|
9
|
+
|
10
|
+
# A alternate formatter for Logger instances.
|
11
|
+
class LogFormatter < Logger::Formatter # :nodoc:
|
12
|
+
|
13
|
+
# The format to output unless debugging is turned on
|
14
|
+
DEFAULT_FORMAT = "[%1$s.%2$06d %3$d/%4$s] %5$5s -- %7$s\n"
|
15
|
+
|
16
|
+
# The format to output if debugging is turned on
|
17
|
+
DEFAULT_DEBUG_FORMAT = "[%1$s.%2$06d %3$d/%4$s] %5$5s {%6$s} -- %7$s\n"
|
18
|
+
|
19
|
+
|
20
|
+
### Initialize the formatter with a reference to the logger so it can check for log level.
|
21
|
+
def initialize( logger, format=DEFAULT_FORMAT, debug=DEFAULT_DEBUG_FORMAT ) # :notnew:
|
22
|
+
@logger = logger
|
23
|
+
@format = format
|
24
|
+
@debug_format = debug
|
25
|
+
|
26
|
+
super()
|
27
|
+
end
|
28
|
+
|
29
|
+
######
|
30
|
+
public
|
31
|
+
######
|
32
|
+
|
33
|
+
# The Logger object associated with the formatter
|
34
|
+
attr_accessor :logger
|
35
|
+
|
36
|
+
# The logging format string
|
37
|
+
attr_accessor :format
|
38
|
+
|
39
|
+
# The logging format string that's used when outputting in debug mode
|
40
|
+
attr_accessor :debug_format
|
41
|
+
|
42
|
+
|
43
|
+
### Log using either the DEBUG_FORMAT if the associated logger is at ::DEBUG level or
|
44
|
+
### using FORMAT if it's anything less verbose.
|
45
|
+
def call( severity, time, progname, msg )
|
46
|
+
args = [
|
47
|
+
time.strftime( '%Y-%m-%d %H:%M:%S' ), # %1$s
|
48
|
+
time.usec, # %2$d
|
49
|
+
Process.pid, # %3$d
|
50
|
+
Thread.current == Thread.main ? 'main' : Thread.object_id, # %4$s
|
51
|
+
severity, # %5$s
|
52
|
+
progname, # %6$s
|
53
|
+
msg # %7$s
|
54
|
+
]
|
55
|
+
|
56
|
+
if @logger.level == Logger::DEBUG
|
57
|
+
return self.debug_format % args
|
58
|
+
else
|
59
|
+
return self.format % args
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end # class LogFormatter
|
63
|
+
|
64
|
+
|
65
|
+
# An alternate formatter for Logger instances that outputs +dd+ HTML
|
66
|
+
# fragments.
|
67
|
+
class HtmlLogFormatter < Logger::Formatter # :nodoc:
|
68
|
+
include ERB::Util # for html_escape()
|
69
|
+
|
70
|
+
# The default HTML fragment that'll be used as the template for each log message.
|
71
|
+
HTML_LOG_FORMAT = %q{
|
72
|
+
<div class="log-message %5$s">
|
73
|
+
<span class="log-time">%1$s.%2$06d</span>
|
74
|
+
[
|
75
|
+
<span class="log-pid">%3$d</span>
|
76
|
+
/
|
77
|
+
<span class="log-tid">%4$s</span>
|
78
|
+
]
|
79
|
+
<span class="log-level">%5$s</span>
|
80
|
+
:
|
81
|
+
<span class="log-name">%6$s</span>
|
82
|
+
<span class="log-message-text">%7$s</span>
|
83
|
+
</div>
|
84
|
+
}
|
85
|
+
|
86
|
+
### Override the logging formats with ones that generate HTML fragments
|
87
|
+
def initialize( logger, format=HTML_LOG_FORMAT ) # :notnew:
|
88
|
+
@logger = logger
|
89
|
+
@format = format
|
90
|
+
super()
|
91
|
+
end
|
92
|
+
|
93
|
+
|
94
|
+
######
|
95
|
+
public
|
96
|
+
######
|
97
|
+
|
98
|
+
# The HTML fragment that will be used as a format() string for the log
|
99
|
+
attr_accessor :format
|
100
|
+
|
101
|
+
|
102
|
+
### Return a log message composed out of the arguments formatted using the
|
103
|
+
### formatter's format string
|
104
|
+
def call( severity, time, progname, msg )
|
105
|
+
args = [
|
106
|
+
time.strftime( '%Y-%m-%d %H:%M:%S' ), # %1$s
|
107
|
+
time.usec, # %2$d
|
108
|
+
Process.pid, # %3$d
|
109
|
+
Thread.current == Thread.main ? 'main' : Thread.object_id, # %4$s
|
110
|
+
severity.downcase, # %5$s
|
111
|
+
progname, # %6$s
|
112
|
+
html_escape( msg ).gsub(/\n/, '<br />') # %7$s
|
113
|
+
]
|
114
|
+
|
115
|
+
return self.format % args
|
116
|
+
end
|
117
|
+
|
118
|
+
end # class HtmlLogFormatter
|
119
|
+
|
120
|
+
end # module OpenLDAP
|
121
|
+
|
122
|
+
# vim: set nosta noet ts=4 sw=4:
|
123
|
+
|
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'pathname'
|
4
|
+
|
5
|
+
require 'openldap'
|
6
|
+
|
7
|
+
|
8
|
+
module OpenLDAP::TestConstants
|
9
|
+
|
10
|
+
unless defined?( TEST_LDAP_URI )
|
11
|
+
|
12
|
+
TEST_CONFIG_FILE = Pathname( __FILE__ ).dirname.parent.parent + 'test.conf'
|
13
|
+
|
14
|
+
TEST_LOCAL_LDAP_STRING = 'ldap://localhost'
|
15
|
+
TEST_LOCAL_LDAP_URI = URI( TEST_LOCAL_LDAP_STRING )
|
16
|
+
|
17
|
+
TEST_LDAP_STRING = 'ldap://ldap.example.com'
|
18
|
+
TEST_LDAP_URI = URI( TEST_LDAP_STRING )
|
19
|
+
|
20
|
+
TEST_LDAPBASE_STRING = 'ldap://ldap.example.com/dc=example,dc=com'
|
21
|
+
TEST_LDAPBASE_URI = URI( TEST_LDAPBASE_STRING )
|
22
|
+
|
23
|
+
constants.each do |cname|
|
24
|
+
const_get(cname).freeze
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
data/spec/lib/helpers.rb
ADDED
@@ -0,0 +1,128 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
# coding: utf-8
|
3
|
+
|
4
|
+
BEGIN {
|
5
|
+
require 'rbconfig'
|
6
|
+
require 'pathname'
|
7
|
+
basedir = Pathname.new( __FILE__ ).dirname.parent
|
8
|
+
|
9
|
+
libdir = basedir + "lib"
|
10
|
+
extdir = libdir + Config::CONFIG['sitearch']
|
11
|
+
|
12
|
+
$LOAD_PATH.unshift( libdir.to_s ) unless $LOAD_PATH.include?( libdir.to_s )
|
13
|
+
$LOAD_PATH.unshift( extdir.to_s ) unless $LOAD_PATH.include?( extdir.to_s )
|
14
|
+
}
|
15
|
+
|
16
|
+
require 'pp'
|
17
|
+
require 'yaml'
|
18
|
+
require 'logger'
|
19
|
+
|
20
|
+
require 'openldap'
|
21
|
+
require 'openldap/mixins'
|
22
|
+
|
23
|
+
require 'spec/lib/constants'
|
24
|
+
|
25
|
+
### Return a string-comparable version vector from +version+.
|
26
|
+
def vvec( version )
|
27
|
+
return version.split( '.' ).map( &:to_i ).pack( 'N' )
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
### RSpec helper functions.
|
32
|
+
module OpenLDAP::SpecHelpers
|
33
|
+
include OpenLDAP::TestConstants
|
34
|
+
|
35
|
+
class ArrayLogger
|
36
|
+
### Create a new ArrayLogger that will append content to +array+.
|
37
|
+
def initialize( array )
|
38
|
+
@array = array
|
39
|
+
end
|
40
|
+
|
41
|
+
### Write the specified +message+ to the array.
|
42
|
+
def write( message )
|
43
|
+
@array << message
|
44
|
+
end
|
45
|
+
|
46
|
+
### No-op -- this is here just so Logger doesn't complain
|
47
|
+
def close; end
|
48
|
+
|
49
|
+
end # class ArrayLogger
|
50
|
+
|
51
|
+
|
52
|
+
unless defined?( LEVEL )
|
53
|
+
LEVEL = {
|
54
|
+
:debug => Logger::DEBUG,
|
55
|
+
:info => Logger::INFO,
|
56
|
+
:warn => Logger::WARN,
|
57
|
+
:error => Logger::ERROR,
|
58
|
+
:fatal => Logger::FATAL,
|
59
|
+
}
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
###############
|
64
|
+
module_function
|
65
|
+
###############
|
66
|
+
|
67
|
+
### Reset the logging subsystem to its default state.
|
68
|
+
def reset_logging
|
69
|
+
OpenLDAP.reset_logger
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
### Alter the output of the default log formatter to be pretty in SpecMate output
|
74
|
+
def setup_logging( level=Logger::FATAL )
|
75
|
+
|
76
|
+
# Turn symbol-style level config into Logger's expected Fixnum level
|
77
|
+
if OpenLDAP::Loggable::LEVEL.key?( level )
|
78
|
+
level = OpenLDAP::Loggable::LEVEL[ level ]
|
79
|
+
end
|
80
|
+
|
81
|
+
logger = Logger.new( $stderr )
|
82
|
+
OpenLDAP.logger = logger
|
83
|
+
OpenLDAP.logger.level = level
|
84
|
+
|
85
|
+
# Only do this when executing from a spec in TextMate
|
86
|
+
if ENV['HTML_LOGGING'] || (ENV['TM_FILENAME'] && ENV['TM_FILENAME'] =~ /_spec\.rb/)
|
87
|
+
Thread.current['logger-output'] = []
|
88
|
+
logdevice = ArrayLogger.new( Thread.current['logger-output'] )
|
89
|
+
OpenLDAP.logger = Logger.new( logdevice )
|
90
|
+
# OpenLDAP.logger.level = level
|
91
|
+
OpenLDAP.logger.formatter = OpenLDAP::HtmlLogFormatter.new( OpenLDAP.logger )
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
|
96
|
+
### Load the testing LDAP config options from a YAML file.
|
97
|
+
def load_ldap_config
|
98
|
+
unless defined?( @ldap_config ) && @ldap_config
|
99
|
+
if TEST_CONFIG_FILE.exist?
|
100
|
+
$stderr.puts "Loading LDAP config from #{TEST_CONFIG_FILE}" if $VERBOSE
|
101
|
+
@ldap_config = YAML.load( TEST_CONFIG_FILE.read )
|
102
|
+
else
|
103
|
+
$stderr.puts "Skipping tests that require access to a live directory. Copy the ",
|
104
|
+
"#{TEST_CONFIG_FILE}-example file and provide valid values for testing",
|
105
|
+
"with an actual LDAP."
|
106
|
+
@ldap_config = {}
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
return @ldap_config
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
|
115
|
+
|
116
|
+
### Mock with Rspec
|
117
|
+
RSpec.configure do |config|
|
118
|
+
include OpenLDAP::TestConstants
|
119
|
+
|
120
|
+
config.mock_with :rspec
|
121
|
+
config.include( OpenLDAP::SpecHelpers )
|
122
|
+
|
123
|
+
config.filter_run_excluding( :ruby_1_9_only => true ) if vvec( RUBY_VERSION ) >= vvec( '1.9.0' )
|
124
|
+
config.filter_run_excluding( :with_ldap_server => true ) unless TEST_CONFIG_FILE.exist?
|
125
|
+
end
|
126
|
+
|
127
|
+
# vim: set nosta noet ts=4 sw=4:
|
128
|
+
|
@@ -0,0 +1,190 @@
|
|
1
|
+
#!/usr/bin/env rspec -cfd -b
|
2
|
+
|
3
|
+
BEGIN {
|
4
|
+
require 'pathname'
|
5
|
+
basedir = Pathname( __FILE__ ).dirname.parent.parent
|
6
|
+
libdir = basedir + 'lib'
|
7
|
+
|
8
|
+
$LOAD_PATH.unshift( basedir.to_s ) unless $LOAD_PATH.include?( basedir.to_s )
|
9
|
+
$LOAD_PATH.unshift( libdir.to_s ) unless $LOAD_PATH.include?( libdir.to_s )
|
10
|
+
}
|
11
|
+
|
12
|
+
require 'uri'
|
13
|
+
require 'rspec'
|
14
|
+
require 'spec/lib/helpers'
|
15
|
+
require 'openldap/connection'
|
16
|
+
|
17
|
+
describe OpenLDAP::Connection do
|
18
|
+
|
19
|
+
before( :all ) do
|
20
|
+
setup_logging( :fatal )
|
21
|
+
end
|
22
|
+
|
23
|
+
after( :all ) do
|
24
|
+
reset_logging()
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
it "can be created with an LDAP URI" do
|
29
|
+
conn = OpenLDAP::Connection.new( TEST_LDAP_URI )
|
30
|
+
conn.uris.should == [ TEST_LDAP_URI ]
|
31
|
+
end
|
32
|
+
|
33
|
+
it "can be created with an LDAP URI String" do
|
34
|
+
conn = OpenLDAP::Connection.new( TEST_LDAP_URI.to_s )
|
35
|
+
conn.uris.should == [ TEST_LDAP_URI ]
|
36
|
+
end
|
37
|
+
|
38
|
+
it "can be created with several LDAP URIs" do
|
39
|
+
conn = OpenLDAP::Connection.new( TEST_LDAP_URI, TEST_LOCAL_LDAP_URI )
|
40
|
+
conn.uris.should == [ TEST_LDAP_URI, TEST_LOCAL_LDAP_URI ]
|
41
|
+
end
|
42
|
+
|
43
|
+
context "an instance" do
|
44
|
+
|
45
|
+
before( :each ) do
|
46
|
+
@conn = OpenLDAP::Connection.new( TEST_LDAP_URI )
|
47
|
+
end
|
48
|
+
|
49
|
+
it "can set the cacert file used for TLS" do
|
50
|
+
@conn.tls_cacertfile = Pathname( '/etc/openssl/cacerts/ldap.pem' )
|
51
|
+
@conn.tls_cacertfile.should == '/etc/openssl/cacerts/ldap.pem'
|
52
|
+
end
|
53
|
+
|
54
|
+
it "can set the cacert directory used for TLS" do
|
55
|
+
@conn.tls_cacertdir = Pathname( '/etc/openssl/cacerts' )
|
56
|
+
@conn.tls_cacertdir.should == '/etc/openssl/cacerts'
|
57
|
+
end
|
58
|
+
|
59
|
+
it "can set the certificate file used for TLS" do
|
60
|
+
@conn.tls_certfile = Pathname( '/etc/openssl/host.pem' )
|
61
|
+
@conn.tls_certfile.should == '/etc/openssl/host.pem'
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
it "can set the cipher suite used for TLS" do
|
66
|
+
@conn.tls_cipher_suite = 'HIGH:MEDIUM:+SSLv2'
|
67
|
+
@conn.tls_cipher_suite.should == 'HIGH:MEDIUM:+SSLv2'
|
68
|
+
end
|
69
|
+
|
70
|
+
it "can set the CRL checking strategy used for TLS" do
|
71
|
+
@conn.tls_crlcheck = :all
|
72
|
+
@conn.tls_crlcheck.should == :all
|
73
|
+
end
|
74
|
+
|
75
|
+
it "can set the CRL file used for TLS" do
|
76
|
+
@conn.tls_crlfile = '/var/db/036D5FF52BA395A08BA2F780F9ADEAD905431757.crl'
|
77
|
+
@conn.tls_crlfile.should == '/var/db/036D5FF52BA395A08BA2F780F9ADEAD905431757.crl'
|
78
|
+
end
|
79
|
+
|
80
|
+
it "can set the dhfile used for TLS" do
|
81
|
+
@conn.tls_dhfile = '/etc/openssl/dh1024.pem'
|
82
|
+
@conn.tls_dhfile.should == '/etc/openssl/dh1024.pem'
|
83
|
+
end
|
84
|
+
|
85
|
+
it "can set the keyfile used for TLS" do
|
86
|
+
@conn.tls_keyfile = '/etc/openssl/host.key'
|
87
|
+
@conn.tls_keyfile.should == '/etc/openssl/host.key'
|
88
|
+
end
|
89
|
+
|
90
|
+
it "can set the package used for TLS in recent versions of libldap" do
|
91
|
+
if OpenLDAP.api_info[:vendor_name] == "OpenLDAP" &&
|
92
|
+
OpenLDAP.api_info[:vendor_version] >= 20426
|
93
|
+
@conn.tls_package.should == 'OpenSSL'
|
94
|
+
else
|
95
|
+
expect {
|
96
|
+
@conn.tls_package
|
97
|
+
}.to raise_error( NotImplementedError, /version of libldap/i )
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
it "can set the minimum protocol version used for TLS" do
|
102
|
+
@conn.tls_protocol_min = 11
|
103
|
+
@conn.tls_protocol_min.should == 11
|
104
|
+
end
|
105
|
+
|
106
|
+
it "can set the random_file used for TLS" do
|
107
|
+
# :TODO: Don't know how to test this appropriately.
|
108
|
+
# @conn.tls_random_file = '/dev/urandom'
|
109
|
+
@conn.tls_random_file.should be_nil()
|
110
|
+
end
|
111
|
+
|
112
|
+
it "can set the certificate verification strategy used for TLS" do
|
113
|
+
@conn.tls_require_cert = :demand
|
114
|
+
@conn.tls_require_cert.should == :demand
|
115
|
+
end
|
116
|
+
|
117
|
+
it "can be set to time out if the connect(2) takes longer than 2 seconds" do
|
118
|
+
@conn.network_timeout = 2.0
|
119
|
+
@conn.network_timeout.should == 2.0
|
120
|
+
end
|
121
|
+
|
122
|
+
it "can have its network timeout reset" do
|
123
|
+
@conn.network_timeout = nil
|
124
|
+
@conn.network_timeout.should be_nil()
|
125
|
+
end
|
126
|
+
|
127
|
+
it "can connect asynchronously" do
|
128
|
+
@conn.async_connect?.should be_false()
|
129
|
+
@conn.async_connect = true
|
130
|
+
@conn.async_connect?.should be_true()
|
131
|
+
end
|
132
|
+
|
133
|
+
it "can disable asynchronous connections after they've been enabled" do
|
134
|
+
@conn.async_connect = true
|
135
|
+
@conn.async_connect = false
|
136
|
+
@conn.async_connect?.should be_false()
|
137
|
+
end
|
138
|
+
|
139
|
+
end
|
140
|
+
|
141
|
+
context "an unconnected instance" do
|
142
|
+
|
143
|
+
before( :each ) do
|
144
|
+
@conn = OpenLDAP::Connection.new( TEST_LDAP_URI )
|
145
|
+
end
|
146
|
+
|
147
|
+
it "knows that its file-descriptor is nil" do
|
148
|
+
@conn.fdno.should be_nil()
|
149
|
+
end
|
150
|
+
|
151
|
+
end
|
152
|
+
|
153
|
+
|
154
|
+
it "can start TLS negotiation synchronously", :with_ldap_server => true do
|
155
|
+
config = load_ldap_config()
|
156
|
+
uri = config['uri'] or abort "No 'uri' in the test config!"
|
157
|
+
|
158
|
+
conn = OpenLDAP::Connection.new( uri )
|
159
|
+
conn.start_tls
|
160
|
+
end
|
161
|
+
|
162
|
+
context "a connected instance", :with_ldap_server => true do
|
163
|
+
|
164
|
+
before( :all ) do
|
165
|
+
config = load_ldap_config()
|
166
|
+
@uri = config['uri'] or abort "No 'uri' in the test config!"
|
167
|
+
end
|
168
|
+
|
169
|
+
before( :each ) do
|
170
|
+
@conn = OpenLDAP::Connection.new( @uri )
|
171
|
+
@conn.start_tls
|
172
|
+
end
|
173
|
+
|
174
|
+
it "knows what its file-descriptor is" do
|
175
|
+
@conn.fdno.should be_a( Fixnum )
|
176
|
+
@conn.fdno.should > 2 # Something past STDERR
|
177
|
+
end
|
178
|
+
|
179
|
+
it "can return an IO for selecting against its file-descriptor" do
|
180
|
+
@conn.socket.should be_an( IO )
|
181
|
+
@conn.socket.fileno.should == @conn.fdno
|
182
|
+
@conn.socket.should_not be_autoclose()
|
183
|
+
@conn.socket.should_not be_close_on_exec()
|
184
|
+
@conn.socket.should be_binmode()
|
185
|
+
end
|
186
|
+
|
187
|
+
end
|
188
|
+
|
189
|
+
end
|
190
|
+
|