Переглянути джерело

Integrate madns into this project

This is what it's all been building up to! Because the madns server returns responses with fixed TTLs, and can send back "weird stuff" like fixed NS or PTR records that wouldn't be configurable in a normal resolver, we can test the _exact_ output of dog and assert that nothing has changed in the command-line interface. I'm really pleased about this!
Benjamin Sago 4 роки тому
батько
коміт
eb143baf93
72 змінених файлів з 936 додано та 12 видалено
  1. 11 4
      Justfile
  2. 3 1
      README.md
  3. 25 7
      xtests/README.md
  4. 0 0
      xtests/live/badssl.toml
  5. 0 0
      xtests/live/basics.toml
  6. 0 0
      xtests/live/bins.toml
  7. 0 0
      xtests/live/https.toml
  8. 0 0
      xtests/live/json.toml
  9. 0 0
      xtests/live/tcp.toml
  10. 0 0
      xtests/live/tls.toml
  11. 0 0
      xtests/live/udp.toml
  12. 44 0
      xtests/madns/a-records.toml
  13. 44 0
      xtests/madns/aaaa-records.toml
  14. 44 0
      xtests/madns/caa-records.toml
  15. 28 0
      xtests/madns/cname-records.toml
  16. 44 0
      xtests/madns/eui48-records.toml
  17. 44 0
      xtests/madns/eui64-records.toml
  18. 28 0
      xtests/madns/hinfo-records.toml
  19. 90 0
      xtests/madns/loc-records.toml
  20. 28 0
      xtests/madns/mx-records.toml
  21. 36 0
      xtests/madns/naptr-records.toml
  22. 28 0
      xtests/madns/ns-records.toml
  23. 28 0
      xtests/madns/openpgpkey-records.toml
  24. 44 0
      xtests/madns/opt-records.toml
  25. 1 0
      xtests/madns/outputs/a.example.ansitxt
  26. 1 0
      xtests/madns/outputs/aaaa.example.ansitxt
  27. 1 0
      xtests/madns/outputs/ansi.str.example.ansitxt
  28. 1 0
      xtests/madns/outputs/bad-regex.naptr.example.ansitxt
  29. 1 0
      xtests/madns/outputs/caa.example.ansitxt
  30. 1 0
      xtests/madns/outputs/cname.example.ansitxt
  31. 1 0
      xtests/madns/outputs/critical.caa.example.ansitxt
  32. 2 0
      xtests/madns/outputs/do-flag.opt.example.ansitxt
  33. 1 0
      xtests/madns/outputs/eui48.example.ansitxt
  34. 1 0
      xtests/madns/outputs/eui64.example.ansitxt
  35. 1 0
      xtests/madns/outputs/far-negative-latitude.loc.invalid.ansitxt
  36. 1 0
      xtests/madns/outputs/far-negative-longitude.loc.invalid.ansitxt
  37. 1 0
      xtests/madns/outputs/far-positive-latitude.loc.invalid.ansitxt
  38. 1 0
      xtests/madns/outputs/far-positive-longitude.loc.invalid.ansitxt
  39. 1 0
      xtests/madns/outputs/hinfo.example.ansitxt
  40. 1 0
      xtests/madns/outputs/loc.example.ansitxt
  41. 1 0
      xtests/madns/outputs/mx.example.ansitxt
  42. 2 0
      xtests/madns/outputs/named.opt.invalid.ansitxt
  43. 1 0
      xtests/madns/outputs/naptr.example.ansitxt
  44. 1 0
      xtests/madns/outputs/newline.str.example.ansitxt
  45. 1 0
      xtests/madns/outputs/ns.example.ansitxt
  46. 1 0
      xtests/madns/outputs/null.str.example.ansitxt
  47. 1 0
      xtests/madns/outputs/openpgpkey.example.ansitxt
  48. 2 0
      xtests/madns/outputs/opt.example.ansitxt
  49. 2 0
      xtests/madns/outputs/other-flags.opt.example.ansitxt
  50. 1 0
      xtests/madns/outputs/others.caa.example.ansitxt
  51. 1 0
      xtests/madns/outputs/ptr.example.ansitxt
  52. 1 0
      xtests/madns/outputs/slash.uri.example.ansitxt
  53. 1 0
      xtests/madns/outputs/soa.example.ansitxt
  54. 1 0
      xtests/madns/outputs/srv.example.ansitxt
  55. 1 0
      xtests/madns/outputs/sshfp.example.ansitxt
  56. 1 0
      xtests/madns/outputs/tab.str.example.ansitxt
  57. 1 0
      xtests/madns/outputs/tlsa.example.ansitxt
  58. 1 0
      xtests/madns/outputs/txt.example.ansitxt
  59. 1 0
      xtests/madns/outputs/upperbit.str.example.ansitxt
  60. 1 0
      xtests/madns/outputs/uri.example.ansitxt
  61. 39 0
      xtests/madns/protocol-chars.toml
  62. 23 0
      xtests/madns/protocol-compression.toml
  63. 39 0
      xtests/madns/protocol-error-codes.toml
  64. 28 0
      xtests/madns/ptr-records.toml
  65. 28 0
      xtests/madns/soa-records.toml
  66. 28 0
      xtests/madns/srv-records.toml
  67. 28 0
      xtests/madns/sshfp-records.toml
  68. 28 0
      xtests/madns/tlsa-records.toml
  69. 28 0
      xtests/madns/txt-records.toml
  70. 44 0
      xtests/madns/uri-records.toml
  71. 5 0
      xtests/options/errors.toml
  72. 9 0
      xtests/options/help.toml

+ 11 - 4
Justfile

@@ -38,7 +38,7 @@ export DOG_DEBUG := ""
 
 # run unit tests (in release mode)
 @test-release:
-    cargo test --lib --bin dog -workspace --release --verbose
+    cargo test --lib --bin dog --workspace --release --verbose
 
 # run unit tests (without some features)
 @test-quick:
@@ -56,15 +56,22 @@ export DOG_DEBUG := ""
 
 # run extended tests
 @xtests:
-    specsheet xtests/*.toml -O cmd.target.dog="${CARGO_TARGET_DIR:-../target}/debug/dog"
+    specsheet xtests/*/*.toml -shide \
+        -O cmd.target.dog="${CARGO_TARGET_DIR:-../../target}/debug/dog"
 
 # run extended tests (in release mode)
 @xtests-release:
-    specsheet xtests/*.toml -O cmd.target.dog="${CARGO_TARGET_DIR:-../target}/release/dog"
+    specsheet xtests/*/*.toml \
+        -O cmd.target.dog="${CARGO_TARGET_DIR:-../../target}/release/dog"
 
 # run extended tests (omitting certain feature tests)
 @xtests-quick:
-    specsheet xtests/*.toml -O cmd.target.dog="${CARGO_TARGET_DIR:-../target}/debug/dog" --skip-tags=udp,tls,https,json
+    specsheet xtests/options/*.toml xtests/live/{basics,tcp}.toml -shide \
+        -O cmd.target.dog="${CARGO_TARGET_DIR:-../../target}/debug/dog"
+
+# display the number of extended tests that get run
+@count-xtests:
+    grep -F '[[cmd]]' -R xtests | wc -l
 
 
 #---------#

+ 3 - 1
README.md

@@ -112,7 +112,9 @@ If you have a copy installed, you can run:
 
     just xtests
 
-Specsheet will test the compiled binary by making DNS requests over the network, checking that dog returns results and does not crash.
+Specsheet will test the compiled binary by making DNS requests over the network, checking that dog returns the correct results and does not crash.
+Note that this will expose your IP address.
+For more information, read [the xtests README](xtests/README.md).
 
 
 ---

+ 25 - 7
xtests/README.md

@@ -1,16 +1,34 @@
 # dog › xtests
 
-This is dog’s extended test suite. It gets run using [Specsheet]. They run a complete end-to-end set of tests, covering network connections, DNS protocol parsing, command-line options, and error handling.
+This is dog’s extended test suite. The checks herein form a complete end-to-end set of tests, covering things like network connections, DNS protocol parsing, command-line options, error handling, and edge case behaviour.
 
-For completeness, this makes connections over the network. This means that the outcome of some of the tests is dependent on your own machine’s connectivity! It also means that your own IP address will be recorded as making the requests.
+The checks are written as [Specsheet] documents, which you’ll need to have installed.
 
-The tests have the following set of Specsheet tags:
+Because these tests make connections over the network, the outcome of the test suite will depend on your own machine‘s Internet connection! It also means that your own IP address will be recorded as making the requests.
+
+
+### Test hierarchy
+
+The tests have been divided into three sections:
+
+1. **live**, which uses both your computer’s default resolver and the [public Cloudflare DNS resolver] to access records that have been created using a public-facing DNS host. This checks that dog works using whatever software is on the Internet right now. Because these are _live_ records, the output will vary as things like the TTL vary, so we cannot assert on the _exact_ output; nevertheless, it’s a good check to see if the basic functionality is working.
+2. **madns**, which sends requests to the [madns resolver]. This resolver has been pre-programmed with deliberately incorrect responses to see how dog handles edge cases in the DNS specification. These are not live records, so things like the TTLs of the responses are fixed, meaning the output should never change over time; however, it does not mean dog will hold up against the network infrastructure of the real world.
+3. **options**, which runs dog using various command-line options and checks that the correct output is returned. These tests should not make network requests when behaving correctly.
+
+All three categories of check are needed to ensure dog is working correctly.
+
+
+### Tags
+
+To run a subset of the checks, you can filter with the following tags:
 
-- `live`: All tests that use the network.
-- `isp`: Tests that use your computer’s default resolver.
-- `google`: Tests that use the [public Google DNS resolver].
 - `cloudflare`: Tests that use the [public Cloudflare DNS resolver].
+- `isp`: Tests that use your computer’s default resolver.
+- `madns`: Tests that use the [madns resolver].
+- `options`: Tests that check the command-line options.
+
+You can also use a DNS record type as a tag to only run the checks for that particular type.
 
 [Specsheet]: https://specsheet.software/
-[public Google DNS resolver]: https://developers.google.com/speed/public-dns
 [public Cloudflare DNS resolver]: https://developers.cloudflare.com/1.1.1.1/
+[madns resolver]: https://madns.binarystar.systems/

+ 0 - 0
xtests/badssl.toml → xtests/live/badssl.toml


+ 0 - 0
xtests/basics.toml → xtests/live/basics.toml


+ 0 - 0
xtests/bins.toml → xtests/live/bins.toml


+ 0 - 0
xtests/https.toml → xtests/live/https.toml


+ 0 - 0
xtests/json.toml → xtests/live/json.toml


+ 0 - 0
xtests/tcp.toml → xtests/live/tcp.toml


+ 0 - 0
xtests/tls.toml → xtests/live/tls.toml


+ 0 - 0
xtests/udp.toml → xtests/live/udp.toml


+ 44 - 0
xtests/madns/a-records.toml

@@ -0,0 +1,44 @@
+# A record successes
+
+[[cmd]]
+name = "Running with ‘a.example’ prints the correct A record"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 A a.example"
+stdout = { file = "outputs/a.example.ansitxt" }
+stderr = { empty = true }
+status = 0
+tags = [ "a", "madns" ]
+
+
+# A record invalid packets
+
+[[cmd]]
+name = "Running with ‘too-long.a.invalid’ displays a record length error"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 A too-long.a.invalid"
+stdout = { empty = true }
+stderr = { string = "Error [protocol]: Malformed packet: record length should be 4, got 5" }
+status = 1
+tags = [ "a", "madns" ]
+
+[[cmd]]
+name = "Running with ‘too-short.a.invalid’ displays a record length error"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 A too-short.a.invalid"
+stdout = { empty = true }
+stderr = { string = "Error [protocol]: Malformed packet: record length should be 4, got 3" }
+status = 1
+tags = [ "a", "madns" ]
+
+[[cmd]]
+name = "Running with ‘empty.a.invalid’ displays a record length error"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 A empty.a.invalid"
+stdout = { empty = true }
+stderr = { string = "Error [protocol]: Malformed packet: record length should be 4, got 0" }
+status = 1
+tags = [ "a", "madns" ]
+
+[[cmd]]
+name = "Running with ‘incomplete.a.invalid’ displays a protocol error"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 A incomplete.a.invalid"
+stdout = { empty = true }
+stderr = { string = "Error [protocol]: Malformed packet: insufficient data" }
+status = 1
+tags = [ "a", "madns" ]

+ 44 - 0
xtests/madns/aaaa-records.toml

@@ -0,0 +1,44 @@
+# AAAA record successes
+
+[[cmd]]
+name = "Running with ‘aaaa.example’ prints the correct AAAA record"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 AAAA aaaa.example"
+stdout = { file = "outputs/aaaa.example.ansitxt" }
+stderr = { empty = true }
+status = 0
+tags = [ "aaaa", "madns" ]
+
+
+# AAAA record invalid packets
+
+[[cmd]]
+name = "Running with ‘too-long.aaaa.invalid’ displays a record length error"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 AAAA too-long.aaaa.invalid"
+stdout = { empty = true }
+stderr = { string = "Error [protocol]: Malformed packet: record length should be 16, got 17" }
+status = 1
+tags = [ "aaaa", "madns" ]
+
+[[cmd]]
+name = "Running with ‘too-short.aaaa.invalid’ displays a record length error"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 AAAA too-short.aaaa.invalid"
+stdout = { empty = true }
+stderr = { string = "Error [protocol]: Malformed packet: record length should be 16, got 8" }
+status = 1
+tags = [ "aaaa", "madns" ]
+
+[[cmd]]
+name = "Running with ‘empty.aaaa.invalid’ displays a record length error"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 AAAA empty.aaaa.invalid"
+stdout = { empty = true }
+stderr = { string = "Error [protocol]: Malformed packet: record length should be 16, got 0" }
+status = 1
+tags = [ "aaaa", "madns" ]
+
+[[cmd]]
+name = "Running with ‘incomplete.aaaa.invalid’ displays a protocol error"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 AAAA incomplete.aaaa.invalid"
+stdout = { empty = true }
+stderr = { string = "Error [protocol]: Malformed packet: insufficient data" }
+status = 1
+tags = [ "aaaa", "madns" ]

+ 44 - 0
xtests/madns/caa-records.toml

@@ -0,0 +1,44 @@
+# CAA record successes
+
+[[cmd]]
+name = "Running with ‘caa.example’ prints the correct CAA record"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 CAA caa.example"
+stdout = { file = "outputs/caa.example.ansitxt" }
+stderr = { empty = true }
+status = 0
+tags = [ "caa", "madns" ]
+
+[[cmd]]
+name = "Running with ‘critical.caa.example’ prints the correct CAA record with the flag"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 CAA critical.caa.example"
+stdout = { file = "outputs/critical.caa.example.ansitxt" }
+stderr = { empty = true }
+status = 0
+tags = [ "caa", "madns" ]
+
+[[cmd]]
+name = "Running with ‘others.caa.example’ prints the correct CAA record and ignores the flags"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 CAA others.caa.example"
+stdout = { file = "outputs/others.caa.example.ansitxt" }
+stderr = { empty = true }
+status = 0
+tags = [ "caa", "madns" ]
+
+
+# CAA record invalid packets
+
+[[cmd]]
+name = "Running with ‘empty.caa.invalid’ displays a protocol error"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 CAA empty.caa.invalid"
+stdout = { empty = true }
+stderr = { string = "Error [protocol]: Malformed packet: insufficient data" }
+status = 1
+tags = [ "caa", "madns" ]
+
+[[cmd]]
+name = "Running with ‘incomplete.caa.invalid’ displays a protocol error"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 CAA incomplete.caa.invalid"
+stdout = { empty = true }
+stderr = { string = "Error [protocol]: Malformed packet: insufficient data" }
+status = 1
+tags = [ "caa", "madns" ]

+ 28 - 0
xtests/madns/cname-records.toml

@@ -0,0 +1,28 @@
+# CNAME record successes
+
+[[cmd]]
+name = "Running with ‘cname.example’ prints the correct CNAME record"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 CNAME cname.example"
+stdout = { file = "outputs/cname.example.ansitxt" }
+stderr = { empty = true }
+status = 0
+tags = [ "cname", "madns" ]
+
+
+# CNAME record invalid packets
+
+[[cmd]]
+name = "Running with ‘empty.cname.invalid’ displays a protocol error"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 CNAME empty.cname.invalid"
+stdout = { empty = true }
+stderr = { string = "Error [protocol]: Malformed packet: insufficient data" }
+status = 1
+tags = [ "cname", "madns" ]
+
+[[cmd]]
+name = "Running with ‘incomplete.cname.invalid’ displays a protocol error"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 CNAME incomplete.cname.invalid"
+stdout = { empty = true }
+stderr = { string = "Error [protocol]: Malformed packet: insufficient data" }
+status = 1
+tags = [ "cname", "madns" ]

+ 44 - 0
xtests/madns/eui48-records.toml

@@ -0,0 +1,44 @@
+# EUI48 record successes
+
+[[cmd]]
+name = "Running with ‘eui48.example’ prints the correct EUI48 record"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 EUI48 eui48.example"
+stdout = { file = "outputs/eui48.example.ansitxt" }
+stderr = { empty = true }
+status = 0
+tags = [ "eui48", "madns" ]
+
+
+# EUI48 record invalid packets
+
+[[cmd]]
+name = "Running with ‘too-long.eui48.invalid’ displays a record length error"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 EUI48 too-long.eui48.invalid"
+stdout = { empty = true }
+stderr = { string = "Error [protocol]: Malformed packet: record length should be 6, got 7" }
+status = 1
+tags = [ "eui48", "madns" ]
+
+[[cmd]]
+name = "Running with ‘too-short.eui48.invalid’ displays a record length error"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 EUI48 too-short.eui48.invalid"
+stdout = { empty = true }
+stderr = { string = "Error [protocol]: Malformed packet: record length should be 6, got 5" }
+status = 1
+tags = [ "eui48", "madns" ]
+
+[[cmd]]
+name = "Running with ‘empty.eui48.invalid’ displays a record length error"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 EUI48 empty.eui48.invalid"
+stdout = { empty = true }
+stderr = { string = "Error [protocol]: Malformed packet: record length should be 6, got 0" }
+status = 1
+tags = [ "eui48", "madns" ]
+
+[[cmd]]
+name = "Running with ‘incomplete.eui48.invalid’ displays a protocol error"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 EUI48 incomplete.eui48.invalid"
+stdout = { empty = true }
+stderr = { string = "Error [protocol]: Malformed packet: insufficient data" }
+status = 1
+tags = [ "eui48", "madns" ]

+ 44 - 0
xtests/madns/eui64-records.toml

@@ -0,0 +1,44 @@
+# EUI64 record successes
+
+[[cmd]]
+name = "Running with ‘eui64.example’ prints the correct EUI64 record"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 EUI64 eui64.example"
+stdout = { file = "outputs/eui64.example.ansitxt" }
+stderr = { empty = true }
+status = 0
+tags = [ "eui64", "madns" ]
+
+
+# EUI64 record invalid packets
+
+[[cmd]]
+name = "Running with ‘too-long.eui64.invalid’ displays a record length error"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 EUI64 too-long.eui64.invalid"
+stdout = { empty = true }
+stderr = { string = "Error [protocol]: Malformed packet: record length should be 8, got 9" }
+status = 1
+tags = [ "eui64", "madns" ]
+
+[[cmd]]
+name = "Running with ‘too-short.eui64.invalid’ displays a record length error"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 EUI64 too-short.eui64.invalid"
+stdout = { empty = true }
+stderr = { string = "Error [protocol]: Malformed packet: record length should be 8, got 7" }
+status = 1
+tags = [ "eui64", "madns" ]
+
+[[cmd]]
+name = "Running with ‘empty.eui64.invalid’ displays a record length error"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 EUI64 empty.eui64.invalid"
+stdout = { empty = true }
+stderr = { string = "Error [protocol]: Malformed packet: record length should be 8, got 0" }
+status = 1
+tags = [ "eui64", "madns" ]
+
+[[cmd]]
+name = "Running with ‘incomplete.eui64.invalid’ displays a protocol error"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 EUI64 incomplete.eui64.invalid"
+stdout = { empty = true }
+stderr = { string = "Error [protocol]: Malformed packet: insufficient data" }
+status = 1
+tags = [ "eui64", "madns" ]

+ 28 - 0
xtests/madns/hinfo-records.toml

@@ -0,0 +1,28 @@
+# HINFO record successes
+
+[[cmd]]
+name = "Running with ‘hinfo.example’ prints the correct HINFO record"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 HINFO hinfo.example"
+stdout = { file = "outputs/hinfo.example.ansitxt" }
+stderr = { empty = true }
+status = 0
+tags = [ "hinfo", "madns" ]
+
+
+# HINFO record invalid packets
+
+[[cmd]]
+name = "Running with ‘empty.hinfo.invalid’ displays a protocol error"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 HINFO empty.hinfo.invalid"
+stdout = { empty = true }
+stderr = { string = "Error [protocol]: Malformed packet: insufficient data" }
+status = 1
+tags = [ "hinfo", "madns" ]
+
+[[cmd]]
+name = "Running with ‘incomplete.hinfo.invalid’ displays a protocol error"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 HINFO incomplete.hinfo.invalid"
+stdout = { empty = true }
+stderr = { string = "Error [protocol]: Malformed packet: insufficient data" }
+status = 1
+tags = [ "hinfo", "madns" ]

+ 90 - 0
xtests/madns/loc-records.toml

@@ -0,0 +1,90 @@
+# LOC record successes
+
+[[cmd]]
+name = "Running with ‘loc.example’ prints the correct LOC record"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 LOC loc.example"
+stdout = { file = "outputs/loc.example.ansitxt" }
+stderr = { empty = true }
+status = 0
+tags = [ "loc", "madns" ]
+
+
+# LOC record out-of-range positions
+
+[[cmd]]
+name = "Running with ‘far-negative-longitude.loc.invalid’ displays a record with an out-of-range field"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 LOC far-negative-longitude.loc.invalid"
+stdout = { file = "outputs/far-negative-longitude.loc.invalid.ansitxt" }
+stderr = { empty = true }
+status = 0
+tags = [ "loc", "madns" ]
+
+[[cmd]]
+name = "Running with ‘far-positive-longitude.loc.invalid’ displays a record length error"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 LOC far-positive-longitude.loc.invalid"
+stdout = { file = "outputs/far-positive-longitude.loc.invalid.ansitxt" }
+stderr = { empty = true }
+status = 0
+tags = [ "loc", "madns" ]
+
+[[cmd]]
+name = "Running with ‘far-negative-latitude.loc.invalid’ displays a record length error"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 LOC far-negative-latitude.loc.invalid"
+stdout = { file = "outputs/far-negative-latitude.loc.invalid.ansitxt" }
+stderr = { empty = true }
+status = 0
+tags = [ "loc", "madns" ]
+
+[[cmd]]
+name = "Running with ‘far-positive-latitude.loc.invalid’ displays a record length error"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 LOC far-positive-latitude.loc.invalid"
+stdout = { file = "outputs/far-positive-latitude.loc.invalid.ansitxt" }
+stderr = { empty = true }
+status = 0
+tags = [ "loc", "madns" ]
+
+
+# LOC record version 1
+
+[[cmd]]
+name = "Running with ‘v1-conform.loc.invalid’ displays a version error"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 LOC v1-conform.loc.invalid"
+stdout = { empty = true }
+stderr = { string = "Error [protocol]: Malformed packet: record specifies version 1, expected up to 0" }
+status = 1
+tags = [ "loc", "madns" ]
+
+[[cmd]]
+name = "Running with ‘v1-nonconform.loc.invalid’ displays a version error"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 LOC v1-nonconform.loc.invalid"
+stdout = { empty = true }
+stderr = { string = "Error [protocol]: Malformed packet: record specifies version 1, expected up to 0" }
+status = 1
+tags = [ "loc", "madns" ]
+
+[[cmd]]
+name = "Running with ‘v1-empty.loc.invalid’ displays a version error"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 LOC v1-empty.loc.invalid"
+stdout = { empty = true }
+stderr = { string = "Error [protocol]: Malformed packet: record specifies version 1, expected up to 0" }
+status = 1
+tags = [ "loc", "madns" ]
+
+
+# LOC record invalid packets
+
+[[cmd]]
+name = "Running with ‘empty.loc.invalid’ displays a record length error"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 LOC empty.loc.invalid"
+stdout = { empty = true }
+stderr = { string = "Error [protocol]: Malformed packet: insufficient data" }
+status = 1
+tags = [ "loc", "madns" ]
+
+[[cmd]]
+name = "Running with ‘incomplete.loc.invalid’ displays a record length error"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 LOC incomplete.loc.invalid"
+stdout = { empty = true }
+stderr = { string = "Error [protocol]: Malformed packet: insufficient data" }
+status = 1
+tags = [ "loc", "madns" ]

+ 28 - 0
xtests/madns/mx-records.toml

@@ -0,0 +1,28 @@
+# MX record successes
+
+[[cmd]]
+name = "Running with ‘mx.example’ prints the correct MX record"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 MX mx.example"
+stdout = { file = "outputs/mx.example.ansitxt" }
+stderr = { empty = true }
+status = 0
+tags = [ "mx", "madns" ]
+
+
+# MX record invalid packets
+
+[[cmd]]
+name = "Running with ‘empty.mx.invalid’ displays a protocol error"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 MX empty.mx.invalid"
+stdout = { empty = true }
+stderr = { string = "Error [protocol]: Malformed packet: insufficient data" }
+status = 1
+tags = [ "mx", "madns" ]
+
+[[cmd]]
+name = "Running with ‘incomplete.mx.invalid’ displays a protocol error"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 MX incomplete.mx.invalid"
+stdout = { empty = true }
+stderr = { string = "Error [protocol]: Malformed packet: insufficient data" }
+status = 1
+tags = [ "mx", "madns" ]

+ 36 - 0
xtests/madns/naptr-records.toml

@@ -0,0 +1,36 @@
+# NAPTR record successes
+
+[[cmd]]
+name = "Running with ‘naptr.example’ prints the correct NAPTR record"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 NAPTR naptr.example"
+stdout = { file = "outputs/naptr.example.ansitxt" }
+stderr = { empty = true }
+status = 0
+tags = [ "naptr", "madns" ]
+
+[[cmd]]
+name = "Running with ‘bad-regex.naptr.example’ still prints the correct NAPTR record"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 NAPTR bad-regex.naptr.example"
+stdout = { file = "outputs/bad-regex.naptr.example.ansitxt" }
+stderr = { empty = true }
+status = 0
+tags = [ "naptr", "madns" ]
+
+
+# NAPTR record invalid packets
+
+[[cmd]]
+name = "Running with ‘empty.naptr.invalid’ displays a protocol error"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 NAPTR empty.naptr.invalid"
+stdout = { empty = true }
+stderr = { string = "Error [protocol]: Malformed packet: insufficient data" }
+status = 1
+tags = [ "naptr", "madns" ]
+
+[[cmd]]
+name = "Running with ‘incomplete.naptr.invalid’ displays a protocol error"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 NAPTR incomplete.naptr.invalid"
+stdout = { empty = true }
+stderr = { string = "Error [protocol]: Malformed packet: insufficient data" }
+status = 1
+tags = [ "naptr", "madns" ]

+ 28 - 0
xtests/madns/ns-records.toml

@@ -0,0 +1,28 @@
+# NS record successes
+
+[[cmd]]
+name = "Running with ‘ns.example’ prints the correct NS record"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 NS ns.example"
+stdout = { file = "outputs/ns.example.ansitxt" }
+stderr = { empty = true }
+status = 0
+tags = [ "ns", "madns" ]
+
+
+# NS record invalid packets
+
+[[cmd]]
+name = "Running with ‘empty.ns.invalid’ displays a protocol error"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 NS empty.ns.invalid"
+stdout = { empty = true }
+stderr = { string = "Error [protocol]: Malformed packet: insufficient data" }
+status = 1
+tags = [ "ns", "madns" ]
+
+[[cmd]]
+name = "Running with ‘incomplete.ns.invalid’ displays a protocol error"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 NS incomplete.ns.invalid"
+stdout = { empty = true }
+stderr = { string = "Error [protocol]: Malformed packet: insufficient data" }
+status = 1
+tags = [ "ns", "madns" ]

+ 28 - 0
xtests/madns/openpgpkey-records.toml

@@ -0,0 +1,28 @@
+# OPENPGPKEY record successes
+
+[[cmd]]
+name = "Running with ‘openpgpkey.example’ prints the correct OPENPGPKEY record"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 OPENPGPKEY openpgpkey.example"
+stdout = { file = "outputs/openpgpkey.example.ansitxt" }
+stderr = { empty = true }
+status = 0
+tags = [ "openpgpkey", "madns" ]
+
+
+# OPENPGPKEY record invalid packets
+
+[[cmd]]
+name = "Running with ‘empty.openpgpkey.invalid’ displays a record length error"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 OPENPGPKEY empty.openpgpkey.invalid"
+stdout = { empty = true }
+stderr = { string = "Error [protocol]: Malformed packet: record length should be at least 1, got 0" }
+status = 1
+tags = [ "openpgpkey", "madns" ]
+
+[[cmd]]
+name = "Running with ‘incomplete.openpgpkey.invalid’ displays a protocol error"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 OPENPGPKEY incomplete.openpgpkey.invalid"
+stdout = { empty = true }
+stderr = { string = "Error [protocol]: Malformed packet: insufficient data" }
+status = 1
+tags = [ "openpgpkey", "madns" ]

+ 44 - 0
xtests/madns/opt-records.toml

@@ -0,0 +1,44 @@
+# OPT record successes
+
+[[cmd]]
+name = "Running with ‘opt.example’ prints the correct OPT record"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 A opt.example --edns=show"
+stdout = { file = "outputs/opt.example.ansitxt" }
+stderr = { empty = true }
+status = 0
+tags = [ "opt", "madns" ]
+
+[[cmd]]
+name = "Running with ‘do-flag.opt.example’ prints the correct OPT record"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 A do-flag.opt.example --edns=show"
+stdout = { file = "outputs/do-flag.opt.example.ansitxt" }
+stderr = { empty = true }
+status = 0
+tags = [ "opt", "madns" ]
+
+[[cmd]]
+name = "Running with ‘other-flags.opt.example’ prints the correct OPT record"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 A other-flags.opt.example --edns=show"
+stdout = { file = "outputs/other-flags.opt.example.ansitxt" }
+stderr = { empty = true }
+status = 0
+tags = [ "opt", "madns" ]
+
+[[cmd]]
+name = "Running with ‘named.opt.invalid’ prints the correct OPT record"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 A named.opt.invalid --edns=show"
+stdout = { file = "outputs/named.opt.invalid.ansitxt" }
+stderr = { empty = true }
+status = 0
+tags = [ "opt", "madns" ]
+
+
+# OPT record invalid packets
+
+[[cmd]]
+name = "Running with ‘incomplete.opt.invalid’ displays a record length error"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 A incomplete.opt.invalid"
+stdout = { empty = true }
+stderr = { string = "Error [protocol]: Malformed packet: insufficient data" }
+status = 1
+tags = [ "opt", "madns" ]

+ 1 - 0
xtests/madns/outputs/a.example.ansitxt

@@ -0,0 +1 @@
+A a.example. 10m00s   127.0.0.1

+ 1 - 0
xtests/madns/outputs/aaaa.example.ansitxt

@@ -0,0 +1 @@
+AAAA aaaa.example. 10m00s   ::1

+ 1 - 0
xtests/madns/outputs/ansi.str.example.ansitxt

@@ -0,0 +1 @@
+CNAME ansi.str.example. 10m00s   "\u{1b}[32mgreen.\u{1b}[34mblue.\u{1b}[31mred.\u{1b}[0m."

+ 1 - 0
xtests/madns/outputs/bad-regex.naptr.example.ansitxt

@@ -0,0 +1 @@
+NAPTR bad-regex.naptr.example. 10m00s   5 10 s "SRV" /(((((((((((((((((((((((((/ "srv.example."

+ 1 - 0
xtests/madns/outputs/caa.example.ansitxt

@@ -0,0 +1 @@
+CAA caa.example. 10m00s   "issuewild" "trustworthy.example" (non-critical)

+ 1 - 0
xtests/madns/outputs/cname.example.ansitxt

@@ -0,0 +1 @@
+CNAME cname.example. 10m00s   "dns.lookup.dog."

+ 1 - 0
xtests/madns/outputs/critical.caa.example.ansitxt

@@ -0,0 +1 @@
+CAA critical.caa.example. 10m00s   "issuewild" "trustworthy.example" (critical)

+ 2 - 0
xtests/madns/outputs/do-flag.opt.example.ansitxt

@@ -0,0 +1,2 @@
+  A do-flag.opt.example. 10m00s   127.0.0.1
+OPT                             + 1452 0 0 32768 []

+ 1 - 0
xtests/madns/outputs/eui48.example.ansitxt

@@ -0,0 +1 @@
+EUI48 eui48.example. 10m00s   "12-34-56-78-90-ab"

+ 1 - 0
xtests/madns/outputs/eui64.example.ansitxt

@@ -0,0 +1 @@
+EUI64 eui64.example. 10m00s   "12-34-56-ff-fe-78-90-ab"

+ 1 - 0
xtests/madns/outputs/far-negative-latitude.loc.invalid.ansitxt

@@ -0,0 +1 @@
+LOC far-negative-latitude.loc.invalid. 10m00s   3e2 (0, 0) (Out of range, 0°0′0″ E, 0m)

+ 1 - 0
xtests/madns/outputs/far-negative-longitude.loc.invalid.ansitxt

@@ -0,0 +1 @@
+LOC far-negative-longitude.loc.invalid. 10m00s   3e2 (0, 0) (0°0′0″ N, Out of range, 0m)

+ 1 - 0
xtests/madns/outputs/far-positive-latitude.loc.invalid.ansitxt

@@ -0,0 +1 @@
+LOC far-positive-latitude.loc.invalid. 10m00s   3e2 (0, 0) (Out of range, 0°0′0″ E, 0m)

+ 1 - 0
xtests/madns/outputs/far-positive-longitude.loc.invalid.ansitxt

@@ -0,0 +1 @@
+LOC far-positive-longitude.loc.invalid. 10m00s   3e2 (0, 0) (0°0′0″ N, Out of range, 0m)

+ 1 - 0
xtests/madns/outputs/hinfo.example.ansitxt

@@ -0,0 +1 @@
+HINFO hinfo.example. 10m00s   "some-kinda-cpu" "some-kinda-os"

+ 1 - 0
xtests/madns/outputs/loc.example.ansitxt

@@ -0,0 +1 @@
+LOC loc.example. 10m00s   3e2 (0, 0) (51°30′12.748″ N, 0°7′39.611″ W, 0m)

+ 1 - 0
xtests/madns/outputs/mx.example.ansitxt

@@ -0,0 +1 @@
+MX mx.example. 10m00s   10 "exchange.example."

+ 2 - 0
xtests/madns/outputs/named.opt.invalid.ansitxt

@@ -0,0 +1,2 @@
+  A named.opt.invalid.           10m00s   127.0.0.1
+OPT bingle.bongle.dingle.dangle.        + 1452 0 0 0 []

+ 1 - 0
xtests/madns/outputs/naptr.example.ansitxt

@@ -0,0 +1 @@
+NAPTR naptr.example. 10m00s   5 10 s "SRV" /\d\d:\d\d:\d\d/ "srv.example."

+ 1 - 0
xtests/madns/outputs/newline.str.example.ansitxt

@@ -0,0 +1 @@
+CNAME newline.str.example. 10m00s   "some\nnew\r\nlines\n.example."

+ 1 - 0
xtests/madns/outputs/ns.example.ansitxt

@@ -0,0 +1 @@
+NS ns.example. 10m00s   "a.gtld-servers.net."

+ 1 - 0
xtests/madns/outputs/null.str.example.ansitxt

@@ -0,0 +1 @@
+CNAME null.str.example. 10m00s   "some\u{0}null\u{0}\u{0}chars\u{0}.example."

+ 1 - 0
xtests/madns/outputs/openpgpkey.example.ansitxt

@@ -0,0 +1 @@
+OPENPGPKEY openpgpkey.example. 10m00s   "EjRWeA=="

+ 2 - 0
xtests/madns/outputs/opt.example.ansitxt

@@ -0,0 +1,2 @@
+  A opt.example. 10m00s   127.0.0.1
+OPT                     + 1452 0 0 0 []

+ 2 - 0
xtests/madns/outputs/other-flags.opt.example.ansitxt

@@ -0,0 +1,2 @@
+  A other-flags.opt.example. 10m00s   127.0.0.1
+OPT                                 + 1452 0 0 32767 []

+ 1 - 0
xtests/madns/outputs/others.caa.example.ansitxt

@@ -0,0 +1 @@
+CAA caa.example. 10m00s   "issuewild" "trustworthy.example" (non-critical)

+ 1 - 0
xtests/madns/outputs/ptr.example.ansitxt

@@ -0,0 +1 @@
+PTR ptr.example. 10m00s   "dns.example."

+ 1 - 0
xtests/madns/outputs/slash.uri.example.ansitxt

@@ -0,0 +1 @@
+URI slash.uri.example. 10m00s   10 1 "/"

+ 1 - 0
xtests/madns/outputs/soa.example.ansitxt

@@ -0,0 +1 @@
+SOA soa.example. 10m00s   "mname.example." "rname.example." 1564274434 1d0h00m00s 2h00m00s 7d0h00m00s 5m00s

+ 1 - 0
xtests/madns/outputs/srv.example.ansitxt

@@ -0,0 +1 @@
+SRV srv.example. 10m00s   1 1 "service.example.":37500

+ 1 - 0
xtests/madns/outputs/sshfp.example.ansitxt

@@ -0,0 +1 @@
+SSHFP sshfp.example. 10m00s   1 1 212223242526

+ 1 - 0
xtests/madns/outputs/tab.str.example.ansitxt

@@ -0,0 +1 @@
+CNAME tab.str.example. 10m00s   "some\ttab\t\tchars\t.example."

+ 1 - 0
xtests/madns/outputs/tlsa.example.ansitxt

@@ -0,0 +1 @@
+TLSA tlsa.example. 10m00s   3 1 1 "112233445566"

+ 1 - 0
xtests/madns/outputs/txt.example.ansitxt

@@ -0,0 +1 @@
+TXT txt.example. 10m00s   "Cache Invalidation and Naming Things"

+ 1 - 0
xtests/madns/outputs/upperbit.str.example.ansitxt

@@ -0,0 +1 @@
+CNAME upperbit.str.example. 10m00s   "\u{7f}�����.example."

+ 1 - 0
xtests/madns/outputs/uri.example.ansitxt

@@ -0,0 +1 @@
+URI uri.example. 10m00s   10 16 "https://rfcs.io/"

+ 39 - 0
xtests/madns/protocol-chars.toml

@@ -0,0 +1,39 @@
+[[cmd]]
+name = "Running with ‘ansi.str.example’ properly escapes the codes"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 CNAME ansi.str.example"
+stdout = { file = "outputs/ansi.str.example.ansitxt" }
+stderr = { empty = true }
+status = 0
+tags = [ "protocol", "madns" ]
+
+[[cmd]]
+name = "Running with ‘newline.str.example’ properly escapes the newlines"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 CNAME newline.str.example"
+stdout = { file = "outputs/newline.str.example.ansitxt" }
+stderr = { empty = true }
+status = 0
+tags = [ "protocol", "madns" ]
+
+[[cmd]]
+name = "Running with ‘null.str.example’ properly handles the null bytes"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 CNAME null.str.example"
+stdout = { file = "outputs/null.str.example.ansitxt" }
+stderr = { empty = true }
+status = 0
+tags = [ "protocol", "madns" ]
+
+[[cmd]]
+name = "Running with ‘tab.str.example’ properly escapes the tabs"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 CNAME tab.str.example"
+stdout = { file = "outputs/tab.str.example.ansitxt" }
+stderr = { empty = true }
+status = 0
+tags = [ "protocol", "madns" ]
+
+[[cmd]]
+name = "Running with ‘upperbit.str.example’ properly escapes the upper-bit characters"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 CNAME upperbit.str.example"
+stdout = { file = "outputs/upperbit.str.example.ansitxt" }
+stderr = { empty = true }
+status = 0
+tags = [ "protocol", "madns" ]

+ 23 - 0
xtests/madns/protocol-compression.toml

@@ -0,0 +1,23 @@
+[[cmd]]
+name = "Running with ‘out-of-range.invalid’ displays a protocol error"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 A out-of-range.invalid"
+stdout = { empty = true }
+stderr = { string = "Error [protocol]: Malformed packet: insufficient data" }
+status = 1
+tags = [ "protocol", "madns" ]
+
+[[cmd]]
+name = "Running with ‘recursive-1.invalid’ displays a recursion error"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 A recursive-1.invalid"
+stdout = { empty = true }
+stderr = { string = "Error [protocol]: Malformed packet: too much recursion: [37]" }
+status = 1
+tags = [ "protocol", "madns" ]
+
+[[cmd]]
+name = "Running with ‘recursive-2.invalid’ displays a recursion error"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 A recursive-2.invalid"
+stdout = { empty = true }
+stderr = { string = "Error [protocol]: Malformed packet: too much recursion: [53, 37]" }
+status = 1
+tags = [ "protocol", "madns" ]

+ 39 - 0
xtests/madns/protocol-error-codes.toml

@@ -0,0 +1,39 @@
+[[cmd]]
+name = "Running with ‘formerr.invalid’ displays the error code"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 A formerr.invalid"
+stdout = { string = "Status: Format Error" }
+stderr = { empty = true }
+status = 0
+tags = [ "protocol", "madns" ]
+
+[[cmd]]
+name = "Running with ‘servfail.invalid’ displays the error code"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 A servfail.invalid"
+stdout = { string = "Status: Server Failure" }
+stderr = { empty = true }
+status = 0
+tags = [ "protocol", "madns" ]
+
+[[cmd]]
+name = "Running with ‘nxdomain.invalid’ displays the error code"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 A nxdomain.invalid"
+stdout = { string = "Status: NXDomain" }
+stderr = { empty = true }
+status = 0
+tags = [ "protocol", "madns" ]
+
+[[cmd]]
+name = "Running with ‘notimp.invalid’ displays the error code"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 A notimp.invalid"
+stdout = { string = "Status: Not Implemented" }
+stderr = { empty = true }
+status = 0
+tags = [ "protocol", "madns" ]
+
+[[cmd]]
+name = "Running with ‘refused.invalid’ displays the error code"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 A refused.invalid"
+stdout = { string = "Status: Query Refused" }
+stderr = { empty = true }
+status = 0
+tags = [ "protocol", "madns" ]

+ 28 - 0
xtests/madns/ptr-records.toml

@@ -0,0 +1,28 @@
+# PTR record successes
+
+[[cmd]]
+name = "Running with ‘ptr.example’ prints the correct PTR record"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 PTR ptr.example"
+stdout = { file = "outputs/ptr.example.ansitxt" }
+stderr = { empty = true }
+status = 0
+tags = [ "ptr", "madns" ]
+
+
+# PTR record invalid packets
+
+[[cmd]]
+name = "Running with ‘empty.ptr.invalid’ displays a protocol error"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 PTR empty.ptr.invalid"
+stdout = { empty = true }
+stderr = { string = "Error [protocol]: Malformed packet: insufficient data" }
+status = 1
+tags = [ "ptr", "madns" ]
+
+[[cmd]]
+name = "Running with ‘incomplete.ptr.invalid’ displays a protocol error"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 PTR incomplete.ptr.invalid"
+stdout = { empty = true }
+stderr = { string = "Error [protocol]: Malformed packet: insufficient data" }
+status = 1
+tags = [ "ptr", "madns" ]

+ 28 - 0
xtests/madns/soa-records.toml

@@ -0,0 +1,28 @@
+# SOA record successes
+
+[[cmd]]
+name = "Running with ‘soa.example’ prints the correct SOA record"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 SOA soa.example"
+stdout = { file = "outputs/soa.example.ansitxt" }
+stderr = { empty = true }
+status = 0
+tags = [ "soa", "madns" ]
+
+
+# SOA record invalid packets
+
+[[cmd]]
+name = "Running with ‘empty.soa.invalid’ displays a protocol error"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 SOA empty.soa.invalid"
+stdout = { empty = true }
+stderr = { string = "Error [protocol]: Malformed packet: insufficient data" }
+status = 1
+tags = [ "soa", "madns" ]
+
+[[cmd]]
+name = "Running with ‘incomplete.soa.invalid’ displays a protocol error"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 SOA incomplete.soa.invalid"
+stdout = { empty = true }
+stderr = { string = "Error [protocol]: Malformed packet: insufficient data" }
+status = 1
+tags = [ "soa", "madns" ]

+ 28 - 0
xtests/madns/srv-records.toml

@@ -0,0 +1,28 @@
+# SRV record successes
+
+[[cmd]]
+name = "Running with ‘srv.example’ prints the correct SRV record"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 SRV srv.example"
+stdout = { file = "outputs/srv.example.ansitxt" }
+stderr = { empty = true }
+status = 0
+tags = [ "soa", "madns" ]
+
+
+# SRV record invalid packets
+
+[[cmd]]
+name = "Running with ‘empty.srv.invalid’ displays a protocol error"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 SRV empty.srv.invalid"
+stdout = { empty = true }
+stderr = { string = "Error [protocol]: Malformed packet: insufficient data" }
+status = 1
+tags = [ "soa", "madns" ]
+
+[[cmd]]
+name = "Running with ‘incomplete.srv.invalid’ displays a protocol error"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 SRV incomplete.srv.invalid"
+stdout = { empty = true }
+stderr = { string = "Error [protocol]: Malformed packet: insufficient data" }
+status = 1
+tags = [ "soa", "madns" ]

+ 28 - 0
xtests/madns/sshfp-records.toml

@@ -0,0 +1,28 @@
+# SSHFP record successes
+
+[[cmd]]
+name = "Running with ‘sshfp.example’ prints the correct SSHFP record"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 SSHFP sshfp.example"
+stdout = { file = "outputs/sshfp.example.ansitxt" }
+stderr = { empty = true }
+status = 0
+tags = [ "sshfp", "madns" ]
+
+
+# SSHFP record invalid packets
+
+[[cmd]]
+name = "Running with ‘empty.sshfp.invalid’ displays a protocol error"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 SSHFP empty.sshfp.invalid"
+stdout = { empty = true }
+stderr = { string = "Error [protocol]: Malformed packet: insufficient data" }
+status = 1
+tags = [ "sshfp", "madns" ]
+
+[[cmd]]
+name = "Running with ‘incomplete.sshfp.invalid’ displays a protocol error"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 SSHFP incomplete.sshfp.invalid"
+stdout = { empty = true }
+stderr = { string = "Error [protocol]: Malformed packet: insufficient data" }
+status = 1
+tags = [ "sshfp", "madns" ]

+ 28 - 0
xtests/madns/tlsa-records.toml

@@ -0,0 +1,28 @@
+# TLSA record successes
+
+[[cmd]]
+name = "Running with ‘tlsa.example’ prints the correct TLSA record"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 TLSA tlsa.example"
+stdout = { file = "outputs/tlsa.example.ansitxt" }
+stderr = { empty = true }
+status = 0
+tags = [ "tlsa", "madns" ]
+
+
+# TLSA record invalid packets
+
+[[cmd]]
+name = "Running with ‘empty.tlsa.invalid’ displays a protocol error"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 TLSA empty.tlsa.invalid"
+stdout = { empty = true }
+stderr = { string = "Error [protocol]: Malformed packet: insufficient data" }
+status = 1
+tags = [ "tlsa", "madns" ]
+
+[[cmd]]
+name = "Running with ‘incomplete.tlsa.invalid’ displays a protocol error"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 TLSA incomplete.tlsa.invalid"
+stdout = { empty = true }
+stderr = { string = "Error [protocol]: Malformed packet: insufficient data" }
+status = 1
+tags = [ "tlsa", "madns" ]

+ 28 - 0
xtests/madns/txt-records.toml

@@ -0,0 +1,28 @@
+# TXT record successes
+
+[[cmd]]
+name = "Running with ‘txt.example’ prints the correct TXT record"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 TXT txt.example"
+stdout = { file = "outputs/txt.example.ansitxt" }
+stderr = { empty = true }
+status = 0
+tags = [ "txt", "madns" ]
+
+
+# TXT record invalid packets
+
+[[cmd]]
+name = "Running with ‘empty.txt.invalid’ displays a protocol error"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 TXT empty.txt.invalid"
+stdout = { empty = true }
+stderr = { string = "Error [protocol]: Malformed packet: insufficient data" }
+status = 1
+tags = [ "txt", "madns" ]
+
+[[cmd]]
+name = "Running with ‘incomplete.txt.invalid’ displays a protocol error"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 TXT incomplete.txt.invalid"
+stdout = { empty = true }
+stderr = { string = "Error [protocol]: Malformed packet: insufficient data" }
+status = 1
+tags = [ "txt", "madns" ]

+ 44 - 0
xtests/madns/uri-records.toml

@@ -0,0 +1,44 @@
+# URI record successes
+
+[[cmd]]
+name = "Running with ‘uri.example’ prints the correct URI record"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 URI uri.example"
+stdout = { file = "outputs/uri.example.ansitxt" }
+stderr = { empty = true }
+status = 0
+tags = [ "uri", "madns" ]
+
+[[cmd]]
+name = "Running with ‘slash.uri.example’ still prints the correct URI record"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 URI slash.uri.example"
+stdout = { file = "outputs/slash.uri.example.ansitxt" }
+stderr = { empty = true }
+status = 0
+tags = [ "uri", "madns" ]
+
+
+# URI record invalid packets
+
+[[cmd]]
+name = "Running with ‘missing-data.uri.invalid’ displays a packet length error"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 URI missing-data.uri.invalid"
+stdout = { empty = true }
+stderr = { string = "Error [protocol]: Malformed packet: record length should be at least 5, got 4" }
+status = 1
+tags = [ "uri", "madns" ]
+
+[[cmd]]
+name = "Running with ‘empty.uri.invalid’ displays a protocol error"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 URI empty.uri.invalid"
+stdout = { empty = true }
+stderr = { string = "Error [protocol]: Malformed packet: insufficient data" }
+status = 1
+tags = [ "uri", "madns" ]
+
+[[cmd]]
+name = "Running with ‘incomplete.uri.invalid’ displays a protocol error"
+shell = "dog --colour=always --tcp @madns.binarystar.systems:5301 URI incomplete.uri.invalid"
+stdout = { empty = true }
+stderr = { string = "Error [protocol]: Malformed packet: insufficient data" }
+status = 1
+tags = [ "uri", "madns" ]

+ 5 - 0
xtests/errors.toml → xtests/options/errors.toml

@@ -4,6 +4,7 @@ shell = "dog --wibble"
 stdout = { empty = true }
 stderr = { string = "wibble" }
 status = 3
+tags = [ 'options' ]
 
 [[cmd]]
 name = "Running dog with ‘XYZZY’ warns about the invalid record type"
@@ -11,6 +12,7 @@ shell = "dog XYZZY dns.google"
 stdout = { empty = true }
 stderr = { string = "XYZZY" }
 status = 3
+tags = [ 'options' ]
 
 [[cmd]]
 name = "Running dog with ‘OPT’ warns that OPT requests are sent by default"
@@ -18,6 +20,7 @@ shell = "dog OPT dns.google"
 stdout = { empty = true }
 stderr = { string = "OPT request is sent by default" }
 status = 3
+tags = [ 'options' ]
 
 [[cmd]]
 name = "Running dog with a domain longer than 255 bytes warns about it being too long"
@@ -25,6 +28,7 @@ shell = "dog 1234567890123456789012345678901234567890123456789012345678901234567
 stdout = { empty = true }
 stderr = { string = "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" }
 status = 3
+tags = [ 'options' ]
 
 [[cmd]]
 name = "Running dog with ‘--https’ and no nameserver warns that one is missing"
@@ -32,3 +36,4 @@ shell = "dog --https dns.google"
 stdout = { empty = true }
 stderr = { string = "You must pass a URL as a nameserver when using --https" }
 status = 3
+tags = [ 'options' ]

+ 9 - 0
xtests/help.toml → xtests/options/help.toml

@@ -6,6 +6,7 @@ shell = "dog --help"
 stdout = { string = "dog ●" }
 stderr = { empty = true }
 status = 0
+tags = [ 'options' ]
 
 [[cmd]]
 name = "Running ‘dog --help --color=automatic’ not to a terminal shows help without colour"
@@ -13,6 +14,7 @@ shell = "dog --help --color=automatic"
 stdout = { string = "dog ●" }
 stderr = { empty = true }
 status = 0
+tags = [ 'options' ]
 
 [[cmd]]
 name = "Running ‘dog --help --colour=always’ shows help with colour"
@@ -20,6 +22,7 @@ shell = "dog --help --colour=always"
 stdout = { string = "dog \u001B[1;32m●\u001B[0m" }
 stderr = { empty = true }
 status = 0
+tags = [ 'options' ]
 
 [[cmd]]
 name = "Running ‘dog --help --color=never’ shows without colour"
@@ -27,6 +30,7 @@ shell = "dog --help --color=never"
 stdout = { string = "dog ●" }
 stderr = { empty = true }
 status = 0
+tags = [ 'options' ]
 
 [[cmd]]
 name = "Running ‘dog’ with no arguments shows help"
@@ -34,6 +38,7 @@ shell = "dog"
 stdout = { string = "dog ●" }
 stderr = { empty = true }
 status = 3
+tags = [ 'options' ]
 
 
 # versions
@@ -44,6 +49,7 @@ shell = "dog --version"
 stdout = { string = "dog ●" }
 stderr = { empty = true }
 status = 0
+tags = [ 'options' ]
 
 [[cmd]]
 name = "Running ‘dog --version --colour=automatic’ not to a terminal shows version information without colour"
@@ -51,6 +57,7 @@ shell = "dog --version --colour=automatic"
 stdout = { string = "dog ●" }
 stderr = { empty = true }
 status = 0
+tags = [ 'options' ]
 
 [[cmd]]
 name = "Running ‘dog --version --color=always’ shows version information with colour"
@@ -58,6 +65,7 @@ shell = "dog --version --color=always"
 stdout = { string = "dog \u001B[1;32m●\u001B[0m" }
 stderr = { empty = true }
 status = 0
+tags = [ 'options' ]
 
 [[cmd]]
 name = "Running ‘dog --version --colour=never’ shows version information without colour"
@@ -65,3 +73,4 @@ shell = "dog --version --colour=never"
 stdout = { string = "dog ●" }
 stderr = { empty = true }
 status = 0
+tags = [ 'options' ]