mte/unikernel/duniverse/domain-name/tests.ml
2025-11-11 02:07:51 +01:00

305 lines
16 KiB
OCaml

let n_of_s = Domain_name.of_string_exn
let raw =
let module M = struct
type t = [ `raw ] Domain_name.t
let pp = Domain_name.pp
let equal = Domain_name.equal ~case_sensitive:false
end in (module M: Alcotest.TESTABLE with type t = M.t)
let host =
let module M = struct
type t = [ `host ] Domain_name.t
let pp = Domain_name.pp
let equal = Domain_name.equal ~case_sensitive:false
end in (module M: Alcotest.TESTABLE with type t = M.t)
let service =
let module M = struct
type t = [ `service ] Domain_name.t
let pp = Domain_name.pp
let equal = Domain_name.equal ~case_sensitive:false
end in (module M: Alcotest.TESTABLE with type t = M.t)
let p_msg =
let module M = struct
type t = [ `Msg of string ]
let pp ppf (`Msg m) = Fmt.string ppf m
let equal (`Msg _) (`Msg _) = true
end in (module M: Alcotest.TESTABLE with type t = M.t)
let is_domain x = match Domain_name.of_string x with
| Ok _ -> true | Error _ -> false
let is_host x = match Domain_name.host x with
| Ok _ -> true | Error _ -> false
let is_service x = match Domain_name.service x with
| Ok _ -> true | Error _ -> false
let longest_label = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk"
let longest_prefix =
let d a b = a ^ "." ^ b in
d longest_label (d longest_label longest_label)
let basic_preds () =
Alcotest.(check bool "root is_hostname" true (is_host Domain_name.root)) ;
Alcotest.(check bool "foo is a hostname" true (is_host (n_of_s "foo"))) ;
Alcotest.(check bool ".foo is no domain" false (is_domain ".foo")) ;
Alcotest.(check bool "bar is a hostname" true (is_host (n_of_s "bar"))) ;
Alcotest.(check bool "foo.bar is a hostname" true (is_host (n_of_s "foo.bar"))) ;
Alcotest.(check bool "longest label is domain name" true (is_domain longest_label)) ;
Alcotest.(check bool "longest label + a is not domain name" false (is_domain (longest_label ^ "a"))) ;
Alcotest.(check bool "ll.ll.ll.ll[:-2] is domain name" true
(is_domain (longest_prefix ^ "." ^ (String.sub longest_label 0 61)))) ;
Alcotest.(check bool "ll.ll.ll.ll[:-1] is not a domain name" false
(is_domain (longest_prefix ^ "." ^ (String.sub longest_label 0 62)))) ;
Alcotest.(check bool "foo._bar is not a hostname" false (is_host (n_of_s "foo._bar"))) ;
Alcotest.(check bool "2foo.bar is a hostname" true (is_host (n_of_s "2foo.bar"))) ;
Alcotest.(check bool "f2.bar is a hostname" true (is_host (n_of_s "f2.bar"))) ;
Alcotest.(check bool "-f2.bar is not a hostname" false (is_host (n_of_s "-f2.bar"))) ;
Alcotest.(check bool "f2.23 is not a hostname" false (is_host (n_of_s "f2.23"))) ;
Alcotest.(check bool "42.23b is a hostname" true (is_host (n_of_s "42.23b"))) ;
Alcotest.(check bool "'bar.foo is not a hostname" false (is_host (n_of_s "'bar.foo"))) ;
Alcotest.(check bool "-foo.bar is not a hostname" false (is_host (n_of_s "'-foo.bar"))) ;
Alcotest.(check bool "foo-.bar is not a hostname" false (is_host (n_of_s "foo-.bar"))) ;
Alcotest.(check bool "f-o-o.bar is a hostname" true (is_host (n_of_s "f-o-o.bar"))) ;
Alcotest.(check bool "2f.b3 is a hostname" true (is_host (n_of_s "2f.b3"))) ;
Alcotest.(check bool "2f3.2b3 is a hostname" true (is_host (n_of_s "2f3.2b3"))) ;
Alcotest.(check bool "root is no service" false (is_service Domain_name.root)) ;
Alcotest.(check bool "_tcp.foo is no service" false
(is_service (n_of_s "_tcp.foo"))) ;
Alcotest.(check bool "_._tcp.foo is no service" false
(is_service (n_of_s "_._tcp.foo"))) ;
Alcotest.(check bool "foo._tcp.foo is no service" false
(is_service (n_of_s "foo._tcp.foo"))) ;
Alcotest.(check bool "f_oo._tcp.foo is no service" false
(is_service (n_of_s "f_oo._tcp.foo"))) ;
Alcotest.(check bool "foo_._tcp.foo is no service" false
(is_service (n_of_s "foo_._tcp.foo"))) ;
Alcotest.(check bool "_xmpp-server._tcp.foo is a service" true
(is_service (n_of_s "_xmpp-server._tcp.foo"))) ;
Alcotest.(check bool "_xmpp-server._tcp2.foo is no service" false
(is_service (n_of_s "_xmpp-server._tcp2.foo"))) ;
Alcotest.(check bool "_xmpp_server._tcp.foo is no service" false
(is_service (n_of_s "_xmpp_server._tcp.foo"))) ;
Alcotest.(check bool "_xmpp-server-server._tcp.foo is no service" false
(is_service (n_of_s "_xmpp-server-server._tcp.foo"))) ;
Alcotest.(check bool "_443._tcp.foo is a service" true
(is_service (n_of_s "_443._tcp.foo"))) ;
let foo = n_of_s "foo" in
Alcotest.(check bool "foo is no subdomain of foo.bar" false
(Domain_name.is_subdomain ~subdomain:foo ~domain:(n_of_s "foo.bar"))) ;
Alcotest.(check bool "foo is a subdomain of foo" true
(Domain_name.is_subdomain ~subdomain:foo ~domain:foo)) ;
Alcotest.(check bool "bar.foo is a subdomain of foo" true
(Domain_name.is_subdomain ~subdomain:(n_of_s "bar.foo") ~domain:foo))
let case () =
Alcotest.(check bool "foo123.com and Foo123.com are equal" true
(Domain_name.equal (n_of_s "foo123.com") (n_of_s "Foo123.com"))) ;
Alcotest.(check bool "foo123.com and Foo123.com are not equal if case" false
(Domain_name.equal ~case_sensitive:true
(n_of_s "foo123.com") (n_of_s "Foo123.com"))) ;
Alcotest.(check bool "foo-123.com and com are not equal" false
(Domain_name.equal (n_of_s "foo-123.com") (n_of_s "com"))) ;
Alcotest.(check bool "foo123.com and Foo123.com are equal if case _and_ canonical used on second"
true
Domain_name.(equal ~case_sensitive:true
(n_of_s "foo123.com") (canonical (n_of_s "Foo123.com")))) ;
Alcotest.(check bool "foo123.com and Foo123.com are not equal if case _and_ canonical used on first"
false
Domain_name.(equal ~case_sensitive:true
(canonical (n_of_s "foo123.com")) (n_of_s "Foo123.com"))) ;
Alcotest.(check bool "foo123.com and Foo123.com are equal if case _and_ canonical used on both"
true
Domain_name.(equal ~case_sensitive:true
(canonical (n_of_s "foo123.com")) (canonical (n_of_s "Foo123.com"))))
let p_name = Alcotest.testable Domain_name.pp Domain_name.equal
let basic_name () =
let lll = String.sub longest_label 0 61
and llt = String.sub longest_label 0 62
in
Alcotest.(check bool "prepend '_foo' to root is not valid hostname"
false (is_host (Domain_name.prepend_label_exn Domain_name.root "_foo"))) ;
Alcotest.(check bool "host (of_strings [ '_foo' ; 'bar' ]) is not valid"
false (is_host (Domain_name.of_strings_exn [ "_foo" ; "bar" ]))) ;
Alcotest.(check (result p_name p_msg) "of_string 'foo.bar' is valid"
(Ok (n_of_s "foo.bar")) (Domain_name.of_string "foo.bar")) ;
Alcotest.(check bool "host (of_string 'foo.bar') is valid"
true (is_host (Domain_name.of_string_exn "foo.bar"))) ;
Alcotest.(check p_name "of_array 'foo.bar' is good"
(n_of_s "foo.bar") (Domain_name.of_array [| "bar" ; "foo" |])) ;
Alcotest.(check bool "host (of_array 'foo.bar') is good"
true (is_host (Domain_name.of_array [| "bar" ; "foo" |]))) ;
Alcotest.(check bool "host (prepend (ll[:-2]) (ll ^ ll ^ ll)) is valid"
true (is_host (Domain_name.prepend_label_exn (n_of_s longest_prefix) lll))) ;
Alcotest.(check (result p_name p_msg) "prepend '' root is invalid"
(Error (`Msg "")) (Domain_name.prepend_label Domain_name.root "")) ;
Alcotest.(check (result p_name p_msg) "prepend ll^a root is invalid"
(Error (`Msg "")) (Domain_name.prepend_label Domain_name.root (longest_label ^ "a"))) ;
Alcotest.(check (result p_name p_msg) "prepend ll (ll ^ ll ^ ll) is invalid"
(Error (`Msg "")) (Domain_name.prepend_label (n_of_s longest_prefix) longest_label)) ;
Alcotest.(check (result p_name p_msg) "prepend ll[:-1] (ll ^ ll ^ ll) is invalid"
(Error (`Msg "")) (Domain_name.prepend_label (n_of_s longest_prefix) llt)) ;
Alcotest.(check (result p_name p_msg) "concat 'foo.bar' 'baz.barf' is good"
(Ok (n_of_s "foo.bar.baz.barf"))
(Domain_name.append (n_of_s "foo.bar") (n_of_s "baz.barf"))) ;
let r = Domain_name.prepend_label_exn (n_of_s longest_prefix) lll in
Alcotest.(check (result p_name p_msg) "concat ll[:-2] lp is good"
(Ok r)
(Domain_name.append (n_of_s lll) (n_of_s longest_prefix))) ;
Alcotest.(check (result p_name p_msg) "concat ll[:-1] lp is bad"
(Error (`Msg ""))
(Domain_name.append (n_of_s llt) (n_of_s longest_prefix)))
let fqdn () =
Alcotest.(check bool "of_string_exn example.com = of_string_exn example.com."
true
(Domain_name.equal (n_of_s "example.com") (n_of_s "example.com."))) ;
Alcotest.(check bool "of_strings_exn ['example' ; 'com'] = of_strings_exn ['example' ; 'com' ; '']"
true
Domain_name.(equal
(of_strings_exn [ "example" ; "com" ])
(of_strings_exn [ "example" ; "com" ; "" ])));
try
Alcotest.(check bool {|of_string_exn "" = of_string_exn "."|})
true
Domain_name.(equal (n_of_s "") (n_of_s "."))
with Invalid_argument _ -> Alcotest.fail "invalid domain name for root"
let fqdn_around () =
let d = n_of_s "foo.com." in
Alcotest.(check bool "of_string (to_string (of_string 'foo.com.')) works"
true Domain_name.(equal d (of_string_exn (to_string d)))) ;
Alcotest.(check bool "of_string (to_string ~trailing:true (of_string 'foo.com.')) works"
true Domain_name.(equal d (of_string_exn (to_string ~trailing:true d))));
try
Alcotest.(check bool "of_string (to_string ~trailing:true (of_string '.')) works")
true
Domain_name.(equal root (of_string_exn (to_string ~trailing:true root)))
with Invalid_argument _ -> Alcotest.fail "invalid domain name for root"
let drop_labels () =
let res = n_of_s "foo.com" in
Alcotest.(check p_name "dropping 1 label from www.foo.com is foo.com"
res
(Domain_name.drop_label_exn (Domain_name.of_string_exn "www.foo.com"))) ;
Alcotest.(check p_name "dropping 2 labels from www.bar.foo.com is foo.com"
res
(Domain_name.drop_label_exn ~amount:2 (Domain_name.of_string_exn "www.bar.foo.com"))) ;
Alcotest.(check p_name "dropping 1 label from the back www.foo.com is www.foo"
(Domain_name.of_string_exn "www.foo")
(Domain_name.drop_label_exn ~rev:true (Domain_name.of_string_exn "www.foo.com"))) ;
Alcotest.(check p_name "prepending 1 and dropping 1 label from foo.com is foo.com"
res
(Domain_name.drop_label_exn (Domain_name.prepend_label_exn (Domain_name.of_string_exn "foo.com") "www"))) ;
Alcotest.(check p_name "prepending 1 and dropping 1 label from foo.com is foo.com"
res
(Domain_name.drop_label_exn (Domain_name.prepend_label_exn (Domain_name.of_string_exn "foo.com") "www"))) ;
Alcotest.(check (result p_name p_msg)
"dropping 10 labels from foo.com leads to error"
(Error (`Msg ""))
(Domain_name.drop_label ~amount:10 (Domain_name.of_string_exn "foo.com")))
let get_and_count_and_find_label () =
Alcotest.(check int "count labels of root is 0" 0
Domain_name.(count_labels root));
Alcotest.(check (result string p_msg) "get_label 0 of root is Error"
(Error (`Msg ""))
Domain_name.(get_label root 0));
Alcotest.(check (result string p_msg) "get_label 1 of root is Error"
(Error (`Msg ""))
Domain_name.(get_label root 1));
Alcotest.(check (result string p_msg) "get_label 2 of root is Error"
(Error (`Msg ""))
Domain_name.(get_label root 2));
Alcotest.(check (result string p_msg) "get_label -1 of root is Error"
(Error (`Msg ""))
Domain_name.(get_label root (-1)));
Alcotest.(check (option int) "find_label root '' is none"
None Domain_name.(find_label root (fun _ -> true)));
Alcotest.(check (option int) "find_label root 'a' is none"
None Domain_name.(find_label root (equal_label "a")));
let n = n_of_s "www.example.com" in
Alcotest.(check int "count labels of www.example.com is 3" 3
(Domain_name.count_labels n));
Alcotest.(check (result string p_msg) "get_label 0 of n is Ok www"
(Ok "www")
(Domain_name.get_label n 0));
Alcotest.(check (result string p_msg) "get_label 1 of n is Ok example"
(Ok "example")
(Domain_name.get_label n 1));
Alcotest.(check (result string p_msg) "get_label 2 of n is Ok com"
(Ok "com")
(Domain_name.get_label n 2));
Alcotest.(check (result string p_msg) "get_label 3 of n is Error"
(Error (`Msg ""))
(Domain_name.get_label n 3));
Alcotest.(check (result string p_msg) "get_label ~rev:true 0 of n is Ok com"
(Ok "com")
(Domain_name.get_label ~rev:true n 0));
Alcotest.(check (result string p_msg) "get_label ~rev:true 1 of n is Ok example"
(Ok "example")
(Domain_name.get_label ~rev:true n 1));
Alcotest.(check (result string p_msg) "get_label ~rev:true 2 of n is Ok www"
(Ok "www")
(Domain_name.get_label ~rev:true n 2));
Alcotest.(check (result string p_msg) "get_label ~rev:true 3 of n is Error"
(Error (`Msg ""))
(Domain_name.get_label ~rev:true n 3));
Alcotest.(check (option int) "find_label www.example.com is Some 0"
(Some 0) Domain_name.(find_label n (fun _ -> true)));
Alcotest.(check (option int) "find_label www.example.com 'a' is none"
None Domain_name.(find_label n (equal_label "a")));
Alcotest.(check (option int) "find_label www.example.com 'w' is none"
None Domain_name.(find_label n (equal_label "w")));
Alcotest.(check (option int) "find_label www.example.com 'www' is Some 0"
(Some 0) Domain_name.(find_label n (equal_label "www")));
Alcotest.(check (option int) "find_label www.example.com 'WWW' is Some 0"
(Some 0) Domain_name.(find_label n (equal_label "WWW")));
Alcotest.(check (option int) "find_label www.example.com 'WWW' is None (case)"
None
Domain_name.(find_label n (equal_label ~case_sensitive:true "WWW")));
let n' = Domain_name.of_string_exn "www.www.www" in
Alcotest.(check (option int) "find_label www.www.www 'www' is 0"
(Some 0) Domain_name.(find_label n' (equal_label "www")));
Alcotest.(check (option int) "find_label ~back:true www.www.www 'www' is 2"
(Some 2) Domain_name.(find_label ~rev:true n' (equal_label "www")))
let test_compare_canonical () =
(* from RFC 4034, 6.1 *)
let names = List.map n_of_s [
"example" ;
"a.example" ;
"yljkjljk.a.example" ;
"Z.a.example" ;
"zABC.a.EXAMPLE" ;
"z.example" ;
"\001.z.example" ;
"*.z.example" ;
"\200.z.example"
] in
let sorted_names = List.sort Domain_name.compare names in
Alcotest.(check (list raw) "compare fulfills canonical form and order"
names sorted_names)
let tests = [
"basic predicates", `Quick, basic_preds ;
"basic name stuff", `Quick, basic_name ;
"case", `Quick, case ;
"fqdn", `Quick, fqdn ;
"fqdn around", `Quick, fqdn_around ;
"drop labels", `Quick, drop_labels ;
"get and count and find labels", `Quick, get_and_count_and_find_label ;
"sorting", `Quick, test_compare_canonical ;
]
let suites = [
"domain names", tests ;
]
let () = Alcotest.run "domain name tests" suites