1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-11 10:19:03 +00:00

Normalize the Ndiff exit codes.

0 if the scans are equal,
	1 if they differ, and
	2 for runtime errors.
Add tests and man page documentation.
This commit is contained in:
david
2009-07-30 14:40:46 +00:00
parent 24b5c338b6
commit 05e5348b57
4 changed files with 115 additions and 4 deletions

View File

@@ -2,12 +2,12 @@
.\" Title: ndiff .\" Title: ndiff
.\" Author: [see the "Authors" section] .\" Author: [see the "Authors" section]
.\" Generator: DocBook XSL Stylesheets v1.74.3 <http://docbook.sf.net/> .\" Generator: DocBook XSL Stylesheets v1.74.3 <http://docbook.sf.net/>
.\" Date: 07/22/2009 .\" Date: 07/30/2009
.\" Manual: User Commands .\" Manual: User Commands
.\" Source: Ndiff .\" Source: Ndiff
.\" Language: English .\" Language: English
.\" .\"
.TH "NDIFF" "1" "07/22/2009" "Ndiff" "User Commands" .TH "NDIFF" "1" "07/30/2009" "Ndiff" "User Commands"
.\" ----------------------------------------------------------------- .\" -----------------------------------------------------------------
.\" * set default formatting .\" * set default formatting
.\" ----------------------------------------------------------------- .\" -----------------------------------------------------------------
@@ -370,6 +370,44 @@ If the script is saved as
.RE .RE
.\} .\}
.sp .sp
.SH "EXIT CODE"
.PP
The exit code indicates whether the scans are equal\&.
.sp
.RS 4
.ie n \{\
\h'-04'\(bu\h'+03'\c
.\}
.el \{\
.sp -1
.IP \(bu 2.3
.\}
0 means that the scans are the same in all the aspects Ndiff knows about\&.
.RE
.sp
.RS 4
.ie n \{\
\h'-04'\(bu\h'+03'\c
.\}
.el \{\
.sp -1
.IP \(bu 2.3
.\}
1 means that the scans differ\&.
.RE
.sp
.RS 4
.ie n \{\
\h'-04'\(bu\h'+03'\c
.\}
.el \{\
.sp -1
.IP \(bu 2.3
.\}
2 indicates a runtime error, such as the failure to open a file\&.
.RE
.sp
.RE
.SH "BUGS" .SH "BUGS"
.PP .PP
Report bugs to the Report bugs to the

View File

@@ -355,6 +355,21 @@ ln -sf scan-$date.xml scan-prev.xml
</para> </para>
</refsect1> </refsect1>
<refsect1>
<title>Exit Code</title>
<para>
The exit code indicates whether the scans are equal.
<itemizedlist spacing="compact">
<listitem><para>0 means that the scans are the same in all the
aspects Ndiff knows about.</para></listitem>
<listitem><para>1 means that the scans differ.</para></listitem>
<listitem><para>2 indicates a runtime error, such as the failure
to open a file.</para></listitem>
</itemizedlist>
</para>
</refsect1>
<refsect1> <refsect1>
<title>Bugs</title> <title>Bugs</title>
<para> <para>

View File

@@ -446,6 +446,8 @@ class ScanDiff(object):
document.writexml(f, addindent = u" ", newl = u"\n", encoding = "UTF-8") document.writexml(f, addindent = u" ", newl = u"\n", encoding = "UTF-8")
document.unlink() document.unlink()
cost = property(lambda self: sum([hd.cost for hd in self.host_diffs.values()]))
class HostDiff(object): class HostDiff(object):
"""A diff of two Hosts. It contains the two hosts, variables describing what """A diff of two Hosts. It contains the two hosts, variables describing what
changed, and a list of PortDiffs and OS differences.""" changed, and a list of PortDiffs and OS differences."""
@@ -1150,10 +1152,14 @@ service and OS detection.
--xml display output in XML format\ --xml display output in XML format\
""" % sys.argv[0] """ % sys.argv[0]
EXIT_EQUAL = 0
EXIT_DIFFERENT = 1
EXIT_ERROR = 2
def usage_error(msg): def usage_error(msg):
print >> sys.stderr, u"%s: %s" % (sys.argv[0], msg) print >> sys.stderr, u"%s: %s" % (sys.argv[0], msg)
print >> sys.stderr, u"Try '%s -h' for help." % sys.argv[0] print >> sys.stderr, u"Try '%s -h' for help." % sys.argv[0]
sys.exit(1) sys.exit(EXIT_ERROR)
def main(): def main():
global verbose global verbose
@@ -1199,5 +1205,17 @@ def main():
elif output_format == "xml": elif output_format == "xml":
diff.print_xml() diff.print_xml()
if diff.cost == 0:
return EXIT_EQUAL
else:
return EXIT_DIFFERENT
# Catch uncaught exceptions so they can produce an exit code of 2 (EXIT_ERROR),
# not 1 like they would by default.
def excepthook(type, value, tb):
sys.__excepthook__(type, value, tb)
sys.exit(EXIT_ERROR)
if __name__ == "__main__": if __name__ == "__main__":
main() sys.excepthook = excepthook
sys.exit(main())

View File

@@ -2,6 +2,7 @@
# Unit tests for Ndiff. # Unit tests for Ndiff.
import subprocess
import unittest import unittest
import xml.dom.minidom import xml.dom.minidom
import StringIO import StringIO
@@ -688,4 +689,43 @@ def host_apply_diff(host, diff):
host.script_results[host.script_results.index(sr_a)] = sr_b host.script_results[host.script_results.index(sr_a)] = sr_b
host.script_results.sort() host.script_results.sort()
def call_quiet(args, **kwargs):
"""Run a command with subprocess.call and hide its output."""
return subprocess.call(args, stdout = subprocess.PIPE,
stderr = subprocess.STDOUT, **kwargs)
class exit_code_test(unittest.TestCase):
NDIFF = "./ndiff"
def test_exit_equal(self):
"""Test that the exit code is 0 when the diff is empty."""
for format in ("--text", "--xml"):
code = call_quiet([self.NDIFF, format,
"test-scans/simple.xml", "test-scans/simple.xml"])
self.assertEqual(code, 0)
# Should be independent of verbosity.
for format in ("--text", "--xml"):
code = call_quiet([self.NDIFF, "-v", format,
"test-scans/simple.xml", "test-scans/simple.xml"])
self.assertEqual(code, 0)
def test_exit_different(self):
"""Test that the exit code is 1 when the diff is not empty."""
for format in ("--text", "--xml"):
code = call_quiet([self.NDIFF, format,
"test-scans/simple.xml", "test-scans/complex.xml"])
self.assertEqual(code, 1)
def test_exit_error(self):
"""Test that the exit code is 2 when there is an error."""
code = call_quiet([self.NDIFF])
self.assertEqual(code, 2)
code = call_quiet([self.NDIFF, "test-scans/simple.xml"])
self.assertEqual(code, 2)
code = call_quiet([self.NDIFF, "test-scans/simple.xml",
"test-scans/nonexistent.xml"])
self.assertEqual(code, 2)
code = call_quiet([self.NDIFF, "--nothing"])
self.assertEqual(code, 2)
unittest.main() unittest.main()