diff --git a/Rakefile b/Rakefile index 724ccaa48..c085a980b 100644 --- a/Rakefile +++ b/Rakefile @@ -58,6 +58,11 @@ task :validate => :parser do lib << "uri" end + if lib == ["resolv"] + lib << "socket" + lib << "timeout" + end + sh "#{ruby} #{rbs} #{lib.map {|l| "-r #{l}"}.join(" ")} validate --silent" end end diff --git a/stdlib/resolv/0/resolv.rbs b/stdlib/resolv/0/resolv.rbs new file mode 100644 index 000000000..7589d9c47 --- /dev/null +++ b/stdlib/resolv/0/resolv.rbs @@ -0,0 +1,1504 @@ +# +# +# Windows NT +# +# +# Resolv is a thread-aware DNS resolver library written in Ruby. Resolv can +# handle multiple DNS requests concurrently without blocking the entire Ruby +# interpreter. +# +# See also resolv-replace.rb to replace the libc resolver with Resolv. +# +# Resolv can look up various DNS resources using the DNS module directly. +# +# Examples: +# +# p Resolv.getaddress "www.ruby-lang.org" +# p Resolv.getname "210.251.121.214" +# +# Resolv::DNS.open do |dns| +# ress = dns.getresources "www.ruby-lang.org", Resolv::DNS::Resource::IN::A +# p ress.map(&:address) +# ress = dns.getresources "ruby-lang.org", Resolv::DNS::Resource::IN::MX +# p ress.map { |r| [r.exchange.to_s, r.preference] } +# end +# +# ## Bugs +# +# * NIS is not supported. +# * /etc/nsswitch.conf is not supported. +# +class Resolv + + # Iterates over all IP addresses for `name`. + # + def self.each_address: (String name) { (String) -> void } -> void + + # Iterates over all hostnames for `address`. + # + def self.each_name: (String address) { (String) -> void } -> void + + # Looks up the first IP address for `name`. + # + def self.getaddress: (String name) -> String + + # Looks up all IP address for `name`. + # + def self.getaddresses: (String name) -> Array[String] + + # Looks up the hostname of `address`. + # + def self.getname: (String address) -> String + + # Looks up all hostnames for `address`. + # + def self.getnames: (String address) -> Array[String] + + public + + # Iterates over all IP addresses for `name`. + # + def each_address: (String name) { (String) -> void } -> void + + # Iterates over all hostnames for `address`. + # + def each_name: (String name) { (String) -> void } -> void + + # Looks up the first IP address for `name`. + # + def getaddress: (String name) -> String + + # Looks up all IP address for `name`. + # + def getaddresses: (String name) -> Array[String] + + # Looks up the hostname of `address`. + # + def getname: (String address) -> String + + # Looks up all hostnames for `address`. + # + def getnames: (String address) -> Array[String] + + private + + # Creates a new Resolv using `resolvers`. + # + def initialize: (?(Resolv::Hosts | Resolv::DNS) resolvers) -> untyped +end + +# Address Regexp to use for matching IP addresses. +Resolv::AddressRegex: Regexp + +# Default resolver to use for Resolv class methods. +Resolv::DefaultResolver: Resolv + +# Resolv::DNS is a DNS stub resolver. +# +# Information taken from the following places: +# +# * STD0013 +# * RFC 1035 +# * ftp://ftp.isi.edu/in-notes/iana/assignments/dns-parameters +# * etc. +# +class Resolv::DNS + type ip_address = Resolv::IPv4 | Resolv::IPv6 + + type dns_name = Name | String + + def self.allocate_request_id: (String host, Integer port) -> Integer + + def self.bind_random_port: (UDPSocket udpsock, ?String bind_host) -> void + + def self.free_request_id: (String host, Integer port, Integer id) -> void + + # Creates a new DNS resolver. See Resolv::DNS.new for argument details. + # + # Yields the created DNS resolver to the block, if given, otherwise returns it. + # + def self.open: (*untyped args) -> instance + | (*untyped args) { (instance) -> void } -> void + + def self.random: (Integer arg) -> (Integer | Float) + + public + + # Closes the DNS resolver. + # + def close: () -> untyped + + # Iterates over all IP addresses for `name` retrieved from the DNS resolver. + # + # `name` can be a Resolv::DNS::Name or a String. Retrieved addresses will be a + # Resolv::IPv4 or Resolv::IPv6 + # + def each_address: (dns_name name) { (ip_address) -> void } -> void + + # Iterates over all hostnames for `address` retrieved from the DNS resolver. + # + # `address` must be a Resolv::IPv4, Resolv::IPv6 or a String. Retrieved names + # will be Resolv::DNS::Name instances. + # + def each_name: (ip_address | dns_name address) { (Resolv::DNS::Name) -> void } -> void + + # Iterates over all `typeclass` DNS resources for `name`. See #getresource for + # argument details. + # + def each_resource: (dns_name name, singleton(Resolv::DNS::Query) typeclass) { (Resolv::DNS::Resource) -> void } -> void + + def extract_resources: (Resolv::DNS::Message msg, dns_name name, singleton(Resolv::DNS::Query) typeclass) { (Resolv::DNS::Resource) -> void } -> void + + def fetch_resource: (Resolv::DNS::Name name, singleton(Resolv::DNS::Query) typeclass) { (Resolv::DNS::Message, Resolv::DNS::Name) -> void } -> void + + # Gets the IP address of `name` from the DNS resolver. + # + # `name` can be a Resolv::DNS::Name or a String. Retrieved address will be a + # Resolv::IPv4 or Resolv::IPv6 + # + def getaddress: (dns_name name) -> ip_address + + # Gets all IP addresses for `name` from the DNS resolver. + # + # `name` can be a Resolv::DNS::Name or a String. Retrieved addresses will be a + # Resolv::IPv4 or Resolv::IPv6 + # + def getaddresses: (dns_name name) -> Array[ip_address] + + # Gets the hostname for `address` from the DNS resolver. + # + # `address` must be a Resolv::IPv4, Resolv::IPv6 or a String. Retrieved name + # will be a Resolv::DNS::Name. + # + def getname: (ip_address | dns_name address) -> Resolv::DNS::Name + + # Gets all hostnames for `address` from the DNS resolver. + # + # `address` must be a Resolv::IPv4, Resolv::IPv6 or a String. Retrieved names + # will be Resolv::DNS::Name instances. + # + def getnames: (ip_address | dns_name address) -> [Resolv::DNS::Name] + + # Look up the `typeclass` DNS resource of `name`. + # + # `name` must be a Resolv::DNS::Name or a String. + # + # `typeclass` should be one of the following: + # + # * Resolv::DNS::Resource::IN::A + # * Resolv::DNS::Resource::IN::AAAA + # * Resolv::DNS::Resource::IN::ANY + # * Resolv::DNS::Resource::IN::CNAME + # * Resolv::DNS::Resource::IN::HINFO + # * Resolv::DNS::Resource::IN::MINFO + # * Resolv::DNS::Resource::IN::MX + # * Resolv::DNS::Resource::IN::NS + # * Resolv::DNS::Resource::IN::PTR + # * Resolv::DNS::Resource::IN::SOA + # * Resolv::DNS::Resource::IN::TXT + # * Resolv::DNS::Resource::IN::WKS + # + # + # Returned resource is represented as a Resolv::DNS::Resource instance, i.e. + # Resolv::DNS::Resource::IN::A. + # + def getresource: (dns_name name, singleton(Resolv::DNS::Query) typeclass) -> Resolv::DNS::Resource + + # Looks up all `typeclass` DNS resources for `name`. See #getresource for + # argument details. + # + def getresources: (dns_name name, singleton(Resolv::DNS::Query) typeclass) -> Array[Resolv::DNS::Resource] + + def lazy_initialize: () -> untyped + + def make_tcp_requester: (String host, Integer port) -> Requester::TCP + + def make_udp_requester: () -> (Requester::ConnectedUDP | Requester::UnconnectedUDP) + + # Sets the resolver timeouts. This may be a single positive number or an array + # of positive numbers representing timeouts in seconds. If an array is + # specified, a DNS request will retry and wait for each successive interval in + # the array until a successful response is received. Specifying `nil` reverts + # to the default timeouts: + # 5, second = 5 * 2 / nameserver_count, 2 * second, 4 * second + # : Example: + # + # dns.timeouts = 3 + # + # + def timeouts=: (Integer | Float | Array[Integer | Float] values) -> void + + private + + # Creates a new DNS resolver. + # + # `config_info` can be: + # + # nil + # : Uses /etc/resolv.conf. + # String + # : Path to a file using /etc/resolv.conf's format. + # Hash + # : Must contain :nameserver, :search and :ndots keys. + # + # :nameserver_port can be used to specify port number of nameserver address. + # + # The value of :nameserver should be an address string or an array of address + # strings. + # * :nameserver => '8.8.8.8' + # * :nameserver => ['8.8.8.8', '8.8.4.4'] + # + # + # The value of :nameserver_port should be an array of pair of nameserver address + # and port number. + # * :nameserver_port => [['8.8.8.8', 53], ['8.8.4.4', 53]] + # + # + # Example: + # + # Resolv::DNS.new(:nameserver => ['210.251.121.21'], + # :search => ['ruby-lang.org'], + # :ndots => 1) + # + def initialize: (?(String | Hash[Symbol, untyped]) config_info) -> untyped + + def use_ipv6?: () -> untyped +end + +# Default DNS Port +Resolv::DNS::Port: Integer + +Resolv::DNS::RequestID: Hash[untyped, untyped] + +Resolv::DNS::RequestIDMutex: Thread::Mutex + +# Default DNS UDP packet size +Resolv::DNS::UDPSize: Integer + +class Resolv::DNS::Config + def self.default_config_hash: (?String filename) -> Hash[Symbol, untyped] + + def self.parse_resolv_conf: (String filename) -> Hash[Symbol, untyped] + + public + + def generate_candidates: (String name) -> Array[Resolv::DNS::Name] + + def generate_timeouts: () -> Array[Integer | Float] + + def lazy_initialize: () -> void + + def nameserver_port: () -> Array[[String, Integer]] + + def resolv: (String name) { (Resolv::DNS::Name, Integer, String, Integer) -> void } -> void + + def single?: () -> [String, Integer]? + + def timeouts=: (Integer | Float | Array[Integer | Float] values) -> void + + private + + def initialize: (?(String | Hash[Symbol, untyped]) config_info) -> untyped +end + +Resolv::DNS::Config::InitialTimeout: Integer + +# Indicates no such domain was found. +class Resolv::DNS::Config::NXDomain < Resolv::ResolvError +end + +# Indicates some other unhandled resolver error was encountered. +class Resolv::DNS::Config::OtherResolvError < Resolv::ResolvError +end + +# Indicates that the DNS response was unable to be decoded. +class Resolv::DNS::DecodeError < StandardError +end + +# Indicates that the DNS request was unable to be encoded. +class Resolv::DNS::EncodeError < StandardError +end + +module Resolv::DNS::Label + def self.split: (untyped arg) -> untyped +end + +class Resolv::DNS::Label::Str + public + + def eql?: (Resolv::DNS::Label::Str other) -> bool + + def downcase: () -> String + + alias == eql? + + def hash: () -> Integer + + def inspect: () -> String + + def string: () -> String + + def to_s: () -> String + + private + + def initialize: (String string) -> untyped +end + +class Resolv::DNS::Message + def self.decode: (String m) -> instance + + public + + def ==: (instance other) -> bool + + def aa: () -> Integer + + def aa=: (Integer) -> void + + def add_additional: (String name, Integer ttl, Resolv::DNS::Resource data) -> void + + def add_answer: (String name, Integer ttl, Resolv::DNS::Resource data) -> void + + def add_authority: (String name, Integer ttl, Resolv::DNS::Resource data) -> void + + def add_question: (String name, singleton(Resolv::DNS::Query) typeclass) -> void + + def additional: () -> Array[[Resolv::DNS::Name, Integer, Resolv::DNS::Resource]] + + def answer: () -> Array[[Resolv::DNS::Name, Integer, Resolv::DNS::Resource]] + + def authority: () -> Array[[Resolv::DNS::Name, Integer, Resolv::DNS::Resource]] + + def each_additional: () { (Resolv::DNS::Name, Integer, Resolv::DNS::Resource) -> void } -> void + + def each_answer: () { (Resolv::DNS::Name, Integer, Resolv::DNS::Resource) -> void } -> void + + def each_authority: () { (Resolv::DNS::Name, Integer, Resolv::DNS::Resource) -> void } -> void + + def each_question: () { (Resolv::DNS::Name, singleton(Resolv::DNS::Query)) -> void } -> void + + def each_resource: () { (Resolv::DNS::Name, Integer, Resolv::DNS::Resource) -> void } -> void + + def encode: () -> String + + def id: () -> Integer + + def id=: (Integer) -> void + + def opcode: () -> Integer + + def opcode=: (Integer) -> void + + def qr: () -> Integer + + def qr=: (Integer) -> void + + def question: () -> Array[[Resolv::DNS::Name, singleton(Resolv::DNS::Resource)]] + + def ra: () -> Integer + + def ra=: (Integer) -> void + + def rcode: () -> Integer + + def rcode=: (Integer) -> void + + def rd: () -> Integer + + def rd=: (Integer) -> void + + def tc: () -> Integer + + def tc=: (Integer) -> void + + private + + def initialize: (?Integer id) -> untyped +end + +class Resolv::DNS::Message::MessageDecoder + public + + def get_bytes: (?Integer len) -> String + + def get_label: () -> Resolv::DNS::Label::Str + + def get_labels: () -> Array[Resolv::DNS::Label::Str] + + def get_length16: () { (Integer) -> Integer } -> Integer + + def get_name: () -> Resolv::DNS::Name + + def get_question: () -> Resolv::DNS::Query + + def get_rr: () -> [Resolv::DNS::Name, Integer, Resolv::DNS::Resource] + + def get_string: () -> String + + def get_string_list: () -> Array[String] + + def get_unpack: (String template) -> Array[untyped] + + def inspect: () -> String + + private + + def initialize: (String data) { (instance) -> void } -> untyped +end + +class Resolv::DNS::Message::MessageEncoder + public + + def put_bytes: (string d) -> void + + def put_label: (_ToS d) -> void + + def put_labels: (Array[_ToS] d) -> void + + def put_length16: () { () -> void } -> void + + def put_name: (Resolv::DNS::Name d) -> void + + def put_pack: (String template, *untyped d) -> void + + def put_string: (String d) -> void + + def put_string_list: (_Each[String] ds) -> void + + def to_s: () -> untyped + + private + + def initialize: () -> untyped +end + +# A representation of a DNS name. +class Resolv::DNS::Name + # Creates a new DNS name from `arg`. `arg` can be: + # + # Name + # : returns `arg`. + # String + # : Creates a new Name. + # + # + def self.create: (Resolv::DNS::dns_name arg) -> untyped + + public + + def ==: (instance other) -> bool + + def []: (Integer i) -> Resolv::DNS::Label::Str? + + # True if this name is absolute. + # + def absolute?: () -> bool + + alias eql? == + + def hash: () -> Integer + + def inspect: () -> String + + def length: () -> Integer + + # Returns true if `other` is a subdomain. + # + # Example: + # + # domain = Resolv::DNS::Name.create("y.z") + # p Resolv::DNS::Name.create("w.x.y.z").subdomain_of?(domain) #=> true + # p Resolv::DNS::Name.create("x.y.z").subdomain_of?(domain) #=> true + # p Resolv::DNS::Name.create("y.z").subdomain_of?(domain) #=> false + # p Resolv::DNS::Name.create("z").subdomain_of?(domain) #=> false + # p Resolv::DNS::Name.create("x.y.z.").subdomain_of?(domain) #=> false + # p Resolv::DNS::Name.create("w.z").subdomain_of?(domain) #=> false + # + def subdomain_of?: (instance other) -> bool + + def to_a: () -> Array[Resolv::DNS::Label::Str] + + # returns the domain name as a string. + # + # The domain name doesn't have a trailing dot even if the name object is + # absolute. + # + # Example: + # + # p Resolv::DNS::Name.create("x.y.z.").to_s #=> "x.y.z" + # p Resolv::DNS::Name.create("x.y.z").to_s #=> "x.y.z" + # + def to_s: () -> untyped + + private + + def initialize: (Array[Resolv::DNS::Label::Str] labels, ?bool absolute) -> untyped +end + +module Resolv::DNS::OpCode +end + +Resolv::DNS::OpCode::IQuery: Integer + +Resolv::DNS::OpCode::Notify: Integer + +Resolv::DNS::OpCode::Query: Integer + +Resolv::DNS::OpCode::Status: Integer + +Resolv::DNS::OpCode::Update: Integer + +# A DNS query abstract class. +class Resolv::DNS::Query + def self.decode_rdata: (Resolv::DNS::Message::MessageDecoder msg) -> instance + + public + + def encode_rdata: (Resolv::DNS::Message::MessageEncoder msg) -> void +end + +module Resolv::DNS::RCode +end + +Resolv::DNS::RCode::BADALG: Integer + +Resolv::DNS::RCode::BADKEY: Integer + +Resolv::DNS::RCode::BADMODE: Integer + +Resolv::DNS::RCode::BADNAME: Integer + +Resolv::DNS::RCode::BADSIG: Integer + +Resolv::DNS::RCode::BADTIME: Integer + +Resolv::DNS::RCode::BADVERS: Integer + +Resolv::DNS::RCode::FormErr: Integer + +Resolv::DNS::RCode::NXDomain: Integer + +Resolv::DNS::RCode::NXRRSet: Integer + +Resolv::DNS::RCode::NoError: Integer + +Resolv::DNS::RCode::NotAuth: Integer + +Resolv::DNS::RCode::NotImp: Integer + +Resolv::DNS::RCode::NotZone: Integer + +Resolv::DNS::RCode::Refused: Integer + +Resolv::DNS::RCode::ServFail: Integer + +Resolv::DNS::RCode::YXDomain: Integer + +Resolv::DNS::RCode::YXRRSet: Integer + +class Resolv::DNS::Requester + public + + def close: () -> void + + def request: (Resolv::DNS::Requester::Sender sender, Numeric tout) -> [Resolv::DNS::Message, String] + + def sender_for: (String addr, Resolv::DNS::Message msg) -> Resolv::DNS::Requester::Sender + + private + + def initialize: () -> untyped +end + +class Resolv::DNS::Requester::ConnectedUDP < Resolv::DNS::Requester + public + + def close: () -> void + + def lazy_initialize: () -> void + + def recv_reply: (Array[UDPSocket] readable_socks) -> [String, String] + + def sender: (Resolv::DNS::Message msg, String data, ?String host, ?Integer port) -> Resolv::DNS::Requester::Sender + + private + + def initialize: (String host, ?Integer port) -> untyped +end + +class Resolv::DNS::Requester::ConnectedUDP::Sender < Resolv::DNS::Requester::Sender + public + + def data: () -> String + + def send: () -> void +end + +class Resolv::DNS::Requester::MDNSOneShot < Resolv::DNS::Requester::UnconnectedUDP + public + + def sender: (Resolv::DNS::Message msg, String data, ?String host, ?Integer port) -> Resolv::DNS::Requester::Sender + + def recv_reply: (Array[UDPSocket] readable_socks) -> [String, String] +end + +# Indicates a problem with the DNS request. +class Resolv::DNS::Requester::RequestError < StandardError +end + +class Resolv::DNS::Requester::Sender + private + + def initialize: (Resolv::DNS::Message msg, String data, Socket sock) -> untyped +end + +class Resolv::DNS::Requester::TCP < Resolv::DNS::Requester + public + + def close: () -> untyped + + def recv_reply: (Array[TCPSocket] readable_socks) -> [String, String] + + def sender: (Resolv::DNS::Message msg, String data, ?String host, ?Integer port) -> Resolv::DNS::Requester::Sender + + private + + def initialize: (String host, ?Integer port) -> untyped +end + +class Resolv::DNS::Requester::TCP::Sender < Resolv::DNS::Requester::Sender + public + + def data: () -> String + + def send: () -> void +end + +class Resolv::DNS::Requester::UnconnectedUDP < Resolv::DNS::Requester + public + + def close: () -> void + + def lazy_initialize: () -> void + + def recv_reply: (Array[UDPSocket] readable_socks) -> [String, String] + + def sender: (Resolv::DNS::Message msg, String data, ?String host, ?Integer port) -> Resolv::DNS::Requester::Sender + + private + + def initialize: (*[String, Integer] nameserver_port) -> untyped +end + +class Resolv::DNS::Requester::UnconnectedUDP::Sender < Resolv::DNS::Requester::Sender + public + + def data: () -> String + + def send: () -> void + + private + + def initialize: (Resolv::DNS::Message msg, String data, UDPSocket sock, String host, Integer port) -> untyped +end + +# A DNS resource abstract class. +class Resolv::DNS::Resource < Resolv::DNS::Query + def self.decode_rdata: (Resolv::DNS::Message::MessageDecoder msg) -> instance + + def self.get_class: (Integer type_value, Integer class_value) -> self + + public + + def eql?: (Resolv::DNS::Resource other) -> bool + + def encode_rdata: (Resolv::DNS::Message::MessageEncoder msg) -> void + + alias == eql? + + def hash: () -> Integer + + # Remaining Time To Live for this Resource. + # + def ttl: () -> Integer +end + +Resolv::DNS::Resource::ClassHash: Hash[[Integer, Integer], singleton(Resolv::DNS::Resource)] + +Resolv::DNS::Resource::ClassInsensitiveTypes: Array[singleton(Resolv::DNS::Resource)] + +Resolv::DNS::Resource::ClassValue: Integer? + +# A Query type requesting any RR. +class Resolv::DNS::Resource::ANY < Resolv::DNS::Query +end + +Resolv::DNS::Resource::ANY::TypeValue: Integer + +# The canonical name for an alias. +class Resolv::DNS::Resource::CNAME < Resolv::DNS::Resource::DomainName +end + +Resolv::DNS::Resource::CNAME::TypeValue: Integer + +# Domain Name resource abstract class. +class Resolv::DNS::Resource::DomainName < Resolv::DNS::Resource + def self.decode_rdata: (Resolv::DNS::Message::MessageDecoder msg) -> instance + + public + + def encode_rdata: (Resolv::DNS::Message::MessageEncoder msg) -> void + + # The name of this DomainName. + # + def name: () -> String + + private + + # Creates a new DomainName from `name`. + # + def initialize: (String name) -> untyped +end + +# A generic resource abstract class. +class Resolv::DNS::Resource::Generic < Resolv::DNS::Resource + def self.create: (Integer type_value, Integer class_value) -> instance + + def self.decode_rdata: (Resolv::DNS::Message::MessageDecoder msg) -> instance + + public + + # Data for this generic resource. + # + def data: () -> String + + def encode_rdata: (Resolv::DNS::Message::MessageEncoder msg) -> void + + private + + # Creates a new generic resource. + # + def initialize: (String data) -> untyped +end + +# Host Information resource. +class Resolv::DNS::Resource::HINFO < Resolv::DNS::Resource + def self.decode_rdata: (Resolv::DNS::Message::MessageDecoder msg) -> instance + + public + + # CPU architecture for this resource. + # + def cpu: () -> String + + def encode_rdata: (Resolv::DNS::Message::MessageEncoder msg) -> void + + # Operating system for this resource. + # + def os: () -> String + + private + + # Creates a new HINFO running `os` on `cpu`. + # + def initialize: (String cpu, String os) -> untyped +end + +Resolv::DNS::Resource::HINFO::TypeValue: Integer + +# module IN contains ARPA Internet specific RRs. +module Resolv::DNS::Resource::IN +end + +Resolv::DNS::Resource::IN::ClassValue: Integer + +# IPv4 Address resource +class Resolv::DNS::Resource::IN::A < Resolv::DNS::Resource + def self.decode_rdata: (Resolv::DNS::Message::MessageDecoder msg) -> instance + + public + + # The Resolv::IPv4 address for this A. + # + def address: () -> Resolv::IPv4 + + def encode_rdata: (Resolv::DNS::Message::MessageEncoder msg) -> void + + private + + # Creates a new A for `address`. + # + def initialize: (String | Resolv::IPv4 address) -> untyped +end + +Resolv::DNS::Resource::IN::A::ClassValue: Integer + +Resolv::DNS::Resource::IN::A::TypeValue: Integer + +# An IPv6 address record. +class Resolv::DNS::Resource::IN::AAAA < Resolv::DNS::Resource + def self.decode_rdata: (Resolv::DNS::Message::MessageDecoder msg) -> instance + + public + + # The Resolv::IPv6 address for this AAAA. + # + def address: () -> Resolv::IPv6 + + def encode_rdata: (Resolv::DNS::Message::MessageEncoder msg) -> void + + private + + # Creates a new AAAA for `address`. + # + def initialize: (String | Resolv::IPv6 address) -> untyped +end + +Resolv::DNS::Resource::IN::AAAA::ClassValue: Integer + +Resolv::DNS::Resource::IN::AAAA::TypeValue: Integer + +class Resolv::DNS::Resource::IN::ANY < Resolv::DNS::Resource::ANY +end + +Resolv::DNS::Resource::IN::ANY::ClassValue: Integer + +Resolv::DNS::Resource::IN::ANY::TypeValue: Integer + +class Resolv::DNS::Resource::IN::CNAME < Resolv::DNS::Resource::CNAME +end + +Resolv::DNS::Resource::IN::CNAME::ClassValue: Integer + +Resolv::DNS::Resource::IN::CNAME::TypeValue: Integer + +class Resolv::DNS::Resource::IN::HINFO < Resolv::DNS::Resource::HINFO +end + +Resolv::DNS::Resource::IN::HINFO::ClassValue: Integer + +Resolv::DNS::Resource::IN::HINFO::TypeValue: Integer + +class Resolv::DNS::Resource::IN::LOC < Resolv::DNS::Resource::LOC +end + +Resolv::DNS::Resource::IN::LOC::ClassValue: Integer + +Resolv::DNS::Resource::IN::LOC::TypeValue: Integer + +class Resolv::DNS::Resource::IN::MINFO < Resolv::DNS::Resource::MINFO +end + +Resolv::DNS::Resource::IN::MINFO::ClassValue: Integer + +Resolv::DNS::Resource::IN::MINFO::TypeValue: Integer + +class Resolv::DNS::Resource::IN::MX < Resolv::DNS::Resource::MX +end + +Resolv::DNS::Resource::IN::MX::ClassValue: Integer + +Resolv::DNS::Resource::IN::MX::TypeValue: Integer + +class Resolv::DNS::Resource::IN::NS < Resolv::DNS::Resource::NS +end + +Resolv::DNS::Resource::IN::NS::ClassValue: Integer + +Resolv::DNS::Resource::IN::NS::TypeValue: Integer + +class Resolv::DNS::Resource::IN::PTR < Resolv::DNS::Resource::PTR +end + +Resolv::DNS::Resource::IN::PTR::ClassValue: Integer + +Resolv::DNS::Resource::IN::PTR::TypeValue: Integer + +class Resolv::DNS::Resource::IN::SOA < Resolv::DNS::Resource::SOA +end + +Resolv::DNS::Resource::IN::SOA::ClassValue: Integer + +Resolv::DNS::Resource::IN::SOA::TypeValue: Integer + +# SRV resource record defined in RFC 2782 +# +# These records identify the hostname and port that a service is available at. +class Resolv::DNS::Resource::IN::SRV < Resolv::DNS::Resource + def self.decode_rdata: (Resolv::DNS::Message::MessageDecoder msg) -> instance + + public + + def encode_rdata: (Resolv::DNS::Message::MessageEncoder msg) -> void + + # The port on this target host of this service. + # + # The range is 0-65535. + # + def port: () -> Integer + + # The priority of this target host. + # + # A client MUST attempt to contact the target host with the lowest-numbered + # priority it can reach; target hosts with the same priority SHOULD be tried in + # an order defined by the weight field. The range is 0-65535. Note that it is + # not widely implemented and should be set to zero. + # + def priority: () -> Integer + + # The domain name of the target host. + # + # A target of "." means that the service is decidedly not available at this + # domain. + # + def target: () -> String + + # A server selection mechanism. + # + # The weight field specifies a relative weight for entries with the same + # priority. Larger weights SHOULD be given a proportionately higher probability + # of being selected. The range of this number is 0-65535. Domain administrators + # SHOULD use Weight 0 when there isn't any server selection to do, to make the + # RR easier to read for humans (less noisy). Note that it is not widely + # implemented and should be set to zero. + # + def weight: () -> Integer + + private + + # Create a SRV resource record. + # + # See the documentation for #priority, #weight, #port and #target for + # `priority`, `weight`, +port and `target` respectively. + # + def initialize: (Integer priority, Integer weight, Integer port, String target) -> untyped +end + +Resolv::DNS::Resource::IN::SRV::ClassValue: Integer + +Resolv::DNS::Resource::IN::SRV::TypeValue: Integer + +class Resolv::DNS::Resource::IN::TXT < Resolv::DNS::Resource::TXT +end + +Resolv::DNS::Resource::IN::TXT::ClassValue: Integer + +Resolv::DNS::Resource::IN::TXT::TypeValue: Integer + +# Well Known Service resource. +class Resolv::DNS::Resource::IN::WKS < Resolv::DNS::Resource + def self.decode_rdata: (Resolv::DNS::Message::MessageDecoder msg) -> instance + + public + + # The host these services run on. + # + def address: () -> Resolv::IPv4 + + # A bit map of enabled services on this host. + # + # If protocol is 6 (TCP) then the 26th bit corresponds to the SMTP service (port + # 25). If this bit is set, then an SMTP server should be listening on TCP port + # 25; if zero, SMTP service is not supported. + # + def bitmap: () -> Integer + + def encode_rdata: (Resolv::DNS::Message::MessageEncoder msg) -> void + + # IP protocol number for these services. + # + def protocol: () -> Integer + + private + + def initialize: (String | Resolv::IPv4 address, Integer protocol, Integer bitmap) -> untyped +end + +Resolv::DNS::Resource::IN::WKS::ClassValue: Integer + +Resolv::DNS::Resource::IN::WKS::TypeValue: Integer + +# Location resource +class Resolv::DNS::Resource::LOC < Resolv::DNS::Resource + def self.decode_rdata: (Resolv::DNS::Message::MessageDecoder msg) -> instance + + public + + # The altitude of the LOC above a reference sphere whose surface sits 100km + # below the WGS84 spheroid in centimeters as an unsigned 32bit integer + # + def altitude: () -> Integer + + def encode_rdata: (Resolv::DNS::Message::MessageEncoder msg) -> void + + # The horizontal precision using ssize type values in meters using scientific + # notation as 2 integers of XeY for precision use value/2 e.g. 2m = +/-1m + # + def hprecision: () -> Integer + + # The latitude for this LOC where 2**31 is the equator in thousandths of an arc + # second as an unsigned 32bit integer + # + def latitude: () -> Integer + + # The longitude for this LOC where 2**31 is the prime meridian in thousandths of + # an arc second as an unsigned 32bit integer + # + def longitude: () -> Integer + + # The spherical size of this LOC in meters using scientific notation as 2 + # integers of XeY + # + def ssize: () -> Integer + + # Returns the version value for this LOC record which should always be 00 + # + def version: () -> Integer + + # The vertical precision using ssize type values in meters using scientific + # notation as 2 integers of XeY for precision use value/2 e.g. 2m = +/-1m + # + def vprecision: () -> Integer + + private + + def initialize: (Integer version, Integer ssize, Integer hprecision, Integer vprecision, Integer latitude, Integer longitude, Integer altitude) -> untyped +end + +Resolv::DNS::Resource::LOC::TypeValue: Integer + +# Mailing list or mailbox information. +class Resolv::DNS::Resource::MINFO < Resolv::DNS::Resource + def self.decode_rdata: (Resolv::DNS::Message::MessageDecoder msg) -> instance + + public + + # Mailbox to use for error messages related to the mail list or mailbox. + # + def emailbx: () -> String + + def encode_rdata: (Resolv::DNS::Message::MessageEncoder msg) -> void + + # Domain name responsible for this mail list or mailbox. + # + def rmailbx: () -> String + + private + + def initialize: (String rmailbx, String emailbx) -> untyped +end + +Resolv::DNS::Resource::MINFO::TypeValue: Integer + +# Mail Exchanger resource. +class Resolv::DNS::Resource::MX < Resolv::DNS::Resource + def self.decode_rdata: (Resolv::DNS::Message::MessageDecoder msg) -> instance + + public + + def encode_rdata: (Resolv::DNS::Message::MessageEncoder msg) -> void + + # The host of this MX. + # + def exchange: () -> String + + # The preference for this MX. + # + def preference: () -> Integer + + private + + # Creates a new MX record with `preference`, accepting mail at `exchange`. + # + def initialize: (Integer preference, String exchange) -> untyped +end + +Resolv::DNS::Resource::MX::TypeValue: Integer + +# An authoritative name server. +class Resolv::DNS::Resource::NS < Resolv::DNS::Resource::DomainName +end + +Resolv::DNS::Resource::NS::TypeValue: Integer + +# A Pointer to another DNS name. +class Resolv::DNS::Resource::PTR < Resolv::DNS::Resource::DomainName +end + +Resolv::DNS::Resource::PTR::TypeValue: Integer + +# Start Of Authority resource. +class Resolv::DNS::Resource::SOA < Resolv::DNS::Resource + def self.decode_rdata: (Resolv::DNS::Message::MessageDecoder msg) -> instance + + public + + def encode_rdata: (Resolv::DNS::Message::MessageEncoder msg) -> void + + # Time in seconds that a secondary name server is to use the data before + # refreshing from the primary name server. + # + def expire: () -> Integer + + # The minimum number of seconds to be used for TTL values in RRs. + # + def minimum: () -> Integer + + # Name of the host where the master zone file for this zone resides. + # + def mname: () -> String + + # How often, in seconds, a secondary name server is to check for updates from + # the primary name server. + # + def refresh: () -> Integer + + # How often, in seconds, a secondary name server is to retry after a failure to + # check for a refresh. + # + def retry: () -> Integer + + # The person responsible for this domain name. + # + def rname: () -> String + + # The version number of the zone file. + # + def serial: () -> Integer + + private + + # Creates a new SOA record. See the attr documentation for the details of each + # argument. + # + def initialize: (String mname, String rname, Integer serial, Integer refresh, Integer retry_, Integer expire, Integer minimum) -> untyped +end + +Resolv::DNS::Resource::SOA::TypeValue: Integer + +# Unstructured text resource. +class Resolv::DNS::Resource::TXT < Resolv::DNS::Resource + def self.decode_rdata: (Resolv::DNS::Message::MessageDecoder msg) -> instance + + public + + # Returns the concatenated string from `strings`. + # + def data: () -> String + + def encode_rdata: (Resolv::DNS::Message::MessageEncoder msg) -> void + + # Returns an Array of Strings for this TXT record. + # + def strings: () -> Array[String] + + private + + def initialize: (String first_string, *String rest_strings) -> untyped +end + +Resolv::DNS::Resource::TXT::TypeValue: Integer + +# Resolv::Hosts is a hostname resolver that uses the system hosts file. +class Resolv::Hosts + public + + # Iterates over all IP addresses for `name` retrieved from the hosts file. + # + def each_address: (String name) { (String) -> void } -> void + + # Iterates over all hostnames for `address` retrieved from the hosts file. + # + def each_name: (String address) { (String) -> void } -> void + + # Gets the IP address of `name` from the hosts file. + # + def getaddress: (String name) -> String + + # Gets all IP addresses for `name` from the hosts file. + # + def getaddresses: (String name) -> Array[String] + + # Gets the hostname of `address` from the hosts file. + # + def getname: (String address) -> String + + # Gets all hostnames for `address` from the hosts file. + # + def getnames: (String address) -> Array[String] + + def lazy_initialize: () -> void + + private + + # Creates a new Resolv::Hosts, using `filename` for its data source. + # + def initialize: (?String filename) -> untyped +end + +Resolv::Hosts::DefaultFileName: String + +# A Resolv::DNS IPv4 address. +class Resolv::IPv4 + def self.create: (String | instance arg) -> instance + + public + + def ==: (instance other) -> bool + + # The raw IPv4 address as a String. + # + def address: () -> String + + def eql?: (instance other) -> bool + + def hash: () -> Integer + + def inspect: () -> String + + # Turns this IPv4 address into a Resolv::DNS::Name. + # + def to_name: () -> Resolv::DNS::Name + + def to_s: () -> String + + private + + def initialize: (String address) -> untyped +end + +Resolv::IPv4::Regex: Regexp + +# Regular expression IPv4 addresses must match. +Resolv::IPv4::Regex256: Regexp + +# A Resolv::DNS IPv6 address. +class Resolv::IPv6 + # Creates a new IPv6 address from `arg` which may be: + # + # IPv6 + # : returns `arg`. + # String + # : `arg` must match one of the IPv6::Regex* constants + # + # + def self.create: (String | instance arg) -> instance + + public + + def ==: (instance other) -> bool + + # The raw IPv6 address as a String. + # + def address: () -> String + + def eql?: (instance other) -> bool + + def hash: () -> Integer + + def inspect: () -> String + + # Turns this IPv6 address into a Resolv::DNS::Name. + # + def to_name: () -> Resolv::DNS::Name + + def to_s: () -> String + + private + + def initialize: (untyped address) -> untyped +end + +# A composite IPv6 address Regexp. +Resolv::IPv6::Regex: Regexp + +# IPv4 mapped IPv6 address format a:b:c:d:e:f:w.x.y.z +Resolv::IPv6::Regex_6Hex4Dec: Regexp + +# IPv6 address format a:b:c:d:e:f:g:h +Resolv::IPv6::Regex_8Hex: Regexp + +# IPv6 link local address format fe80:b:c:d:e:f:g:h%em1 +Resolv::IPv6::Regex_8HexLinkLocal: Regexp + +# Compressed IPv6 address format a::b +Resolv::IPv6::Regex_CompressedHex: Regexp + +# Compressed IPv4 mapped IPv6 address format a::b:w.x.y.z +Resolv::IPv6::Regex_CompressedHex4Dec: Regexp + +# Compressed IPv6 link local address format fe80::b%em1 +Resolv::IPv6::Regex_CompressedHexLinkLocal: Regexp + +module Resolv::LOC +end + +# A Resolv::LOC::Alt +class Resolv::LOC::Alt + # Creates a new LOC::Alt from `arg` which may be: + # + # LOC::Alt + # : returns `arg`. + # String + # : `arg` must match the LOC::Alt::Regex constant + # + # + def self.create: (Resolv::LOC::Alt | String arg) -> instance + + public + + def eql?: (Resolv::LOC::Alt other) -> bool + + # The raw altitude + # + def altitude: () -> Integer + + alias == eql? + + def hash: () -> Integer + + def inspect: () -> String + + def to_s: () -> String + + private + + def initialize: (Integer altitude) -> untyped +end + +Resolv::LOC::Alt::Regex: Regexp + +# A Resolv::LOC::Coord +class Resolv::LOC::Coord + type orientation = "lat" | "lon" + + # Creates a new LOC::Coord from `arg` which may be: + # + # LOC::Coord + # : returns `arg`. + # String + # : `arg` must match the LOC::Coord::Regex constant + # + # + def self.create: (Resolv::LOC::Coord | String arg) -> instance + + public + + def eql?: (Resolv::LOC::Coord other) -> bool + + # The raw coordinates + # + def coordinates: () -> String + + alias == eql? + + def hash: () -> Integer + + def inspect: () -> String + + # The orientation of the hemisphere as 'lat' or 'lon' + # + def orientation: () -> orientation + + def to_s: () -> String + + private + + def initialize: (String coordinates, orientation orientation) -> untyped +end + +Resolv::LOC::Coord::Regex: Regexp + +# A Resolv::LOC::Size +class Resolv::LOC::Size + # Creates a new LOC::Size from `arg` which may be: + # + # LOC::Size + # : returns `arg`. + # String + # : `arg` must match the LOC::Size::Regex constant + # + # + def self.create: (Resolv::LOC::Size | String arg) -> instance + + public + + def eql?: (Resolv::LOC::Size other) -> bool + + alias == eql? + + def hash: () -> Integer + + def inspect: () -> String + + # The raw size + # + def scalar: () -> String + + def to_s: () -> String + + private + + def initialize: (String scalar) -> untyped +end + +Resolv::LOC::Size::Regex: Regexp + +# Resolv::MDNS is a one-shot Multicast DNS (mDNS) resolver. It blindly makes +# queries to the mDNS addresses without understanding anything about multicast +# ports. +# +# Information taken form the following places: +# +# * RFC 6762 +# +class Resolv::MDNS < Resolv::DNS + public + + # Iterates over all IP addresses for `name` retrieved from the mDNS resolver, + # provided name ends with "local". If the name does not end in "local" no + # records will be returned. + # + # `name` can be a Resolv::DNS::Name or a String. Retrieved addresses will be a + # Resolv::IPv4 or Resolv::IPv6 + # + def each_address: (Resolv::DNS::dns_name name) -> Resolv::DNS::ip_address + + def make_udp_requester: () -> (Resolv::DNS::Requester::ConnectedUDP | Resolv::DNS::Requester::UnconnectedUDP) + + private + + # Creates a new one-shot Multicast DNS (mDNS) resolver. + # + # `config_info` can be: + # + # nil + # : Uses the default mDNS addresses + # + # Hash + # : Must contain :nameserver or :nameserver_port like Resolv::DNS#initialize. + # + # + def initialize: (?(String | Hash[Symbol, untyped]) config_info) -> untyped +end + +# Default IPv4 mDNS address +Resolv::MDNS::AddressV4: String + +# Default IPv6 mDNS address +Resolv::MDNS::AddressV6: String + +# Default mDNS addresses +Resolv::MDNS::Addresses: Array[untyped] + +# Default mDNS Port +Resolv::MDNS::Port: Integer + +# Indicates a failure to resolve a name or address. +class Resolv::ResolvError < StandardError +end + +# Indicates a timeout resolving a name or address. +class Resolv::ResolvTimeout < Timeout::Error +end diff --git a/stdlib/timeout/0/timeout.rbs b/stdlib/timeout/0/timeout.rbs index 6ad03128b..63dee304f 100644 --- a/stdlib/timeout/0/timeout.rbs +++ b/stdlib/timeout/0/timeout.rbs @@ -54,4 +54,9 @@ module Timeout def self?.timeout: [T] (Numeric? sec, ?singleton(Exception) klass, ?String message) { (Numeric sec) -> T } -> T end +# Raised by Timeout.timeout when the block times out. +class Timeout::Error < RuntimeError + attr_reader thread: Thread? +end + Timeout::VERSION: String diff --git a/test/stdlib/Resolv_test.rb b/test/stdlib/Resolv_test.rb new file mode 100644 index 000000000..e2be1073b --- /dev/null +++ b/test/stdlib/Resolv_test.rb @@ -0,0 +1,80 @@ +require_relative "test_helper" +require "resolv" + +class ResolvSingletonTest < Test::Unit::TestCase + include TypeAssertions + + library "resolv" + testing "singleton(::Resolv)" + + def test_each_address + assert_send_type "(String) { (String) -> void } -> void", + Resolv, :each_address, "localhost" do |c| c end + end + + def test_each_name + assert_send_type "(String) { (String) -> void } -> void", + Resolv, :each_name, "127.0.0.1" do |c| c end + end + + def test_getaddress + assert_send_type "(String) -> String", + Resolv, :getaddress, "localhost" + end + + def test_getaddresses + assert_send_type "(String) -> Array[String]", + Resolv, :getaddresses, "localhost" + end + + def test_getname + assert_send_type "(String) -> String", + Resolv, :getname, "127.0.0.1" + end + + def test_getnames + assert_send_type "(String) -> Array[String]", + Resolv, :getnames, "127.0.0.1" + end +end + +class ResolvInstanceTest < Test::Unit::TestCase + include TypeAssertions + + library "resolv" + testing "::Resolv" + + def resolv + Resolv.new + end + + def test_each_address + assert_send_type "(String) { (String) -> void } -> void", + resolv, :each_address, "localhost" do |c| c end + end + + def test_each_name + assert_send_type "(String) { (String) -> void } -> void", + resolv, :each_name, "127.0.0.1" do |c| c end + end + + def test_getaddress + assert_send_type "(String) -> String", + resolv, :getaddress, "localhost" + end + + def test_getaddresses + assert_send_type "(String) -> Array[String]", + resolv, :getaddresses, "localhost" + end + + def test_getname + assert_send_type "(String) -> String", + resolv, :getname, "127.0.0.1" + end + + def test_getnames + assert_send_type "(String) -> Array[String]", + resolv, :getnames, "127.0.0.1" + end + end diff --git a/test/stdlib/resolv/DNS_test.rb b/test/stdlib/resolv/DNS_test.rb new file mode 100644 index 000000000..d542a89ea --- /dev/null +++ b/test/stdlib/resolv/DNS_test.rb @@ -0,0 +1,481 @@ +require_relative '../test_helper' +require 'resolv' + +class ResolvDNSSingletonTest < Test::Unit::TestCase + include TypeAssertions + library 'resolv' + testing 'singleton(::Resolv::DNS)' + + def test_allocate_request_id + assert_send_type '(String, Integer) -> Integer', + Resolv::DNS, :allocate_request_id, "localhost", 53 + end + + def test_bind_random_port + assert_send_type '(UDPSocket) -> void', + Resolv::DNS, :bind_random_port, UDPSocket.new + assert_send_type '(UDPSocket, String) -> void', + Resolv::DNS, :bind_random_port, UDPSocket.new, "127.0.0.1" + end + + def test_free_request_id + assert_send_type '(String, Integer, Integer) -> void', + Resolv::DNS, :free_request_id, "localhost", 53, 123 + end + + def test_open + assert_send_type '(Hash[Symbol, untyped]) -> Resolv::DNS', + Resolv::DNS, :open, :nameserver => ["8.8.8.8"] + assert_send_type '(Hash[Symbol, untyped]) { (Resolv::DNS) -> void } -> void', + Resolv::DNS, :open, :nameserver => ["8.8.8.8"] do |c| c; end + end + + def test_random + assert_send_type '(Numeric) -> Numeric', + Resolv::DNS, :random, 2 + end +end + + +class ResolvDNSinstanceTest < Test::Unit::TestCase + include TypeAssertions + library 'resolv' + testing '::Resolv::DNS' + + def resolv_dns(*args) + dns = Resolv::DNS.new(*args) + dns.lazy_initialize + dns + end + + def test_close + assert_send_type "() -> void", + resolv_dns, :close + end + + def test_each_address + assert_send_type "(String) { (Resolv::IPv4 | Resolv::IPv6) -> void } -> void", + resolv_dns, :each_address, "localhost" do |c| c end + assert_send_type "(Resolv::DNS::Name) { (Resolv::IPv4 | Resolv::IPv6) -> void } -> void", + resolv_dns, :each_address, Resolv::DNS::Name.create("localhost") do |c| c end + end + + def test_each_name + assert_send_type "(String | Resolv::DNS::Name) { (Resolv::DNS::Name) -> void } -> void", + resolv_dns, :each_name, "127.0.0.1" do |c| c end + end + + def test_each_resource + assert_send_type "(String, singleton(Resolv::DNS::Query)) { (Resolv::DNS::Resource) -> void } -> void", + resolv_dns, :each_resource, "localhost", Resolv::DNS::Resource::IN::A do |*c| c end + assert_send_type "(Resolv::DNS::Name, singleton(Resolv::DNS::Query)) { (Resolv::DNS::Resource) -> void } -> void", + resolv_dns, :each_resource, Resolv::DNS::Name.create("localhost"), Resolv::DNS::Resource::IN::A do |*c| c end + end + + def test_extract_resources + msg = Resolv::DNS::Message.new + assert_send_type "(Resolv::DNS::Message, String, singleton(Resolv::DNS::Query)) { (Resolv::DNS::Resource) -> void } -> void", + resolv_dns, :extract_resources, msg, "localhost", Resolv::DNS::Resource::IN::A do |c| c end + assert_send_type "(Resolv::DNS::Message, Resolv::DNS::Name, singleton(Resolv::DNS::Query)) { (Resolv::DNS::Resource) -> void } -> void", + resolv_dns, :extract_resources, msg, Resolv::DNS::Name.create("localhost"), Resolv::DNS::Resource::IN::A do |c| c end + end + + def test_fetch_resource + assert_send_type "(Resolv::DNS::Name, singleton(Resolv::DNS::Query)) { (Resolv::DNS::Message, Resolv::DNS::Name) -> void } -> void", + resolv_dns, :fetch_resource, Resolv::DNS::Name.create("localhost"), Resolv::DNS::Resource::IN::A do |*c| c end + end + + def test_getaddress + assert_send_type "(String) -> (Resolv::IPv4 | Resolv::IPv6)", + resolv_dns, :getaddress, "localhost" + assert_send_type "(Resolv::DNS::Name) -> (Resolv::IPv4 | Resolv::IPv6)", + resolv_dns, :getaddress, Resolv::DNS::Name.create("localhost") + end + + def test_getaddresses + assert_send_type "(String) -> Array[Resolv::IPv4 | Resolv::IPv6]", + resolv_dns, :getaddresses, "localhost" + assert_send_type "(Resolv::DNS::Name) -> Array[Resolv::IPv4 | Resolv::IPv6]", + resolv_dns, :getaddresses, Resolv::DNS::Name.create("localhost") + end + + def test_getname + assert_send_type "(String) -> Resolv::DNS::Name", + resolv_dns, :getname, "127.0.0.1" + assert_send_type "(Resolv::IPv4) -> Resolv::DNS::Name", + resolv_dns, :getname, Resolv::IPv4.create("127.0.0.1") + assert_send_type "(Resolv::DNS::Name) -> Resolv::DNS::Name", + resolv_dns, :getname, Resolv::IPv4.create("127.0.0.1").to_name + end + + def test_getnames + assert_send_type "(String) -> Array[Resolv::DNS::Name]", + resolv_dns, :getnames, "127.0.0.1" + end + + def test_getresource + assert_send_type "(String, singleton(Resolv::DNS::Query)) -> Resolv::DNS::Resource", + resolv_dns, :getresource, "localhost", Resolv::DNS::Resource::IN::A + end + + def test_getresources + assert_send_type "(String, singleton(Resolv::DNS::Query)) -> Array[Resolv::DNS::Resource]", + resolv_dns, :getresources, "localhost", Resolv::DNS::Resource::IN::A + assert_send_type "(Resolv::DNS::Name, singleton(Resolv::DNS::Query)) -> Array[Resolv::DNS::Resource]", + resolv_dns, :getresources, Resolv::DNS::Name.create("localhost"), Resolv::DNS::Resource::IN::A + end + + def test_make_tcp_requester + assert_send_type "(String, Integer) -> Resolv::DNS::Requester::TCP", + resolv_dns, :make_tcp_requester, "8.8.8.8", 53 + end + + def test_make_udp_requester + assert_send_type "() -> Resolv::DNS::Requester::ConnectedUDP", + resolv_dns(nameserver: ["8.8.8.8"]), :make_udp_requester + assert_send_type "() -> Resolv::DNS::Requester::UnconnectedUDP", + resolv_dns(nameserver: ["127.0.0.1", "8.8.8.8"]), :make_udp_requester + end + + def test_timeouts= + assert_send_type "(Integer) -> void", + resolv_dns, :timeouts=, 5 + + assert_send_type "(Array[Integer]) -> void", + resolv_dns, :timeouts=, [5, 3, 2, 1] + end +end + +class ResolvDNSConfigSingletonTest < Test::Unit::TestCase + include TypeAssertions + library 'resolv' + testing 'singleton(::Resolv::DNS::Config)' + + def test_default_config_hash + assert_send_type '() -> Hash[Symbol, untyped]', + Resolv::DNS::Config, :default_config_hash + assert_send_type '(String) -> Hash[Symbol, untyped]', + Resolv::DNS::Config, :default_config_hash, "/etc/resolv.conf" + end + + def test_parse_resolv_conf + assert_send_type '(String) -> Hash[Symbol, untyped]', + Resolv::DNS::Config, :parse_resolv_conf, "/etc/resolv.conf" + end +end + +class ResolvDNSConfigInstanceTest < Test::Unit::TestCase + include TypeAssertions + library 'resolv' + testing '::Resolv::DNS::Config' + + def dns_config(*args) + config = Resolv::DNS::Config.new(*args) + config.lazy_initialize + config + end + + def test_generate_candidates + assert_send_type '(String) -> Array[Resolv::DNS::Name]', + dns_config, :generate_candidates, "localhost" + end + + def test_generate_timeouts + assert_send_type '() -> Array[Integer]', + dns_config, :generate_timeouts + end + + def test_nameserver_port + assert_send_type '() -> Array[[String, Integer]]', + dns_config, :nameserver_port + end + + def test_resolv + assert_send_type '(String) { (Resolv::DNS::Name, Integer, String, Integer) -> void } -> void', + dns_config, :resolv, "localhost" do |*c| c ; end + end + + def test_single? + assert_send_type '() -> [String, Integer]', + dns_config, :single? + end + + def test_timeouts= + assert_send_type "(Integer) -> void", + dns_config, :timeouts=, 5 + + assert_send_type "(Array[Integer]) -> void", + dns_config, :timeouts=, [5, 3, 2, 1] + end +end + +# class ResolvDNSMessageSingletonTest < Test::Unit::TestCase +# include TypeAssertions +# library 'resolv' +# testing 'singleton(::Resolv::DNS::Message)' + +# def test_decode +# assert_send_type "(String) -> Resolv::DNS::Message", +# Resolv::DNS::Message, :decode, "" +# end +# end + +class ResolvDNSMessageInstanceTest < Test::Unit::TestCase + include TypeAssertions + library 'resolv' + testing '::Resolv::DNS::Message' + + def dns_message + msg = Resolv::DNS::Message.new(0) + msg.add_additional("localhost", 220, Resolv::DNS::Resource::IN::A.new("127.0.0.1")) + msg.add_answer("localhost", 220, Resolv::DNS::Resource::IN::A.new("127.0.0.1")) + msg.add_authority("localhost", 220, Resolv::DNS::Resource::IN::A.new("127.0.0.1")) + msg.add_question("localhost", Resolv::DNS::Resource::IN::A) + msg + end + + def test_eql? + assert_send_type "(Resolv::DNS::Message) -> bool", + dns_message, :==, Resolv::DNS::Message.new(0) + end + + def test_add_additional + assert_send_type "(String, Integer, Resolv::DNS::Resource) -> void", + dns_message, :add_additional, "localhost", 220, Resolv::DNS::Resource::IN::A.new("127.0.0.1") + end + + def test_add_answer + assert_send_type "(String, Integer, Resolv::DNS::Resource) -> void", + dns_message, :add_answer, "localhost", 220, Resolv::DNS::Resource::IN::A.new("127.0.0.1") + end + + def test_add_authority + assert_send_type "(String, Integer, Resolv::DNS::Resource) -> void", + dns_message, :add_authority, "localhost", 220, Resolv::DNS::Resource::IN::A.new("127.0.0.1") + end + + def test_add_question + assert_send_type "(String, singleton(Resolv::DNS::Query)) -> void", + dns_message, :add_question, "localhost", Resolv::DNS::Resource::IN::A + end + + def test_each_additional + assert_send_type "() { (Resolv::DNS::Name, Integer, Resolv::DNS::Resource) -> void } -> void", + dns_message, :each_additional do |*c| c ; end + end + + def test_each_answer + assert_send_type "() { (Resolv::DNS::Name, Integer, Resolv::DNS::Resource) -> void } -> void", + dns_message, :each_answer do |*c| c ; end + end + + def test_each_authority + assert_send_type "() { (Resolv::DNS::Name, Integer, Resolv::DNS::Resource) -> void } -> void", + dns_message, :each_authority do |*c| c ; end + end + + def test_each_question + assert_send_type "() { (Resolv::DNS::Name, singleton(Resolv::DNS::Query)) -> void } -> void", + dns_message, :each_question do |*c| c ; end + end + + def test_each_resource + assert_send_type "() { (Resolv::DNS::Name, Integer, Resolv::DNS::Resource) -> void } -> void", + dns_message, :each_resource do |*c| c ; end + end + + def test_encode + assert_send_type "() -> String", + dns_message, :encode + end +end + +class ResolvDNSMessageEncoderInstanceTest < Test::Unit::TestCase + include TypeAssertions + library 'resolv' + testing '::Resolv::DNS::Message::MessageEncoder' + + def encoder + Resolv::DNS::Message::MessageEncoder.new{} + end + + def test_put_bytes + assert_send_type "(String) -> void", + encoder, :put_bytes, "a" + end + + def test_put_label + assert_send_type "(String) -> void", + encoder, :put_label, "data" + end + + def test_put_labels + assert_send_type "(Array[String]) -> void", + encoder, :put_labels, %w[data] + end + + def test_put_length16 + assert_send_type "() { () -> void } -> void", + encoder, :put_length16 do |c| c ; end + end + + def test_put_name + assert_send_type "(Resolv::DNS::Name) -> void", + encoder, :put_name, Resolv::DNS::Name.create("localhost") + end + + def test_put_pack + assert_send_type "(String, *untyped) -> void", + encoder, :put_pack, "C", 4 + end + + def test_put_string + assert_send_type "(String) -> void", + encoder, :put_string, "data" + end + + def test_put_string_list + assert_send_type "(Array[String]) -> void", + encoder, :put_string_list, ["data1", "data2"] + end +end + +class ResolvDNSMessageDecoderInstanceTest < Test::Unit::TestCase + include TypeAssertions + library 'resolv' + testing '::Resolv::DNS::Message::MessageDecoder' + + def decoder(data = "\u0004data\u0000") + Resolv::DNS::Message::MessageDecoder.new(data) {} + end + + def test_get_bytes + assert_send_type "() -> String", + decoder, :get_bytes + assert_send_type "(Integer) -> String", + decoder, :get_bytes, 2 + end + + def test_get_label + assert_send_type "() -> Resolv::DNS::Label::Str", + decoder, :get_label + end + + def test_get_labels + assert_send_type "() -> Array[Resolv::DNS::Label::Str]", + decoder, :get_labels + end + + def test_get_name + assert_send_type "() -> Resolv::DNS::Name", + decoder, :get_name + end + + def test_get_unpack + assert_send_type "(String) -> Array[untyped]", + decoder, :get_unpack, "c" + end + + def test_get_string + assert_send_type "() -> String", + decoder, :get_string + end + + def test_get_rr + assert_send_type "() -> [Resolv::DNS::Name, Integer, Resolv::DNS::Resource]", + decoder("\x05data0\x00\x05data1\x00\xC0\x00\xC0\a"), :get_rr + end + + def test_get_string_list + assert_send_type "() -> Array[String]", + decoder("\u0004data\u0000"), :get_string_list + end +end + +class ResolvDNSNameInstanceTest < Test::Unit::TestCase + include TypeAssertions + library 'resolv' + testing '::Resolv::DNS::Name' + + def dns_name + Resolv::DNS::Name.create("localhost") + end + + def test_eql? + assert_send_type "(Resolv::DNS::Name) -> bool", + dns_name, :==, Resolv::DNS::Name.create("localhost2") + end + + def test_lookup + assert_send_type "(Integer) -> Resolv::DNS::Label::Str", + dns_name, :[], 0 + assert_send_type "(Integer) -> nil", + dns_name, :[], 1 + end + + def test_absolute? + assert_send_type "() -> bool", + dns_name, :absolute? + end + + def test_hash + assert_send_type "() -> Integer", + dns_name, :hash + end + + def test_length + assert_send_type "() -> Integer", + dns_name, :length + end + + def test_subdomain_of? + assert_send_type "(Resolv::DNS::Name) -> bool", + dns_name, :subdomain_of?, Resolv::DNS::Name.create("localhost2") + end +end + +class ResolvDNSLabelStrInstanceTest < Test::Unit::TestCase + include TypeAssertions + library 'resolv' + testing '::Resolv::DNS::Label::Str' + + def label + Resolv::DNS::Label::Str.new("localhost") + end + + def test_eql? + assert_send_type "(Resolv::DNS::Label::Str) -> bool", + label, :==, Resolv::DNS::Label::Str.new("localhost2") + end + + def test_downcase + assert_send_type "() -> String", + label, :downcase + end + + def test_string + assert_send_type "() -> String", + label, :string + end + + def test_hash + assert_send_type "() -> Integer", + label, :hash + end +end + + +class ResolvDNSRequesterInstanceTest < Test::Unit::TestCase + include TypeAssertions + library 'resolv' + testing '::Resolv::DNS::Requester' + + def requester + Resolv::DNS::Requester.new + end + + def test_close + assert_send_type "() -> void", + requester, :close + end +end diff --git a/test/stdlib/resolv/Hosts_test.rb b/test/stdlib/resolv/Hosts_test.rb new file mode 100644 index 000000000..f511b029c --- /dev/null +++ b/test/stdlib/resolv/Hosts_test.rb @@ -0,0 +1,42 @@ +require_relative '../test_helper' +require 'resolv' + +class ResolvHostsInstanceTest < Test::Unit::TestCase + include TypeAssertions + library 'resolv' + testing '::Resolv::Hosts' + + def hosts + Resolv::Hosts.new + end + + def test_each_address + assert_send_type "(String) { (String) -> void } -> void", + hosts, :each_address, "localhost" do |c| c end + end + + def test_each_name + assert_send_type "(String) { (String) -> void } -> void", + hosts, :each_name, "127.0.0.1" do |c| c end + end + + def test_getaddress + assert_send_type "(String) -> String", + hosts, :getaddress, "localhost" + end + + def test_getaddresses + assert_send_type "(String) -> Array[String]", + hosts, :getaddresses, "localhost" + end + + def test_getname + assert_send_type "(String) -> String", + hosts, :getname, "127.0.0.1" + end + + def test_getnames + assert_send_type "(String) -> Array[String]", + hosts, :getnames, "127.0.0.1" + end +end diff --git a/test/stdlib/resolv/IPv4_test.rb b/test/stdlib/resolv/IPv4_test.rb new file mode 100644 index 000000000..a3e288bd2 --- /dev/null +++ b/test/stdlib/resolv/IPv4_test.rb @@ -0,0 +1,50 @@ +require_relative '../test_helper' +require 'resolv' + + +class ResolvIPv4SingletonTest < Test::Unit::TestCase + include TypeAssertions + library 'resolv' + testing 'singleton(::Resolv::IPv4)' + + def test_create + assert_send_type "(String) -> Resolv::IPv4", + Resolv::IPv4, :create, "8.8.8.8" + + rdata = [8,8,8,8].pack("CCCC") + ip = Resolv::IPv4.new(rdata) + assert_send_type "(Resolv::IPv4) -> Resolv::IPv4", + Resolv::IPv4, :create, ip + end +end + +class ResolvIPv4InstanceTest < Test::Unit::TestCase + include TypeAssertions + library 'resolv' + testing '::Resolv::IPv4' + + def ip(ipv4 = "127.0.0.1") + rdata = ipv4.split(".").map(&:to_i).pack("CCCC") + Resolv::IPv4.new(rdata) + end + + def test_eql? + assert_send_type "(Resolv::IPv4) -> bool", + ip, :==, ip("8.8.8.8") + end + + def test_address + assert_send_type "() -> String", + ip, :address + end + + def test_hash + assert_send_type "() -> Integer", + ip, :hash + end + + def test_to_name + assert_send_type "() -> Resolv::DNS::Name", + ip, :to_name + end +end diff --git a/test/stdlib/resolv/IPv6_test.rb b/test/stdlib/resolv/IPv6_test.rb new file mode 100644 index 000000000..380e9a1c5 --- /dev/null +++ b/test/stdlib/resolv/IPv6_test.rb @@ -0,0 +1,48 @@ +require_relative '../test_helper' +require 'resolv' + + +class ResolvIPv6SingletonTest < Test::Unit::TestCase + include TypeAssertions + library 'resolv' + testing 'singleton(::Resolv::IPv6)' + + def test_create + assert_send_type "(String) -> Resolv::IPv6", + Resolv::IPv6, :create, "2001:4860:4860::8888" + + ip = Resolv::IPv6.create("2001:4860:4860::8888") + assert_send_type "(Resolv::IPv6) -> Resolv::IPv6", + Resolv::IPv6, :create, ip + end +end + +class ResolvIPv6InstanceTest < Test::Unit::TestCase + include TypeAssertions + library 'resolv' + testing '::Resolv::IPv6' + + def ip(ipv6 = "::1") + Resolv::IPv6.create(ipv6) + end + + def test_eql? + assert_send_type "(Resolv::IPv6) -> bool", + ip, :==, ip("2001:4860:4860::8888") + end + + def test_address + assert_send_type "() -> String", + ip, :address + end + + def test_hash + assert_send_type "() -> Integer", + ip, :hash + end + + def test_to_name + assert_send_type "() -> Resolv::DNS::Name", + ip, :to_name + end +end