devdnsd 3.1.2 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +2 -2
- data/.rubocop.yml +82 -0
- data/.travis-gemfile +4 -10
- data/.travis.yml +11 -5
- data/CHANGELOG.md +11 -0
- data/Gemfile +9 -8
- data/README.md +4 -5
- data/Rakefile +22 -6
- data/bin/devdnsd +42 -36
- data/config/devdnsd_config.sample +11 -11
- data/devdnsd.gemspec +7 -6
- data/doc/DevDNSd.html +6 -6
- data/doc/DevDNSd/{ApplicationMethods/Aliases.html → Aliases.html} +96 -100
- data/doc/DevDNSd/Application.html +2170 -1084
- data/doc/DevDNSd/Configuration.html +63 -33
- data/doc/DevDNSd/Errors.html +3 -3
- data/doc/DevDNSd/Errors/InvalidRule.html +3 -3
- data/doc/DevDNSd/{ApplicationMethods/System.html → OSX.html} +116 -489
- data/doc/DevDNSd/Rule.html +448 -749
- data/doc/DevDNSd/{ApplicationMethods/Server.html → Server.html} +77 -73
- data/doc/DevDNSd/System.html +895 -0
- data/doc/DevDNSd/Version.html +6 -6
- data/doc/_index.html +28 -27
- data/doc/class_list.html +6 -2
- data/doc/file.README.html +8 -9
- data/doc/file_list.html +5 -1
- data/doc/frames.html +1 -1
- data/doc/index.html +8 -9
- data/doc/js/full_list.js +4 -1
- data/doc/method_list.html +106 -84
- data/doc/top-level-namespace.html +3 -3
- data/lib/devdnsd.rb +10 -8
- data/lib/devdnsd/aliases.rb +171 -0
- data/lib/devdnsd/application.rb +93 -704
- data/lib/devdnsd/configuration.rb +20 -11
- data/lib/devdnsd/errors.rb +1 -1
- data/lib/devdnsd/osx.rb +217 -0
- data/lib/devdnsd/rule.rb +65 -94
- data/lib/devdnsd/server.rb +118 -0
- data/lib/devdnsd/system.rb +102 -0
- data/lib/devdnsd/version.rb +3 -3
- data/locales/en.yml +17 -16
- data/locales/it.yml +17 -16
- data/spec/devdnsd/application_spec.rb +188 -184
- data/spec/devdnsd/configuration_spec.rb +2 -2
- data/spec/devdnsd/rule_spec.rb +33 -34
- data/spec/resolver_helper.rb +10 -27
- data/spec/spec_helper.rb +21 -7
- metadata +36 -21
- data/doc/DevDNSd/ApplicationMethods.html +0 -125
- data/doc/DevDNSd/ApplicationMethods/System/ClassMethods.html +0 -538
- data/spec/coverage_helper.rb +0 -20
@@ -0,0 +1,118 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
# This file is part of the devdnsd gem. Copyright (C) 2013 and above Shogun <shogun@cowtech.it>.
|
4
|
+
# Licensed under the MIT license, which can be found at http://www.opensource.org/licenses/mit-license.php.
|
5
|
+
#
|
6
|
+
|
7
|
+
# A small DNS server to enable local .dev domain resolution.
|
8
|
+
module DevDNSd
|
9
|
+
# Methods to process requests.
|
10
|
+
module Server
|
11
|
+
# Starts the DNS server.
|
12
|
+
#
|
13
|
+
# @return [Object] The result of stop callbacks.
|
14
|
+
def perform_server
|
15
|
+
application = self
|
16
|
+
|
17
|
+
@server = RubyDNS.run_server(server_options) do
|
18
|
+
self.logger = application.logger
|
19
|
+
|
20
|
+
match(/.+/, DevDNSd::Application::ANY_CLASSES) do |transaction, match_data|
|
21
|
+
# During debugging, wrap the inside of the block with a begin rescue and PRINT the exception because RubyDNS hides it.
|
22
|
+
application.config.rules.each { |rule| application.process_rule_in_classes(rule, match_data, transaction) }
|
23
|
+
end
|
24
|
+
|
25
|
+
# Default DNS handler and event handlers
|
26
|
+
otherwise { |transaction| transaction.failure!(:NXDomain) }
|
27
|
+
on(:start) { application.on_start }
|
28
|
+
on(:stop) { application.on_stop }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
alias_method :startup, :perform_server
|
33
|
+
|
34
|
+
# Processes a DNS rule.
|
35
|
+
#
|
36
|
+
# @param rule [Rule] The rule to process.
|
37
|
+
# @param type [Symbol] The type of the query.
|
38
|
+
# @param match_data [MatchData|nil] If the rule pattern was a Regexp, then this holds the match data, otherwise `nil` is passed.
|
39
|
+
# @param transaction [RubyDNS::Transaction] The current DNS transaction (http://rubydoc.info/gems/rubydns/RubyDNS/Transaction).
|
40
|
+
def process_rule(rule, type, match_data, transaction)
|
41
|
+
reply, type = perform_process_rule(rule, type, match_data, transaction)
|
42
|
+
logger.debug(reply ? i18n.reply(reply, type) : i18n.no_reply)
|
43
|
+
|
44
|
+
if reply
|
45
|
+
transaction.respond!(*finalize_reply(reply, rule, type))
|
46
|
+
else
|
47
|
+
reply.is_a?(FalseClass) ? false : nil
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Processes a rule against a set of DNS resource classes.
|
52
|
+
#
|
53
|
+
# @param rule [Rule] The rule to process.
|
54
|
+
# @param match_data [MatchData|nil] If the rule pattern was a Regexp, then this holds the match data, otherwise `nil` is passed.
|
55
|
+
# @param transaction [RubyDNS::Transaction] The current DNS transaction (http://rubydoc.info/gems/rubydns/RubyDNS/Transaction).
|
56
|
+
def process_rule_in_classes(rule, match_data, transaction)
|
57
|
+
# Get the subset of handled class that is valid for the rule
|
58
|
+
resource_classes = DevDNSd::Application::ANY_CLASSES & rule.resource_class.ensure_array
|
59
|
+
resource_classes &= [transaction.resource_class] if transaction.resource_class != DevDNSd::Application::ANY_REQUEST
|
60
|
+
|
61
|
+
if resource_classes.present?
|
62
|
+
resource_classes.each do |resource_class| # Now for every class
|
63
|
+
matches = rule.match_host(match_data[0])
|
64
|
+
process_rule(rule, resource_class, rule.regexp? ? matches : nil, transaction) if matches
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
# :nodoc:
|
72
|
+
def server_options
|
73
|
+
{asynchronous: !@config.foreground, listen: build_listen_interfaces}
|
74
|
+
end
|
75
|
+
|
76
|
+
# :nodoc:
|
77
|
+
def build_listen_interfaces
|
78
|
+
port = @config.port.to_integer
|
79
|
+
@config.bind_addresses.ensure_array { |address| [:udp, address, port] } + @config.bind_addresses.ensure_array { |address| [:tcp, address, port] }
|
80
|
+
end
|
81
|
+
|
82
|
+
# :nodoc:
|
83
|
+
def perform_process_rule(rule, type, match_data, transaction)
|
84
|
+
type = DevDNSd::Rule.resource_class_to_symbol(type)
|
85
|
+
reply = execute_rule(transaction, rule, type, match_data)
|
86
|
+
|
87
|
+
logger.debug(i18n.match(rule.match, type))
|
88
|
+
[reply, type]
|
89
|
+
end
|
90
|
+
|
91
|
+
# :nodoc:
|
92
|
+
def execute_rule(transaction, rule, type, match_data)
|
93
|
+
reply = rule.block ? rule.block.call(match_data, type, transaction) : rule.reply
|
94
|
+
reply = match_data[0].gsub(rule.match, reply.gsub("$", "\\")) if rule.match.is_a?(::Regexp) && reply && match_data && match_data[0]
|
95
|
+
reply
|
96
|
+
end
|
97
|
+
|
98
|
+
# :nodoc:
|
99
|
+
def finalize_reply(reply, rule, type)
|
100
|
+
rv = []
|
101
|
+
rv << rule.options.delete(:priority).to_integer(10) if type == :MX
|
102
|
+
rv << ([:A, :AAAA].include?(type) ? reply : Resolv::DNS::Name.create(reply))
|
103
|
+
rv << prepare_reply_options(rule, type)
|
104
|
+
rv
|
105
|
+
end
|
106
|
+
|
107
|
+
# :nodoc:
|
108
|
+
def prepare_reply_options(rule, type)
|
109
|
+
rule.options.merge({resource_class: DevDNSd::Rule.symbol_to_resource_class(type, @locale), ttl: validate_ttl(rule.options.delete(:ttl))})
|
110
|
+
end
|
111
|
+
|
112
|
+
# :nodoc:
|
113
|
+
def validate_ttl(current, default = 300)
|
114
|
+
current = current.to_integer
|
115
|
+
current > 0 ? current : default
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
# This file is part of the devdnsd gem. Copyright (C) 2013 and above Shogun <shogun@cowtech.it>.
|
4
|
+
# Licensed under the MIT license, which can be found at http://www.opensource.org/licenses/mit-license.php.
|
5
|
+
#
|
6
|
+
|
7
|
+
# A small DNS server to enable local .dev domain resolution.
|
8
|
+
module DevDNSd
|
9
|
+
# System management methods.
|
10
|
+
module System
|
11
|
+
extend ActiveSupport::Concern
|
12
|
+
|
13
|
+
# Returns the name of the daemon.
|
14
|
+
#
|
15
|
+
# @return [String] The name of the daemon.
|
16
|
+
def daemon_name
|
17
|
+
config ? File.basename(config.pid_file, ".pid") : "devdnsd"
|
18
|
+
end
|
19
|
+
|
20
|
+
alias_method :name, :daemon_name
|
21
|
+
|
22
|
+
# Returns the standard location of the PID file.
|
23
|
+
#
|
24
|
+
# @return [String] The standard location of the PID file.
|
25
|
+
def working_directory
|
26
|
+
config ? File.dirname(config.pid_file) : Dir.pwd
|
27
|
+
end
|
28
|
+
alias_method :runtime_directory, :working_directory
|
29
|
+
|
30
|
+
# Returns the complete path of the PID file.
|
31
|
+
#
|
32
|
+
# @return [String] The complete path of the PID file.
|
33
|
+
def process_file_path
|
34
|
+
config ? config.pid_file : Dir.pwd + "devdnsd.pid"
|
35
|
+
end
|
36
|
+
|
37
|
+
# Returns the complete path of the log file.
|
38
|
+
#
|
39
|
+
# @return [String] The complete path of the log file.
|
40
|
+
def log_file_path
|
41
|
+
config.log_file
|
42
|
+
end
|
43
|
+
|
44
|
+
# Returns the standard location of the log file.
|
45
|
+
#
|
46
|
+
# @return [String] The standard location of the log file.
|
47
|
+
def log_directory
|
48
|
+
File.dirname(config.log_file)
|
49
|
+
end
|
50
|
+
|
51
|
+
# Starts the server in background.
|
52
|
+
#
|
53
|
+
# @return [Boolean] `true` if action succeeded, `false` otherwise.
|
54
|
+
def action_start
|
55
|
+
logger.info(i18n.starting)
|
56
|
+
|
57
|
+
prepare_start
|
58
|
+
|
59
|
+
@config.foreground ? perform_server : self.class.start
|
60
|
+
true
|
61
|
+
end
|
62
|
+
|
63
|
+
# Stops the server in background.
|
64
|
+
#
|
65
|
+
# @return [Boolean] `true` if action succeeded, `false` otherwise.
|
66
|
+
def action_stop
|
67
|
+
self.class.stop
|
68
|
+
true
|
69
|
+
end
|
70
|
+
|
71
|
+
# Restarts the server in background.
|
72
|
+
#
|
73
|
+
# @return [Boolean] `true` if action succeeded, `false` otherwise.
|
74
|
+
def action_restart
|
75
|
+
action_stop
|
76
|
+
action_start
|
77
|
+
true
|
78
|
+
end
|
79
|
+
|
80
|
+
# Shows the status of the server
|
81
|
+
#
|
82
|
+
# @return [Boolean] `true` if action succeeded, `false` otherwise.
|
83
|
+
def action_status
|
84
|
+
status = self.class.status
|
85
|
+
status = :crashed if status == :unknown && self.class.crashed?
|
86
|
+
|
87
|
+
log_status(self.class.controller.pid, status)
|
88
|
+
end
|
89
|
+
|
90
|
+
private
|
91
|
+
|
92
|
+
# :nodoc:
|
93
|
+
def prepare_start
|
94
|
+
if !Process.respond_to?(:fork)
|
95
|
+
logger.warn(i18n.no_fork)
|
96
|
+
@config.foreground = true
|
97
|
+
elsif @command.options[:foreground].value
|
98
|
+
@config.foreground = true
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
data/lib/devdnsd/version.rb
CHANGED
@@ -10,13 +10,13 @@ module DevDNSd
|
|
10
10
|
# @see http://semver.org
|
11
11
|
module Version
|
12
12
|
# The major version.
|
13
|
-
MAJOR =
|
13
|
+
MAJOR = 4
|
14
14
|
|
15
15
|
# The minor version.
|
16
|
-
MINOR =
|
16
|
+
MINOR = 0
|
17
17
|
|
18
18
|
# The patch version.
|
19
|
-
PATCH =
|
19
|
+
PATCH = 0
|
20
20
|
|
21
21
|
# The current version number of DevDNSd.
|
22
22
|
STRING = [MAJOR, MINOR, PATCH].compact.join(".")
|
data/locales/en.yml
CHANGED
@@ -5,33 +5,34 @@
|
|
5
5
|
#
|
6
6
|
|
7
7
|
---
|
8
|
+
en:
|
8
9
|
devdnsd:
|
9
10
|
rule_invalid_call: "You must specify at least a rule and a host (also via a block). Optionally you can add a record type (default: A) and the options."
|
10
11
|
rule_invalid_options: "You can only use hashs for options."
|
11
|
-
rule_invalid_resource: "Invalid resource class %
|
12
|
+
rule_invalid_resource: "Invalid resource class %s."
|
12
13
|
dns_update: "Flushing DNS cache and resolvers ..."
|
13
14
|
no_jruby: "DevDNSd is not available on JRuby."
|
14
15
|
no_fork: "Forking is not available for this platform. Running in foreground ..."
|
15
16
|
starting: "Starting DevDNSd ..."
|
16
|
-
match: "Found match on %
|
17
|
-
reply: "Reply is %
|
17
|
+
match: "Found match on %s with type %s."
|
18
|
+
reply: "Reply is %s with type %s."
|
18
19
|
no_reply: "No reply found."
|
19
20
|
no_agent: "Install DevDNSd as a local resolver is only available on MacOSX."
|
20
21
|
admin_privileges_warning: "Basing on your setup, the system might ask you up to twice to grant {mark=bright}osascript{/mark} application admin privileges."
|
21
|
-
resolver_creating: "Creating the resolver in {mark=bright}%
|
22
|
+
resolver_creating: "Creating the resolver in {mark=bright}%s{/mark} ..."
|
22
23
|
resolver_creating_error: "Cannot create the resolver file."
|
23
|
-
resolver_deleting: "Deleting the resolver %
|
24
|
+
resolver_deleting: "Deleting the resolver %s ..."
|
24
25
|
resolver_deleting_error: "Cannot delete the resolver file."
|
25
|
-
agent_creating: "Creating the launch agent in {mark=bright}%
|
26
|
+
agent_creating: "Creating the launch agent in {mark=bright}%s{/mark} ..."
|
26
27
|
agent_creating_error: "Cannot create the launch agent."
|
27
|
-
agent_deleting: "Deleting the launch agent %
|
28
|
+
agent_deleting: "Deleting the launch agent %s ..."
|
28
29
|
agent_deleting_error: "Cannot delete the launch agent."
|
29
|
-
agent_loading: "Loading the launch agent %
|
30
|
+
agent_loading: "Loading the launch agent %s ..."
|
30
31
|
agent_loading_error: "Cannot load the launch agent."
|
31
|
-
agent_unloading: "Unloading the launch agent %
|
32
|
+
agent_unloading: "Unloading the launch agent %s ..."
|
32
33
|
agent_unloading_error: "Cannot unload the launch agent."
|
33
|
-
logging_failed: "Cannot log to {mark=bright}%
|
34
|
-
invalid_directory: "Cannot write on directory {mark=bright}%
|
34
|
+
logging_failed: "Cannot log to {mark=bright}%s{/mark}. Logging to terminal..."
|
35
|
+
invalid_directory: "Cannot write on directory {mark=bright}%s{/mark}. Exiting..."
|
35
36
|
application_description: "A small DNS server to enable local domain resolution."
|
36
37
|
application_help_configuration: "The configuration file to use. Default is \"~/.devdnsd_config\"."
|
37
38
|
application_help_tld: "The TLD to handle. Default is \"dev\"."
|
@@ -56,7 +57,7 @@
|
|
56
57
|
application_meta_addresses: "ADDRESSES"
|
57
58
|
application_meta_aliases: "ALIASES"
|
58
59
|
application_meta_command: "COMMAND"
|
59
|
-
application_create_config: "To execute devdnsd, please create the file {mark=bright}%
|
60
|
+
application_create_config: "To execute devdnsd, please create the file {mark=bright}%s{/mark}. An empty file is sufficient."
|
60
61
|
command_start: "Starts the server."
|
61
62
|
command_stop: "Stops the server."
|
62
63
|
command_restart: "Restarts the server."
|
@@ -67,7 +68,7 @@
|
|
67
68
|
command_aliases: "Adds or removes aliases to network interfaces."
|
68
69
|
command_add: "Adds aliases."
|
69
70
|
command_remove: "Removes aliases."
|
70
|
-
status_running: "The server is running with process ID {mark=bright}%
|
71
|
+
status_running: "The server is running with process ID {mark=bright}%s{/mark}."
|
71
72
|
status_stopped: "The server is stopped."
|
72
73
|
status_crashed: "The server crashed. See the log for more information."
|
73
74
|
status_unknown: "The server status is unknown."
|
@@ -77,8 +78,8 @@
|
|
77
78
|
add: "add"
|
78
79
|
to: "to "
|
79
80
|
from: "from "
|
80
|
-
general_error: "Cannot {mark=bright}%
|
81
|
+
general_error: "Cannot {mark=bright}%s{/mark} address {mark=bright}%s{/mark} %sinterface {mark=bright}%s{/mark}."
|
81
82
|
add_empty: "No valid addresses to add to the interface found."
|
82
83
|
remove_empty: "No valid addresses to remove from the interface found."
|
83
|
-
run: "%
|
84
|
-
dry_run: "%
|
84
|
+
run: "%s {mark=bright}%s{/mark} address {mark=bright}%s{/mark} %sinterface {mark=bright}%s{/mark}..."
|
85
|
+
dry_run: "%s I will {mark=bright}%s{/mark} address {mark=bright}%s{/mark} %sinterface {mark=bright}%s{/mark}..."
|
data/locales/it.yml
CHANGED
@@ -5,33 +5,34 @@
|
|
5
5
|
#
|
6
6
|
|
7
7
|
---
|
8
|
+
it:
|
8
9
|
devdnsd:
|
9
10
|
rule_invalid_call: "Devi specificare almeno una regola e un host (anche tramite un blocco). Opzionalmente puoi aggiungere un tipo di record (default: A) e le opzioni."
|
10
11
|
rule_invalid_options: "Puoi usare solo hash per le opzioni."
|
11
|
-
rule_invalid_resource: "Classe di risorsa %
|
12
|
+
rule_invalid_resource: "Classe di risorsa %s non valida."
|
12
13
|
no_jruby: "DevDNSd non è disponibile per JRuby."
|
13
14
|
no_fork: "Il forking non è disponibile per questa piattaforma. Eseguo foreground ..."
|
14
15
|
dns_update: "Cancello la cache dei DNS e dei resolver ..."
|
15
16
|
starting: "Avvio DevDNSd ..."
|
16
|
-
match: "Trovata corrispondenza per %
|
17
|
-
reply: "La risposta è %
|
17
|
+
match: "Trovata corrispondenza per %s con tipo %s."
|
18
|
+
reply: "La risposta è %s con tipo %s."
|
18
19
|
no_reply: "Nessuna risposta trovata."
|
19
20
|
no_agent: "Installare DevDNSd come resolver locale è disponibile solo su MacOSX."
|
20
21
|
admin_privileges_warning: "In base alla tua configurazione, il sistema potrebbe chiederti fino a due volte di garantire all'applicazione {mark=bright}osascript{/mark} i privilegi di amministratore."
|
21
|
-
resolver_creating: "Creo il resolver in {mark=bright}%
|
22
|
+
resolver_creating: "Creo il resolver in {mark=bright}%s{/mark} ..."
|
22
23
|
resolver_creating_error: "Impossible creare il file del resolver."
|
23
|
-
resolver_deleting: "Cancello resolver %
|
24
|
+
resolver_deleting: "Cancello resolver %s ..."
|
24
25
|
resolver_deleting_error: "Impossibile cancellare il file del resolver."
|
25
|
-
agent_creating: "Creo il launch agent in {mark=bright}%
|
26
|
+
agent_creating: "Creo il launch agent in {mark=bright}%s{/mark} ..."
|
26
27
|
agent_creating_error: "Impossibile creare il launch agent."
|
27
|
-
agent_deleting: "Cancello il launch agent %
|
28
|
+
agent_deleting: "Cancello il launch agent %s ..."
|
28
29
|
agent_deleting_error: "Impossibile cancellare launch agent."
|
29
|
-
agent_loading: "Avvio il launch agent %
|
30
|
+
agent_loading: "Avvio il launch agent %s ..."
|
30
31
|
agent_loading_error: "Impossibile avviare il launch agent."
|
31
|
-
agent_unloading: "Fermo il launch agent %
|
32
|
+
agent_unloading: "Fermo il launch agent %s ..."
|
32
33
|
agent_unloading_error: "Impossible fermare il launch agent."
|
33
|
-
logging_failed: "Impossibile eseguire il logging in {mark=bright}%
|
34
|
-
invalid_directory: "Impossibile scrivere sulla directory {mark=bright}%
|
34
|
+
logging_failed: "Impossibile eseguire il logging in {mark=bright}%s{/mark}. Eseguo il logging nel terminale..."
|
35
|
+
invalid_directory: "Impossibile scrivere sulla directory {mark=bright}%s{/mark}. Esco..."
|
35
36
|
application_description: "Un piccolo server DNS per abilitare la risoluzione di domini locali."
|
36
37
|
application_help_configuration: "Il file di configurazione da usare. Il valore predefinito è \"~/.devdnsd_config\"."
|
37
38
|
application_help_tld: "Il TLD da gestiere. Il valore predefinito è \"dev\"."
|
@@ -57,7 +58,7 @@
|
|
57
58
|
application_meta_addresses: "INDIRIZZI"
|
58
59
|
application_meta_aliases: "ALIAS"
|
59
60
|
application_meta_command: "COMANDO"
|
60
|
-
application_create_config: "Per eseguire devdnsd, per favore crea il file {mark=bright}%
|
61
|
+
application_create_config: "Per eseguire devdnsd, per favore crea il file {mark=bright}%s{/mark}. Un file vuoto è sufficiente."
|
61
62
|
command_start: "Avvia server."
|
62
63
|
command_stop: "Ferma il server."
|
63
64
|
command_restart: "Riavvia server."
|
@@ -68,7 +69,7 @@
|
|
68
69
|
command_aliases: "Aggiunge or rimuove indirizzi dalle interfacce di rete."
|
69
70
|
command_add: "Aggiungi indirizzi"
|
70
71
|
command_remove: "Rimuovi indirizzi."
|
71
|
-
status_running: "Il server è in esecuzione con ID processo {mark=bright}%
|
72
|
+
status_running: "Il server è in esecuzione con ID processo {mark=bright}%s{/mark}."
|
72
73
|
status_stopped: "Il server è stato fermato."
|
73
74
|
status_crashed: "Il server è terminato con errori. Guarda il log per maggiori informazioni."
|
74
75
|
status_unknown: "Lo status del server è sconosciuto."
|
@@ -78,8 +79,8 @@
|
|
78
79
|
add: "aggiungere"
|
79
80
|
to: "all'"
|
80
81
|
from: "dall'"
|
81
|
-
general_error: "Impossibile {mark=bright}%
|
82
|
+
general_error: "Impossibile {mark=bright}%s{/mark} l'indirizzo {mark=bright}%s{/mark} %sinterfaccia {mark=bright}%s{/mark}."
|
82
83
|
add_empty: "Nessun indirizzo valido da aggiungere all'interfaccia trovato."
|
83
84
|
remove_empty: "Nessun indirizzo valido da rimuovere dall'interfaccia trovato."
|
84
|
-
run: "%
|
85
|
-
dry_run: "%
|
85
|
+
run: "%s {mark=bright}%s{/mark} l'indirizzo {mark=bright}%s{/mark} %sinterfaccia {mark=bright}%s{/mark}..."
|
86
|
+
dry_run: "%s Sto per {mark=bright}%s{/mark} l'indirizzo {mark=bright}%s{/mark} %sinterfaccia {mark=bright}%s{/mark}..."
|
@@ -10,6 +10,7 @@ describe DevDNSd::Application do
|
|
10
10
|
before(:each) do
|
11
11
|
allow(Bovem::Logger).to receive(:default_file).and_return("/dev/null")
|
12
12
|
allow(DevDNSd::Application).to receive(:instance).and_return(application)
|
13
|
+
allow(Kernel).to receive(:exit)
|
13
14
|
end
|
14
15
|
|
15
16
|
def create_application(overrides = {})
|
@@ -24,7 +25,7 @@ describe DevDNSd::Application do
|
|
24
25
|
end
|
25
26
|
|
26
27
|
let(:log_file) { "/tmp/devdnsd-test-log-#{Time.now.strftime("%Y%m%d-%H%M%S")}" }
|
27
|
-
let(:application){ create_application({"log_file" => log_file}) }
|
28
|
+
let(:application){ create_application({"log_file" => log_file, "configuration" => "/dev/null"}) }
|
28
29
|
let(:executable) { ::Pathname.new(::File.dirname((__FILE__))) + "../../bin/devdnsd" }
|
29
30
|
let(:sample_config) { ::Pathname.new(::File.dirname((__FILE__))) + "../../config/devdnsd_config.sample" }
|
30
31
|
let(:resolver_path) { "/tmp/devdnsd-test-resolver-#{Time.now.strftime("%Y%m%d-%H%M%S")}" }
|
@@ -37,7 +38,7 @@ describe DevDNSd::Application do
|
|
37
38
|
|
38
39
|
it "should fallback logger to STDOUT" do
|
39
40
|
allow_any_instance_of(DevDNSd::Application).to receive(:read_configuration)
|
40
|
-
expect(Bovem::Logger).to receive(:create).with($stdout, Logger::INFO)
|
41
|
+
expect(Bovem::Logger).to receive(:create).with($stdout, level: Logger::INFO)
|
41
42
|
create_application({"log_file" => "/invalid/logger"})
|
42
43
|
end
|
43
44
|
|
@@ -53,14 +54,16 @@ describe DevDNSd::Application do
|
|
53
54
|
file.write("config.port = ")
|
54
55
|
file.close
|
55
56
|
|
56
|
-
|
57
|
+
expect_any_instance_of(DevDNSd::Application).to receive(:shutdown).and_call_original
|
58
|
+
create_application({"configuration" => file.path, "log_file" => log_file})
|
57
59
|
::File.unlink(path)
|
58
60
|
end
|
59
61
|
|
60
62
|
it "should abort when the log file is invalid" do
|
61
63
|
allow_any_instance_of(Bovem::Logger).to receive(:fatal)
|
62
64
|
allow_any_instance_of(Bovem::Logger).to receive(:warn)
|
63
|
-
|
65
|
+
expect_any_instance_of(DevDNSd::Application).to receive(:shutdown).and_call_original
|
66
|
+
create_application({"pid_file" => "/invalid/pid", "log_file" => "/dev/null"})
|
64
67
|
end
|
65
68
|
end
|
66
69
|
|
@@ -73,13 +76,13 @@ describe DevDNSd::Application do
|
|
73
76
|
|
74
77
|
describe ".quit" do
|
75
78
|
it "should quit the application" do
|
76
|
-
allow(
|
77
|
-
expect(EM).to receive(:stop)
|
79
|
+
allow(application).to receive(:instance).and_call_original
|
78
80
|
DevDNSd::Application.quit
|
79
81
|
end
|
80
82
|
|
81
|
-
it "should
|
82
|
-
allow(
|
83
|
+
it "should return with error code 1 in case of errors" do
|
84
|
+
allow(application).to receive(:shutdown).and_raise(RuntimeError)
|
85
|
+
expect(Kernel).to receive(:exit).with(1)
|
83
86
|
expect { DevDNSd::Application.quit }.not_to raise_error
|
84
87
|
end
|
85
88
|
end
|
@@ -126,153 +129,138 @@ describe DevDNSd::Application do
|
|
126
129
|
end
|
127
130
|
end
|
128
131
|
|
129
|
-
describe "
|
132
|
+
describe "#process_file_path" do
|
130
133
|
let(:application){ create_application({"log_file" => log_file, "configuration" => sample_config}) }
|
131
134
|
|
132
135
|
it "returns the default file" do
|
133
|
-
expect(DevDNSd::Application.process_file_path).to eq("/var/run/devdnsd.pid")
|
136
|
+
expect(DevDNSd::Application.instance.process_file_path).to eq("/var/run/devdnsd.pid")
|
134
137
|
end
|
135
138
|
|
136
139
|
it "return the set file" do
|
137
140
|
DevDNSd::Application.instance.config.pid_file = "/this/is/a/daemon.pid"
|
138
|
-
expect(DevDNSd::Application.process_file_path).to eq("/this/is/a/daemon.pid")
|
141
|
+
expect(DevDNSd::Application.instance.process_file_path).to eq("/this/is/a/daemon.pid")
|
139
142
|
end
|
140
143
|
end
|
141
144
|
|
142
|
-
describe "
|
145
|
+
describe "#log_file_path" do
|
143
146
|
let(:application){ create_application({"log_file" => log_file, "configuration" => sample_config}) }
|
144
147
|
|
145
148
|
it "returns the default file" do
|
146
|
-
expect(DevDNSd::Application.log_file_path).to eq(log_file)
|
149
|
+
expect(DevDNSd::Application.instance.log_file_path).to eq(log_file)
|
147
150
|
end
|
148
151
|
|
149
152
|
it "return the set file" do
|
150
153
|
DevDNSd::Application.instance.config.log_file = "/this/is/a/daemon.log"
|
151
|
-
expect(DevDNSd::Application.log_file_path).to eq("/this/is/a/daemon.log")
|
154
|
+
expect(DevDNSd::Application.instance.log_file_path).to eq("/this/is/a/daemon.log")
|
152
155
|
end
|
153
156
|
end
|
154
157
|
|
155
|
-
describe "
|
158
|
+
describe "#working_directory" do
|
156
159
|
let(:application){ create_application({"log_file" => log_file, "configuration" => sample_config}) }
|
157
160
|
|
158
161
|
it "returns the default path" do
|
159
|
-
expect(DevDNSd::Application.working_directory).to eq("/var/run")
|
162
|
+
expect(DevDNSd::Application.instance.working_directory).to eq("/var/run")
|
160
163
|
end
|
161
164
|
|
162
165
|
it "return the set path basing on the PID file" do
|
163
166
|
DevDNSd::Application.instance.config.pid_file = "/this/is/a/daemon.pid"
|
164
|
-
expect(DevDNSd::Application.working_directory).to eq("/this/is/a")
|
167
|
+
expect(DevDNSd::Application.instance.working_directory).to eq("/this/is/a")
|
165
168
|
end
|
166
169
|
end
|
167
170
|
|
168
|
-
describe "
|
171
|
+
describe "#log_directory" do
|
169
172
|
let(:application){ create_application({"log_file" => log_file, "configuration" => sample_config}) }
|
170
173
|
|
171
174
|
it "returns the default path" do
|
172
|
-
expect(DevDNSd::Application.log_directory).to eq(File.dirname(log_file))
|
175
|
+
expect(DevDNSd::Application.instance.log_directory).to eq(File.dirname(log_file))
|
173
176
|
end
|
174
177
|
|
175
178
|
it "return the set path basing on the PID file" do
|
176
179
|
DevDNSd::Application.instance.config.log_file = "/this/is/a/daemon.log"
|
177
|
-
expect(DevDNSd::Application.log_directory).to eq("/this/is/a")
|
180
|
+
expect(DevDNSd::Application.instance.log_directory).to eq("/this/is/a")
|
178
181
|
end
|
179
182
|
end
|
180
183
|
|
181
|
-
describe "
|
184
|
+
describe "#daemon_name" do
|
182
185
|
let(:application){ create_application({"log_file" => log_file, "configuration" => sample_config}) }
|
183
186
|
|
184
187
|
it "returns the default name" do
|
185
|
-
expect(DevDNSd::Application.daemon_name).to eq("devdnsd")
|
188
|
+
expect(DevDNSd::Application.instance.daemon_name).to eq("devdnsd")
|
186
189
|
end
|
187
190
|
|
188
191
|
it "return the set name basing on the PID file" do
|
189
192
|
DevDNSd::Application.instance.config.pid_file = "/this/is/a/daemon.pid"
|
190
|
-
expect(DevDNSd::Application.daemon_name).to eq("daemon")
|
193
|
+
expect(DevDNSd::Application.instance.daemon_name).to eq("daemon")
|
191
194
|
end
|
192
195
|
end
|
193
196
|
|
194
197
|
describe "#perform_server" do
|
195
|
-
let(:application){ create_application({"log_file" => log_file, "configuration" => sample_config, "port" => 60771}) }
|
196
|
-
|
197
|
-
def test_resolve(host = "match_1.dev", type = "ANY", nameserver = "127.0.0.1", port = 60771, logger = nil)
|
198
|
-
result = nil
|
199
|
-
|
200
|
-
EM.run do
|
201
|
-
EM.add_timer(0.01) { application.perform_server }
|
202
|
-
EM.add_timer(0.1) {
|
203
|
-
Fiber.new {
|
204
|
-
result = devdnsd_resolv(host, type, nameserver, port, logger)
|
205
|
-
EM.stop
|
206
|
-
}.resume
|
207
|
-
}
|
208
|
-
end
|
209
|
-
|
210
|
-
result
|
211
|
-
end
|
198
|
+
let(:application) { create_application({"log_file" => log_file, "configuration" => sample_config, "port" => 60771}) }
|
212
199
|
|
213
|
-
it "should
|
214
|
-
expect(RubyDNS).to receive(:run_server)
|
200
|
+
it "should free resources correctly" do
|
215
201
|
application.perform_server
|
202
|
+
application.shutdown
|
203
|
+
application.perform_server
|
204
|
+
application.shutdown
|
216
205
|
end
|
217
206
|
|
218
207
|
it "should setup callbacks" do
|
219
208
|
expect_any_instance_of(RubyDNS::RuleBasedServer).to receive(:on).with(:start)
|
220
209
|
expect_any_instance_of(RubyDNS::RuleBasedServer).to receive(:on).with(:stop)
|
221
|
-
|
222
|
-
|
223
|
-
EM.add_timer(0.01) { application.perform_server }
|
224
|
-
EM.add_timer(0.2) { DevDNSd::Application.quit }
|
225
|
-
end
|
226
|
-
end
|
227
|
-
|
228
|
-
it "should iterate the rules" do
|
229
|
-
test_resolve do
|
230
|
-
expect(application.config.rules).to receive(:each).at_least(1)
|
231
|
-
application.perform_server
|
232
|
-
end
|
233
|
-
end
|
234
|
-
|
235
|
-
it "should call process_rule" do
|
236
|
-
test_resolve do
|
237
|
-
expect(application).to receive(:process_rule).at_least(1)
|
238
|
-
application.perform_server
|
239
|
-
end
|
210
|
+
application.perform_server
|
211
|
+
application.shutdown
|
240
212
|
end
|
241
213
|
|
242
|
-
|
243
|
-
test_resolve
|
244
|
-
|
245
|
-
expect { application.perform_server }.to raise_exception
|
214
|
+
describe "using rules" do
|
215
|
+
def test_resolve(host = "match_1.dev", type = "ANY", nameserver = "127.0.0.1", port = 60771, logger = nil)
|
216
|
+
devdnsd_resolv(host, type, nameserver, port, logger)
|
246
217
|
end
|
247
|
-
end
|
248
218
|
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
expect(test_resolve("match_4.dev")).to eq(["cowtech.it", :CNAME])
|
219
|
+
around(:each) do |example|
|
220
|
+
app = application
|
221
|
+
app.perform_server
|
222
|
+
example.call
|
223
|
+
app.shutdown
|
255
224
|
end
|
256
225
|
|
257
|
-
it "
|
258
|
-
expect(
|
259
|
-
|
260
|
-
expect(test_resolve("match_6_33.dev")).to eq(["10.0.6.33", :PTR])
|
261
|
-
expect(test_resolve("match_6_44.dev")).to eq(["10.0.6.44", :PTR])
|
262
|
-
expect(test_resolve("match_7_55.dev")).to eq(["10.0.7.55", :A])
|
263
|
-
expect(test_resolve("match_7_66.dev")).to eq(["10.0.7.66", :A])
|
264
|
-
expect(test_resolve("match_8_77.dev")).to eq(["10.0.8.77", :PTR])
|
265
|
-
expect(test_resolve("match_8_88.dev")).to eq(["10.0.8.88", :PTR])
|
226
|
+
it "should iterate the rules" do
|
227
|
+
expect(application.config.rules).to receive(:each).at_least(1)
|
228
|
+
test_resolve
|
266
229
|
end
|
267
230
|
|
268
|
-
it "
|
269
|
-
|
270
|
-
|
231
|
+
it "should call process_rule" do
|
232
|
+
expect_any_instance_of(DevDNSd::Application).to receive(:process_rule).at_least(1)
|
233
|
+
test_resolve
|
271
234
|
end
|
272
235
|
|
273
|
-
|
274
|
-
|
275
|
-
|
236
|
+
describe "should correctly resolve hostnames" do
|
237
|
+
it "basing on a exact pattern" do
|
238
|
+
expect(test_resolve("match_1.dev")).to eq(["10.0.1.1", :A])
|
239
|
+
expect(test_resolve("match_2.dev")).to eq(["10.0.2.1", :MX])
|
240
|
+
expect(test_resolve("match_3.dev")).to eq(["10.0.3.1", :A])
|
241
|
+
expect(test_resolve("match_4.dev")).to eq(["cowtech.it", :CNAME])
|
242
|
+
end
|
243
|
+
|
244
|
+
it "basing on a regexp pattern" do
|
245
|
+
expect(test_resolve("match_5_11.dev")).to eq(["ns.cowtech.it", :NS])
|
246
|
+
expect(test_resolve("match_5_22.dev")).to eq(["ns.cowtech.it", :NS])
|
247
|
+
expect(test_resolve("match_6_33.dev")).to eq(["10.0.6.33", :PTR])
|
248
|
+
expect(test_resolve("match_6_44.dev")).to eq(["10.0.6.44", :PTR])
|
249
|
+
expect(test_resolve("match_7_55.dev")).to eq(["10.0.7.55", :A])
|
250
|
+
expect(test_resolve("match_7_66.dev")).to eq(["10.0.7.66", :A])
|
251
|
+
expect(test_resolve("match_8_77.dev")).to eq(["10.0.8.77", :PTR])
|
252
|
+
expect(test_resolve("match_8_88.dev")).to eq(["10.0.8.88", :PTR])
|
253
|
+
end
|
254
|
+
|
255
|
+
it "and return multiple or only relevant answsers" do
|
256
|
+
expect(test_resolve("match_10.dev")).to eq([["10.0.10.1", :A], ["10.0.10.2", :MX]])
|
257
|
+
expect(test_resolve("match_10.dev", "MX")).to eq(["10.0.10.2", :MX])
|
258
|
+
end
|
259
|
+
|
260
|
+
it "and reject invalid matches (with or without rules)" do
|
261
|
+
expect(test_resolve("match_9.dev")).to eq([])
|
262
|
+
expect(test_resolve("invalid.dev")).to eq([])
|
263
|
+
end
|
276
264
|
end
|
277
265
|
end
|
278
266
|
end
|
@@ -295,51 +283,51 @@ describe DevDNSd::Application do
|
|
295
283
|
|
296
284
|
it "should match a valid string request" do
|
297
285
|
rule = application.config.rules[0]
|
298
|
-
expect(application.process_rule(rule, rule.resource_class, nil, transaction)).to
|
286
|
+
expect(application.process_rule(rule, rule.resource_class, nil, transaction)).to be_truthy
|
299
287
|
end
|
300
288
|
|
301
289
|
it "should match a valid string request with specific type" do
|
302
290
|
rule = application.config.rules[1]
|
303
|
-
expect(application.process_rule(rule, rule.resource_class, nil, transaction)).to
|
291
|
+
expect(application.process_rule(rule, rule.resource_class, nil, transaction)).to be_truthy
|
304
292
|
end
|
305
293
|
|
306
294
|
it "should match a valid string request with a block" do
|
307
295
|
rule = application.config.rules[2]
|
308
|
-
expect(application.process_rule(rule, rule.resource_class, nil, transaction)).to
|
296
|
+
expect(application.process_rule(rule, rule.resource_class, nil, transaction)).to be_truthy
|
309
297
|
end
|
310
298
|
|
311
299
|
it "should match a valid string request with a block" do
|
312
300
|
rule = application.config.rules[3]
|
313
|
-
expect(application.process_rule(rule, rule.resource_class, nil, transaction)).to
|
301
|
+
expect(application.process_rule(rule, rule.resource_class, nil, transaction)).to be_truthy
|
314
302
|
end
|
315
303
|
|
316
304
|
it "should match a valid regexp request" do
|
317
305
|
rule = application.config.rules[4]
|
318
306
|
mo = rule.match_host("match_5_12.dev")
|
319
|
-
expect(application.process_rule(rule, rule.resource_class, mo, transaction)).to
|
307
|
+
expect(application.process_rule(rule, rule.resource_class, mo, transaction)).to be_truthy
|
320
308
|
end
|
321
309
|
|
322
310
|
it "should match a valid regexp request with specific type" do
|
323
311
|
rule = application.config.rules[5]
|
324
312
|
mo = rule.match_host("match_6_34.dev")
|
325
|
-
expect(application.process_rule(rule, rule.resource_class, mo, transaction)).to
|
313
|
+
expect(application.process_rule(rule, rule.resource_class, mo, transaction)).to be_truthy
|
326
314
|
end
|
327
315
|
|
328
316
|
it "should match a valid regexp request with a block" do
|
329
317
|
rule = application.config.rules[6]
|
330
318
|
mo = rule.match_host("match_7_56.dev")
|
331
|
-
expect(application.process_rule(rule, rule.resource_class, mo, transaction)).to
|
319
|
+
expect(application.process_rule(rule, rule.resource_class, mo, transaction)).to be_truthy
|
332
320
|
end
|
333
321
|
|
334
322
|
it "should match a valid regexp request with a block and specific type" do
|
335
323
|
rule = application.config.rules[7]
|
336
324
|
mo = rule.match_host("match_8_78.dev")
|
337
|
-
expect(application.process_rule(rule, rule.resource_class, mo, transaction)).to
|
325
|
+
expect(application.process_rule(rule, rule.resource_class, mo, transaction)).to be_truthy
|
338
326
|
end
|
339
327
|
|
340
328
|
it "should return false for a false block" do
|
341
329
|
rule = application.config.rules[8]
|
342
|
-
expect(application.process_rule(rule, rule.resource_class, nil, transaction)).to
|
330
|
+
expect(application.process_rule(rule, rule.resource_class, nil, transaction)).to be_falsey
|
343
331
|
end
|
344
332
|
|
345
333
|
it "should return nil for a nil reply" do
|
@@ -356,12 +344,12 @@ describe DevDNSd::Application do
|
|
356
344
|
end
|
357
345
|
end
|
358
346
|
|
359
|
-
describe "#
|
347
|
+
describe "#osx?" do
|
360
348
|
it "should return the correct information" do
|
361
349
|
stub_const("RbConfig::CONFIG", {"host_os" => "darwin foo"})
|
362
|
-
expect(application.
|
350
|
+
expect(application.osx?).to be_truthy
|
363
351
|
stub_const("RbConfig::CONFIG", {"host_os" => "another"})
|
364
|
-
expect(application.
|
352
|
+
expect(application.osx?).to be_falsey
|
365
353
|
end
|
366
354
|
end
|
367
355
|
|
@@ -387,22 +375,22 @@ describe DevDNSd::Application do
|
|
387
375
|
|
388
376
|
describe "#manage_aliases" do
|
389
377
|
it "should override configuration" do
|
390
|
-
|
378
|
+
expect_any_instance_of(DevDNSd::Application).to receive(:manage_address)
|
391
379
|
application.manage_aliases(:add, "MESSAGE", {aliases: 10})
|
392
380
|
expect(application.config.aliases).to eq(10)
|
393
381
|
end
|
394
382
|
|
395
383
|
it "should log an error if no interfaces are found" do
|
396
|
-
|
384
|
+
expect_any_instance_of(DevDNSd::Application).to receive(:compute_addresses).and_return([])
|
397
385
|
expect(application.logger).to receive(:error).with("MESSAGE")
|
398
|
-
expect(application.manage_aliases(:add, "MESSAGE", {aliases: 10})).to
|
386
|
+
expect(application.manage_aliases(:add, "MESSAGE", {aliases: 10})).to be_falsey
|
399
387
|
end
|
400
388
|
|
401
389
|
it "should call #manage_address for each address" do
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
expect(application.manage_aliases("OPERATION", "MESSAGE", {aliases: 3, dry_run: "DRY_RUN"})).to
|
390
|
+
expect_any_instance_of(DevDNSd::Application).to receive(:manage_address).with("OPERATION", IPAddr.new("10.0.0.1"), "DRY_RUN").and_return(true)
|
391
|
+
expect_any_instance_of(DevDNSd::Application).to receive(:manage_address).with("OPERATION", IPAddr.new("10.0.0.2"), "DRY_RUN").and_return(true)
|
392
|
+
expect_any_instance_of(DevDNSd::Application).to receive(:manage_address).with("OPERATION", IPAddr.new("10.0.0.3"), "DRY_RUN").and_return(true)
|
393
|
+
expect(application.manage_aliases("OPERATION", "MESSAGE", {aliases: 3, dry_run: "DRY_RUN"})).to be_truthy
|
406
394
|
end
|
407
395
|
end
|
408
396
|
|
@@ -416,24 +404,24 @@ describe DevDNSd::Application do
|
|
416
404
|
end
|
417
405
|
|
418
406
|
it "should call the right system command" do
|
419
|
-
|
407
|
+
expect_any_instance_of(DevDNSd::Application).to receive(:execute_command).with("sudo ifconfig lo0 alias 10.0.0.3 > /dev/null 2>&1")
|
420
408
|
application.manage_address(:add, "10.0.0.3")
|
421
409
|
|
422
|
-
|
410
|
+
expect_any_instance_of(DevDNSd::Application).to receive(:execute_command).with("sudo ifconfig lo0 -alias 10.0.0.3 > /dev/null 2>&1")
|
423
411
|
application.manage_address(:remove, "10.0.0.3")
|
424
412
|
end
|
425
413
|
|
426
414
|
it "should return true if the command succeded" do
|
427
415
|
application.config.add_command = "echo {{interface}}"
|
428
|
-
expect(application.manage_address(:add, "10.0.0.3")).to
|
416
|
+
expect(application.manage_address(:add, "10.0.0.3")).to be_truthy
|
429
417
|
end
|
430
418
|
|
431
419
|
it "should return false if the command failed" do
|
432
|
-
expect(application.manage_address(:add, "10.0.0.256")).to
|
420
|
+
expect(application.manage_address(:add, "10.0.0.256")).to be_falsey
|
433
421
|
end
|
434
422
|
|
435
423
|
it "should respect dry-run mode" do
|
436
|
-
|
424
|
+
expect_any_instance_of(DevDNSd::Application).not_to receive(:execute_command)
|
437
425
|
expect(application.logger).to receive(:info).with(/.+.*3.*\/.*5.*.+ I will .*add.* address .*10.0.0.3.* to interface .*lo0.*/)
|
438
426
|
expect(application.logger).to receive(:info).with(/.+.*3.*\/.*5.*.+ I will .*remove.* address .*10.0.0.3.* from interface .*lo0.*/)
|
439
427
|
|
@@ -491,39 +479,39 @@ describe DevDNSd::Application do
|
|
491
479
|
end
|
492
480
|
end
|
493
481
|
|
494
|
-
describe "#
|
482
|
+
describe "#ipv4?" do
|
495
483
|
it "correctly detects valid IPv4 address" do
|
496
|
-
expect(application.
|
497
|
-
expect(application.
|
498
|
-
expect(application.
|
484
|
+
expect(application.ipv4?("10.0.0.1")).to be_truthy
|
485
|
+
expect(application.ipv4?("255.0.0.1")).to be_truthy
|
486
|
+
expect(application.ipv4?("192.168.0.1")).to be_truthy
|
499
487
|
end
|
500
488
|
|
501
489
|
it "rejects other values" do
|
502
|
-
expect(application.
|
503
|
-
expect(application.
|
504
|
-
expect(application.
|
505
|
-
expect(application.
|
506
|
-
expect(application.
|
490
|
+
expect(application.ipv4?("10.0.0.256")).to be_falsey
|
491
|
+
expect(application.ipv4?("10.0.0.-1")).to be_falsey
|
492
|
+
expect(application.ipv4?("::1")).to be_falsey
|
493
|
+
expect(application.ipv4?("INVALID")).to be_falsey
|
494
|
+
expect(application.ipv4?(nil)).to be_falsey
|
507
495
|
end
|
508
496
|
end
|
509
497
|
|
510
|
-
describe "#
|
498
|
+
describe "#ipv6?" do
|
511
499
|
it "correctly detects valid IPv4 address" do
|
512
|
-
expect(application.
|
513
|
-
expect(application.
|
514
|
-
expect(application.
|
515
|
-
expect(application.
|
516
|
-
expect(application.
|
517
|
-
expect(application.
|
518
|
-
expect(application.
|
519
|
-
expect(application.
|
500
|
+
expect(application.ipv6?("2001:0db8:0000:0000:0000:1428:57ab")).to be_truthy
|
501
|
+
expect(application.ipv6?("2001:0db8:0:000:00:1428:57ab")).to be_truthy
|
502
|
+
expect(application.ipv6?("2001:0db8:0::1428:57ab")).to be_truthy
|
503
|
+
expect(application.ipv6?("2001::")).to be_truthy
|
504
|
+
expect(application.ipv6?("::1")).to be_truthy
|
505
|
+
expect(application.ipv6?("::2:1")).to be_truthy
|
506
|
+
expect(application.ipv6?("2011::10.0.0.1")).to be_truthy
|
507
|
+
expect(application.ipv6?("2011::0:10.0.0.1")).to be_truthy
|
520
508
|
end
|
521
509
|
|
522
510
|
it "rejects other values" do
|
523
|
-
expect(application.
|
524
|
-
expect(application.
|
525
|
-
expect(application.
|
526
|
-
expect(application.
|
511
|
+
expect(application.ipv6?("::H")).to be_falsey
|
512
|
+
expect(application.ipv6?("192.168.0.256")).to be_falsey
|
513
|
+
expect(application.ipv6?("INVALID")).to be_falsey
|
514
|
+
expect(application.ipv6?(nil)).to be_falsey
|
527
515
|
end
|
528
516
|
end
|
529
517
|
|
@@ -534,7 +522,7 @@ describe DevDNSd::Application do
|
|
534
522
|
option :foreground, [:n, "foreground"], {default: true}
|
535
523
|
})
|
536
524
|
|
537
|
-
|
525
|
+
allow_any_instance_of(DevDNSd::Application).to receive(:perform_server)
|
538
526
|
application.action_start
|
539
527
|
end
|
540
528
|
|
@@ -544,7 +532,7 @@ describe DevDNSd::Application do
|
|
544
532
|
option :foreground, [:n, "foreground"], {default: false}
|
545
533
|
})
|
546
534
|
|
547
|
-
expect(::
|
535
|
+
expect(::DevDNSd::Application).to receive(:start)
|
548
536
|
application.action_start
|
549
537
|
end
|
550
538
|
|
@@ -552,48 +540,48 @@ describe DevDNSd::Application do
|
|
552
540
|
application.config.foreground = false
|
553
541
|
|
554
542
|
allow(Process).to receive(:respond_to?).and_return(false)
|
555
|
-
|
543
|
+
allow_any_instance_of(DevDNSd::Application).to receive(:perform_server)
|
556
544
|
expect(application.logger).to receive(:warn)
|
557
545
|
|
558
546
|
application.action_start
|
559
|
-
expect(application.config.foreground).to
|
547
|
+
expect(application.config.foreground).to be_truthy
|
560
548
|
end
|
561
549
|
end
|
562
550
|
|
563
551
|
describe "#action_stop" do
|
564
552
|
it "should stop the daemon" do
|
565
|
-
expect(::
|
553
|
+
expect(::DevDNSd::Application).to receive(:stop)
|
566
554
|
application.action_stop
|
567
555
|
end
|
568
556
|
end
|
569
557
|
|
570
558
|
describe "#action_restart" do
|
571
559
|
it "should stop and restart the server" do
|
572
|
-
|
573
|
-
|
560
|
+
expect_any_instance_of(DevDNSd::Application).to receive(:action_stop)
|
561
|
+
expect_any_instance_of(DevDNSd::Application).to receive(:action_start)
|
574
562
|
application.action_restart
|
575
563
|
end
|
576
564
|
end
|
577
565
|
|
578
566
|
describe "#action_status" do
|
579
567
|
it "should get the status of the daemon when running" do
|
580
|
-
expect(
|
581
|
-
expect(
|
568
|
+
expect(Process::Daemon::ProcessFile).to receive(:status).and_return(:running)
|
569
|
+
expect(DevDNSd::Application.controller).to receive(:pid).and_return(123)
|
582
570
|
|
583
|
-
expect(application.logger).to receive(:info).with("The server is running with process ID
|
571
|
+
expect(application.logger).to receive(:info).with("The server is running with process ID \e[1m123\e[0m.")
|
584
572
|
application.action_status
|
585
573
|
end
|
586
574
|
|
587
575
|
it "should get the status of the daemon when stopped" do
|
588
|
-
expect(
|
589
|
-
expect(
|
576
|
+
expect(Process::Daemon::ProcessFile).to receive(:status).and_return(:stopped)
|
577
|
+
expect(DevDNSd::Application.controller).to receive(:pid).and_return(123)
|
590
578
|
|
591
579
|
expect(application.logger).to receive(:info).with("The server is stopped.")
|
592
580
|
application.action_status
|
593
581
|
end
|
594
582
|
|
595
583
|
it "should get the status of the daemon when crashed" do
|
596
|
-
expect(
|
584
|
+
expect(Process::Daemon::ProcessFile).to receive(:status).and_return(:unknown)
|
597
585
|
expect(application.class).to receive(:crashed?).and_return(true)
|
598
586
|
|
599
587
|
expect(application.logger).to receive(:info).with("The server crashed. See the log for more information.")
|
@@ -601,7 +589,7 @@ describe DevDNSd::Application do
|
|
601
589
|
end
|
602
590
|
|
603
591
|
it "should get the status of the daemon when unknown" do
|
604
|
-
expect(
|
592
|
+
expect(Process::Daemon::ProcessFile).to receive(:status).and_return(:unknown)
|
605
593
|
expect(application.class).to receive(:crashed?).and_return(false)
|
606
594
|
|
607
595
|
expect(application.logger).to receive(:info).with("The server status is unknown.")
|
@@ -611,46 +599,46 @@ describe DevDNSd::Application do
|
|
611
599
|
|
612
600
|
describe "#action_install" do
|
613
601
|
before(:each) do
|
614
|
-
allow(application).to receive(:
|
602
|
+
allow(application).to receive(:osx?).and_return(true)
|
615
603
|
allow(application).to receive(:execute_command)
|
616
604
|
expect(Kernel).to receive(:system).at_least(1)
|
617
605
|
end
|
618
606
|
|
619
607
|
it "should create the resolver" do
|
620
|
-
|
621
|
-
|
608
|
+
allow_any_instance_of(DevDNSd::Application).to receive(:resolver_path).and_return(resolver_path)
|
609
|
+
allow_any_instance_of(DevDNSd::Application).to receive(:launch_agent_path).and_return(launch_agent_path)
|
622
610
|
::File.unlink(application.resolver_path) if ::File.exists?(application.resolver_path)
|
623
611
|
::File.unlink(application.launch_agent_path) if ::File.exists?(application.launch_agent_path)
|
624
612
|
|
625
|
-
|
613
|
+
allow_any_instance_of(DevDNSd::Application).to receive(:create_resolver) {|_, path| FileUtils.touch(path) }
|
626
614
|
application.action_install
|
627
|
-
expect(::File.exists?(resolver_path)).to
|
615
|
+
expect(::File.exists?(resolver_path)).to be_truthy
|
628
616
|
|
629
617
|
::File.unlink(application.resolver_path) if ::File.exists?(application.resolver_path)
|
630
618
|
::File.unlink(application.launch_agent_path) if ::File.exists?(application.launch_agent_path)
|
631
619
|
end
|
632
620
|
|
633
621
|
it "should create the agent" do
|
634
|
-
|
635
|
-
|
622
|
+
allow_any_instance_of(DevDNSd::Application).to receive(:resolver_path).and_return(resolver_path)
|
623
|
+
allow_any_instance_of(DevDNSd::Application).to receive(:launch_agent_path).and_return(launch_agent_path)
|
636
624
|
::File.unlink(application.resolver_path) if ::File.exists?(application.resolver_path)
|
637
625
|
::File.unlink(application.launch_agent_path) if ::File.exists?(application.launch_agent_path)
|
638
626
|
|
639
|
-
|
627
|
+
allow_any_instance_of(DevDNSd::Application).to receive(:resolver_path).and_return(resolver_path)
|
640
628
|
application.action_install
|
641
|
-
expect(::File.exists?(application.launch_agent_path)).to
|
629
|
+
expect(::File.exists?(application.launch_agent_path)).to be_truthy
|
642
630
|
|
643
631
|
::File.unlink(application.resolver_path) if ::File.exists?(application.resolver_path)
|
644
632
|
::File.unlink(application.launch_agent_path) if ::File.exists?(application.launch_agent_path)
|
645
633
|
end
|
646
634
|
|
647
635
|
it "should update the DNS cache" do
|
648
|
-
|
649
|
-
|
636
|
+
allow_any_instance_of(DevDNSd::Application).to receive(:resolver_path).and_return(resolver_path)
|
637
|
+
allow_any_instance_of(DevDNSd::Application).to receive(:launch_agent_path).and_return(launch_agent_path)
|
650
638
|
::File.unlink(application.resolver_path) if ::File.exists?(application.resolver_path)
|
651
639
|
::File.unlink(application.launch_agent_path) if ::File.exists?(application.launch_agent_path)
|
652
640
|
|
653
|
-
|
641
|
+
expect_any_instance_of(DevDNSd::Application).to receive(:dns_update)
|
654
642
|
application.action_install
|
655
643
|
|
656
644
|
::File.unlink(application.resolver_path) if ::File.exists?(application.resolver_path)
|
@@ -658,13 +646,13 @@ describe DevDNSd::Application do
|
|
658
646
|
end
|
659
647
|
|
660
648
|
it "should not create an invalid resolver" do
|
661
|
-
|
662
|
-
|
649
|
+
allow_any_instance_of(DevDNSd::Application).to receive(:resolver_path).and_return("/invalid/resolver")
|
650
|
+
allow_any_instance_of(DevDNSd::Application).to receive(:launch_agent_path).and_return("/invalid/agent")
|
663
651
|
::File.unlink(application.resolver_path) if ::File.exists?(application.resolver_path)
|
664
652
|
::File.unlink(application.launch_agent_path) if ::File.exists?(application.launch_agent_path)
|
665
653
|
|
666
|
-
|
667
|
-
expect_any_instance_of(
|
654
|
+
allow_any_instance_of(DevDNSd::Application).to receive(:create_agent).and_return(true)
|
655
|
+
expect_any_instance_of(Bovem::I18n).to receive(:resolver_creating).and_raise(ArgumentError)
|
668
656
|
expect(application.logger).to receive(:error).with("Cannot create the resolver file.")
|
669
657
|
application.action_install
|
670
658
|
|
@@ -673,8 +661,8 @@ describe DevDNSd::Application do
|
|
673
661
|
end
|
674
662
|
|
675
663
|
it "should not create an invalid agent" do
|
676
|
-
|
677
|
-
|
664
|
+
allow_any_instance_of(DevDNSd::Application).to receive(:resolver_path).and_return(resolver_path)
|
665
|
+
allow_any_instance_of(DevDNSd::Application).to receive(:launch_agent_path).and_return("/invalid/agent")
|
678
666
|
::File.unlink(application.resolver_path) if ::File.exists?(application.resolver_path)
|
679
667
|
::File.unlink(application.launch_agent_path) if ::File.exists?(application.launch_agent_path)
|
680
668
|
|
@@ -690,11 +678,12 @@ describe DevDNSd::Application do
|
|
690
678
|
command =~ /^launchctl/ ? raise(StandardError) : true
|
691
679
|
end
|
692
680
|
|
693
|
-
|
694
|
-
|
681
|
+
allow_any_instance_of(DevDNSd::Application).to receive(:resolver_path).and_return(resolver_path)
|
682
|
+
allow_any_instance_of(DevDNSd::Application).to receive(:launch_agent_path).and_return(launch_agent_path)
|
695
683
|
::File.unlink(application.resolver_path) if ::File.exists?(application.resolver_path)
|
696
684
|
::File.unlink(application.launch_agent_path) if ::File.exists?(application.launch_agent_path)
|
697
685
|
|
686
|
+
allow_any_instance_of(DevDNSd::Application).to receive(:create_agent).and_return(true)
|
698
687
|
expect(application.logger).to receive(:error).with("Cannot load the launch agent.")
|
699
688
|
application.action_install
|
700
689
|
|
@@ -703,41 +692,41 @@ describe DevDNSd::Application do
|
|
703
692
|
end
|
704
693
|
|
705
694
|
it "should raise an exception if not running on OSX" do
|
706
|
-
|
695
|
+
allow_any_instance_of(DevDNSd::Application).to receive(:osx?).and_return(false)
|
707
696
|
expect(application.logger).to receive(:fatal).with("Install DevDNSd as a local resolver is only available on MacOSX.")
|
708
|
-
expect(application.action_install).to
|
697
|
+
expect(application.action_install).to be_falsey
|
709
698
|
end
|
710
699
|
end
|
711
700
|
|
712
701
|
describe "#action_uninstall" do
|
713
702
|
before(:each) do
|
714
|
-
allow(application).to receive(:
|
703
|
+
allow(application).to receive(:osx?).and_return(true)
|
715
704
|
allow(application).to receive(:execute_command)
|
716
705
|
expect(Kernel).to receive(:system).at_least(1)
|
717
706
|
end
|
718
707
|
|
719
708
|
it "should remove the resolver" do
|
720
|
-
|
721
|
-
|
709
|
+
allow_any_instance_of(DevDNSd::Application).to receive(:resolver_path).and_return(resolver_path)
|
710
|
+
allow_any_instance_of(DevDNSd::Application).to receive(:launch_agent_path).and_return(launch_agent_path)
|
722
711
|
::File.unlink(application.resolver_path) if ::File.exists?(application.resolver_path)
|
723
712
|
::File.unlink(application.launch_agent_path) if ::File.exists?(application.launch_agent_path)
|
724
713
|
|
725
714
|
application.action_install
|
726
715
|
application.action_uninstall
|
727
|
-
expect(::File.exists?(resolver_path)).to
|
716
|
+
expect(::File.exists?(resolver_path)).to be_falsey
|
728
717
|
|
729
718
|
::File.unlink(application.resolver_path) if ::File.exists?(application.resolver_path)
|
730
719
|
::File.unlink(application.launch_agent_path) if ::File.exists?(application.launch_agent_path)
|
731
720
|
end
|
732
721
|
|
733
722
|
it "should not remove an invalid resolver" do
|
734
|
-
|
735
|
-
|
723
|
+
allow_any_instance_of(DevDNSd::Application).to receive(:resolver_path).and_return("/invalid/resolver")
|
724
|
+
allow_any_instance_of(DevDNSd::Application).to receive(:launch_agent_path).and_return("/invalid/agent")
|
736
725
|
::File.unlink(application.resolver_path) if ::File.exists?(application.resolver_path)
|
737
726
|
::File.unlink(application.launch_agent_path) if ::File.exists?(application.launch_agent_path)
|
738
727
|
|
739
728
|
allow(application).to receive(:unload_agent).and_return(true)
|
740
|
-
expect_any_instance_of(
|
729
|
+
expect_any_instance_of(Bovem::I18n).to receive(:resolver_deleting).and_raise(ArgumentError)
|
741
730
|
expect(application.logger).to receive(:warn)
|
742
731
|
expect(application.logger).to receive(:warn).with("Cannot delete the resolver file.")
|
743
732
|
|
@@ -748,15 +737,30 @@ describe DevDNSd::Application do
|
|
748
737
|
end
|
749
738
|
|
750
739
|
it "should remove the agent" do
|
751
|
-
|
752
|
-
|
740
|
+
allow_any_instance_of(DevDNSd::Application).to receive(:resolver_path).and_return(resolver_path)
|
741
|
+
allow_any_instance_of(DevDNSd::Application).to receive(:launch_agent_path).and_return(launch_agent_path)
|
742
|
+
::File.unlink(application.resolver_path) if ::File.exists?(application.resolver_path)
|
743
|
+
::File.unlink(application.launch_agent_path) if ::File.exists?(application.launch_agent_path)
|
744
|
+
|
745
|
+
allow(Bovem::Logger).to receive(:default_file).and_return($stdout)
|
746
|
+
application.action_install
|
747
|
+
application.action_uninstall
|
748
|
+
expect(::File.exists?(application.launch_agent_path)).to be_falsey
|
749
|
+
|
750
|
+
::File.unlink(application.resolver_path) if ::File.exists?(application.resolver_path)
|
751
|
+
::File.unlink(application.launch_agent_path) if ::File.exists?(application.launch_agent_path)
|
752
|
+
end
|
753
|
+
|
754
|
+
it "should not fail if the agent cannot be removed" do
|
755
|
+
allow_any_instance_of(DevDNSd::Application).to receive(:resolver_path).and_return(resolver_path)
|
756
|
+
allow_any_instance_of(DevDNSd::Application).to receive(:launch_agent_path).and_return(launch_agent_path)
|
753
757
|
::File.unlink(application.resolver_path) if ::File.exists?(application.resolver_path)
|
754
758
|
::File.unlink(application.launch_agent_path) if ::File.exists?(application.launch_agent_path)
|
755
759
|
|
760
|
+
allow(File).to receive(:delete).and_raise(RuntimeError)
|
756
761
|
allow(Bovem::Logger).to receive(:default_file).and_return($stdout)
|
757
762
|
application.action_install
|
758
763
|
application.action_uninstall
|
759
|
-
expect(::File.exists?(application.launch_agent_path)).to be_false
|
760
764
|
|
761
765
|
::File.unlink(application.resolver_path) if ::File.exists?(application.resolver_path)
|
762
766
|
::File.unlink(application.launch_agent_path) if ::File.exists?(application.launch_agent_path)
|
@@ -807,7 +811,7 @@ describe DevDNSd::Application do
|
|
807
811
|
::File.unlink(application.launch_agent_path) if ::File.exists?(application.launch_agent_path)
|
808
812
|
|
809
813
|
application.action_install
|
810
|
-
|
814
|
+
expect_any_instance_of(DevDNSd::Application).to receive(:dns_update)
|
811
815
|
application.action_uninstall
|
812
816
|
|
813
817
|
::File.unlink(application.resolver_path) if ::File.exists?(application.resolver_path)
|
@@ -815,22 +819,22 @@ describe DevDNSd::Application do
|
|
815
819
|
end
|
816
820
|
|
817
821
|
it "should raise an exception if not running on OSX" do
|
818
|
-
|
822
|
+
allow_any_instance_of(DevDNSd::Application).to receive(:osx?).and_return(false)
|
819
823
|
expect(application.logger).to receive(:fatal).with("Install DevDNSd as a local resolver is only available on MacOSX.")
|
820
|
-
expect(application.action_uninstall).to
|
824
|
+
expect(application.action_uninstall).to be_falsey
|
821
825
|
end
|
822
826
|
end
|
823
827
|
|
824
828
|
describe "#action_add" do
|
825
829
|
it "should #manage_aliases" do
|
826
|
-
|
830
|
+
expect_any_instance_of(DevDNSd::Application).to receive(:manage_aliases).with(:add, "No valid addresses to add to the interface found.", {a: 1})
|
827
831
|
application.action_add({a: 1})
|
828
832
|
end
|
829
833
|
end
|
830
834
|
|
831
835
|
describe "#action_remove" do
|
832
836
|
it "should #manage_aliases" do
|
833
|
-
|
837
|
+
expect_any_instance_of(DevDNSd::Application).to receive(:manage_aliases).with(:remove, "No valid addresses to remove from the interface found.", {a: 1})
|
834
838
|
application.action_remove({a: 1})
|
835
839
|
end
|
836
840
|
end
|