diff options
Diffstat (limited to 'src/test')
33 files changed, 6928 insertions, 2679 deletions
diff --git a/src/test/bench.c b/src/test/bench.c index 70bac63727..825299835b 100644 --- a/src/test/bench.c +++ b/src/test/bench.c @@ -30,6 +30,7 @@ const char tor_git_revision[] = ""; #include "crypto_curve25519.h" #include "onion_ntor.h" #endif +#include "crypto_ed25519.h" #if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_PROCESS_CPUTIME_ID) static uint64_t nanostart; @@ -79,6 +80,9 @@ perftime(void) #define NANOCOUNT(start,end,iters) \ ( ((double)((end)-(start))) / (iters) ) +#define MICROCOUNT(start,end,iters) \ + ( NANOCOUNT((start), (end), (iters)) / 1000.0 ) + /** Run AES performance benchmarks. */ static void bench_aes(void) @@ -232,6 +236,63 @@ bench_onion_ntor(void) ntor_handshake_state_free(state); dimap_free(keymap, NULL); } + +static void +bench_ed25519(void) +{ + uint64_t start, end; + const int iters = 1<<12; + int i; + const uint8_t msg[] = "but leaving, could not tell what they had heard"; + ed25519_signature_t sig; + ed25519_keypair_t kp; + curve25519_keypair_t curve_kp; + ed25519_public_key_t pubkey_tmp; + + ed25519_secret_key_generate(&kp.seckey, 0); + start = perftime(); + for (i = 0; i < iters; ++i) { + ed25519_public_key_generate(&kp.pubkey, &kp.seckey); + } + end = perftime(); + printf("Generate public key: %.2f usec\n", + MICROCOUNT(start, end, iters)); + + start = perftime(); + for (i = 0; i < iters; ++i) { + ed25519_sign(&sig, msg, sizeof(msg), &kp); + } + end = perftime(); + printf("Sign a short message: %.2f usec\n", + MICROCOUNT(start, end, iters)); + + start = perftime(); + for (i = 0; i < iters; ++i) { + ed25519_checksig(&sig, msg, sizeof(msg), &kp.pubkey); + } + end = perftime(); + printf("Verify signature: %.2f usec\n", + MICROCOUNT(start, end, iters)); + + curve25519_keypair_generate(&curve_kp, 0); + start = perftime(); + for (i = 0; i < iters; ++i) { + ed25519_public_key_from_curve25519_public_key(&pubkey_tmp, + &curve_kp.pubkey, 1); + } + end = perftime(); + printf("Convert public point from curve25519: %.2f usec\n", + MICROCOUNT(start, end, iters)); + + curve25519_keypair_generate(&curve_kp, 0); + start = perftime(); + for (i = 0; i < iters; ++i) { + ed25519_public_blind(&pubkey_tmp, &kp.pubkey, msg); + } + end = perftime(); + printf("Blind a public key: %.2f usec\n", + MICROCOUNT(start, end, iters)); +} #endif static void @@ -514,6 +575,7 @@ static struct benchmark_t benchmarks[] = { ENT(onion_TAP), #ifdef CURVE25519_ENABLED ENT(onion_ntor), + ENT(ed25519), #endif ENT(cell_aes), ENT(cell_ops), diff --git a/src/test/ed25519_exts_ref.py b/src/test/ed25519_exts_ref.py new file mode 100644 index 0000000000..93dc49ee93 --- /dev/null +++ b/src/test/ed25519_exts_ref.py @@ -0,0 +1,234 @@ +#!/usr/bin/python +# Copyright 2014, The Tor Project, Inc +# See LICENSE for licensing information + +""" + Reference implementations for the ed25519 tweaks that Tor uses. + + Includes self-tester and test vector generator. +""" + +import slow_ed25519 +from slow_ed25519 import * + +import os +import random +import slownacl_curve25519 +import unittest +import binascii +import textwrap + +#define a synonym that doesn't look like 1 +ell = l + +# This replaces expmod above and makes it go a lot faster. +slow_ed25519.expmod = pow + +def curve25519ToEd25519(c, sign): + u = decodeint(c) + y = ((u - 1) * inv(u + 1)) % q + x = xrecover(y) + if x & 1 != sign: x = q-x + return encodepoint([x,y]) + +def blindESK(esk, param): + h = H("Derive temporary signing key" + param) + mult = 2**(b-2) + sum(2**i * bit(h,i) for i in range(3,b-2)) + s = decodeint(esk[:32]) + s_prime = (s * mult) % ell + k = esk[32:] + assert(len(k) == 32) + k_prime = H("Derive temporary signing key hash input" + k)[:32] + return encodeint(s_prime) + k_prime + +def blindPK(pk, param): + h = H("Derive temporary signing key" + param) + mult = 2**(b-2) + sum(2**i * bit(h,i) for i in range(3,b-2)) + P = decodepoint(pk) + return encodepoint(scalarmult(P, mult)) + +def expandSK(sk): + h = H(sk) + a = 2**(b-2) + sum(2**i * bit(h,i) for i in range(3,b-2)) + k = ''.join([h[i] for i in range(b/8,b/4)]) + assert len(k) == 32 + return encodeint(a)+k + +def publickeyFromESK(h): + a = decodeint(h[:32]) + A = scalarmult(B,a) + return encodepoint(A) + +def signatureWithESK(m,h,pk): + a = decodeint(h[:32]) + r = Hint(''.join([h[i] for i in range(b/8,b/4)]) + m) + R = scalarmult(B,r) + S = (r + Hint(encodepoint(R) + pk + m) * a) % l + return encodepoint(R) + encodeint(S) + +def newSK(): + return os.urandom(32) + +# ------------------------------------------------------------ + +MSG = "This is extremely silly. But it is also incredibly serious business!" + +class SelfTest(unittest.TestCase): + + def _testSignatures(self, esk, pk): + sig = signatureWithESK(MSG, esk, pk) + checkvalid(sig, MSG, pk) + bad = False + try: + checkvalid(sig, MSG*2, pk) + bad = True + except Exception: + pass + + self.failIf(bad) + + def testExpand(self): + sk = newSK() + pk = publickey(sk) + esk = expandSK(sk) + sig1 = signature(MSG, sk, pk) + sig2 = signatureWithESK(MSG, esk, pk) + self.assertEquals(sig1, sig2) + + def testSignatures(self): + sk = newSK() + esk = expandSK(sk) + pk = publickeyFromESK(esk) + pk2 = publickey(sk) + self.assertEquals(pk, pk2) + + self._testSignatures(esk, pk) + + def testDerivation(self): + priv = slownacl_curve25519.Private() + pub = priv.get_public() + + ed_pub0 = publickeyFromESK(priv.private) + sign = (ord(ed_pub0[31]) & 255) >> 7 + ed_pub1 = curve25519ToEd25519(pub.public, sign) + + self.assertEquals(ed_pub0, ed_pub1) + + def testBlinding(self): + sk = newSK() + esk = expandSK(sk) + pk = publickeyFromESK(esk) + param = os.urandom(32) + besk = blindESK(esk, param) + bpk = blindPK(pk, param) + bpk2 = publickeyFromESK(besk) + self.assertEquals(bpk, bpk2) + + self._testSignatures(besk, bpk) + +# ------------------------------------------------------------ + +# From pprint.pprint([ binascii.b2a_hex(os.urandom(32)) for _ in xrange(8) ]) +RAND_INPUTS = [ + '26c76712d89d906e6672dafa614c42e5cb1caac8c6568e4d2493087db51f0d36', + 'fba7a5366b5cb98c2667a18783f5cf8f4f8d1a2ce939ad22a6e685edde85128d', + '67e3aa7a14fac8445d15e45e38a523481a69ae35513c9e4143eb1c2196729a0e', + 'd51385942033a76dc17f089a59e6a5a7fe80d9c526ae8ddd8c3a506b99d3d0a6', + '5c8eac469bb3f1b85bc7cd893f52dc42a9ab66f1b02b5ce6a68e9b175d3bb433', + 'eda433d483059b6d1ff8b7cfbd0fe406bfb23722c8f3c8252629284573b61b86', + '4377c40431c30883c5fbd9bc92ae48d1ed8a47b81d13806beac5351739b5533d', + 'c6bbcce615839756aed2cc78b1de13884dd3618f48367a17597a16c1cd7a290b'] + +# From pprint.pprint([ binascii.b2a_hex(os.urandom(32)) for _ in xrange(8) ]) +BLINDING_PARAMS = [ + '54a513898b471d1d448a2f3c55c1de2c0ef718c447b04497eeb999ed32027823', + '831e9b5325b5d31b7ae6197e9c7a7baf2ec361e08248bce055908971047a2347', + 'ac78a1d46faf3bfbbdc5af5f053dc6dc9023ed78236bec1760dadfd0b2603760', + 'f9c84dc0ac31571507993df94da1b3d28684a12ad14e67d0a068aba5c53019fc', + 'b1fe79d1dec9bc108df69f6612c72812755751f21ecc5af99663b30be8b9081f', + '81f1512b63ab5fb5c1711a4ec83d379c420574aedffa8c3368e1c3989a3a0084', + '97f45142597c473a4b0e9a12d64561133ad9e1155fe5a9807fe6af8a93557818', + '3f44f6a5a92cde816635dfc12ade70539871078d2ff097278be2a555c9859cd0'] + +PREFIX = "ED25519_" + +def writeArray(name, array): + print "static const char *{prefix}{name}[] = {{".format( + prefix=PREFIX,name=name) + for a in array: + h = binascii.b2a_hex(a) + if len(h) > 70: + h1 = h[:70] + h2 = h[70:] + print ' "{0}"\n "{1}",'.format(h1,h2) + else: + print ' "{0}",'.format(h) + print "};\n" + +def comment(text, initial="/**"): + print initial + print textwrap.fill(text,initial_indent=" * ",subsequent_indent=" * ") + print " */" + +def makeTestVectors(): + comment("""Test vectors for our ed25519 implementation and related + functions. These were automatically generated by the + ed25519_exts_ref.py script.""", initial="/*") + + + comment("""Secret key seeds used as inputs for the ed25519 test vectors. + Randomly generated. """) + secretKeys = [ binascii.a2b_hex(r) for r in RAND_INPUTS ] + writeArray("SECRET_KEYS", secretKeys) + + comment("""Secret ed25519 keys after expansion from seeds. This is how Tor + represents them internally.""") + expandedSecretKeys = [ expandSK(sk) for sk in secretKeys ] + writeArray("EXPANDED_SECRET_KEYS", expandedSecretKeys) + + comment("""Public keys derived from the above secret keys""") + publicKeys = [ publickey(sk) for sk in secretKeys ] + writeArray("PUBLIC_KEYS", publicKeys) + + comment("""The curve25519 public keys from which the ed25519 keys can be + derived. Used to test our 'derive ed25519 from curve25519' + code.""") + writeArray("CURVE25519_PUBLIC_KEYS", + (slownacl_curve25519.smult_curve25519_base(sk[:32]) + for sk in expandedSecretKeys)) + + comment("""Parameters used for key blinding tests. Randomly generated.""") + blindingParams = [ binascii.a2b_hex(r) for r in BLINDING_PARAMS ] + writeArray("BLINDING_PARAMS", blindingParams) + + comment("""Blinded secret keys for testing key blinding. The nth blinded + key corresponds to the nth secret key blidned with the nth + blinding parameter.""") + writeArray("BLINDED_SECRET_KEYS", + (blindESK(expandSK(sk), bp) + for sk,bp in zip(secretKeys,blindingParams))) + + comment("""Blinded public keys for testing key blinding. The nth blinded + key corresponds to the nth public key blidned with the nth + blinding parameter.""") + writeArray("BLINDED_PUBLIC_KEYS", + (blindPK(pk, bp) for pk,bp in zip(publicKeys,blindingParams))) + + comment("""Signatures of the public keys, made with their corresponding + secret keys.""") + writeArray("SELF_SIGNATURES", + (signature(pk, sk, pk) for pk,sk in zip(publicKeys,secretKeys))) + + + +if __name__ == '__main__': + import sys + if len(sys.argv) == 1 or sys.argv[1] not in ("SelfTest", "MakeVectors"): + print "You should specify one of 'SelfTest' or 'MakeVectors'" + sys.exit(1) + if sys.argv[1] == 'SelfTest': + unittest.main() + else: + makeTestVectors() + + diff --git a/src/test/ed25519_vectors.inc b/src/test/ed25519_vectors.inc new file mode 100644 index 0000000000..760bafb971 --- /dev/null +++ b/src/test/ed25519_vectors.inc @@ -0,0 +1,150 @@ +/* + * Test vectors for our ed25519 implementation and related + * functions. These were automatically generated by the + * ed25519_exts_ref.py script. + */ +/** + * Secret key seeds used as inputs for the ed25519 test vectors. + * Randomly generated. + */ +static const char *ED25519_SECRET_KEYS[] = { + "26c76712d89d906e6672dafa614c42e5cb1caac8c6568e4d2493087db51f0d36", + "fba7a5366b5cb98c2667a18783f5cf8f4f8d1a2ce939ad22a6e685edde85128d", + "67e3aa7a14fac8445d15e45e38a523481a69ae35513c9e4143eb1c2196729a0e", + "d51385942033a76dc17f089a59e6a5a7fe80d9c526ae8ddd8c3a506b99d3d0a6", + "5c8eac469bb3f1b85bc7cd893f52dc42a9ab66f1b02b5ce6a68e9b175d3bb433", + "eda433d483059b6d1ff8b7cfbd0fe406bfb23722c8f3c8252629284573b61b86", + "4377c40431c30883c5fbd9bc92ae48d1ed8a47b81d13806beac5351739b5533d", + "c6bbcce615839756aed2cc78b1de13884dd3618f48367a17597a16c1cd7a290b", +}; + +/** + * Secret ed25519 keys after expansion from seeds. This is how Tor + * represents them internally. + */ +static const char *ED25519_EXPANDED_SECRET_KEYS[] = { + "c0a4de23cc64392d85aa1da82b3defddbea946d13bb053bf8489fa9296281f495022f1" + "f7ec0dcf52f07d4c7965c4eaed121d5d88d0a8ff546b06116a20e97755", + "18a8a69a06790dac778e882f7e868baacfa12521a5c058f5194f3a729184514a2a656f" + "e7799c3e41f43d756da8d9cd47a061316cfe6147e23ea2f90d1ca45f30", + "58d84f8862d2ecfa30eb491a81c36d05b574310ea69dae18ecb57e992a896656b98218" + "7ee96c15bf4caeeab2d0b0ae4cd0b8d17470fc7efa98bb26428f4ef36d", + "50702d20b3550c6e16033db5ad4fba16436f1ecc7485be6af62b0732ceb5d173c47ccd" + "9d044b6ea99dd99256adcc9c62191be194e7cb1a5b58ddcec85d876a2b", + "7077464c864c2ed5ed21c9916dc3b3ba6256f8b742fec67658d8d233dadc8d5a7a82c3" + "71083cc86892c2c8782dda2a09b6baf016aec51b689183ae59ce932ff2", + "8883c1387a6c86fc0bd7b9f157b4e4cd83f6885bf55e2706d2235d4527a2f05311a359" + "5953282e436df0349e1bb313a19b3ddbf7a7b91ecce8a2c34abadb38b3", + "186791ac8d03a3ac8efed6ac360467edd5a3bed2d02b3be713ddd5be53b3287ee37436" + "e5fd7ac43794394507ad440ecfdf59c4c255f19b768a273109e06d7d8e", + "b003077c1e52a62308eef7950b2d532e1d4a7eea50ad22d8ac11b892851f1c40ffb9c9" + "ff8dcd0c6c233f665a2e176324d92416bfcfcd1f787424c0c667452d86", +}; + +/** + * Public keys derived from the above secret keys + */ +static const char *ED25519_PUBLIC_KEYS[] = { + "c2247870536a192d142d056abefca68d6193158e7c1a59c1654c954eccaff894", + "1519a3b15816a1aafab0b213892026ebf5c0dc232c58b21088d88cb90e9b940d", + "081faa81992e360ea22c06af1aba096e7a73f1c665bc8b3e4e531c46455fd1dd", + "73cfa1189a723aad7966137cbffa35140bb40d7e16eae4c40b79b5f0360dd65a", + "66c1a77104d86461b6f98f73acf3cd229c80624495d2d74d6fda1e940080a96b", + "d21c294db0e64cb2d8976625786ede1d9754186ae8197a64d72f68c792eecc19", + "c4d58b4cf85a348ff3d410dd936fa460c4f18da962c01b1963792b9dcc8a6ea6", + "95126f14d86494020665face03f2d42ee2b312a85bc729903eb17522954a1c4a", +}; + +/** + * The curve25519 public keys from which the ed25519 keys can be + * derived. Used to test our 'derive ed25519 from curve25519' + * code. + */ +static const char *ED25519_CURVE25519_PUBLIC_KEYS[] = { + "17ba77846e04c7ee5ca17cade774ac1884408f9701f439d4df32cbd8736c6a1f", + "022be2124bc1899a78ba2b4167d191af3b59cadf94f0382bc31ce183a117f161", + "bf4fd38ef22f718f03c0a12ba5127bd1e3afd494793753f519728b29cc577571", + "56c493e490261cef31633efd2461d2b896908e90459e4eecde950a895aef681d", + "089675a3e8ff2a7d8b2844a79269c95b7f97a4b8b5ea0cbeec669c6f2dea9b39", + "59e20dcb691c4a345fe86c8a79ac817e5b514d84bbf0512a842a08e43f7f087e", + "9e43b820b320eda35f66f122c155b2bf8e2192c468617b7115bf067d19e08369", + "861f33296cb57f8f01e4a5e8a7e5d5d7043a6247586ab36dea8a1a3c4403ee30", +}; + +/** + * Parameters used for key blinding tests. Randomly generated. + */ +static const char *ED25519_BLINDING_PARAMS[] = { + "54a513898b471d1d448a2f3c55c1de2c0ef718c447b04497eeb999ed32027823", + "831e9b5325b5d31b7ae6197e9c7a7baf2ec361e08248bce055908971047a2347", + "ac78a1d46faf3bfbbdc5af5f053dc6dc9023ed78236bec1760dadfd0b2603760", + "f9c84dc0ac31571507993df94da1b3d28684a12ad14e67d0a068aba5c53019fc", + "b1fe79d1dec9bc108df69f6612c72812755751f21ecc5af99663b30be8b9081f", + "81f1512b63ab5fb5c1711a4ec83d379c420574aedffa8c3368e1c3989a3a0084", + "97f45142597c473a4b0e9a12d64561133ad9e1155fe5a9807fe6af8a93557818", + "3f44f6a5a92cde816635dfc12ade70539871078d2ff097278be2a555c9859cd0", +}; + +/** + * Blinded secret keys for testing key blinding. The nth blinded + * key corresponds to the nth secret key blidned with the nth + * blinding parameter. + */ +static const char *ED25519_BLINDED_SECRET_KEYS[] = { + "014e83abadb2ca9a27e0ffe23920333d817729f48700e97656ec2823d694050e171d43" + "f24e3f53e70ec7ac280044ac77d4942dee5d6807118a59bdf3ee647e89", + "fad8cca0b4335847795288b1452508752b253e64e6c7c78d4a02dbbd7d46aa0eb8ceff" + "20dfcf53eb52b891fc078c934efbf0353af7242e7dc51bb32a093afa29", + "116eb0ae0a4a91763365bdf86db427b00862db448487808788cc339ac10e5e089217f5" + "2e92797462bd890fc274672e05c98f2c82970d640084781334aae0f940", + "bd1fbb0ee5acddc4adbcf5f33e95d9445f40326ce579fdd764a24483a9ccb20f509ece" + "e77082ce088f7c19d5a00e955eeef8df6fa41686abc1030c2d76807733", + "237f5345cefe8573ce9fa7e216381a1172796c9e3f70668ab503b1352952530fb57b95" + "a440570659a440a3e4771465022a8e67af86bdf2d0990c54e7bb87ff9a", + "ba8ff23bc4ad2b739e1ccffc9fbc7837053ea81cdfdb15073f56411cfbae1d0ec492fc" + "87d5ec2a1b185ca5a40541fdef0b1e128fd5c2380c888bfa924711bcab", + "0fa68f969de038c7a90a4a74ee6167c77582006f2dedecc1956501ba6b6fb10391b476" + "8f8e556d78f4bdcb9a13b6f6066fe81d3134ae965dc48cd0785b3af2b8", + "deaa3456d1c21944d5dcd361a646858c6cf9336b0a6851d925717eb1ae186902053d9c" + "00c81e1331c06ab50087be8cfc7dc11691b132614474f1aa9c2503cccd", +}; + +/** + * Blinded public keys for testing key blinding. The nth blinded + * key corresponds to the nth public key blidned with the nth + * blinding parameter. + */ +static const char *ED25519_BLINDED_PUBLIC_KEYS[] = { + "722d6da6348e618967ef782e71061e27163a8b35f21856475d9d2023f65b6495", + "1dffa0586da6cbfcff2024eedf4fc6c818242d9a82dbbe635d6da1b975a1160d", + "5ed81f98fed5a6acda4ea6da2c34fab0ab359d950c510c256473f1f33ff438b4", + "6e6f92a54fb282120c46d9603df41135f025bc1f58f283809d04be96aeb04040", + "cda236f28edc4c7e02d18007b8dab49d669265b0f7aefb1824d7cc8e73a2cd63", + "367b03b17b67ca7329b89a520bdab91782402a41cd67264e34b5541a4b3f875b", + "8d486b03ac4e3b486b7a1d563706c7fdac75aee789a7cf6f22789eedeff61a31", + "9f297ff0aa2ceda91c5ab1b6446f12533d145940de6d850dc323417afde0cb78", +}; + +/** + * Signatures of the public keys, made with their corresponding + * secret keys. + */ +static const char *ED25519_SELF_SIGNATURES[] = { + "d23188eac3773a316d46006fa59c095060be8b1a23582a0dd99002a82a0662bd246d84" + "49e172e04c5f46ac0d1404cebe4aabd8a75a1457aa06cae41f3334f104", + "3a785ac1201c97ee5f6f0d99323960d5f264c7825e61aa7cc81262f15bef75eb4fa572" + "3add9b9d45b12311b6d403eb3ac79ff8e4e631fc3cd51e4ad2185b200b", + "cf431fd0416bfbd20c9d95ef9b723e2acddffb33900edc72195dea95965d52d888d30b" + "7b8a677c0bd8ae1417b1e1a0ec6700deadd5d8b54b6689275e04a04509", + "2375380cd72d1a6c642aeddff862be8a5804b916acb72c02d9ed052c1561881aa658a5" + "af856fcd6d43113e42f698cd6687c99efeef7f2ce045824440d26c5d00", + "2385a472f599ca965bbe4d610e391cdeabeba9c336694b0d6249e551458280be122c24" + "41dd9746a81bbfb9cd619364bab0df37ff4ceb7aefd24469c39d3bc508", + "e500cd0b8cfff35442f88008d894f3a2fa26ef7d3a0ca5714ae0d3e2d40caae58ba7cd" + "f69dd126994dad6be536fcda846d89dd8138d1683cc144c8853dce7607", + "d187b9e334b0050154de10bf69b3e4208a584e1a65015ec28b14bcc252cf84b8baa9c9" + "4867daa60f2a82d09ba9652d41e8dde292b624afc8d2c26441b95e3c0e", + "815213640a643d198bd056e02bba74e1c8d2d931643e84497adf3347eb485079c9afe0" + "afce9284cdc084946b561abbb214f1304ca11228ff82702185cf28f60d", +}; + diff --git a/src/test/example_extrainfo.inc b/src/test/example_extrainfo.inc new file mode 100644 index 0000000000..606279a765 --- /dev/null +++ b/src/test/example_extrainfo.inc @@ -0,0 +1,192 @@ +static const char EX_EI_MINIMAL[] = + "extra-info bob 3E1B2DC141F2B7C6A0F3C4ED9A14A9C35762E24B\n" + "published 2014-10-05 20:07:00\n" + "router-signature\n" + "-----BEGIN SIGNATURE-----\n" + "K5GAkVjpUlofL78NIOE1VDxFn8yYbHK50rVuZG2HxqG/727bon+uMprv4MHjfDcP\n" + "V3l9u1uUdGiUPOl8j+hRNw4z/ODeCj/24r2+L32MTjyfUhK49Ld2IlK9iZKlgKYi\n" + "zyoatxdAjU8Xc5WPX692HO4/R9CGLsUfYcEEFU2R3EA=\n" + "-----END SIGNATURE-----\n" + ; + +static const char EX_EI_MINIMAL_FP[] = "3E1B2DC141F2B7C6A0F3C4ED9A14A9C35762E24B"; +static const char EX_EI_MINIMAL_KEY[] = + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBALSppIF3t3wOAm4fzxRvK+q/wh1gGAWwS0JEn8d+c/x+rt1oQabGkqsB\n" + "GU6rz1z1AN02W0P2+EcyJQVBjGR3gHQNoDGx0KIdnr3caGAw3XmQXrJLPaViEk28\n" + "RJMxx6umpP27YKSyEMHgVTDXblKImT0mE7fVOx8tD0EWRYazmp4NAgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n"; + +static const char EX_EI_MAXIMAL[] = + "extra-info bob FF8248FE780A7236D3FA5D62DEA642055135F942\n" + "published 2014-10-05 20:07:00\n" + "opt foobarbaz\n" + "read-history 900 1,2,3\n" + "write-history 900 1,2,3\n" + "dirreq-v2-ips 1\n" + "dirreq-v3-ips 100\n" + "dirreq-v3-reqs blahblah\n" + "dirreq-v2-share blahblah\n" + "dirreq-v3-share blahblah\n" + "dirreq-v2-resp djfkdj\n" + "dirreq-v3-resp djfkdj\n" + "dirreq-v2-direct-dl djfkdj\n" + "dirreq-v3-direct-dl djfkdj\n" + "dirreq-v2-tunneled-dl djfkdj\n" + "dirreq-v3-tunneled-dl djfkdj\n" + "dirreq-stats-end foobar\n" + "entry-ips jfsdfds\n" + "entry-stats-end ksdflkjfdkf\n" + "cell-stats-end FOO\n" + "cell-processed-cells FOO\n" + "cell-queued-cells FOO\n" + "cell-time-in-queue FOO\n" + "cell-circuits-per-decile FOO\n" + "exit-stats-end FOO\n" + "exit-kibibytes-written FOO\n" + "exit-kibibytes-read FOO\n" + "exit-streams-opened FOO\n" + "router-signature\n" + "-----BEGIN SIGNATURE-----\n" + "ZO79bLlWVNIruCnWW9duDcOKydPWbL5DfrpUv5IRLF4MMFoacMUdJPDUs9e+wY2C\n" + "zndHe6i2JK7yKJj+uCOSC8cx61OLG+kVxMLJ/qhA4H5thrYb+GpzMKwbHzQc3PTH\n" + "zHRzj041iWXTL7/DMaQlpJOBoac/wTSIKzoV2B00jBw=\n" + "-----END SIGNATURE-----\n" + ; + +static const char EX_EI_MAXIMAL_FP[] = "FF8248FE780A7236D3FA5D62DEA642055135F942"; +static const char EX_EI_MAXIMAL_KEY[] = + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBANSpkYhHUW1EqodY4d3JRbvEM1vjjR/vEE8gjONiJ5t2Sten53jzt8bh\n" + "8/VJn7pQGs8zR5CIxCw4P68xMtZJJedS3hhjqubheOE/yW1DtpkiCf+zVEaLpeA8\n" + "fYQChkRICnR/BZd4W9bbohLVII5ym2PaJt2ihB3FeVZIsGXm4wxhAgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n"; + +static const char EX_EI_BAD_SIG1[] = + "extra-info bob 3E1B2DC141F2B7C6A0F3C4ED9A14A9C35762E24B\n" + "published 2014-10-05 20:07:00\n" + "router-signature\n" + "-----BEGIN SIGNATURE-----\n" + "K5GAkVjpUlofL78NIOE1VDxFn8yYbHK50rVuZG2HxqG/727bon+uMprv4MHjfDcP\n" + "V3l9u1uUdGiUPOl8j+hXXw4z/ODeCj/24r2+L32MTjyfUhK49Ld2IlK9iZKlgKYi\n" + "zyoatxdAjU8Xc5WPX692HO4/R9CGLsUfYcEEFU2R3EA=\n" + "-----END SIGNATURE-----\n" + ; + +static const char EX_EI_BAD_SIG2[] = + "extra-info bob 3E1B2DC141F2B7C6A0F3C4ED9A14A9C35762E24B\n" + "published 2014-10-06 20:07:00\n" + "router-signature\n" + "-----BEGIN SIGNATURE-----\n" + "K5GAkVjpUlofL78NIOE1VDxFn8yYbHK50rVuZG2HxqG/727bon+uMprv4MHjfDcP\n" + "V3l9u1uUdGiUPOl8j+hRNw4z/ODeCj/24r2+L32MTjyfUhK49Ld2IlK9iZKlgKYi\n" + "zyoatxdAjU8Xc5WPX692HO4/R9CGLsUfYcEEFU2R3EA=\n" + "-----END SIGNATURE-----\n" + ; + +static const char EX_EI_BAD_SIG3[] = + "extra-info bob 3E1B2DC141F2B7C6A0F3C4ED9A14A9C35762E24B\n" + "published 2014-10-05 20:07:00\n" + "router-signature\n" + "-----BEGIN SIGNATURE-----\n" + "K5GAkVjpUlofL78NIOE1VDxFn8yYbHK50rVuZG2HxqG/727bon+uMprv4MHjfDcP\n" + "V3l9u1uUdGiUPOl8j+hRNw4z/ODeCj/24r2+L32MTjyfUhK49Ld2IlK9iZKlgKYi\n" + "zyoatxdAjU8Xc5WPX692HO4/R9CGLsUfYcEEFU2=\n" + "-----END SIGNATURE-----\n" + ; + +static const char EX_EI_BAD_FP[] = + "extra-info bob C34293303F0F1E42CB14E593717B834E8E53797D8888\n" + "published 2014-10-05 20:07:00\n" + "router-signature\n" + "-----BEGIN SIGNATURE-----\n" + "IDA8ryUYeMx7+Au/xQmX7Y8fXksoHUOXmePND2JYM4rPfishQJ1LpQ15KrolOZDH\n" + "FVIk3RmCefNlJeS1/UgWPcU8u2nGw1YQuRBHF4ViTmZ0OevI1pTsSApl4+oIx2dy\n" + "DGgCQmKfMbaOixIK8Ioh1Z2NUfMkjbUUE2WWgFTAsac=\n" + "-----END SIGNATURE-----\n" + ; + +static const char EX_EI_BAD_FP_FP[] = "C34293303F0F1E42CB14E593717B834E8E53797D"; +static const char EX_EI_BAD_FP_KEY[] = + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBAKXMSbif4fG+BW/5lIq5V1tMRondIUfKiNizp0E6EcBw5LvYfQV6zrj8\n" + "HmMFbB/WGf9XGVMxIBzxzeQBRvCQJh+0QH7+ju5/isIHJZsACMILepr6ywmCcjVU\n" + "iYRtC8zGQLqfkf2cNoo7AhcI5i/YzyW2u1zmbPX5J+8sUErfxydbAgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n"; + +static const char EX_EI_BAD_NICKNAME[] = + "extra-info bobhasaverylongnameandidontthinkweshouldlethim A4EA2389A52459B3F7C7121A46012F098BDFC2A4\n" + "published 2014-10-05 20:07:00\n" + "router-signature\n" + "-----BEGIN SIGNATURE-----\n" + "e2wLJFThRMGawxKrQPuH2XCLek/LJsg4XOB8waAjE0xdHOrzjur9x1jIxy7DVU6t\n" + "z1edbIoL24qucMJvFy2xjSQhFRX4OsyNc0nWr3LfJnTW9aEmxuwXM+mltUD2uFN1\n" + "2vYOIQjUmJwS2yfeSKnhXEl2PWVUmgzYL3r4S5kHco4=\n" + "-----END SIGNATURE-----\n" + ; + +static const char EX_EI_BAD_NICKNAME_FP[] = "A4EA2389A52459B3F7C7121A46012F098BDFC2A4"; +static const char EX_EI_BAD_NICKNAME_KEY[] = + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBAKfq7oxD1kMu1+zeG2UVXN4vOu6FDp0V/olA3ttmXpUCgCiBxWTgtwNl\n" + "nPf0HcKMaCp/0D9XrbhvIoOsg0OTf1TcJfGsA/zPG7jrWYa4xhD50KYvty9EINK9\n" + "/UBWNSyXCFDMqnddb/LZ8+VgttmxfYkpeRzSSmDijN3RbOvYJhhBAgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n"; + +const char EX_EI_BAD_TOKENS[] = + "extra-info bob 6F314FB01A31162BD5E473D4977AC570DC5B86BB\n" + "published 2014-10-05 20:07:00\n" + "published 2014-10-05 20:07:00\n" + "router-signature\n" + "-----BEGIN SIGNATURE-----\n" + "lhRIafrkKoQmnUoBLiq4XC8XKXrleGJZ5vefkLcgjOJ5IffsvVdIA7Vqq/ISbPrG\n" + "b/Zs0sJNL6naHPxJBglgHJqksSyiYHaeOetXg2Rb+vZ1v2S5BrVgk1nPMDhyIzqc\n" + "zU7eCxFf/1sXKtWlEKxGdX4LmVfnIln5aI31Bc4xRrE=\n" + "-----END SIGNATURE-----\n" + ; + +const char EX_EI_BAD_TOKENS_FP[] = "6F314FB01A31162BD5E473D4977AC570DC5B86BB"; +const char EX_EI_BAD_TOKENS_KEY[] = + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBAL7Z8tz45Tb4tnEFS2sAyjubBV/giSfZdmXRkDV8Jo4xqWqhWFJn7+zN\n" + "AXBWBThGeVH2WXrpz5seNJXgZJPxMTMsrnSCGcRXZw0Npti2MkLuQ6+prZa+OPwE\n" + "OyC6jivtAaY/o9iYQjDC2avLXD3N4LvoygyF418KnNcjbzuFygffAgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n"; + +static const char EX_EI_BAD_START[] = + "published 2014-10-05 20:07:00\n" + "extra-info bob 5CCCACE71A9BDB5E8E0C942AB3407452350434C0\n" + "router-signature\n" + "-----BEGIN SIGNATURE-----\n" + "BOiWgexqCAMZ8uyJ7jwBwRkz7Ox8cT4BImkmkV3bQiZgcWvPiYA3EnCm2ye48Ldg\n" + "zBST2p6zJM5o4MEDYGMxfViS86Abj/z7DOY1gtLhjmAaVjIIpXc3koxEZtzCecqy\n" + "JQz6xEg9/KoEuoT0DRrfYQ+KtQfzBDWrotfOvEa1rvc=\n" + "-----END SIGNATURE-----\n" + ; + +static const char EX_EI_BAD_START_FP[] = "5CCCACE71A9BDB5E8E0C942AB3407452350434C0"; +static const char EX_EI_BAD_START_KEY[] = + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBAK2OCIfM6Cin/lq99Z3w9tl6HeyGlkBZu9MQEPHxqGIHTq78lIC1UkrC\n" + "6NTqlrHBV9dmfzdwJn4GgMWsCZafL0FPIH3HNyNKUxLgyjixyKljHx2rfErSfOxI\n" + "bMoOGBKv7m1EZZ0O5uG9ly9MBiNGdJyLdlnVvH7wSCnYciizpO4lAgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n"; + +static const char EX_EI_BAD_PUBLISHED[] = + "extra-info bob E67C477E3536BDE348BD407426D9679E5AE0BC16\n" + "published 2014-99-05 20:07:00\n" + "router-signature\n" + "-----BEGIN SIGNATURE-----\n" + "l45IziBaXRKIjPAIUogMFNjQgH6k6Vm0+6r5+oByr4sP+B3ufNdUA6+WqBs43F0Z\n" + "IqcJiT9nFn0DuNd/liOyOCixppDLx5h5NrhoGqcT3ySADEEXhzjlmc35TI3YBNVO\n" + "v98fotmwIEg9YRWVGPg6XuIn2PRyiboFyjUpaYGCV0Q=\n" + "-----END SIGNATURE-----\n" + ; + +static const char EX_EI_BAD_PUBLISHED_FP[] = "E67C477E3536BDE348BD407426D9679E5AE0BC16"; +static const char EX_EI_BAD_PUBLISHED_KEY[] = + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBAL7q8GEI18iv8Fo0QbNHmFatQ2FNacalPldpmKUdMJYEVZtdOR0nhcrY\n" + "BvG6303md3INygg+KP49RvWEJR/cU4RZ9QfHpORxH2OocMyRedw2rLex2E7jNNSi\n" + "52yd1sHFYI8ZQ4aff+ZHUjJUGKRyqpbc8okVbq/Rl7vug0dd12eHAgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n"; diff --git a/src/test/failing_routerdescs.inc b/src/test/failing_routerdescs.inc new file mode 100644 index 0000000000..b49d59fd8a --- /dev/null +++ b/src/test/failing_routerdescs.inc @@ -0,0 +1,668 @@ +/* This one actually succeeds */ +static const char EX_RI_MINIMAL[] = + "router fred 127.0.0.1 9001 0 9002\n" + "signing-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBAObzT4opT9uaThByupbb96tYxVpGxzL9CRPKUcU0beGpHyognD9USHWc\n" + "SpSpKfBL5P3xr2i/XTs34M4UTbT9PE7bVyxv7RD/BZmI4gc8R3PMU77xxbpEU5bK\n" + "LF3QUPpuB88m/2fXUGgMNVDc5MIq6pod2NRoDpeU7WA8T3ewXzK5AgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "onion-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBAM1QKsQiup9DNMCgNeE2FkAhCWzpMZKCn1nNlZbDGfE3Z22ex6bdWWY6\n" + "ocEZ3JZDsZsnaZrdYxrL3Mquq7MbHdfx90EdlOvDRP1SAIbZ55mLR77fZTu4BKd/\n" + "h9BC6I26uZE0QavFq3+BhoVVhVn5Mqv05nR9CeUMSSZLxw/RJm4DAgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "published 2014-10-05 12:00:00\n" + "bandwidth 1000 1000 1000\n" + "reject *:*\n" + "router-signature\n" + "-----BEGIN SIGNATURE-----\n" + "Ft/y3JXowjItgfTHwYcZzuUgXrskluoINW5sr+GQoNYE2F4sT8o0tBBJwqJ6FwKd\n" + "fkIprv9UXqkv5iY+pXSYSI12mY1K5GMNkXiObk46NjuoNNP9l8oidhO6eNfcE+k3\n" + "CRIYS4FbBaD0fWUSwgMuo0Bp83/Wzp3B9ytEBh0/624=\n" + "-----END SIGNATURE-----\n"; + +/* So does this, and it's bigger. */ +static const char EX_RI_MAXIMAL[] = + "router fred 127.0.0.1 9001 0 9002\n" + "signing-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBANNI56H+b7SW5LMzvXyY5NJzXszsHZZ4O1CPm4CePhBsAz1r0s1JYJ1F\n" + "Anrc0mEcLtmj0c5+HnhPBNrfpjO6G94Wp3NZMVykHDhfNVDBRyFZMroG8/GlysYB\n" + "MQPGQYR0xBgiuclNHoyk/vygQhZekumamu2O86EIPcfg9LhGIgEbAgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "onion-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBALvuNVSmg6R9USFbQcNbRjMCJAV0Rwdv0DlS6Rl02ibJgb01G7v391xE\n" + "d9Njzgf93n8gOrE195bkUbvS6k/DM3HFGgArq6q9AZ2LTbu3KbAYy1YPsSIh07kB\n" + "/8kkvRRGx37X9WGZU3j5VUEuzqI//xDE9lbanlnnFXpnb6ymehDJAgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "published 2014-10-05 12:00:00\n" + "bandwidth 1000 1000 1000\n" + "reject 127.0.0.1:*\n" + "accept *:80\n" + "reject *:*\n" + "ipv6-policy accept 80,100,101\n" + "ntor-onion-key s7rSohmz9SXn8WWh1EefTHIsWePthsEntQi0WL+ScVw\n" + "uptime 1000\n" + "hibernating 0\n" + "unrecognized-keywords are just dandy in this format\n" + "platform Tor 0.2.4.23 on a Banana PC Jr 6000 Series\n" + "contact O.W.Jones\n" + "fingerprint CC43 DC8E 8C9E 3E6D 59CD 0399 2491 0C8C E1E4 50D2\n" + "read-history 900 1,2,3,4\n" + "write-history 900 1,2,3,4\n" + "extra-info-digest AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" + "hidden-service-dir\n" + "allow-single-hop-exits\n" + "family $AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA $BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n" + "caches-extra-info\n" + "or-address [::1:2:3:4]:9999\n" + "or-address 127.0.0.99:10000\n" + "opt fred is a fine router\n" + "router-signature\n" + "-----BEGIN SIGNATURE-----\n" + "x5cxL2h2UsEKk2OVnCTxOF8a89HAe/HwQnSlrBy8+l0YdVCcePDJhm1WyWU7ToHZ\n" + "K8auwreuw+u/n14sQHPYrM9NQE689hP4LC9AYOnrCnMHysfVqKuou+DSKYYRgs0D\n" + "ySCmJ9p+xekfmms+JBmS5o5DVo48VGlG0VksegoB264=\n" + "-----END SIGNATURE-----\n" + ; + +/* I've messed with 12 bits of the signature on this one */ +static const char EX_RI_BAD_SIG1[] = + "router fred 127.0.0.1 9001 0 9002\n" + "signing-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBAObzT4opT9uaThByupbb96tYxVpGxzL9CRPKUcU0beGpHyognD9USHWc\n" + "SpSpKfBL5P3xr2i/XTs34M4UTbT9PE7bVyxv7RD/BZmI4gc8R3PMU77xxbpEU5bK\n" + "LF3QUPpuB88m/2fXUGgMNVDc5MIq6pod2NRoDpeU7WA8T3ewXzK5AgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "onion-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBAM1QKsQiup9DNMCgNeE2FkAhCWzpMZKCn1nNlZbDGfE3Z22ex6bdWWY6\n" + "ocEZ3JZDsZsnaZrdYxrL3Mquq7MbHdfx90EdlOvDRP1SAIbZ55mLR77fZTu4BKd/\n" + "h9BC6I26uZE0QavFq3+BhoVVhVn5Mqv05nR9CeUMSSZLxw/RJm4DAgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "published 2014-10-05 12:00:00\n" + "bandwidth 1000 1000 1000\n" + "reject *:*\n" + "router-signature\n" + "-----BEGIN SIGNATURE-----\n" + "Ft/y3JXowjItgfTHwYcZzuUgXrskluoINW5sr+GQoNYE2F4sT8o0tBBJwqJ6FwKd\n" + "fkIprv9UXqkv5iY+pXSYXX12mY1K5GMNkXiObk46NjuoNNP9l8oidhO6eNfcE+k3\n" + "CRIYS4FbBaD0fWUSwgMuo0Bp83/Wzp3B9ytEBh0/624=\n" + "-----END SIGNATURE-----\n"; + +/* This is a good signature of the wrong data: I changed 'published' */ +static const char EX_RI_BAD_SIG2[] = + "router fred 127.0.0.1 9001 0 9002\n" + "signing-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBAObzT4opT9uaThByupbb96tYxVpGxzL9CRPKUcU0beGpHyognD9USHWc\n" + "SpSpKfBL5P3xr2i/XTs34M4UTbT9PE7bVyxv7RD/BZmI4gc8R3PMU77xxbpEU5bK\n" + "LF3QUPpuB88m/2fXUGgMNVDc5MIq6pod2NRoDpeU7WA8T3ewXzK5AgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "onion-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBAM1QKsQiup9DNMCgNeE2FkAhCWzpMZKCn1nNlZbDGfE3Z22ex6bdWWY6\n" + "ocEZ3JZDsZsnaZrdYxrL3Mquq7MbHdfx90EdlOvDRP1SAIbZ55mLR77fZTu4BKd/\n" + "h9BC6I26uZE0QavFq3+BhoVVhVn5Mqv05nR9CeUMSSZLxw/RJm4DAgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "published 2014-10-05 12:00:01\n" + "bandwidth 1000 1000 1000\n" + "reject *:*\n" + "router-signature\n" + "-----BEGIN SIGNATURE-----\n" + "Ft/y3JXowjItgfTHwYcZzuUgXrskluoINW5sr+GQoNYE2F4sT8o0tBBJwqJ6FwKd\n" + "fkIprv9UXqkv5iY+pXSYSI12mY1K5GMNkXiObk46NjuoNNP9l8oidhO6eNfcE+k3\n" + "CRIYS4FbBaD0fWUSwgMuo0Bp83/Wzp3B9ytEBh0/624=\n" + "-----END SIGNATURE-----\n"; + +/* This one will fail while tokenizing the first line. */ +static const char EX_RI_BAD_TOKENS[] = + "router bob\n" + "signing-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBANGCgvZc+JRtAzuzk3gBD2rH9SHrXzjJ1wqdU3tLKr7FamKCMI2pLwSA\n" + "FZUpTuSqB9wJ/iVcYws+/kA3FjLqgPtzJFI0SVLvQcz5oIC1rEWpuP6t88duMlO9\n" + "flOUzmYu29sBffrXkQr8pesYvakyXArOJVeRR7fSvouneV5aDYWrAgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "onion-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBAML+pYZoYc+whKLijupd63xn0gzlEQqe7k07x/lWMqWFT37FfG6YeNr5\n" + "fpFoo77FDfuFaL+VfPfI8i88g157hcPKBVX6OyRH54+l5By0tN91S0H+abXjXQpv\n" + "U/Bvmul+5QpUeVJa1nPg71HRIauoDnBNexUQ7Xf/Bwb2xCt+IJ6DAgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "published 2014-10-05 12:00:00\n" + "bandwidth 1000 1000 1000\n" + "reject *:*\n" + "router-signature\n" + "-----BEGIN SIGNATURE-----\n" + "tbxtYYzyVqi6w6jz1k8NPjFvZaSNR0WzixVTTvKKGoMPx/6+Z8QAFK1ILzRUVucB\n" + "nRhmZMFaPr3vREMErLRE47ODAzwoBCE9C+vYFvROhgfzuQ3cYXla+4sMaRXYZzjH\n" + "PQ82bTwvSbHsR8fTTgePD/Ac082WxXTGpx6HOLBfNsQ=\n" + "-----END SIGNATURE-----\n" + ; + +static const char EX_RI_BAD_PUBLISHED[] = + "router fred 127.0.0.1 9001 0 9002\n" + "signing-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBAMoipSwZgTG6SpSOm6ENbyALS1Ljqqa1LSGmtHSRfGYgUQGWZXERXKQj\n" + "P5ql6o7EbGr1wnispGW/KB8Age09jGDvd/oGhQ9TDFluhLZon3obkZSFw7f9iA7Q\n" + "s29rNxoeXXLZVyS7+sux70b8x2Dt4CeG8GA8nQLljy1euwU+qYYJAgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "onion-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBAPzfzQ+2WFMUvnB3z0xD+zwczWcFyYYNW8Lj7/aRGSNN2DICp5uzSjKq\n" + "qkYQ+C8jG21+MR2PE+ZBmq6CL5mvlFKlWKouXUlN7BejwWf2gw0UYag0SYctae1b\n" + "bu8NuUEvdeGWg5Odgs+abH7U9S0hEtjKrmE5vvJS5L841IcaPLCFAgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "published 2014-10-05 99:00:00\n" + "bandwidth 1000 1000 1000\n" + "reject *:*\n" + "router-signature\n" + "-----BEGIN SIGNATURE-----\n" + "G92pnwCIXGJ9Q0fI9y4m/fHpWCsD0Hnk81/6T4TmRH3jt77fc0uRdomUOC5id4kz\n" + "J2M4vqXwRs5OK+eaPbtxf8Yv6FPmB3OBNCIhwNHIIqzKQStHUhPxD3P6j8uJFwot\n" + "/CNGciDN+owZ2DzwrXpszDfzcyp/nmwhApbi3W601vY=\n" + "-----END SIGNATURE-----\n" + ; + +/* Bandwidth field isn't an integer. */ +static const char EX_RI_BAD_BANDWIDTH[] = + "router fred 127.0.0.1 9001 0 9002\n" + "signing-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBAN32LAvXQaq0p554FcL4LVwnxyiZvscfuFnfpXwWTDRJJHd2+JCttWIx\n" + "v+eW7dNq+rq/tzSzaZwnp8b4V2skLRojSt6UUHD234eZcsPwUNhSr0y1eMuoZbnV\n" + "UBBPevpuXea85aSFEXXRlIpQfvFc43y3/UFoRzo5iMPqReo2uQ4BAgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "onion-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBAMBuF1GvOyVcRDNjzlEmGHJkTA7qkaWgTp33NSY/DPEJoahg0Qswuh2w\n" + "1YCBqem6Txp+/Vl9hoUoUGwb7Vwq0+YDMSyr0z3Ih2NcNjOMZPVtjJuv+3wXrQC8\n" + "LPpCpfU9m9QvhQ7f9zprEqUHOQTT0v5j2a5bpfd++6LFxrMUNwbfAgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "published 2014-10-05 12:00:00\n" + "bandwidth hello world today\n" + "reject *:*\n" + "router-signature\n" + "-----BEGIN SIGNATURE-----\n" + "svABTGDNJOgaiPLqDlkRU6ldYJcoEe2qHlr4O30lVM2hS3Gg6o4QARL7QRt7VepT\n" + "SruR6pE83xOr7/5Ijq5PlamS4WtODMJSH3DXT2hM5dYYrEX5jsJNZTQ+cYwPQI3y\n" + "ykuvQIutH6ipz5MYc9n0GWAzDjLq1G8wlcEfFXQLD10=\n" + "-----END SIGNATURE-----\n" + ; + +/* Onion key is actually a signature. */ +static const char EX_RI_BAD_ONIONKEY1[] = + "router fred 127.0.0.1 9001 0 9002\n" + "signing-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBANByIdFOKA3r2nnWyLjdZE8oGHqJE62T1zjW/nsCzCJQ8/kBMRYeGDu4\n" + "SeUJJ2rsh2t3PNzkqJM14f4DKmc2q76STsOW0Zcj70Bjhxb9r/OfyELVsi+x3CsE\n" + "Zo/W4JtdlVFjqevhODJdyFNLKOvqwG7sZo/K++Hx01Iu0zXLeg8nAgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "onion-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "svABTGDNJOgaiPLqDlkRU6ldYJcoEe2qHlr4O30lVM2hS3Gg6o4QARL7QRt7VepT\n" + "SruR6pE83xOr7/5Ijq5PlamS4WtODMJSH3DXT2hM5dYYrEX5jsJNZTQ+cYwPQI3y\n" + "ykuvQIutH6ipz5MYc9n0GWAzDjLq1G8wlcEfFXQLD10=\n" + "-----END RSA PUBLIC KEY-----\n" + "published 2014-10-05 12:00:00\n" + "bandwidth 1000 1000 1000\n" + "reject *:*\n" + "router-signature\n" + "-----BEGIN SIGNATURE-----\n" + "Cc/Y22KFvxXPXZtjvGIyQdjm4EMhXVXJEBwt8PvK7qlO1AgiVjEBPkUrTQQ/paLQ\n" + "lmeCN6jEVcZ8lNiVZgzRQ/2mTO3xLBPj26UNSDuouUwZ01tZ4wPENylNYnLKv5hg\n" + "gYARg/nXEJiTVe9LHl99Hr9EWWruRG2wFQjjTILaWzI=\n" + "-----END SIGNATURE-----\n" + ; + +/* Onion key has exponent 3 */ +static const char EX_RI_BAD_ONIONKEY2[] = + "router fred 127.0.0.1 9001 0 9002\n" + "signing-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBAKP1kWHsH/BZhNSZmn0FyzIrAHtMl1IVPzc7ABbx+kK+IIEMD9k1fy2h\n" + "AP2JTm2UmJDUwutVxPsxmndI+9QsRDpu33E5Ai4U1Rb6Qu+2BRj43YAyg414caIu\n" + "J5LLn6bOzt7gtz0+q69WHbnwgI4zUgUbwYpwoB7k0dRY97xip9fHAgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "onion-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGHAoGBANBKlyoqApWzG7UzmXcxhXM4T370FbN1edPbw4WAczBDXJslXCU9Xk1r\n" + "fKfoi/+WiTGvH7RcZWPm7wnThq2u2EAO/IPPcLE9cshLBkK28EvDg5K/WsYedbY9\n" + "1Gou+7ZSwMEPv2b13c7eWnSW1YvFa64pVDKu2sKnIjX6Bm0HZGbXAgED\n" + "-----END RSA PUBLIC KEY-----\n" + "published 2014-10-05 12:00:00\n" + "bandwidth 1000 1000 1000\n" + "reject *:*\n" + "router-signature\n" + "-----BEGIN SIGNATURE-----\n" + "cYcBOlapA+R4xq3nn5CjpnzNXdDArMlHuXv4MairjleF1n755ecH8A/R8YIc2ioV\n" + "n/C1TACzFVQ12Q9P3iikVOjIXNxYzaz4Lm/L/Lq4sEOPRJC38QEXeIHEaeM51lE6\n" + "p6kCqXcGu/51p5vAFCSiXI1ciucmx93N+TH1yGKRLV0=\n" + "-----END SIGNATURE-----\n" + ; + +static const char EX_RI_BAD_PORTS[] = + "router fred 127.0.0.1 900001 0 9002\n" + "signing-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBANVi/MVWhzT5uo3Jxw4ElS7UGmA24dnckdkCLetMhZOcE9e9mg4WcImL\n" + "NuBe2L/9YaL4PFVchCGlq73phKG6yFdqJdjDV8Qh9MJdAYWW2ORrjRvCrspPaYPN\n" + "BGJrkD2Gd4u3sq7f26TIkzmBx0Acd/FD4PQf8+XOt9YYd36ooS4vAgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "onion-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBALtP4cIpAYp9nqo1ak4SxALcndFw4o51U36R4oa+uJS/lYQPHkMMOj6K\n" + "+AVnj9sxkDJ1POaU5lsCQ5JPG1t+Tkh7vDlJb6RCUy25vJOuaQCb9GVVY7KQTJqA\n" + "E0fU73JdKACNjMlbF36aliQhrG4Fq2Uv+y7yp8qsRxQ8jvzEMES/AgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "published 2014-10-05 12:00:00\n" + "bandwidth 1000 1000 1000\n" + "reject *:*\n" + "router-signature\n" + "-----BEGIN SIGNATURE-----\n" + "xzu2T+pMZtdsS5q1cwXM2hMIH2c8mpAV31G2hKIuiQRwtPD1ne4iJsnoVCXhFakd\n" + "QTq7eTXM174fGWyIT93wvQx/Uqnp29dGZp/VaNOsxHFdYVB4VIVqkBh757h+PSJ+\n" + "VNV5JUm4XQ1QbmniJGdTQp4PLBM++fOXMR3ZNd6rt4o=\n" + "-----END SIGNATURE-----\n" + ; +static const char EX_RI_NEG_BANDWIDTH[] = + "router fred 100.127.0.0.1 9001 0 9002\n" + "signing-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBAMCG/ZCXNCF02uXRSCP7qWBN75jDMQZ363ubnQWhF9KDDNWWiwj3UiZR\n" + "zqsM4zKRgjtarWZvp2qxKABFAODd+j9iq5DvUGRbbXv+aR8TT/ifMtwwxHZQBk1F\n" + "1hbsLdwWzGIiyz5k2MVhXnt6JTlklH2hgT++gt9YTHYKxkssaq5TAgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "onion-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBAM3vk/4kOTB1VXrve29JeHOzNUsPwKruBcjxJf+aatxjf6KO2/RW41bM\n" + "gRYq9V7VAYeZTsbS727fy03F5rk3QIBhMJxm9FHatQ6rT/iEDD4Q1UZQsNtm+OLf\n" + "/TkZZhgfB3MiDQ4ld/+GKd7qww8HXTE+m/g1rXNyZPKozn8K7YUHAgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "published 2014-10-05 12:00:00\n" + "bandwidth 1000 -1000 1000\n" + "reject *:*\n" + "router-signature\n" + "-----BEGIN SIGNATURE-----\n" + "bUBBZYZWqCbsH4/7fNXtC/HgIZNGOfDF9v4d9YfKaDs5xDYf2o67hRcwx5imhrgC\n" + "IU7n9AI4AGxkFoN6g3Y/t4pqebxdkF678rRDCtrlwwreAiUktgrwnetp9Tpo16xj\n" + "V7Uf6LcqQdvu78lRh1dsrY78sf7sb90vusFMPLXGUKM=\n" + "-----END SIGNATURE-----\n" + ; +static const char EX_RI_BAD_IP[] = + "router fred 100.127.0.0.1 9001 0 9002\n" + "signing-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBAMtMrM24AJpJCevxnseIpRlSuAIMksfkfky2+noe7Rok8xn6AMQzMrwx\n" + "AiCJ8Jy4DBzIKUiJK4/y1FimyM08qZGR0xeqblCxZ1lbSiXv6OYxoaD2xmWw8zEP\n" + "Zgu4jKReHh+gan1D+XpAbFNY0KrANhjRo96ZZ3AQsZQcWBiPKCynAgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "onion-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBAOPclmBO/amw1RWTSI1y80qY/EPjc0I+sk9HKr0BQOovxqJ0lmy9Gaue\n" + "y+MOejQ9H2hNev0nd7z1fPxEogt7SCe22qJHHX3xDf+D9RpKsvVzDYZsk7hVL7T1\n" + "mwHzuiV/dtRa7yAMp7+q0vTUGesU2PYFYMOyPvz5skNLSWrXOm05AgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "published 2014-10-05 12:00:00\n" + "bandwidth 1000 1000 1000\n" + "reject *:*\n" + "router-signature\n" + "-----BEGIN SIGNATURE-----\n" + "g6besL/zxOp0N6Q5/7QZgai2kmCU5EAWJlvZrf5jyrjKhsv2a4LDkap07m9QRFqW\n" + "GGe7g5iiABIqnl0kzv7NLX7ah+d/xxv+IILXyZfVTxSw0e+zFb3uPlQ7f9JsGJ8i\n" + "a+w8wyyDBpOAmi8Ny866Cnp9ojVzCyIErUYHFaPvKao=\n" + "-----END SIGNATURE-----\n" + ; + +static const char EX_RI_BAD_DIRPORT[] = + "router fred 127.0.0.1 9001 0 bob\n" + "signing-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBANKcD6DJ16X3yvdq05jatdwgjO+hyoIpckW9sV/OkdfIZwf+S6Q4pZGC\n" + "doMw5XeOM52gjpx42kUp6M2WlTGDFEpaNU0VyeZYG/M1CM1xvfj3+1PoebioAGdf\n" + "GuhNBCHZdaYNiOGnh9t2GgUomgpE6njdS/lovSrDeTL469hfcUghAgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "onion-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBANWeGHig5wE9UijaNnEW5au3B3hZKSlzCi+T6MYDPbbYhm8qJaVoXUXF\n" + "EP1EUgzDcX3dPEo9upUA1+91GkjGQCo9eOYlqGib8kHIwKnHZK+hernBc/DnOeUp\n" + "Wyk9SW5s+fi12OQhr3NGjbSn76FMY9XU3Qt7m3EviTwWpI3Jr5eRAgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "published 2014-10-05 12:00:00\n" + "bandwidth 1000 1000 1000\n" + "reject *:*\n" + "router-signature\n" + "-----BEGIN SIGNATURE-----\n" + "t77wEoLjyfMf9LKgBfjveosgwvJ8Go0nb27Ae3Ng9tGtR4qaJQfmwZ5fOOuVU9QC\n" + "3s8ww3aY91KD3NTcN3v3FKngxWtRM8AIfwh4pqT3zW6OSP4+nO3xml7ql0Zf6wfj\n" + "TPFV2941O3yplAsmBJ41sRSWizF04wTtZAIgzY7dMLA=\n" + "-----END SIGNATURE-----\n" + ; +static const char EX_RI_BAD_NAME2[] = + "router verylongnamethatnevereverendsandgoesontoolong 127.0.0.1 9001 0 9002\n" + "signing-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBAL0mcUxg7GJ6oxgciLiBCbo+NuZ/OVKRrERCSM6j6iHERcB9+ciSRgQ5\n" + "H6o6FUX2LoRmHYzBk1x7kIjHa9kx9g6CAbBamdZrQbdVnc1y2NrdHB/jvwLj3C48\n" + "PgzFIrLg9OlkuoWck/E+YpPllONfF65e0+ualgVjPgpQpXwmz+ktAgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "onion-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBAOgHvvTAxyjJtHx9W2X7aOI05H9sYDDY+sxhovT/8EpAHrioex54tsMT\n" + "ifgtoXTjGIBEOTDi/1ry39nEW5WPbowqvyzRfR2M43pc96WV7e1nhmD/JrnTYgtR\n" + "5/15KxcMJxoDhod7WZ/wlXBnHc2VevX8JTaeOe9KYORCj5iNbtVZAgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "published 2014-10-05 12:00:00\n" + "bandwidth 1000 1000 1000\n" + "reject *:*\n" + "router-signature\n" + "-----BEGIN SIGNATURE-----\n" + "j/nFT5gyj20cLHWv94O1jmnqy3n6qkO8Av0OdvvfNeXsMK2UHxk84vzFvEwpUF/Y\n" + "i+VR3LXY4CjTpuliMtjt7BQGtmJSvB8W0CeIUenIGzfwDxW9dG2o7spDldKDB/OU\n" + "C1wyHvKaA6Yss/02RIDa4AxyjsfbgdJ91qK+aAnYAtA=\n" + "-----END SIGNATURE-----\n" + ; +static const char EX_RI_BAD_BANDWIDTH2[] = + "router fred 127.0.0.1 9001 0 9002\n" + "signing-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBALQDCm9VEopiYILmt4X9kP6DQazfgKnLXv+6rHbc4qtmvQQD3TVYbxMP\n" + "F4sEUaz+YHAPnomfDVW3a0YFRYXwDzUm1n47YYCyhUzEaD2f69Mcl/gLpKdg+QOy\n" + "boGB1oD4CStWL3y05KhxxTNiTrg+veMzXTqNwryCYm+GoihIAM9fAgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "onion-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBALYHwdx6bmYy09AW5ElN/DWh0fHh3mBK97ryiIMi8FImYfzbw2BR6xuT\n" + "aQT5omqS3PNJJcNWZt5gOyDtA9kLh03cch7t1PenXSYJshbME2bDrZDJKVJMN6vV\n" + "B1v/9HjXsVF50jBzZsJo3j26XCPT5s6u9wqUFWW09QR3E/1HInHVAgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "published 2014-10-05 12:00:00\n" + "bandwidth 1000 -1000 1000\n" + "reject *:*\n" + "router-signature\n" + "-----BEGIN SIGNATURE-----\n" + "p09ijyuvcW+WKRj4mJA/nkLCvZkRcMzykAWheJi1IHCoqhXFdkFLiIRqjaeDVHRr\n" + "zBtD+YCQiGvFcaQJ9IUhh7IleHcyyljmDYlvuBAxWiKvVZstJac0kclCU4W+g8yK\n" + "0Qug3PmGKk115x2TllHaCZqMo5OkK4I/WAsKp+DnJ1A=\n" + "-----END SIGNATURE-----\n" + ; +static const char EX_RI_BAD_UPTIME[] = + "router fred 127.0.0.1 9001 0 9002\n" + "signing-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBAMM0Nubr1VXQ/FcgIQTFxZpZDlAEh2XN8FoJ8d+X5S46VDGijmMoYmyN\n" + "oLXqMTGmOaR0RGZOeGLgDzeY8tLrfF821IjfkXeAANZibUjdsHwqHO3wlWD2v+GN\n" + "0GBocWXEdAp/os229mQQKgYAATJ0Ib3jKhBdtgm5R444u8VX5XnbAgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "onion-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBAMpyOr4kEtSTZw4H9eSkH2+WmwIlO4VBpY2HkPS00l6L5fM2REjt50Xi\n" + "lsNOz8Q6mAn5cMYmsGlv61kg01mCvYc7Z715jGh+1hhVAxMaNS3ED/nSPnslyjhq\n" + "BUm51LhYNHD4ktISIqPMurx6aC8B68UYgKzLgCYNzkathFXSBpjRAgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "uptime forever-and-a-day\n" + "published 2014-10-05 12:00:00\n" + "bandwidth 1000 1000 1000\n" + "reject *:*\n" + "router-signature\n" + "-----BEGIN SIGNATURE-----\n" + "NHYeiQOu0nZdrhSy31Xz4F0T6OTU23hPQDzoLax1/zq6iTVrz9xi3HGm7HhOMW1j\n" + "YgFGK3+Xm4iJL+DwriunsAIuL5axr3z2hlmFDQHYItP//KyPpOqSrfEOhwcuj/PE\n" + "VbWsiVYwz9VJLO8SfHoBeHI6PsjQRQFt2REBKZhYdxA=\n" + "-----END SIGNATURE-----\n" + ; + +static const char EX_RI_BAD_BANDWIDTH3[] = + "router lucy 127.0.0.1 9001 0 9002\n" + "signing-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBAO6HrITQTEjV/v/rInQ2REmCFZa4dZg8zIh6+B51U/I6hDiZaKGwpNey\n" + "9OfjoRqT2DwyLEe3ORm9A2RAz2twLBixrpt5IvC0sbGustmW964BHW7k9VvRupwl\n" + "ovujHpLIj5dkLxD15jGXHoTp1yHUVk9NkMGN+ahg6y+QhTbIrWbRAgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "onion-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBAOEpciJFXauEqs31GMTUTzu6edBj9WtV+sIflhGKvU1KKRfwCgOcuKMx\n" + "QiLHHD9AjhMAFGT/qtNbPFkzfYxHKLHw+NLJsxmNtdkYM26FX3ButPiX+69sq9fI\n" + "PCHqQy6z/A7hHwtEk6niWgK2PLhAZCg9duAv+mqFVXe2QEBjax/lAgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "published 2014-10-05 12:00:00\n" + "bandwidth 1000 1000 electric\n" + "reject *:*\n" + "router-signature\n" + "-----BEGIN SIGNATURE-----\n" + "Jk0Xk1RMJSjEflNRcp4qznaHKcfe2r0kOc7TdLAnM8zyNDVj6+Bn8HWmyp/oFmf6\n" + "xtWKKgkKxriAVIJgqZMchPbr9RuZS+i+cad++FCwpTVkyBP920XWC47jA3ZXSBee\n" + "HK6FaoK5LfmUm8XEU9BVhiwISXaUfTdkR8HfzugFbWk=\n" + "-----END SIGNATURE-----\n" + ; +static const char EX_RI_BAD_NTOR_KEY[] = + "router fred 127.0.0.1 9001 0 9002\n" + "signing-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBAKYDCSr0Jh9d/mJKjnGYAHKNBcxR3EJk6GGLwKUrRpN8z/aHRxdWlZF2\n" + "lBml6yQNK/VPftcvOekxrKq3/dISrIFBzFYj6XHNtg31d09UgitVkk0VfRarZiGu\n" + "O6Yv55GSJ9a3AZDE4YmIp5eBjVuChyVkeDFYKVn0ed4sj9gg35rjAgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "onion-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBALXdUQuq1pYHyYP0qU6Ik+oOmwl0eOsuwiLWf9Vd+dsgEszICX4DRWPx\n" + "syDxfxyA/g9FEPvlI7Nglx6cKe2MT0AutSRLbbML4smfuRZNIF35Cnfu5qTGVVzL\n" + "GWVSA2Ip7p+9S9xLhLBdc6qmrxEXCPL6anEhCR4f8AeybXAsz2JLAgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "published 2014-10-05 12:00:00\n" + "ntor-onion-key s7rSohmz9SXn8WWh1EefTHIsWePthsEntQi0WL+ScVfjdklsdfjkf\n" + "bandwidth 1000 1000 1000\n" + "reject *:*\n" + "router-signature\n" + "-----BEGIN SIGNATURE-----\n" + "Yf9axWyzPudnRvQstNdbtBYo7pGpUEIdECMGcJtFb6v/00pxk4Tt3RiOKa84cOBV\n" + "7V9NjOLdqlx88pGz0DNCJKqToIrwjZDeQ8Q1yi9XClLDkC32fQRX4y6vNBZ3LXLe\n" + "ayVrdRrb41/DP+E7FP4RNPA5czujTfs8xLBMbGew8AA=\n" + "-----END SIGNATURE-----\n" + ; +static const char EX_RI_BAD_FINGERPRINT[] = + "router fred 127.0.0.1 9001 0 9002\n" + "signing-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBAM0wDWF2dBLzsmoIDHRugzosCSR9TSvEE0TkvKu6+agfogGtkQJwQ5zO\n" + "sGzZbRR+okO7d+QCED2i3rUs1iikoMUT+pwgvOm8Bxg9R64GK7fl9K5WuAiG11Uj\n" + "DQAfSx5Fo30+rhOhe16c9CT7xJhj//ZKDbXUW7BrJI8zpuOnvgD5AgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "onion-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBAKACg1nWM/WjpUiGwlLQsY3Tq1h0RTz/HmOMx/6rTRxS5HLz0KnLg5zV\n" + "dvmfhxqQVKBkt1N2+y+qO7x71oFzIsFMfHYWSxOCEo8Nkff1BqAPqxxUHvM0HwJo\n" + "d7lswJ/UT1j4+WZNZ4sFIujsIW2/zZqKlxG9xaw0GXJ082Cj9XkPAgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "published 2014-10-05 12:00:00\n" + "fingerprint 5555\n" + "bandwidth 1000 1000 1000\n" + "reject *:*\n" + "router-signature\n" + "-----BEGIN SIGNATURE-----\n" + "mlqyJ/ZGBINKwSNEi7GpNBCMqIVbL0pGAOBYHJF1GbRlU28uRyNyeELIxIK5ZIet\n" + "ZzKr7KPvlBxlyolScPhTJfP98TFSubrwYz7NnQv0vLI0bD0OyoBf/9/1GYlzgTso\n" + "3mKfnV7THUalpxe9EjQ/x61Yqf26Co0+jYpt8/Ck6tg=\n" + "-----END SIGNATURE-----\n" + ; +static const char EX_RI_MISMATCHED_FINGERPRINT[] = + "router fred 127.0.0.1 9001 0 9002\n" + "signing-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBANUAvwbpGbsAyA+mBwjFkvurtRzdw9btDqNKtPImufIE+q+AFTaCnwPr\n" + "kA7vm/O6h6OhgfdYEC2GfYJfwPGM7MDuz+NnuKxUb3qb2DQN2laqow6qWs9La/if\n" + "oHKUjC5mNeAgHcbWapx9CygwaFeVW6FBPl6Db6GIRAlywPSX+XMJAgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "onion-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBANlSGd+Vm9nLiUk6zgu8dPnSFfw4F0R2GYfmzncIGJWtRFTF9ThW/0av\n" + "/9vZAWyVBjjtnpAP5R1BzdJYV2RwimC/6tqoHtkSbCBhdq5Cb/EHG7Xgb8KwNWVJ\n" + "NV1EESDwvWnRfSPGTreRw9+2LkdXri17FhDo2GjRxAq/N7YkLK5hAgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "published 2014-10-05 12:00:00\n" + "fingerprint CC43 DC8E 8C9E 3E6D 59CD 0399 2491 0C8C E1E4 50D2\n" + "bandwidth 1000 1000 1000\n" + "reject *:*\n" + "router-signature\n" + "-----BEGIN SIGNATURE-----\n" + "Y8MwYBeEfMhoAABK/FgpVRYolZ7jQ2BJL+8Lb6i4yAuk+HeVmPKTX7MqQoekUuin\n" + "/HdPKP+g/9HPMS5pCiW4FMwnXAF0ZocPXF0ndmsTuh0/7VWVOUGgvBpPbIW6guvt\n" + "sLLQ3Cq9a4Kwmd+koatfLB6xSZjhXmOn7nRy7gOdwJ8=\n" + "-----END SIGNATURE-----\n" + ; +static const char EX_RI_BAD_HAS_ACCEPT6[] = + "router fred 127.0.0.1 9001 0 9002\n" + "signing-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBAJfPJNA3zZ77v2nlX2j5dXImcB/NhRtkG8XQgF7z+3H17sqoXgBgZ1dq\n" + "IbyJmAy2Lrvk/8VkXNFrT5/ErThn1B98V/PsJOOW1x7jGcix6X4zDYn/MvwC+AxA\n" + "zNP0ozNcVZ6BzVYq8w4I1V4O3Cd6VJesxRVX6mUeSeNawOb7fBY7AgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "onion-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBAKBzfB4mDEJjFTnmtqZxDG8G1yAiccVgAtq9ECEREL/BOQyukixUBeBe\n" + "j/FgXzbMJ7DZAuopuJZU2ma6h14G63fZs7eNFceDtmdLpuCOsFuvJ5Mlkf3hDZ1u\n" + "1KK5q+tiG7MKxgnGrqjPBUO2uubs2Cpx0HmsqBNUalXd/KAkFJbXAgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "published 2014-10-05 12:00:00\n" + "bandwidth 1000 1000 1000\n" + "reject *:*\n" + "accept6 *:80\n" + "reject6 *:*\n" + "router-signature\n" + "-----BEGIN SIGNATURE-----\n" + "Dp9dLgs9s5beMPxfD0m96as9gNBvlmKhH1RQ/kcOKscia4R8Q42CnUtIqLkCdjOu\n" + "zErc2Vj9QzjKOvlqUqHxP+J+l+ZJez6F+E1tcmK/Ydz3exL8cg9f4sAOCSXcpBey\n" + "llTFDibz6GkQ2j3/Uc4bN/uLzoyZKunpJbSKZP5nt8Q=\n" + "-----END SIGNATURE-----\n" + ; +static const char EX_RI_BAD_NO_EXIT_POLICY[] = + "router fred 127.0.0.1 9001 0 9002\n" + "signing-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBAK4fbjTKYqv2fygfjzY53sVTdtbNMjq293/uffKKxFYnOVvPzrHlP6Go\n" + "2S19ZcyDxOuH1unbBChPnV0GpxXX6+bgfDkaFh7+jef0RQ3fpJl84hSvdM8J8SCt\n" + "Q/F4Oqk3NeKKs+zAHDjhAU1G4LkF9/SZ9WZVXlH4a4pf7xgQtaShAgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "onion-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBAKahvyDkmh33ob/bLVO1icgz2ntOZN6ZQUfgpMU4Cd6DQtOEwFUGhbVt\n" + "gvtMHv2+VbxM31ZfUsyBqJ1rJBLpOqlPvSoYwSac2+twa+w/qjfGqcJYhBjP9TV9\n" + "n9y8DzBX85p6vRcCzcuZ4qUJ2nRzdLHwjdgzeLmmCHuPO2dQxQhXAgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "published 2014-10-05 12:00:00\n" + "bandwidth 1000 1000 1000\n" + "router-signature\n" + "-----BEGIN SIGNATURE-----\n" + "ntgCtMC0VrsY42dKts8igGQ2Nu1BpuzUltisIsJz75dDx2LCqTn7p4VpWbTrj1sH\n" + "MRNOvEPFxVMs0Lu50ZUGRzeV6GrHmzIRnOIWanb3I/jyrJLM0jTIjCOLwdMRA298\n" + "tw8Y9Hnwj4K7K6VvgU8LP4l7MAJNfR6UT46AJ6vkgL0=\n" + "-----END SIGNATURE-----\n" + ; +static const char EX_RI_BAD_IPV6_EXIT_POLICY[] = + "router fred 127.0.0.1 9001 0 9002\n" + "signing-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBAKHJKLHqjYoW9M+1q0CGHJRT5u2CnZWb8Qr1DpLkkusQ6ru+cDAG12so\n" + "IpDQh7IyB2JosVJi9ogekYxJ3O1p5WlFUi0X19DMoer9FJ9J7/3s4enGJ/yMBeuu\n" + "jLVRkjMJhsfhj3Cykon+8Rrf520wSmBg1dpJQCXTwtb7DARgYRpZAgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "onion-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBAPJH61Ir6XSu9/Q9tXGaINbXO1GWQQUXtwh6TX9lxnaCNDLGnxiY+ZZw\n" + "+Vqj3LAQoMrz1PpPsF5e0VIxok10Vc8y4cWC+kIitcecut4vWC5FYTtVVP9wtlyg\n" + "YCcVOVhtFQxtLiGqprl84+EVxrR7RQVCMLNDUXIgxAfdnS24eBPDAgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "published 2014-10-05 12:00:00\n" + "bandwidth 1000 1000 1000\n" + "reject *:*\n" + "ipv6-policy kfdslfdfj sdjfk sdfjsdf\n" + "router-signature\n" + "-----BEGIN SIGNATURE-----\n" + "XWorzVT5Owg+QcsBtksiUNtpQQ5+IdvbsN+0O9FbFtGZeaeBAbPJ3Poz+KFCUjZY\n" + "DeDAiu1cVgODx2St+99LpwEuIBx78HaD8RYU8tHx8LoA+mGC43ogQQS9lmfxzvP5\n" + "eT5WXhkOS5AZ8LZOCOmT+tj/LkSXev2x/NC9+Vc1HPo=\n" + "-----END SIGNATURE-----\n" + ; +static const char EX_RI_BAD_FAMILY[] = + "router fred 127.0.0.1 9001 0 9002\n" + "signing-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBAM62QoRxSPnm+ZM4fv9p03Qqbz5SzhXYSNjKWqylBruaofTw6oIM8DtX\n" + "7QnrEe/ou/WtfB+swV/2rt/r0EzmeWBWuDmuSUrN5TC2AdOi9brSJMgXVW6VW77X\n" + "fuIlLd5DVSId2zs3cKLDqp36CUsooA9sS6I5HrvW9QDf3VS3pGBtAgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "onion-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBANg1trpnRzkCi4t4Z4qnBKF612H5A3Zrjg7Jo2b3ajUnON/KEuLPTc3t\n" + "PPN0W4qqeCMmVQEuxf3DRbTPS20ycy4B/JDWYfxCNwuj5YAx04REf7T0Hlx7Aee/\n" + "sHEQBhIBfasA2idhTh3cAm4DMYn+00BqjxF6jmyRA0hyntEABabrAgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "published 2014-10-05 12:00:00\n" + "bandwidth 1000 1000 1000\n" + "family aaaa,bbbb\n" + "reject *:*\n" + "router-signature\n" + "-----BEGIN SIGNATURE-----\n" + "xOgP3liKF/WEvwbbGzUUVRZ5WPrOI7jex8pZU/02UEnHjit7vCf9fsUcvkeo0xjz\n" + "n3FQHIO1iAJS7dEaEM4nz6wtPUb2iXSU9QajkGBkJ9/V7NHMFIU3FGfP47PIJJkd\n" + "nz5INoS+AsE7PmnDjUMm1H45TCCl8N8y4FO6TtN7p8I=\n" + "-----END SIGNATURE-----\n" + ; +static const char EX_RI_BAD_EI_DIGEST[] = + "router fred 127.0.0.1 9001 0 9002\n" + "signing-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBAJ8Sn8AxBRbeIAHUvaKjqmcYOvXz7YFlpYFiVHp/cn+l+KUkIYTOFQXf\n" + "K8AtwjmJ4R2qJIbNlY/6oZGFbizt/B+WPuWsTj+8ACEEDlxx0ibg3EJRB8AZYiWv\n" + "0zC/loiUvHm6fXF5ghvDr9BQzEUo9kBk5haoHwROtGawr1+vOEiNAgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "onion-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBAMzok3ZJtLjXOC8RKltXI8xulwn/ctCvQFHImR0+ccA1uBxaZNYgiIcc\n" + "q8XngROfV8xEgDbYPiWiLXJOMSwOd7hfs3YzRWF+LKftYs8PuRyMJcCoBjOPZ4QX\n" + "HRfTetEvu2SijZMby+lkqpZg2nuF/ipsXUjrabRZdNiIGhC451vdAgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "extra-info-digest not-a-digest\n" + "published 2014-10-05 12:00:00\n" + "bandwidth 1000 1000 1000\n" + "reject *:*\n" + "router-signature\n" + "-----BEGIN SIGNATURE-----\n" + "c/6zAxO04izQvqdM4bZVGE+ak0nna5pz9XZizFkieZEDWGzWQuVMhXyL5sbsFbsx\n" + "6Hn7DvNRYR/2nA0teDeRyIHMoMHi76te5X9OFDgaeUVCbyJ8h/KZYfPnN86IDbsR\n" + "dCSmj9kX55keu64ccCAH1CqwcN/UsbplXiJJVG5pTfI=\n" + "-----END SIGNATURE-----\n" + ; +static const char EX_RI_ZERO_ORPORT[] = + "router fred 127.0.0.1 0 0 9002\n" + "signing-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBAMc4MOhLG3PKPgc+xYVf4eScWzeOf8wq7Cb/JxZm50G0LuvVbhHtHEZX\n" + "VOSHI7mLE1ifakJvCFJRLobMU7lU0yhn18/nKl2Cu5NfFHHeF/NieUBSxBGb2wD6\n" + "aM1azheXrRqvDVVfbI0DLc/XfQC/YNiohOsQ/c9C6wuffA4+Sg85AgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "onion-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBALBWdl9/Vft+NQKQlg5kgvZo+krnhNTRVQojWtUEzom4TFIT+NNKJyMG\n" + "reQXcNdzNptTB0aOBGGwqAesqzsZ2Hje699NsDe7hdl7Sb5yhKDqtdQY6yDXJUFt\n" + "zqpAUkmYMLe2p3kPiWefNso56KYXrZrlNAiIS/FhQ5cmuMC2jPydAgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "published 2014-10-05 12:00:00\n" + "bandwidth 1000 1000 1000\n" + "reject *:*\n" + "router-signature\n" + "-----BEGIN SIGNATURE-----\n" + "gFg08P9A6QNQjURlebfdhU3DSV0BeM0j2SFza1jF9JcBOWDRmT8FvYFK1B3js6jK\n" + "8LNV8JOUssv14z5CnUY9CO1BD0xSl+vGlSS4VOXD7rxui8IoWgnqnZsitq+Qzs95\n" + "wgFKhHI/49NHyWHX5IMQpeicg0T7Qa6qwnUvspH62p8=\n" + "-----END SIGNATURE-----\n" + ; diff --git a/src/test/include.am b/src/test/include.am index 77c92f12f8..8d05b3b700 100644 --- a/src/test/include.am +++ b/src/test/include.am @@ -34,6 +34,7 @@ src_test_test_SOURCES = \ src/test/test_logging.c \ src/test/test_microdesc.c \ src/test/test_oom.c \ + src/test/test_accounting.c \ src/test/test_options.c \ src/test/test_pt.c \ src/test/test_relaycell.c \ @@ -60,7 +61,7 @@ src_test_test_LDFLAGS = @TOR_LDFLAGS_zlib@ @TOR_LDFLAGS_openssl@ \ @TOR_LDFLAGS_libevent@ src_test_test_LDADD = src/or/libtor-testing.a src/common/libor-testing.a \ src/common/libor-crypto-testing.a $(LIBDONNA) \ - src/common/libor-event-testing.a \ + src/common/libor-event-testing.a src/trunnel/libor-trunnel-testing.a \ @TOR_ZLIB_LIBS@ @TOR_LIB_MATH@ @TOR_LIBEVENT_LIBS@ \ @TOR_OPENSSL_LIBS@ @TOR_LIB_WS32@ @TOR_LIB_GDI@ @CURVE25519_LIBS@ @@ -74,7 +75,10 @@ src_test_bench_LDADD = src/or/libtor.a src/common/libor.a \ noinst_HEADERS+= \ src/test/test.h \ - src/test/test_descriptors.inc + src/test/test_descriptors.inc \ + src/test/example_extrainfo.inc \ + src/test/failing_routerdescs.inc \ + src/test/ed25519_vectors.inc if CURVE25519_ENABLED noinst_PROGRAMS+= src/test/test-ntor-cl diff --git a/src/test/slow_ed25519.py b/src/test/slow_ed25519.py new file mode 100644 index 0000000000..f44708b200 --- /dev/null +++ b/src/test/slow_ed25519.py @@ -0,0 +1,115 @@ +# This is the ed25519 implementation from +# http://ed25519.cr.yp.to/python/ed25519.py . +# It is in the public domain. +# +# It isn't constant-time. Don't use it except for testing. Also, see +# warnings about how very slow it is. Only use this for generating +# test vectors, I'd suggest. +# +# Don't edit this file. Mess with ed25519_ref.py + +import hashlib + +b = 256 +q = 2**255 - 19 +l = 2**252 + 27742317777372353535851937790883648493 + +def H(m): + return hashlib.sha512(m).digest() + +def expmod(b,e,m): + if e == 0: return 1 + t = expmod(b,e/2,m)**2 % m + if e & 1: t = (t*b) % m + return t + +def inv(x): + return expmod(x,q-2,q) + +d = -121665 * inv(121666) +I = expmod(2,(q-1)/4,q) + +def xrecover(y): + xx = (y*y-1) * inv(d*y*y+1) + x = expmod(xx,(q+3)/8,q) + if (x*x - xx) % q != 0: x = (x*I) % q + if x % 2 != 0: x = q-x + return x + +By = 4 * inv(5) +Bx = xrecover(By) +B = [Bx % q,By % q] + +def edwards(P,Q): + x1 = P[0] + y1 = P[1] + x2 = Q[0] + y2 = Q[1] + x3 = (x1*y2+x2*y1) * inv(1+d*x1*x2*y1*y2) + y3 = (y1*y2+x1*x2) * inv(1-d*x1*x2*y1*y2) + return [x3 % q,y3 % q] + +def scalarmult(P,e): + if e == 0: return [0,1] + Q = scalarmult(P,e/2) + Q = edwards(Q,Q) + if e & 1: Q = edwards(Q,P) + return Q + +def encodeint(y): + bits = [(y >> i) & 1 for i in range(b)] + return ''.join([chr(sum([bits[i * 8 + j] << j for j in range(8)])) for i in range(b/8)]) + +def encodepoint(P): + x = P[0] + y = P[1] + bits = [(y >> i) & 1 for i in range(b - 1)] + [x & 1] + return ''.join([chr(sum([bits[i * 8 + j] << j for j in range(8)])) for i in range(b/8)]) + +def bit(h,i): + return (ord(h[i/8]) >> (i%8)) & 1 + +def publickey(sk): + h = H(sk) + a = 2**(b-2) + sum(2**i * bit(h,i) for i in range(3,b-2)) + A = scalarmult(B,a) + return encodepoint(A) + +def Hint(m): + h = H(m) + return sum(2**i * bit(h,i) for i in range(2*b)) + +def signature(m,sk,pk): + h = H(sk) + a = 2**(b-2) + sum(2**i * bit(h,i) for i in range(3,b-2)) + r = Hint(''.join([h[i] for i in range(b/8,b/4)]) + m) + R = scalarmult(B,r) + S = (r + Hint(encodepoint(R) + pk + m) * a) % l + return encodepoint(R) + encodeint(S) + +def isoncurve(P): + x = P[0] + y = P[1] + return (-x*x + y*y - 1 - d*x*x*y*y) % q == 0 + +def decodeint(s): + return sum(2**i * bit(s,i) for i in range(0,b)) + +def decodepoint(s): + y = sum(2**i * bit(s,i) for i in range(0,b-1)) + x = xrecover(y) + if x & 1 != bit(s,b-1): x = q-x + P = [x,y] + if not isoncurve(P): raise Exception("decoding point that is not on curve") + return P + +def checkvalid(s,m,pk): + if len(s) != b/4: raise Exception("signature length is wrong") + if len(pk) != b/8: raise Exception("public-key length is wrong") + R = decodepoint(s[0:b/8]) + A = decodepoint(pk) + S = decodeint(s[b/8:b/4]) + h = Hint(encodepoint(R) + pk + m) + if scalarmult(B,S) != edwards(R,scalarmult(A,h)): + raise Exception("signature does not pass verification") + diff --git a/src/test/test-network.sh b/src/test/test-network.sh index 7b59864166..d28fbde80f 100755 --- a/src/test/test-network.sh +++ b/src/test/test-network.sh @@ -1,5 +1,7 @@ #! /bin/sh +ECHO_N="/bin/echo -n" + until [ -z $1 ] do case $1 in @@ -15,6 +17,10 @@ do export NETWORK_FLAVOUR="$2" shift ;; + --delay|--sleep|--bootstrap-time|--time) + export BOOTSTRAP_TIME="$2" + shift + ;; *) echo "Sorry, I don't know what to do with '$1'." exit 2 @@ -39,9 +45,14 @@ PATH="$TOR_DIR/src/or:$TOR_DIR/src/tools:$PATH" # Sleep some, waiting for the network to bootstrap. # TODO: Add chutney command 'bootstrap-status' and use that instead. -BOOTSTRAP_TIME=18 -echo -n "$myname: sleeping for $BOOTSTRAP_TIME seconds" +BOOTSTRAP_TIME=${BOOTSTRAP_TIME:-18} +$ECHO_N "$myname: sleeping for $BOOTSTRAP_TIME seconds" n=$BOOTSTRAP_TIME; while [ $n -gt 0 ]; do - sleep 1; n=$(expr $n - 1); echo -n . + sleep 1; n=$(expr $n - 1); $ECHO_N . done; echo "" ./chutney verify $CHUTNEY_NETWORK +VERIFY_EXIT_STATUS=$? +# work around a bug/feature in make -j2 (or more) +# where make hangs if any child processes are still alive +./chutney stop $CHUTNEY_NETWORK +exit $VERIFY_EXIT_STATUS diff --git a/src/test/test.c b/src/test/test.c index a14064f237..16ad6f3ae6 100644 --- a/src/test/test.c +++ b/src/test/test.c @@ -232,7 +232,7 @@ free_pregenerated_keys(void) /** Run unit tests for the onion handshake code. */ static void -test_onion_handshake(void) +test_onion_handshake(void *arg) { /* client-side */ crypto_dh_t *c_dh = NULL; @@ -245,12 +245,13 @@ test_onion_handshake(void) /* shared */ crypto_pk_t *pk = NULL, *pk2 = NULL; + (void)arg; pk = pk_generate(0); pk2 = pk_generate(1); /* client handshake 1. */ memset(c_buf, 0, TAP_ONIONSKIN_CHALLENGE_LEN); - test_assert(! onion_skin_TAP_create(pk, &c_dh, c_buf)); + tt_assert(! onion_skin_TAP_create(pk, &c_dh, c_buf)); for (i = 1; i <= 3; ++i) { crypto_pk_t *k1, *k2; @@ -267,16 +268,16 @@ test_onion_handshake(void) memset(s_buf, 0, TAP_ONIONSKIN_REPLY_LEN); memset(s_keys, 0, 40); - test_assert(! onion_skin_TAP_server_handshake(c_buf, k1, k2, + tt_assert(! onion_skin_TAP_server_handshake(c_buf, k1, k2, s_buf, s_keys, 40)); /* client handshake 2 */ memset(c_keys, 0, 40); - test_assert(! onion_skin_TAP_client_handshake(c_dh, s_buf, c_keys, 40)); + tt_assert(! onion_skin_TAP_client_handshake(c_dh, s_buf, c_keys, 40)); - test_memeq(c_keys, s_keys, 40); + tt_mem_op(c_keys,==, s_keys, 40); memset(s_buf, 0, 40); - test_memneq(c_keys, s_buf, 40); + tt_mem_op(c_keys,!=, s_buf, 40); } done: crypto_dh_free(c_dh); @@ -323,7 +324,7 @@ test_bad_onion_handshake(void *arg) /* client handshake 1: do it straight. */ memset(c_buf, 0, TAP_ONIONSKIN_CHALLENGE_LEN); - test_assert(! onion_skin_TAP_create(pk, &c_dh, c_buf)); + tt_assert(! onion_skin_TAP_create(pk, &c_dh, c_buf)); /* Server: Case 3: we just don't have the right key. */ tt_int_op(-1, ==, @@ -351,7 +352,7 @@ test_bad_onion_handshake(void *arg) /* Let the client finish; make sure it can. */ tt_int_op(0, ==, onion_skin_TAP_client_handshake(c_dh, s_buf, c_keys, 40)); - test_memeq(s_keys, c_keys, 40); + tt_mem_op(s_keys,==, c_keys, 40); /* Client: Case 2: The server sent back a degenerate DH. */ memset(s_buf, 0, sizeof(s_buf)); @@ -408,9 +409,9 @@ test_ntor_handshake(void *arg) tt_int_op(0, ==, onion_skin_ntor_client_handshake(c_state, s_buf, c_keys, 400)); - test_memeq(c_keys, s_keys, 400); + tt_mem_op(c_keys,==, s_keys, 400); memset(s_buf, 0, 40); - test_memneq(c_keys, s_buf, 40); + tt_mem_op(c_keys,!=, s_buf, 40); done: ntor_handshake_state_free(c_state); @@ -420,7 +421,7 @@ test_ntor_handshake(void *arg) /** Run unit tests for the onion queues. */ static void -test_onion_queues(void) +test_onion_queues(void *arg) { uint8_t buf1[TAP_ONIONSKIN_CHALLENGE_LEN] = {0}; uint8_t buf2[NTOR_ONIONSKIN_LEN] = {0}; @@ -431,6 +432,7 @@ test_onion_queues(void) create_cell_t *onionskin = NULL, *create2_ptr; create_cell_t *create1 = tor_malloc_zero(sizeof(create_cell_t)); create_cell_t *create2 = tor_malloc_zero(sizeof(create_cell_t)); + (void)arg; create2_ptr = create2; /* remember, but do not free */ create_cell_init(create1, CELL_CREATE, ONION_HANDSHAKE_TYPE_TAP, @@ -438,24 +440,24 @@ test_onion_queues(void) create_cell_init(create2, CELL_CREATE, ONION_HANDSHAKE_TYPE_NTOR, NTOR_ONIONSKIN_LEN, buf2); - test_eq(0, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP)); - test_eq(0, onion_pending_add(circ1, create1)); + tt_int_op(0,==, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP)); + tt_int_op(0,==, onion_pending_add(circ1, create1)); create1 = NULL; - test_eq(1, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP)); + tt_int_op(1,==, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP)); - test_eq(0, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR)); - test_eq(0, onion_pending_add(circ2, create2)); + tt_int_op(0,==, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR)); + tt_int_op(0,==, onion_pending_add(circ2, create2)); create2 = NULL; - test_eq(1, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR)); + tt_int_op(1,==, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR)); - test_eq_ptr(circ2, onion_next_task(&onionskin)); - test_eq(1, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP)); - test_eq(0, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR)); + tt_ptr_op(circ2,==, onion_next_task(&onionskin)); + tt_int_op(1,==, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP)); + tt_int_op(0,==, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR)); tt_ptr_op(onionskin, ==, create2_ptr); clear_pending_onions(); - test_eq(0, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP)); - test_eq(0, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR)); + tt_int_op(0,==, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP)); + tt_int_op(0,==, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR)); done: circuit_free(TO_CIRCUIT(circ1)); @@ -466,7 +468,7 @@ test_onion_queues(void) } static void -test_circuit_timeout(void) +test_circuit_timeout(void *arg) { /* Plan: * 1. Generate 1000 samples @@ -484,6 +486,7 @@ test_circuit_timeout(void) or_state_t *state=NULL; int i, runs; double close_ms; + (void)arg; circuit_build_times_init(&initial); circuit_build_times_init(&estimate); circuit_build_times_init(&final); @@ -518,11 +521,11 @@ test_circuit_timeout(void) } while (fabs(circuit_build_times_cdf(&initial, timeout0) - circuit_build_times_cdf(&initial, timeout1)) > 0.02); - test_assert(estimate.total_build_times <= CBT_NCIRCUITS_TO_OBSERVE); + tt_assert(estimate.total_build_times <= CBT_NCIRCUITS_TO_OBSERVE); circuit_build_times_update_state(&estimate, state); circuit_build_times_free_timeouts(&final); - test_assert(circuit_build_times_parse_state(&final, state) == 0); + tt_assert(circuit_build_times_parse_state(&final, state) == 0); circuit_build_times_update_alpha(&final); timeout2 = circuit_build_times_calculate_timeout(&final, @@ -532,7 +535,7 @@ test_circuit_timeout(void) log_notice(LD_CIRC, "Timeout2 is %f, Xm is %d", timeout2, final.Xm); /* 5% here because some accuracy is lost due to histogram conversion */ - test_assert(fabs(circuit_build_times_cdf(&initial, timeout0) - + tt_assert(fabs(circuit_build_times_cdf(&initial, timeout0) - circuit_build_times_cdf(&initial, timeout2)) < 0.05); for (runs = 0; runs < 50; runs++) { @@ -555,8 +558,8 @@ test_circuit_timeout(void) CBT_DEFAULT_QUANTILE_CUTOFF/100.0)); } - test_assert(!circuit_build_times_network_check_changed(&estimate)); - test_assert(!circuit_build_times_network_check_changed(&final)); + tt_assert(!circuit_build_times_network_check_changed(&estimate)); + tt_assert(!circuit_build_times_network_check_changed(&final)); /* Reset liveness to be non-live */ final.liveness.network_last_live = 0; @@ -565,27 +568,27 @@ test_circuit_timeout(void) build_times_idx = estimate.build_times_idx; total_build_times = estimate.total_build_times; - test_assert(circuit_build_times_network_check_live(&estimate)); - test_assert(circuit_build_times_network_check_live(&final)); + tt_assert(circuit_build_times_network_check_live(&estimate)); + tt_assert(circuit_build_times_network_check_live(&final)); circuit_build_times_count_close(&estimate, 0, (time_t)(approx_time()-estimate.close_ms/1000.0-1)); circuit_build_times_count_close(&final, 0, (time_t)(approx_time()-final.close_ms/1000.0-1)); - test_assert(!circuit_build_times_network_check_live(&estimate)); - test_assert(!circuit_build_times_network_check_live(&final)); + tt_assert(!circuit_build_times_network_check_live(&estimate)); + tt_assert(!circuit_build_times_network_check_live(&final)); log_info(LD_CIRC, "idx: %d %d, tot: %d %d", build_times_idx, estimate.build_times_idx, total_build_times, estimate.total_build_times); /* Check rollback index. Should match top of loop. */ - test_assert(build_times_idx == estimate.build_times_idx); + tt_assert(build_times_idx == estimate.build_times_idx); // This can fail if estimate.total_build_times == 1000, because // in that case, rewind actually causes us to lose timeouts if (total_build_times != CBT_NCIRCUITS_TO_OBSERVE) - test_assert(total_build_times == estimate.total_build_times); + tt_assert(total_build_times == estimate.total_build_times); /* Now simulate that the network has become live and we need * a change */ @@ -600,12 +603,12 @@ test_circuit_timeout(void) } } - test_assert(estimate.liveness.after_firsthop_idx == 0); - test_assert(final.liveness.after_firsthop_idx == + tt_assert(estimate.liveness.after_firsthop_idx == 0); + tt_assert(final.liveness.after_firsthop_idx == CBT_DEFAULT_MAX_RECENT_TIMEOUT_COUNT-1); - test_assert(circuit_build_times_network_check_live(&estimate)); - test_assert(circuit_build_times_network_check_live(&final)); + tt_assert(circuit_build_times_network_check_live(&estimate)); + tt_assert(circuit_build_times_network_check_live(&final)); circuit_build_times_count_timeout(&final, 1); } @@ -619,7 +622,7 @@ test_circuit_timeout(void) /** Test encoding and parsing of rendezvous service descriptors. */ static void -test_rend_fns(void) +test_rend_fns(void *arg) { rend_service_descriptor_t *generated = NULL, *parsed = NULL; char service_id[DIGEST_LEN]; @@ -642,16 +645,17 @@ test_rend_fns(void) char address6[] = "foo.bar.abcdefghijklmnop.onion"; char address7[] = ".abcdefghijklmnop.onion"; - test_assert(BAD_HOSTNAME == parse_extended_hostname(address1)); - test_assert(ONION_HOSTNAME == parse_extended_hostname(address2)); - test_streq(address2, "aaaaaaaaaaaaaaaa"); - test_assert(EXIT_HOSTNAME == parse_extended_hostname(address3)); - test_assert(NORMAL_HOSTNAME == parse_extended_hostname(address4)); - test_assert(ONION_HOSTNAME == parse_extended_hostname(address5)); - test_streq(address5, "abcdefghijklmnop"); - test_assert(ONION_HOSTNAME == parse_extended_hostname(address6)); - test_streq(address6, "abcdefghijklmnop"); - test_assert(BAD_HOSTNAME == parse_extended_hostname(address7)); + (void)arg; + tt_assert(BAD_HOSTNAME == parse_extended_hostname(address1)); + tt_assert(ONION_HOSTNAME == parse_extended_hostname(address2)); + tt_str_op(address2,==, "aaaaaaaaaaaaaaaa"); + tt_assert(EXIT_HOSTNAME == parse_extended_hostname(address3)); + tt_assert(NORMAL_HOSTNAME == parse_extended_hostname(address4)); + tt_assert(ONION_HOSTNAME == parse_extended_hostname(address5)); + tt_str_op(address5,==, "abcdefghijklmnop"); + tt_assert(ONION_HOSTNAME == parse_extended_hostname(address6)); + tt_str_op(address6,==, "abcdefghijklmnop"); + tt_assert(BAD_HOSTNAME == parse_extended_hostname(address7)); pk1 = pk_generate(0); pk2 = pk_generate(1); @@ -684,40 +688,41 @@ test_rend_fns(void) intro->intro_key = crypto_pk_dup_key(pk2); smartlist_add(generated->intro_nodes, intro); } - test_assert(rend_encode_v2_descriptors(descs, generated, now, 0, + tt_assert(rend_encode_v2_descriptors(descs, generated, now, 0, REND_NO_AUTH, NULL, NULL) > 0); - test_assert(rend_compute_v2_desc_id(computed_desc_id, service_id_base32, + tt_assert(rend_compute_v2_desc_id(computed_desc_id, service_id_base32, NULL, now, 0) == 0); - test_memeq(((rend_encoded_v2_service_descriptor_t *) - smartlist_get(descs, 0))->desc_id, computed_desc_id, DIGEST_LEN); - test_assert(rend_parse_v2_service_descriptor(&parsed, parsed_desc_id, + tt_mem_op(((rend_encoded_v2_service_descriptor_t *) + smartlist_get(descs, 0))->desc_id, ==, + computed_desc_id, DIGEST_LEN); + tt_assert(rend_parse_v2_service_descriptor(&parsed, parsed_desc_id, &intro_points_encrypted, &intro_points_size, &encoded_size, &next_desc, ((rend_encoded_v2_service_descriptor_t *) smartlist_get(descs, 0))->desc_str) == 0); - test_assert(parsed); - test_memeq(((rend_encoded_v2_service_descriptor_t *) - smartlist_get(descs, 0))->desc_id, parsed_desc_id, DIGEST_LEN); - test_eq(rend_parse_introduction_points(parsed, intro_points_encrypted, - intro_points_size), 3); - test_assert(!crypto_pk_cmp_keys(generated->pk, parsed->pk)); - test_eq(parsed->timestamp, now); - test_eq(parsed->version, 2); - test_eq(parsed->protocols, 42); - test_eq(smartlist_len(parsed->intro_nodes), 3); + tt_assert(parsed); + tt_mem_op(((rend_encoded_v2_service_descriptor_t *) + smartlist_get(descs, 0))->desc_id,==, parsed_desc_id, DIGEST_LEN); + tt_int_op(rend_parse_introduction_points(parsed, intro_points_encrypted, + intro_points_size),==, 3); + tt_assert(!crypto_pk_cmp_keys(generated->pk, parsed->pk)); + tt_int_op(parsed->timestamp,==, now); + tt_int_op(parsed->version,==, 2); + tt_int_op(parsed->protocols,==, 42); + tt_int_op(smartlist_len(parsed->intro_nodes),==, 3); for (i = 0; i < smartlist_len(parsed->intro_nodes); i++) { rend_intro_point_t *par_intro = smartlist_get(parsed->intro_nodes, i), *gen_intro = smartlist_get(generated->intro_nodes, i); extend_info_t *par_info = par_intro->extend_info; extend_info_t *gen_info = gen_intro->extend_info; - test_assert(!crypto_pk_cmp_keys(gen_info->onion_key, par_info->onion_key)); - test_memeq(gen_info->identity_digest, par_info->identity_digest, + tt_assert(!crypto_pk_cmp_keys(gen_info->onion_key, par_info->onion_key)); + tt_mem_op(gen_info->identity_digest,==, par_info->identity_digest, DIGEST_LEN); - test_streq(gen_info->nickname, par_info->nickname); - test_assert(tor_addr_eq(&gen_info->addr, &par_info->addr)); - test_eq(gen_info->port, par_info->port); + tt_str_op(gen_info->nickname,==, par_info->nickname); + tt_assert(tor_addr_eq(&gen_info->addr, &par_info->addr)); + tt_int_op(gen_info->port,==, par_info->port); } rend_service_descriptor_free(parsed); @@ -761,17 +766,17 @@ test_rend_fns(void) } while (0) #define CHECK_COUNTRY(country, val) do { \ /* test ipv4 country lookup */ \ - test_streq(country, \ + tt_str_op(country, ==, \ geoip_get_country_name(geoip_get_country_by_ipv4(val))); \ /* test ipv6 country lookup */ \ SET_TEST_IPV6(val); \ - test_streq(country, \ + tt_str_op(country, ==, \ geoip_get_country_name(geoip_get_country_by_ipv6(&in6))); \ } while (0) /** Run unit tests for GeoIP code. */ static void -test_geoip(void) +test_geoip(void *arg) { int i, j; time_t now = 1281533250; /* 2010-08-11 13:27:30 UTC */ @@ -825,23 +830,24 @@ test_geoip(void) /* Populate the DB a bit. Add these in order, since we can't do the final * 'sort' step. These aren't very good IP addresses, but they're perfectly * fine uint32_t values. */ - test_eq(0, geoip_parse_entry("10,50,AB", AF_INET)); - test_eq(0, geoip_parse_entry("52,90,XY", AF_INET)); - test_eq(0, geoip_parse_entry("95,100,AB", AF_INET)); - test_eq(0, geoip_parse_entry("\"105\",\"140\",\"ZZ\"", AF_INET)); - test_eq(0, geoip_parse_entry("\"150\",\"190\",\"XY\"", AF_INET)); - test_eq(0, geoip_parse_entry("\"200\",\"250\",\"AB\"", AF_INET)); + (void)arg; + tt_int_op(0,==, geoip_parse_entry("10,50,AB", AF_INET)); + tt_int_op(0,==, geoip_parse_entry("52,90,XY", AF_INET)); + tt_int_op(0,==, geoip_parse_entry("95,100,AB", AF_INET)); + tt_int_op(0,==, geoip_parse_entry("\"105\",\"140\",\"ZZ\"", AF_INET)); + tt_int_op(0,==, geoip_parse_entry("\"150\",\"190\",\"XY\"", AF_INET)); + tt_int_op(0,==, geoip_parse_entry("\"200\",\"250\",\"AB\"", AF_INET)); /* Populate the IPv6 DB equivalently with fake IPs in the same range */ - test_eq(0, geoip_parse_entry("::a,::32,AB", AF_INET6)); - test_eq(0, geoip_parse_entry("::34,::5a,XY", AF_INET6)); - test_eq(0, geoip_parse_entry("::5f,::64,AB", AF_INET6)); - test_eq(0, geoip_parse_entry("::69,::8c,ZZ", AF_INET6)); - test_eq(0, geoip_parse_entry("::96,::be,XY", AF_INET6)); - test_eq(0, geoip_parse_entry("::c8,::fa,AB", AF_INET6)); + tt_int_op(0,==, geoip_parse_entry("::a,::32,AB", AF_INET6)); + tt_int_op(0,==, geoip_parse_entry("::34,::5a,XY", AF_INET6)); + tt_int_op(0,==, geoip_parse_entry("::5f,::64,AB", AF_INET6)); + tt_int_op(0,==, geoip_parse_entry("::69,::8c,ZZ", AF_INET6)); + tt_int_op(0,==, geoip_parse_entry("::96,::be,XY", AF_INET6)); + tt_int_op(0,==, geoip_parse_entry("::c8,::fa,AB", AF_INET6)); /* We should have 4 countries: ??, ab, xy, zz. */ - test_eq(4, geoip_get_n_countries()); + tt_int_op(4,==, geoip_get_n_countries()); memset(&in6, 0, sizeof(in6)); CHECK_COUNTRY("??", 3); @@ -852,9 +858,9 @@ test_geoip(void) CHECK_COUNTRY("xy", 190); CHECK_COUNTRY("??", 2000); - test_eq(0, geoip_get_country_by_ipv4(3)); + tt_int_op(0,==, geoip_get_country_by_ipv4(3)); SET_TEST_IPV6(3); - test_eq(0, geoip_get_country_by_ipv6(&in6)); + tt_int_op(0,==, geoip_get_country_by_ipv6(&in6)); get_options_mutable()->BridgeRelay = 1; get_options_mutable()->BridgeRecordUsageByCountry = 1; @@ -877,41 +883,41 @@ test_geoip(void) geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, NULL, now); } geoip_get_client_history(GEOIP_CLIENT_CONNECT, &s, &v); - test_assert(s); - test_assert(v); - test_streq("zz=24,ab=16,xy=8", s); - test_streq("v4=16,v6=16", v); + tt_assert(s); + tt_assert(v); + tt_str_op("zz=24,ab=16,xy=8",==, s); + tt_str_op("v4=16,v6=16",==, v); tor_free(s); tor_free(v); /* Now clear out all the AB observations. */ geoip_remove_old_clients(now-6000); geoip_get_client_history(GEOIP_CLIENT_CONNECT, &s, &v); - test_assert(s); - test_assert(v); - test_streq("zz=24,xy=8", s); - test_streq("v4=16,v6=16", v); + tt_assert(s); + tt_assert(v); + tt_str_op("zz=24,xy=8",==, s); + tt_str_op("v4=16,v6=16",==, v); tor_free(s); tor_free(v); /* Start testing bridge statistics by making sure that we don't output * bridge stats without initializing them. */ s = geoip_format_bridge_stats(now + 86400); - test_assert(!s); + tt_assert(!s); /* Initialize stats and generate the bridge-stats history string out of * the connecting clients added above. */ geoip_bridge_stats_init(now); s = geoip_format_bridge_stats(now + 86400); - test_assert(s); - test_streq(bridge_stats_1, s); + tt_assert(s); + tt_str_op(bridge_stats_1,==, s); tor_free(s); /* Stop collecting bridge stats and make sure we don't write a history * string anymore. */ geoip_bridge_stats_term(); s = geoip_format_bridge_stats(now + 86400); - test_assert(!s); + tt_assert(!s); /* Stop being a bridge and start being a directory mirror that gathers * directory request statistics. */ @@ -925,7 +931,7 @@ test_geoip(void) SET_TEST_ADDRESS(100); geoip_note_client_seen(GEOIP_CLIENT_NETWORKSTATUS, &addr, NULL, now); s = geoip_format_dirreq_stats(now + 86400); - test_assert(!s); + tt_assert(!s); /* Initialize stats, note one connecting client, and generate the * dirreq-stats history string. */ @@ -933,7 +939,7 @@ test_geoip(void) SET_TEST_ADDRESS(100); geoip_note_client_seen(GEOIP_CLIENT_NETWORKSTATUS, &addr, NULL, now); s = geoip_format_dirreq_stats(now + 86400); - test_streq(dirreq_stats_1, s); + tt_str_op(dirreq_stats_1,==, s); tor_free(s); /* Stop collecting stats, add another connecting client, and ensure we @@ -942,7 +948,7 @@ test_geoip(void) SET_TEST_ADDRESS(101); geoip_note_client_seen(GEOIP_CLIENT_NETWORKSTATUS, &addr, NULL, now); s = geoip_format_dirreq_stats(now + 86400); - test_assert(!s); + tt_assert(!s); /* Re-start stats, add a connecting client, reset stats, and make sure * that we get an all empty history string. */ @@ -951,20 +957,20 @@ test_geoip(void) geoip_note_client_seen(GEOIP_CLIENT_NETWORKSTATUS, &addr, NULL, now); geoip_reset_dirreq_stats(now); s = geoip_format_dirreq_stats(now + 86400); - test_streq(dirreq_stats_2, s); + tt_str_op(dirreq_stats_2,==, s); tor_free(s); /* Note a successful network status response and make sure that it * appears in the history string. */ geoip_note_ns_response(GEOIP_SUCCESS); s = geoip_format_dirreq_stats(now + 86400); - test_streq(dirreq_stats_3, s); + tt_str_op(dirreq_stats_3,==, s); tor_free(s); /* Start a tunneled directory request. */ geoip_start_dirreq((uint64_t) 1, 1024, DIRREQ_TUNNELED); s = geoip_format_dirreq_stats(now + 86400); - test_streq(dirreq_stats_4, s); + tt_str_op(dirreq_stats_4,==, s); tor_free(s); /* Stop collecting directory request statistics and start gathering @@ -978,7 +984,7 @@ test_geoip(void) SET_TEST_ADDRESS(100); geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, NULL, now); s = geoip_format_entry_stats(now + 86400); - test_assert(!s); + tt_assert(!s); /* Initialize stats, note one connecting client, and generate the * entry-stats history string. */ @@ -986,7 +992,7 @@ test_geoip(void) SET_TEST_ADDRESS(100); geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, NULL, now); s = geoip_format_entry_stats(now + 86400); - test_streq(entry_stats_1, s); + tt_str_op(entry_stats_1,==, s); tor_free(s); /* Stop collecting stats, add another connecting client, and ensure we @@ -995,7 +1001,7 @@ test_geoip(void) SET_TEST_ADDRESS(101); geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, NULL, now); s = geoip_format_entry_stats(now + 86400); - test_assert(!s); + tt_assert(!s); /* Re-start stats, add a connecting client, reset stats, and make sure * that we get an all empty history string. */ @@ -1004,7 +1010,7 @@ test_geoip(void) geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, NULL, now); geoip_reset_entry_stats(now); s = geoip_format_entry_stats(now + 86400); - test_streq(entry_stats_2, s); + tt_str_op(entry_stats_2,==, s); tor_free(s); /* Stop collecting entry statistics. */ @@ -1017,7 +1023,7 @@ test_geoip(void) } static void -test_geoip_with_pt(void) +test_geoip_with_pt(void *arg) { time_t now = 1281533250; /* 2010-08-11 13:27:30 UTC */ char *s = NULL; @@ -1025,6 +1031,7 @@ test_geoip_with_pt(void) tor_addr_t addr; struct in6_addr in6; + (void)arg; get_options_mutable()->BridgeRelay = 1; get_options_mutable()->BridgeRecordUsageByCountry = 1; @@ -1076,7 +1083,7 @@ test_geoip_with_pt(void) /* Test the transport history string. */ s = geoip_get_transport_history(); tor_assert(s); - test_streq(s, "<OR>=8,alpha=16,beta=8,charlie=16,ddr=136," + tt_str_op(s,==, "<OR>=8,alpha=16,beta=8,charlie=16,ddr=136," "entropy=8,fire=8,google=8"); /* Stop collecting entry statistics. */ @@ -1093,7 +1100,7 @@ test_geoip_with_pt(void) /** Run unit tests for stats code. */ static void -test_stats(void) +test_stats(void *arg) { time_t now = 1281533250; /* 2010-08-11 13:27:30 UTC */ char *s = NULL; @@ -1101,10 +1108,11 @@ test_stats(void) /* Start with testing exit port statistics; we shouldn't collect exit * stats without initializing them. */ + (void)arg; rep_hist_note_exit_stream_opened(80); rep_hist_note_exit_bytes(80, 100, 10000); s = rep_hist_format_exit_stats(now + 86400); - test_assert(!s); + tt_assert(!s); /* Initialize stats, note some streams and bytes, and generate history * string. */ @@ -1115,10 +1123,10 @@ test_stats(void) rep_hist_note_exit_bytes(443, 100, 10000); rep_hist_note_exit_bytes(443, 100, 10000); s = rep_hist_format_exit_stats(now + 86400); - test_streq("exit-stats-end 2010-08-12 13:27:30 (86400 s)\n" + tt_str_op("exit-stats-end 2010-08-12 13:27:30 (86400 s)\n" "exit-kibibytes-written 80=1,443=1,other=0\n" "exit-kibibytes-read 80=10,443=20,other=0\n" - "exit-streams-opened 80=4,443=4,other=0\n", s); + "exit-streams-opened 80=4,443=4,other=0\n",==, s); tor_free(s); /* Add a few bytes on 10 more ports and ensure that only the top 10 @@ -1128,13 +1136,13 @@ test_stats(void) rep_hist_note_exit_stream_opened(i); } s = rep_hist_format_exit_stats(now + 86400); - test_streq("exit-stats-end 2010-08-12 13:27:30 (86400 s)\n" + tt_str_op("exit-stats-end 2010-08-12 13:27:30 (86400 s)\n" "exit-kibibytes-written 52=1,53=1,54=1,55=1,56=1,57=1,58=1," "59=1,80=1,443=1,other=1\n" "exit-kibibytes-read 52=1,53=1,54=1,55=1,56=1,57=1,58=1," "59=1,80=10,443=20,other=1\n" "exit-streams-opened 52=4,53=4,54=4,55=4,56=4,57=4,58=4," - "59=4,80=4,443=4,other=4\n", s); + "59=4,80=4,443=4,other=4\n",==, s); tor_free(s); /* Stop collecting stats, add some bytes, and ensure we don't generate @@ -1142,7 +1150,7 @@ test_stats(void) rep_hist_exit_stats_term(); rep_hist_note_exit_bytes(80, 100, 10000); s = rep_hist_format_exit_stats(now + 86400); - test_assert(!s); + tt_assert(!s); /* Re-start stats, add some bytes, reset stats, and see what history we * get when observing no streams or bytes at all. */ @@ -1151,17 +1159,17 @@ test_stats(void) rep_hist_note_exit_bytes(80, 100, 10000); rep_hist_reset_exit_stats(now); s = rep_hist_format_exit_stats(now + 86400); - test_streq("exit-stats-end 2010-08-12 13:27:30 (86400 s)\n" + tt_str_op("exit-stats-end 2010-08-12 13:27:30 (86400 s)\n" "exit-kibibytes-written other=0\n" "exit-kibibytes-read other=0\n" - "exit-streams-opened other=0\n", s); + "exit-streams-opened other=0\n",==, s); tor_free(s); /* Continue with testing connection statistics; we shouldn't collect * conn stats without initializing them. */ rep_hist_note_or_conn_bytes(1, 20, 400, now); s = rep_hist_format_conn_stats(now + 86400); - test_assert(!s); + tt_assert(!s); /* Initialize stats, note bytes, and generate history string. */ rep_hist_conn_stats_init(now); @@ -1170,7 +1178,7 @@ test_stats(void) rep_hist_note_or_conn_bytes(2, 400000, 30000, now + 10); rep_hist_note_or_conn_bytes(2, 400000, 30000, now + 15); s = rep_hist_format_conn_stats(now + 86400); - test_streq("conn-bi-direct 2010-08-12 13:27:30 (86400 s) 0,0,1,0\n", s); + tt_str_op("conn-bi-direct 2010-08-12 13:27:30 (86400 s) 0,0,1,0\n",==, s); tor_free(s); /* Stop collecting stats, add some bytes, and ensure we don't generate @@ -1178,7 +1186,7 @@ test_stats(void) rep_hist_conn_stats_term(); rep_hist_note_or_conn_bytes(2, 400000, 30000, now + 15); s = rep_hist_format_conn_stats(now + 86400); - test_assert(!s); + tt_assert(!s); /* Re-start stats, add some bytes, reset stats, and see what history we * get when observing no bytes at all. */ @@ -1189,26 +1197,26 @@ test_stats(void) rep_hist_note_or_conn_bytes(2, 400000, 30000, now + 15); rep_hist_reset_conn_stats(now); s = rep_hist_format_conn_stats(now + 86400); - test_streq("conn-bi-direct 2010-08-12 13:27:30 (86400 s) 0,0,0,0\n", s); + tt_str_op("conn-bi-direct 2010-08-12 13:27:30 (86400 s) 0,0,0,0\n",==, s); tor_free(s); /* Continue with testing buffer statistics; we shouldn't collect buffer * stats without initializing them. */ rep_hist_add_buffer_stats(2.0, 2.0, 20); s = rep_hist_format_buffer_stats(now + 86400); - test_assert(!s); + tt_assert(!s); /* Initialize stats, add statistics for a single circuit, and generate * the history string. */ rep_hist_buffer_stats_init(now); rep_hist_add_buffer_stats(2.0, 2.0, 20); s = rep_hist_format_buffer_stats(now + 86400); - test_streq("cell-stats-end 2010-08-12 13:27:30 (86400 s)\n" + tt_str_op("cell-stats-end 2010-08-12 13:27:30 (86400 s)\n" "cell-processed-cells 20,0,0,0,0,0,0,0,0,0\n" "cell-queued-cells 2.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00," "0.00,0.00\n" "cell-time-in-queue 2,0,0,0,0,0,0,0,0,0\n" - "cell-circuits-per-decile 1\n", s); + "cell-circuits-per-decile 1\n",==, s); tor_free(s); /* Add nineteen more circuit statistics to the one that's already in the @@ -1218,12 +1226,12 @@ test_stats(void) for (i = 20; i < 30; i++) rep_hist_add_buffer_stats(3.5, 3.5, i); s = rep_hist_format_buffer_stats(now + 86400); - test_streq("cell-stats-end 2010-08-12 13:27:30 (86400 s)\n" + tt_str_op("cell-stats-end 2010-08-12 13:27:30 (86400 s)\n" "cell-processed-cells 29,28,27,26,25,24,23,22,21,20\n" "cell-queued-cells 2.75,2.75,2.75,2.75,2.75,2.75,2.75,2.75," "2.75,2.75\n" "cell-time-in-queue 3,3,3,3,3,3,3,3,3,3\n" - "cell-circuits-per-decile 2\n", s); + "cell-circuits-per-decile 2\n",==, s); tor_free(s); /* Stop collecting stats, add statistics for one circuit, and ensure we @@ -1231,7 +1239,7 @@ test_stats(void) rep_hist_buffer_stats_term(); rep_hist_add_buffer_stats(2.0, 2.0, 20); s = rep_hist_format_buffer_stats(now + 86400); - test_assert(!s); + tt_assert(!s); /* Re-start stats, add statistics for one circuit, reset stats, and make * sure that the history has all zeros. */ @@ -1239,46 +1247,21 @@ test_stats(void) rep_hist_add_buffer_stats(2.0, 2.0, 20); rep_hist_reset_buffer_stats(now); s = rep_hist_format_buffer_stats(now + 86400); - test_streq("cell-stats-end 2010-08-12 13:27:30 (86400 s)\n" + tt_str_op("cell-stats-end 2010-08-12 13:27:30 (86400 s)\n" "cell-processed-cells 0,0,0,0,0,0,0,0,0,0\n" "cell-queued-cells 0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00," "0.00,0.00\n" "cell-time-in-queue 0,0,0,0,0,0,0,0,0,0\n" - "cell-circuits-per-decile 0\n", s); + "cell-circuits-per-decile 0\n",==, s); done: tor_free(s); } -static void * -legacy_test_setup(const struct testcase_t *testcase) -{ - return testcase->setup_data; -} - -void -legacy_test_helper(void *data) -{ - void (*fn)(void) = data; - fn(); -} - -static int -legacy_test_cleanup(const struct testcase_t *testcase, void *ptr) -{ - (void)ptr; - (void)testcase; - return 1; -} - -const struct testcase_setup_t legacy_setup = { - legacy_test_setup, legacy_test_cleanup -}; - #define ENT(name) \ - { #name, legacy_test_helper, 0, &legacy_setup, test_ ## name } + { #name, test_ ## name , 0, NULL, NULL } #define FORK(name) \ - { #name, legacy_test_helper, TT_FORK, &legacy_setup, test_ ## name } + { #name, test_ ## name , TT_FORK, NULL, NULL } static struct testcase_t test_array[] = { ENT(onion_handshake), @@ -1322,6 +1305,7 @@ extern struct testcase_t hs_tests[]; extern struct testcase_t nodelist_tests[]; extern struct testcase_t routerkeys_tests[]; extern struct testcase_t oom_tests[]; +extern struct testcase_t accounting_tests[]; extern struct testcase_t policy_tests[]; extern struct testcase_t status_tests[]; extern struct testcase_t routerset_tests[]; @@ -1354,6 +1338,7 @@ static struct testgroup_t testgroups[] = { { "nodelist/", nodelist_tests }, { "routerkeys/", routerkeys_tests }, { "oom/", oom_tests }, + { "accounting/", accounting_tests }, { "policy/" , policy_tests }, { "status/" , status_tests }, { "routerset/" , routerset_tests }, diff --git a/src/test/test.h b/src/test/test.h index b9e4d5bdb4..8eb2dfc016 100644 --- a/src/test/test.h +++ b/src/test/test.h @@ -22,25 +22,6 @@ #define PRETTY_FUNCTION "" #endif -#define test_fail_msg(msg) TT_DIE((msg)) - -#define test_fail() test_fail_msg("Assertion failed.") - -#define test_assert(expr) tt_assert(expr) - -#define test_eq(expr1, expr2) tt_int_op((expr1), ==, (expr2)) -#define test_eq_ptr(expr1, expr2) tt_ptr_op((expr1), ==, (expr2)) -#define test_neq(expr1, expr2) tt_int_op((expr1), !=, (expr2)) -#define test_neq_ptr(expr1, expr2) tt_ptr_op((expr1), !=, (expr2)) -#define test_streq(expr1, expr2) tt_str_op((expr1), ==, (expr2)) -#define test_strneq(expr1, expr2) tt_str_op((expr1), !=, (expr2)) - -#define test_mem_op(expr1, op, expr2, len) \ - tt_mem_op((expr1), op, (expr2), (len)) - -#define test_memeq(expr1, expr2, len) test_mem_op((expr1), ==, (expr2), len) -#define test_memneq(expr1, expr2, len) test_mem_op((expr1), !=, (expr2), len) - /* As test_mem_op, but decodes 'hex' before comparing. There must be a * local char* variable called mem_op_hex_tmp for this to work. */ #define test_mem_op_hex(expr1, op, hex) \ @@ -50,7 +31,7 @@ mem_op_hex_tmp = tor_malloc(length/2); \ tor_assert((length&1)==0); \ base16_decode(mem_op_hex_tmp, length/2, hex, length); \ - test_mem_op(expr1, op, mem_op_hex_tmp, length/2); \ + tt_mem_op(expr1, op, mem_op_hex_tmp, length/2); \ STMT_END #define test_memeq_hex(expr1, hex) test_mem_op_hex(expr1, ==, hex) @@ -85,9 +66,6 @@ const char *get_fname(const char *name); crypto_pk_t *pk_generate(int idx); -void legacy_test_helper(void *data); -extern const struct testcase_setup_t legacy_setup; - #define US2_CONCAT_2__(a, b) a ## __ ## b #define US_CONCAT_2__(a, b) a ## _ ## b #define US_CONCAT_3__(a, b, c) a ## _ ## b ## _ ## c diff --git a/src/test/test_accounting.c b/src/test/test_accounting.c new file mode 100644 index 0000000000..25908e942c --- /dev/null +++ b/src/test/test_accounting.c @@ -0,0 +1,76 @@ +#include "or.h" +#include "test.h" +#define HIBERNATE_PRIVATE +#include "hibernate.h" +#include "config.h" +#define STATEFILE_PRIVATE +#include "statefile.h" + +#define NS_MODULE accounting + +#define NS_SUBMODULE limits + +/* + * Test to make sure accounting triggers hibernation + * correctly with both sum or max rules set + */ + +static or_state_t *or_state; +NS_DECL(or_state_t *, get_or_state, (void)); +static or_state_t * +NS(get_or_state)(void) +{ + return or_state; +} + +static void +test_accounting_limits(void *arg) +{ + or_options_t *options = get_options_mutable(); + time_t fake_time = time(NULL); + (void) arg; + + NS_MOCK(get_or_state); + or_state = or_state_new(); + + options->AccountingMax = 100; + options->AccountingRule = ACCT_MAX; + + tor_assert(accounting_is_enabled(options)); + configure_accounting(fake_time); + + accounting_add_bytes(10, 0, 1); + fake_time += 1; + consider_hibernation(fake_time); + tor_assert(we_are_hibernating() == 0); + + accounting_add_bytes(90, 0, 1); + fake_time += 1; + consider_hibernation(fake_time); + tor_assert(we_are_hibernating() == 1); + + options->AccountingMax = 200; + options->AccountingRule = ACCT_SUM; + + accounting_add_bytes(0, 10, 1); + fake_time += 1; + consider_hibernation(fake_time); + tor_assert(we_are_hibernating() == 0); + + accounting_add_bytes(0, 90, 1); + fake_time += 1; + consider_hibernation(fake_time); + tor_assert(we_are_hibernating() == 1); + goto done; + done: + NS_UNMOCK(get_or_state); + or_state_free(or_state); +} + +#undef NS_SUBMODULE + +struct testcase_t accounting_tests[] = { + { "bwlimits", test_accounting_limits, TT_FORK, NULL, NULL }, + END_OF_TESTCASES +}; + diff --git a/src/test/test_addr.c b/src/test/test_addr.c index 50011e606b..043c2a0d4a 100644 --- a/src/test/test_addr.c +++ b/src/test/test_addr.c @@ -10,49 +10,50 @@ #include "addressmap.h" static void -test_addr_basic(void) +test_addr_basic(void *arg) { uint32_t u32; uint16_t u16; char *cp; /* Test addr_port_lookup */ + (void)arg; cp = NULL; u32 = 3; u16 = 3; - test_assert(!addr_port_lookup(LOG_WARN, "1.2.3.4", &cp, &u32, &u16)); - test_streq(cp, "1.2.3.4"); - test_eq(u32, 0x01020304u); - test_eq(u16, 0); + tt_assert(!addr_port_lookup(LOG_WARN, "1.2.3.4", &cp, &u32, &u16)); + tt_str_op(cp,==, "1.2.3.4"); + tt_int_op(u32,==, 0x01020304u); + tt_int_op(u16,==, 0); tor_free(cp); - test_assert(!addr_port_lookup(LOG_WARN, "4.3.2.1:99", &cp, &u32, &u16)); - test_streq(cp, "4.3.2.1"); - test_eq(u32, 0x04030201u); - test_eq(u16, 99); + tt_assert(!addr_port_lookup(LOG_WARN, "4.3.2.1:99", &cp, &u32, &u16)); + tt_str_op(cp,==, "4.3.2.1"); + tt_int_op(u32,==, 0x04030201u); + tt_int_op(u16,==, 99); tor_free(cp); - test_assert(!addr_port_lookup(LOG_WARN, "nonexistent.address:4040", + tt_assert(!addr_port_lookup(LOG_WARN, "nonexistent.address:4040", &cp, NULL, &u16)); - test_streq(cp, "nonexistent.address"); - test_eq(u16, 4040); + tt_str_op(cp,==, "nonexistent.address"); + tt_int_op(u16,==, 4040); tor_free(cp); - test_assert(!addr_port_lookup(LOG_WARN, "localhost:9999", &cp, &u32, &u16)); - test_streq(cp, "localhost"); - test_eq(u32, 0x7f000001u); - test_eq(u16, 9999); + tt_assert(!addr_port_lookup(LOG_WARN, "localhost:9999", &cp, &u32, &u16)); + tt_str_op(cp,==, "localhost"); + tt_int_op(u32,==, 0x7f000001u); + tt_int_op(u16,==, 9999); tor_free(cp); u32 = 3; - test_assert(!addr_port_lookup(LOG_WARN, "localhost", NULL, &u32, &u16)); - test_eq_ptr(cp, NULL); - test_eq(u32, 0x7f000001u); - test_eq(u16, 0); + tt_assert(!addr_port_lookup(LOG_WARN, "localhost", NULL, &u32, &u16)); + tt_ptr_op(cp,==, NULL); + tt_int_op(u32,==, 0x7f000001u); + tt_int_op(u16,==, 0); tor_free(cp); - test_assert(addr_port_lookup(LOG_WARN, "localhost:3", &cp, &u32, NULL)); + tt_assert(addr_port_lookup(LOG_WARN, "localhost:3", &cp, &u32, NULL)); tor_free(cp); - test_eq(0, addr_mask_get_bits(0x0u)); - test_eq(32, addr_mask_get_bits(0xFFFFFFFFu)); - test_eq(16, addr_mask_get_bits(0xFFFF0000u)); - test_eq(31, addr_mask_get_bits(0xFFFFFFFEu)); - test_eq(1, addr_mask_get_bits(0x80000000u)); + tt_int_op(0,==, addr_mask_get_bits(0x0u)); + tt_int_op(32,==, addr_mask_get_bits(0xFFFFFFFFu)); + tt_int_op(16,==, addr_mask_get_bits(0xFFFF0000u)); + tt_int_op(31,==, addr_mask_get_bits(0xFFFFFFFEu)); + tt_int_op(1,==, addr_mask_get_bits(0x80000000u)); /* Test inet_ntop */ { @@ -61,15 +62,15 @@ test_addr_basic(void) struct in_addr in; /* good round trip */ - test_eq(tor_inet_pton(AF_INET, ip, &in), 1); - test_eq_ptr(tor_inet_ntop(AF_INET, &in, tmpbuf, sizeof(tmpbuf)), &tmpbuf); - test_streq(tmpbuf, ip); + tt_int_op(tor_inet_pton(AF_INET, ip, &in),==, 1); + tt_ptr_op(tor_inet_ntop(AF_INET, &in, tmpbuf, sizeof(tmpbuf)),==, &tmpbuf); + tt_str_op(tmpbuf,==, ip); /* just enough buffer length */ - test_streq(tor_inet_ntop(AF_INET, &in, tmpbuf, strlen(ip) + 1), ip); + tt_str_op(tor_inet_ntop(AF_INET, &in, tmpbuf, strlen(ip) + 1),==, ip); /* too short buffer */ - test_eq_ptr(tor_inet_ntop(AF_INET, &in, tmpbuf, strlen(ip)), NULL); + tt_ptr_op(tor_inet_ntop(AF_INET, &in, tmpbuf, strlen(ip)),==, NULL); } done: @@ -96,67 +97,68 @@ test_addr_basic(void) /** Helper: Assert that two strings both decode as IPv6 addresses with * tor_inet_pton(), and both decode to the same address. */ -#define test_pton6_same(a,b) STMT_BEGIN \ - test_eq(tor_inet_pton(AF_INET6, a, &a1), 1); \ - test_eq(tor_inet_pton(AF_INET6, b, &a2), 1); \ - test_op_ip6_(&a1,==,&a2,#a,#b); \ +#define test_pton6_same(a,b) STMT_BEGIN \ + tt_int_op(tor_inet_pton(AF_INET6, a, &a1), ==, 1); \ + tt_int_op(tor_inet_pton(AF_INET6, b, &a2), ==, 1); \ + test_op_ip6_(&a1,==,&a2,#a,#b); \ STMT_END /** Helper: Assert that <b>a</b> is recognized as a bad IPv6 address by * tor_inet_pton(). */ #define test_pton6_bad(a) \ - test_eq(0, tor_inet_pton(AF_INET6, a, &a1)) + tt_int_op(0, ==, tor_inet_pton(AF_INET6, a, &a1)) /** Helper: assert that <b>a</b>, when parsed by tor_inet_pton() and displayed * with tor_inet_ntop(), yields <b>b</b>. Also assert that <b>b</b> parses to * the same value as <b>a</b>. */ -#define test_ntop6_reduces(a,b) STMT_BEGIN \ - test_eq(tor_inet_pton(AF_INET6, a, &a1), 1); \ - test_streq(tor_inet_ntop(AF_INET6, &a1, buf, sizeof(buf)), b); \ - test_eq(tor_inet_pton(AF_INET6, b, &a2), 1); \ - test_op_ip6_(&a1, ==, &a2, a, b); \ +#define test_ntop6_reduces(a,b) STMT_BEGIN \ + tt_int_op(tor_inet_pton(AF_INET6, a, &a1), ==, 1); \ + tt_str_op(tor_inet_ntop(AF_INET6, &a1, buf, sizeof(buf)), ==, b); \ + tt_int_op(tor_inet_pton(AF_INET6, b, &a2), ==, 1); \ + test_op_ip6_(&a1, ==, &a2, a, b); \ STMT_END /** Helper: assert that <b>a</b> parses by tor_inet_pton() into a address that * passes tor_addr_is_internal() with <b>for_listening</b>. */ #define test_internal_ip(a,for_listening) STMT_BEGIN \ - test_eq(tor_inet_pton(AF_INET6, a, &t1.addr.in6_addr), 1); \ + tt_int_op(tor_inet_pton(AF_INET6, a, &t1.addr.in6_addr), ==, 1); \ t1.family = AF_INET6; \ if (!tor_addr_is_internal(&t1, for_listening)) \ - test_fail_msg( a "was not internal."); \ + TT_DIE(("%s was not internal", a)); \ STMT_END /** Helper: assert that <b>a</b> parses by tor_inet_pton() into a address that * does not pass tor_addr_is_internal() with <b>for_listening</b>. */ #define test_external_ip(a,for_listening) STMT_BEGIN \ - test_eq(tor_inet_pton(AF_INET6, a, &t1.addr.in6_addr), 1); \ + tt_int_op(tor_inet_pton(AF_INET6, a, &t1.addr.in6_addr), ==, 1); \ t1.family = AF_INET6; \ if (tor_addr_is_internal(&t1, for_listening)) \ - test_fail_msg(a "was not external."); \ + TT_DIE(("%s was not internal", a)); \ STMT_END /** Helper: Assert that <b>a</b> and <b>b</b>, when parsed by * tor_inet_pton(), give addresses that compare in the order defined by * <b>op</b> with tor_addr_compare(). */ #define test_addr_compare(a, op, b) STMT_BEGIN \ - test_eq(tor_inet_pton(AF_INET6, a, &t1.addr.in6_addr), 1); \ - test_eq(tor_inet_pton(AF_INET6, b, &t2.addr.in6_addr), 1); \ + tt_int_op(tor_inet_pton(AF_INET6, a, &t1.addr.in6_addr), ==, 1); \ + tt_int_op(tor_inet_pton(AF_INET6, b, &t2.addr.in6_addr), ==, 1); \ t1.family = t2.family = AF_INET6; \ r = tor_addr_compare(&t1,&t2,CMP_SEMANTIC); \ if (!(r op 0)) \ - test_fail_msg("failed: tor_addr_compare("a","b") "#op" 0"); \ + TT_DIE(("Failed: tor_addr_compare(%s,%s) %s 0", a, b, #op));\ STMT_END /** Helper: Assert that <b>a</b> and <b>b</b>, when parsed by * tor_inet_pton(), give addresses that compare in the order defined by * <b>op</b> with tor_addr_compare_masked() with <b>m</b> masked. */ #define test_addr_compare_masked(a, op, b, m) STMT_BEGIN \ - test_eq(tor_inet_pton(AF_INET6, a, &t1.addr.in6_addr), 1); \ - test_eq(tor_inet_pton(AF_INET6, b, &t2.addr.in6_addr), 1); \ + tt_int_op(tor_inet_pton(AF_INET6, a, &t1.addr.in6_addr), ==, 1); \ + tt_int_op(tor_inet_pton(AF_INET6, b, &t2.addr.in6_addr), ==, 1); \ t1.family = t2.family = AF_INET6; \ r = tor_addr_compare_masked(&t1,&t2,m,CMP_SEMANTIC); \ if (!(r op 0)) \ - test_fail_msg("failed: tor_addr_compare_masked("a","b","#m") "#op" 0"); \ + TT_DIE(("Failed: tor_addr_compare_masked(%s,%s,%d) %s 0", \ + a, b, m, #op)); \ STMT_END /** Helper: assert that <b>xx</b> is parseable as a masked IPv6 address with @@ -165,21 +167,21 @@ test_addr_basic(void) * as <b>pt1..pt2</b>. */ #define test_addr_mask_ports_parse(xx, f, ip1, ip2, ip3, ip4, mm, pt1, pt2) \ STMT_BEGIN \ - test_eq(tor_addr_parse_mask_ports(xx, 0, &t1, &mask, &port1, &port2), \ - f); \ + tt_int_op(tor_addr_parse_mask_ports(xx, 0, &t1, &mask, &port1, &port2), \ + ==, f); \ p1=tor_inet_ntop(AF_INET6, &t1.addr.in6_addr, bug, sizeof(bug)); \ - test_eq(htonl(ip1), tor_addr_to_in6_addr32(&t1)[0]); \ - test_eq(htonl(ip2), tor_addr_to_in6_addr32(&t1)[1]); \ - test_eq(htonl(ip3), tor_addr_to_in6_addr32(&t1)[2]); \ - test_eq(htonl(ip4), tor_addr_to_in6_addr32(&t1)[3]); \ - test_eq(mask, mm); \ - test_eq(port1, pt1); \ - test_eq(port2, pt2); \ + tt_int_op(htonl(ip1), ==, tor_addr_to_in6_addr32(&t1)[0]); \ + tt_int_op(htonl(ip2), ==, tor_addr_to_in6_addr32(&t1)[1]); \ + tt_int_op(htonl(ip3), ==, tor_addr_to_in6_addr32(&t1)[2]); \ + tt_int_op(htonl(ip4), ==, tor_addr_to_in6_addr32(&t1)[3]); \ + tt_int_op(mask, ==, mm); \ + tt_uint_op(port1, ==, pt1); \ + tt_uint_op(port2, ==, pt2); \ STMT_END /** Run unit tests for IPv6 encoding/decoding/manipulation functions. */ static void -test_addr_ip6_helpers(void) +test_addr_ip6_helpers(void *arg) { char buf[TOR_ADDR_BUF_LEN], bug[TOR_ADDR_BUF_LEN]; char rbuf[REVERSE_LOOKUP_NAME_BUF_LEN]; @@ -194,28 +196,29 @@ test_addr_ip6_helpers(void) struct sockaddr_in6 *sin6; /* Test tor_inet_ntop and tor_inet_pton: IPv6 */ + (void)arg; { const char *ip = "2001::1234"; const char *ip_ffff = "::ffff:192.168.1.2"; /* good round trip */ - test_eq(tor_inet_pton(AF_INET6, ip, &a1), 1); - test_eq_ptr(tor_inet_ntop(AF_INET6, &a1, buf, sizeof(buf)), &buf); - test_streq(buf, ip); + tt_int_op(tor_inet_pton(AF_INET6, ip, &a1),==, 1); + tt_ptr_op(tor_inet_ntop(AF_INET6, &a1, buf, sizeof(buf)),==, &buf); + tt_str_op(buf,==, ip); /* good round trip - ::ffff:0:0 style */ - test_eq(tor_inet_pton(AF_INET6, ip_ffff, &a2), 1); - test_eq_ptr(tor_inet_ntop(AF_INET6, &a2, buf, sizeof(buf)), &buf); - test_streq(buf, ip_ffff); + tt_int_op(tor_inet_pton(AF_INET6, ip_ffff, &a2),==, 1); + tt_ptr_op(tor_inet_ntop(AF_INET6, &a2, buf, sizeof(buf)),==, &buf); + tt_str_op(buf,==, ip_ffff); /* just long enough buffer (remember \0) */ - test_streq(tor_inet_ntop(AF_INET6, &a1, buf, strlen(ip)+1), ip); - test_streq(tor_inet_ntop(AF_INET6, &a2, buf, strlen(ip_ffff)+1), + tt_str_op(tor_inet_ntop(AF_INET6, &a1, buf, strlen(ip)+1),==, ip); + tt_str_op(tor_inet_ntop(AF_INET6, &a2, buf, strlen(ip_ffff)+1),==, ip_ffff); /* too short buffer (remember \0) */ - test_eq_ptr(tor_inet_ntop(AF_INET6, &a1, buf, strlen(ip)), NULL); - test_eq_ptr(tor_inet_ntop(AF_INET6, &a2, buf, strlen(ip_ffff)), NULL); + tt_ptr_op(tor_inet_ntop(AF_INET6, &a1, buf, strlen(ip)),==, NULL); + tt_ptr_op(tor_inet_ntop(AF_INET6, &a2, buf, strlen(ip_ffff)),==, NULL); } /* ==== Converting to and from sockaddr_t. */ @@ -224,16 +227,16 @@ test_addr_ip6_helpers(void) sin->sin_port = htons(9090); sin->sin_addr.s_addr = htonl(0x7f7f0102); /*127.127.1.2*/ tor_addr_from_sockaddr(&t1, (struct sockaddr *)sin, &port1); - test_eq(tor_addr_family(&t1), AF_INET); - test_eq(tor_addr_to_ipv4h(&t1), 0x7f7f0102); + tt_int_op(tor_addr_family(&t1),==, AF_INET); + tt_int_op(tor_addr_to_ipv4h(&t1),==, 0x7f7f0102); tt_int_op(port1, ==, 9090); memset(&sa_storage, 0, sizeof(sa_storage)); - test_eq(sizeof(struct sockaddr_in), + tt_int_op(sizeof(struct sockaddr_in),==, tor_addr_to_sockaddr(&t1, 1234, (struct sockaddr *)&sa_storage, sizeof(sa_storage))); - test_eq(1234, ntohs(sin->sin_port)); - test_eq(0x7f7f0102, ntohl(sin->sin_addr.s_addr)); + tt_int_op(1234,==, ntohs(sin->sin_port)); + tt_int_op(0x7f7f0102,==, ntohl(sin->sin_addr.s_addr)); memset(&sa_storage, 0, sizeof(sa_storage)); sin6 = (struct sockaddr_in6 *)&sa_storage; @@ -241,37 +244,37 @@ test_addr_ip6_helpers(void) sin6->sin6_port = htons(7070); sin6->sin6_addr.s6_addr[0] = 128; tor_addr_from_sockaddr(&t1, (struct sockaddr *)sin6, &port1); - test_eq(tor_addr_family(&t1), AF_INET6); + tt_int_op(tor_addr_family(&t1),==, AF_INET6); tt_int_op(port1, ==, 7070); p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 0); - test_streq(p1, "8000::"); + tt_str_op(p1,==, "8000::"); memset(&sa_storage, 0, sizeof(sa_storage)); - test_eq(sizeof(struct sockaddr_in6), + tt_int_op(sizeof(struct sockaddr_in6),==, tor_addr_to_sockaddr(&t1, 9999, (struct sockaddr *)&sa_storage, sizeof(sa_storage))); - test_eq(AF_INET6, sin6->sin6_family); - test_eq(9999, ntohs(sin6->sin6_port)); - test_eq(0x80000000, ntohl(S6_ADDR32(sin6->sin6_addr)[0])); + tt_int_op(AF_INET6,==, sin6->sin6_family); + tt_int_op(9999,==, ntohs(sin6->sin6_port)); + tt_int_op(0x80000000,==, ntohl(S6_ADDR32(sin6->sin6_addr)[0])); /* ==== tor_addr_lookup: static cases. (Can't test dns without knowing we * have a good resolver. */ - test_eq(0, tor_addr_lookup("127.128.129.130", AF_UNSPEC, &t1)); - test_eq(AF_INET, tor_addr_family(&t1)); - test_eq(tor_addr_to_ipv4h(&t1), 0x7f808182); + tt_int_op(0,==, tor_addr_lookup("127.128.129.130", AF_UNSPEC, &t1)); + tt_int_op(AF_INET,==, tor_addr_family(&t1)); + tt_int_op(tor_addr_to_ipv4h(&t1),==, 0x7f808182); - test_eq(0, tor_addr_lookup("9000::5", AF_UNSPEC, &t1)); - test_eq(AF_INET6, tor_addr_family(&t1)); - test_eq(0x90, tor_addr_to_in6_addr8(&t1)[0]); - test_assert(tor_mem_is_zero((char*)tor_addr_to_in6_addr8(&t1)+1, 14)); - test_eq(0x05, tor_addr_to_in6_addr8(&t1)[15]); + tt_int_op(0,==, tor_addr_lookup("9000::5", AF_UNSPEC, &t1)); + tt_int_op(AF_INET6,==, tor_addr_family(&t1)); + tt_int_op(0x90,==, tor_addr_to_in6_addr8(&t1)[0]); + tt_assert(tor_mem_is_zero((char*)tor_addr_to_in6_addr8(&t1)+1, 14)); + tt_int_op(0x05,==, tor_addr_to_in6_addr8(&t1)[15]); /* === Test pton: valid af_inet6 */ /* Simple, valid parsing. */ r = tor_inet_pton(AF_INET6, "0102:0304:0506:0708:090A:0B0C:0D0E:0F10", &a1); - test_assert(r==1); - for (i=0;i<16;++i) { test_eq(i+1, (int)a1.s6_addr[i]); } + tt_int_op(r, ==, 1); + for (i=0;i<16;++i) { tt_int_op(i+1,==, (int)a1.s6_addr[i]); } /* ipv4 ending. */ test_pton6_same("0102:0304:0506:0708:090A:0B0C:0D0E:0F10", "0102:0304:0506:0708:090A:0B0C:13.14.15.16"); @@ -311,7 +314,7 @@ test_addr_ip6_helpers(void) "1000:1:0:7::"); /* Bad af param */ - test_eq(tor_inet_pton(AF_UNSPEC, 0, 0), -1); + tt_int_op(tor_inet_pton(AF_UNSPEC, 0, 0),==, -1); /* === Test pton: invalid in6. */ test_pton6_bad("foobar."); @@ -414,10 +417,10 @@ test_addr_ip6_helpers(void) test_addr_compare("0::ffff:5.2.2.1", <, "::ffff:6.0.0.0"); /* XXXX wrong. */ tor_addr_parse_mask_ports("[::ffff:2.3.4.5]", 0, &t1, NULL, NULL, NULL); tor_addr_parse_mask_ports("2.3.4.5", 0, &t2, NULL, NULL, NULL); - test_assert(tor_addr_compare(&t1, &t2, CMP_SEMANTIC) == 0); + tt_assert(tor_addr_compare(&t1, &t2, CMP_SEMANTIC) == 0); tor_addr_parse_mask_ports("[::ffff:2.3.4.4]", 0, &t1, NULL, NULL, NULL); tor_addr_parse_mask_ports("2.3.4.5", 0, &t2, NULL, NULL, NULL); - test_assert(tor_addr_compare(&t1, &t2, CMP_SEMANTIC) < 0); + tt_assert(tor_addr_compare(&t1, &t2, CMP_SEMANTIC) < 0); /* test compare_masked */ test_addr_compare_masked("ffff::", ==, "ffff::0", 128); @@ -426,113 +429,113 @@ test_addr_ip6_helpers(void) test_addr_compare_masked("0::2:2:1", ==, "0::8000:2:1", 80); /* Test undecorated tor_addr_to_str */ - test_eq(AF_INET6, tor_addr_parse(&t1, "[123:45:6789::5005:11]")); + tt_int_op(AF_INET6,==, tor_addr_parse(&t1, "[123:45:6789::5005:11]")); p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 0); - test_streq(p1, "123:45:6789::5005:11"); - test_eq(AF_INET, tor_addr_parse(&t1, "18.0.0.1")); + tt_str_op(p1,==, "123:45:6789::5005:11"); + tt_int_op(AF_INET,==, tor_addr_parse(&t1, "18.0.0.1")); p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 0); - test_streq(p1, "18.0.0.1"); + tt_str_op(p1,==, "18.0.0.1"); /* Test decorated tor_addr_to_str */ - test_eq(AF_INET6, tor_addr_parse(&t1, "[123:45:6789::5005:11]")); + tt_int_op(AF_INET6,==, tor_addr_parse(&t1, "[123:45:6789::5005:11]")); p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1); - test_streq(p1, "[123:45:6789::5005:11]"); - test_eq(AF_INET, tor_addr_parse(&t1, "18.0.0.1")); + tt_str_op(p1,==, "[123:45:6789::5005:11]"); + tt_int_op(AF_INET,==, tor_addr_parse(&t1, "18.0.0.1")); p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1); - test_streq(p1, "18.0.0.1"); + tt_str_op(p1,==, "18.0.0.1"); /* Test buffer bounds checking of tor_addr_to_str */ - test_eq(AF_INET6, tor_addr_parse(&t1, "::")); /* 2 + \0 */ - test_eq_ptr(tor_addr_to_str(buf, &t1, 2, 0), NULL); /* too short buf */ - test_streq(tor_addr_to_str(buf, &t1, 3, 0), "::"); - test_eq_ptr(tor_addr_to_str(buf, &t1, 4, 1), NULL); /* too short buf */ - test_streq(tor_addr_to_str(buf, &t1, 5, 1), "[::]"); - - test_eq(AF_INET6, tor_addr_parse(&t1, "2000::1337")); /* 10 + \0 */ - test_eq_ptr(tor_addr_to_str(buf, &t1, 10, 0), NULL); /* too short buf */ - test_streq(tor_addr_to_str(buf, &t1, 11, 0), "2000::1337"); - test_eq_ptr(tor_addr_to_str(buf, &t1, 12, 1), NULL); /* too short buf */ - test_streq(tor_addr_to_str(buf, &t1, 13, 1), "[2000::1337]"); - - test_eq(AF_INET, tor_addr_parse(&t1, "1.2.3.4")); /* 7 + \0 */ - test_eq_ptr(tor_addr_to_str(buf, &t1, 7, 0), NULL); /* too short buf */ - test_streq(tor_addr_to_str(buf, &t1, 8, 0), "1.2.3.4"); - - test_eq(AF_INET, tor_addr_parse(&t1, "255.255.255.255")); /* 15 + \0 */ - test_eq_ptr(tor_addr_to_str(buf, &t1, 15, 0), NULL); /* too short buf */ - test_streq(tor_addr_to_str(buf, &t1, 16, 0), "255.255.255.255"); - test_eq_ptr(tor_addr_to_str(buf, &t1, 15, 1), NULL); /* too short buf */ - test_streq(tor_addr_to_str(buf, &t1, 16, 1), "255.255.255.255"); + tt_int_op(AF_INET6,==, tor_addr_parse(&t1, "::")); /* 2 + \0 */ + tt_ptr_op(tor_addr_to_str(buf, &t1, 2, 0),==, NULL); /* too short buf */ + tt_str_op(tor_addr_to_str(buf, &t1, 3, 0),==, "::"); + tt_ptr_op(tor_addr_to_str(buf, &t1, 4, 1),==, NULL); /* too short buf */ + tt_str_op(tor_addr_to_str(buf, &t1, 5, 1),==, "[::]"); + + tt_int_op(AF_INET6,==, tor_addr_parse(&t1, "2000::1337")); /* 10 + \0 */ + tt_ptr_op(tor_addr_to_str(buf, &t1, 10, 0),==, NULL); /* too short buf */ + tt_str_op(tor_addr_to_str(buf, &t1, 11, 0),==, "2000::1337"); + tt_ptr_op(tor_addr_to_str(buf, &t1, 12, 1),==, NULL); /* too short buf */ + tt_str_op(tor_addr_to_str(buf, &t1, 13, 1),==, "[2000::1337]"); + + tt_int_op(AF_INET,==, tor_addr_parse(&t1, "1.2.3.4")); /* 7 + \0 */ + tt_ptr_op(tor_addr_to_str(buf, &t1, 7, 0),==, NULL); /* too short buf */ + tt_str_op(tor_addr_to_str(buf, &t1, 8, 0),==, "1.2.3.4"); + + tt_int_op(AF_INET,==, tor_addr_parse(&t1, "255.255.255.255")); /* 15 + \0 */ + tt_ptr_op(tor_addr_to_str(buf, &t1, 15, 0),==, NULL); /* too short buf */ + tt_str_op(tor_addr_to_str(buf, &t1, 16, 0),==, "255.255.255.255"); + tt_ptr_op(tor_addr_to_str(buf, &t1, 15, 1),==, NULL); /* too short buf */ + tt_str_op(tor_addr_to_str(buf, &t1, 16, 1),==, "255.255.255.255"); t1.family = AF_UNSPEC; - test_eq_ptr(tor_addr_to_str(buf, &t1, sizeof(buf), 0), NULL); + tt_ptr_op(tor_addr_to_str(buf, &t1, sizeof(buf), 0),==, NULL); /* Test tor_addr_parse_PTR_name */ i = tor_addr_parse_PTR_name(&t1, "Foobar.baz", AF_UNSPEC, 0); - test_eq(0, i); + tt_int_op(0,==, i); i = tor_addr_parse_PTR_name(&t1, "Foobar.baz", AF_UNSPEC, 1); - test_eq(0, i); + tt_int_op(0,==, i); i = tor_addr_parse_PTR_name(&t1, "9999999999999999999999999999.in-addr.arpa", AF_UNSPEC, 1); - test_eq(-1, i); + tt_int_op(-1,==, i); i = tor_addr_parse_PTR_name(&t1, "1.0.168.192.in-addr.arpa", AF_UNSPEC, 1); - test_eq(1, i); - test_eq(tor_addr_family(&t1), AF_INET); + tt_int_op(1,==, i); + tt_int_op(tor_addr_family(&t1),==, AF_INET); p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1); - test_streq(p1, "192.168.0.1"); + tt_str_op(p1,==, "192.168.0.1"); i = tor_addr_parse_PTR_name(&t1, "192.168.0.99", AF_UNSPEC, 0); - test_eq(0, i); + tt_int_op(0,==, i); i = tor_addr_parse_PTR_name(&t1, "192.168.0.99", AF_UNSPEC, 1); - test_eq(1, i); + tt_int_op(1,==, i); p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1); - test_streq(p1, "192.168.0.99"); + tt_str_op(p1,==, "192.168.0.99"); memset(&t1, 0, sizeof(t1)); i = tor_addr_parse_PTR_name(&t1, "0.1.2.3.4.5.6.7.8.9.a.b.c.d.e.f." "f.e.e.b.1.e.b.e.e.f.f.e.e.e.d.9." "ip6.ARPA", AF_UNSPEC, 0); - test_eq(1, i); + tt_int_op(1,==, i); p1 = tor_addr_to_str(buf, &t1, sizeof(buf), 1); - test_streq(p1, "[9dee:effe:ebe1:beef:fedc:ba98:7654:3210]"); + tt_str_op(p1,==, "[9dee:effe:ebe1:beef:fedc:ba98:7654:3210]"); /* Failing cases. */ i = tor_addr_parse_PTR_name(&t1, "6.7.8.9.a.b.c.d.e.f." "f.e.e.b.1.e.b.e.e.f.f.e.e.e.d.9." "ip6.ARPA", AF_UNSPEC, 0); - test_eq(i, -1); + tt_int_op(i,==, -1); i = tor_addr_parse_PTR_name(&t1, "6.7.8.9.a.b.c.d.e.f.a.b.c.d.e.f.0." "f.e.e.b.1.e.b.e.e.f.f.e.e.e.d.9." "ip6.ARPA", AF_UNSPEC, 0); - test_eq(i, -1); + tt_int_op(i,==, -1); i = tor_addr_parse_PTR_name(&t1, "6.7.8.9.a.b.c.d.e.f.X.0.0.0.0.9." "f.e.e.b.1.e.b.e.e.f.f.e.e.e.d.9." "ip6.ARPA", AF_UNSPEC, 0); - test_eq(i, -1); + tt_int_op(i,==, -1); i = tor_addr_parse_PTR_name(&t1, "32.1.1.in-addr.arpa", AF_UNSPEC, 0); - test_eq(i, -1); + tt_int_op(i,==, -1); i = tor_addr_parse_PTR_name(&t1, ".in-addr.arpa", AF_UNSPEC, 0); - test_eq(i, -1); + tt_int_op(i,==, -1); i = tor_addr_parse_PTR_name(&t1, "1.2.3.4.5.in-addr.arpa", AF_UNSPEC, 0); - test_eq(i, -1); + tt_int_op(i,==, -1); i = tor_addr_parse_PTR_name(&t1, "1.2.3.4.5.in-addr.arpa", AF_INET6, 0); - test_eq(i, -1); + tt_int_op(i,==, -1); i = tor_addr_parse_PTR_name(&t1, "6.7.8.9.a.b.c.d.e.f.a.b.c.d.e.0." "f.e.e.b.1.e.b.e.e.f.f.e.e.e.d.9." "ip6.ARPA", AF_INET, 0); - test_eq(i, -1); + tt_int_op(i,==, -1); /* === Test tor_addr_to_PTR_name */ @@ -544,19 +547,19 @@ test_addr_ip6_helpers(void) tor_addr_from_sockaddr(&t1, (struct sockaddr *)sin, NULL); /* Check IPv4 PTR - too short buffer */ - test_eq(tor_addr_to_PTR_name(rbuf, 1, &t1), -1); - test_eq(tor_addr_to_PTR_name(rbuf, + tt_int_op(tor_addr_to_PTR_name(rbuf, 1, &t1),==, -1); + tt_int_op(tor_addr_to_PTR_name(rbuf, strlen("3.2.1.127.in-addr.arpa") - 1, - &t1), -1); + &t1),==, -1); /* Check IPv4 PTR - valid addr */ - test_eq(tor_addr_to_PTR_name(rbuf, sizeof(rbuf), &t1), + tt_int_op(tor_addr_to_PTR_name(rbuf, sizeof(rbuf), &t1),==, strlen("3.2.1.127.in-addr.arpa")); - test_streq(rbuf, "3.2.1.127.in-addr.arpa"); + tt_str_op(rbuf,==, "3.2.1.127.in-addr.arpa"); /* Invalid addr family */ t1.family = AF_UNSPEC; - test_eq(tor_addr_to_PTR_name(rbuf, sizeof(rbuf), &t1), -1); + tt_int_op(tor_addr_to_PTR_name(rbuf, sizeof(rbuf), &t1),==, -1); /* Stage IPv6 addr */ memset(&sa_storage, 0, sizeof(sa_storage)); @@ -573,114 +576,114 @@ test_addr_ip6_helpers(void) "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.ip6.arpa"; /* Check IPv6 PTR - too short buffer */ - test_eq(tor_addr_to_PTR_name(rbuf, 0, &t1), -1); - test_eq(tor_addr_to_PTR_name(rbuf, strlen(addr_PTR) - 1, &t1), -1); + tt_int_op(tor_addr_to_PTR_name(rbuf, 0, &t1),==, -1); + tt_int_op(tor_addr_to_PTR_name(rbuf, strlen(addr_PTR) - 1, &t1),==, -1); /* Check IPv6 PTR - valid addr */ - test_eq(tor_addr_to_PTR_name(rbuf, sizeof(rbuf), &t1), + tt_int_op(tor_addr_to_PTR_name(rbuf, sizeof(rbuf), &t1),==, strlen(addr_PTR)); - test_streq(rbuf, addr_PTR); + tt_str_op(rbuf,==, addr_PTR); } /* XXXX turn this into a separate function; it's not all IPv6. */ /* test tor_addr_parse_mask_ports */ test_addr_mask_ports_parse("[::f]/17:47-95", AF_INET6, 0, 0, 0, 0x0000000f, 17, 47, 95); - test_streq(p1, "::f"); + tt_str_op(p1,==, "::f"); //test_addr_parse("[::fefe:4.1.1.7/120]:999-1000"); //test_addr_parse_check("::fefe:401:107", 120, 999, 1000); test_addr_mask_ports_parse("[::ffff:4.1.1.7]/120:443", AF_INET6, 0, 0, 0x0000ffff, 0x04010107, 120, 443, 443); - test_streq(p1, "::ffff:4.1.1.7"); + tt_str_op(p1,==, "::ffff:4.1.1.7"); test_addr_mask_ports_parse("[abcd:2::44a:0]:2-65000", AF_INET6, 0xabcd0002, 0, 0, 0x044a0000, 128, 2, 65000); - test_streq(p1, "abcd:2::44a:0"); + tt_str_op(p1,==, "abcd:2::44a:0"); /* Try some long addresses. */ r=tor_addr_parse_mask_ports("[ffff:1111:1111:1111:1111:1111:1111:1111]", 0, &t1, NULL, NULL, NULL); - test_assert(r == AF_INET6); + tt_assert(r == AF_INET6); r=tor_addr_parse_mask_ports("[ffff:1111:1111:1111:1111:1111:1111:11111]", 0, &t1, NULL, NULL, NULL); - test_assert(r == -1); + tt_int_op(r, ==, -1); r=tor_addr_parse_mask_ports("[ffff:1111:1111:1111:1111:1111:1111:1111:1]", 0, &t1, NULL, NULL, NULL); - test_assert(r == -1); + tt_int_op(r, ==, -1); r=tor_addr_parse_mask_ports( "[ffff:1111:1111:1111:1111:1111:1111:ffff:" "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:" "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:" "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff]", 0, &t1, NULL, NULL, NULL); - test_assert(r == -1); + tt_int_op(r, ==, -1); /* Try some failing cases. */ r=tor_addr_parse_mask_ports("[fefef::]/112", 0, &t1, NULL, NULL, NULL); - test_assert(r == -1); + tt_int_op(r, ==, -1); r=tor_addr_parse_mask_ports("[fefe::/112", 0, &t1, NULL, NULL, NULL); - test_assert(r == -1); + tt_int_op(r, ==, -1); r=tor_addr_parse_mask_ports("[fefe::", 0, &t1, NULL, NULL, NULL); - test_assert(r == -1); + tt_int_op(r, ==, -1); r=tor_addr_parse_mask_ports("[fefe::X]", 0, &t1, NULL, NULL, NULL); - test_assert(r == -1); + tt_int_op(r, ==, -1); r=tor_addr_parse_mask_ports("efef::/112", 0, &t1, NULL, NULL, NULL); - test_assert(r == -1); + tt_int_op(r, ==, -1); r=tor_addr_parse_mask_ports("[f:f:f:f:f:f:f:f::]",0,&t1, NULL, NULL, NULL); - test_assert(r == -1); + tt_int_op(r, ==, -1); r=tor_addr_parse_mask_ports("[::f:f:f:f:f:f:f:f]",0,&t1, NULL, NULL, NULL); - test_assert(r == -1); + tt_int_op(r, ==, -1); r=tor_addr_parse_mask_ports("[f:f:f:f:f:f:f:f:f]",0,&t1, NULL, NULL, NULL); - test_assert(r == -1); + tt_int_op(r, ==, -1); r=tor_addr_parse_mask_ports("[f:f:f:f:f::]/fred",0,&t1,&mask, NULL, NULL); - test_assert(r == -1); + tt_int_op(r, ==, -1); r=tor_addr_parse_mask_ports("[f:f:f:f:f::]/255.255.0.0", 0,&t1, NULL, NULL, NULL); - test_assert(r == -1); + tt_int_op(r, ==, -1); /* This one will get rejected because it isn't a pure prefix. */ r=tor_addr_parse_mask_ports("1.1.2.3/255.255.64.0",0,&t1, &mask,NULL,NULL); - test_assert(r == -1); + tt_int_op(r, ==, -1); /* Test for V4-mapped address with mask < 96. (arguably not valid) */ r=tor_addr_parse_mask_ports("[::ffff:1.1.2.2/33]",0,&t1, &mask, NULL, NULL); - test_assert(r == -1); + tt_int_op(r, ==, -1); r=tor_addr_parse_mask_ports("1.1.2.2/33",0,&t1, &mask, NULL, NULL); - test_assert(r == -1); + tt_int_op(r, ==, -1); /* Try extended wildcard addresses with out TAPMP_EXTENDED_STAR*/ r=tor_addr_parse_mask_ports("*4",0,&t1, &mask, NULL, NULL); - test_assert(r == -1); + tt_int_op(r, ==, -1); r=tor_addr_parse_mask_ports("*6",0,&t1, &mask, NULL, NULL); - test_assert(r == -1); + tt_int_op(r, ==, -1); #if 0 /* Try a mask with a wildcard. */ r=tor_addr_parse_mask_ports("*/16",0,&t1, &mask, NULL, NULL); - test_assert(r == -1); + tt_assert(r == -1); r=tor_addr_parse_mask_ports("*4/16",TAPMP_EXTENDED_STAR, &t1, &mask, NULL, NULL); - test_assert(r == -1); + tt_assert(r == -1); r=tor_addr_parse_mask_ports("*6/30",TAPMP_EXTENDED_STAR, &t1, &mask, NULL, NULL); - test_assert(r == -1); + tt_assert(r == -1); #endif /* Basic mask tests*/ r=tor_addr_parse_mask_ports("1.1.2.2/31",0,&t1, &mask, NULL, NULL); - test_assert(r == AF_INET); + tt_assert(r == AF_INET); tt_int_op(mask,==,31); tt_int_op(tor_addr_family(&t1),==,AF_INET); tt_int_op(tor_addr_to_ipv4h(&t1),==,0x01010202); r=tor_addr_parse_mask_ports("3.4.16.032:1-2",0,&t1, &mask, &port1, &port2); - test_assert(r == AF_INET); + tt_assert(r == AF_INET); tt_int_op(mask,==,32); tt_int_op(tor_addr_family(&t1),==,AF_INET); tt_int_op(tor_addr_to_ipv4h(&t1),==,0x03041020); - test_assert(port1 == 1); - test_assert(port2 == 2); + tt_assert(port1 == 1); + tt_assert(port2 == 2); r=tor_addr_parse_mask_ports("1.1.2.3/255.255.128.0",0,&t1, &mask,NULL,NULL); - test_assert(r == AF_INET); + tt_assert(r == AF_INET); tt_int_op(mask,==,17); tt_int_op(tor_addr_family(&t1),==,AF_INET); tt_int_op(tor_addr_to_ipv4h(&t1),==,0x01010203); r=tor_addr_parse_mask_ports("[efef::]/112",0,&t1, &mask, &port1, &port2); - test_assert(r == AF_INET6); - test_assert(port1 == 1); - test_assert(port2 == 65535); + tt_assert(r == AF_INET6); + tt_assert(port1 == 1); + tt_assert(port2 == 65535); /* Try regular wildcard behavior without TAPMP_EXTENDED_STAR */ r=tor_addr_parse_mask_ports("*:80-443",0,&t1,&mask,&port1,&port2); tt_int_op(r,==,AF_INET); /* Old users of this always get inet */ @@ -715,11 +718,11 @@ test_addr_ip6_helpers(void) tt_int_op(port2,==,65535); /* make sure inet address lengths >= max */ - test_assert(INET_NTOA_BUF_LEN >= sizeof("255.255.255.255")); - test_assert(TOR_ADDR_BUF_LEN >= + tt_assert(INET_NTOA_BUF_LEN >= sizeof("255.255.255.255")); + tt_assert(TOR_ADDR_BUF_LEN >= sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")); - test_assert(sizeof(tor_addr_t) >= sizeof(struct in6_addr)); + tt_assert(sizeof(tor_addr_t) >= sizeof(struct in6_addr)); /* get interface addresses */ r = get_interface_address6(LOG_DEBUG, AF_INET, &t1); @@ -736,7 +739,7 @@ test_addr_ip6_helpers(void) /** Test tor_addr_port_parse(). */ static void -test_addr_parse(void) +test_addr_parse(void *arg) { int r; tor_addr_t addr; @@ -744,89 +747,90 @@ test_addr_parse(void) uint16_t port = 0; /* Correct call. */ + (void)arg; r= tor_addr_port_parse(LOG_DEBUG, "192.0.2.1:1234", &addr, &port, -1); - test_assert(r == 0); + tt_int_op(r, ==, 0); tor_addr_to_str(buf, &addr, sizeof(buf), 0); - test_streq(buf, "192.0.2.1"); - test_eq(port, 1234); + tt_str_op(buf,==, "192.0.2.1"); + tt_int_op(port,==, 1234); r= tor_addr_port_parse(LOG_DEBUG, "[::1]:1234", &addr, &port, -1); - test_assert(r == 0); + tt_int_op(r, ==, 0); tor_addr_to_str(buf, &addr, sizeof(buf), 0); - test_streq(buf, "::1"); - test_eq(port, 1234); + tt_str_op(buf,==, "::1"); + tt_int_op(port,==, 1234); /* Domain name. */ r= tor_addr_port_parse(LOG_DEBUG, "torproject.org:1234", &addr, &port, -1); - test_assert(r == -1); + tt_int_op(r, ==, -1); /* Only IP. */ r= tor_addr_port_parse(LOG_DEBUG, "192.0.2.2", &addr, &port, -1); - test_assert(r == -1); + tt_int_op(r, ==, -1); r= tor_addr_port_parse(LOG_DEBUG, "192.0.2.2", &addr, &port, 200); - test_assert(r == 0); + tt_int_op(r, ==, 0); tt_int_op(port,==,200); r= tor_addr_port_parse(LOG_DEBUG, "[::1]", &addr, &port, -1); - test_assert(r == -1); + tt_int_op(r, ==, -1); r= tor_addr_port_parse(LOG_DEBUG, "[::1]", &addr, &port, 400); - test_assert(r == 0); + tt_int_op(r, ==, 0); tt_int_op(port,==,400); /* Bad port. */ r= tor_addr_port_parse(LOG_DEBUG, "192.0.2.2:66666", &addr, &port, -1); - test_assert(r == -1); + tt_int_op(r, ==, -1); r= tor_addr_port_parse(LOG_DEBUG, "192.0.2.2:66666", &addr, &port, 200); - test_assert(r == -1); + tt_int_op(r, ==, -1); /* Only domain name */ r= tor_addr_port_parse(LOG_DEBUG, "torproject.org", &addr, &port, -1); - test_assert(r == -1); + tt_int_op(r, ==, -1); r= tor_addr_port_parse(LOG_DEBUG, "torproject.org", &addr, &port, 200); - test_assert(r == -1); + tt_int_op(r, ==, -1); /* Bad IP address */ r= tor_addr_port_parse(LOG_DEBUG, "192.0.2:1234", &addr, &port, -1); - test_assert(r == -1); + tt_int_op(r, ==, -1); /* Make sure that the default port has lower priority than the real one */ r= tor_addr_port_parse(LOG_DEBUG, "192.0.2.2:1337", &addr, &port, 200); - test_assert(r == 0); + tt_int_op(r, ==, 0); tt_int_op(port,==,1337); r= tor_addr_port_parse(LOG_DEBUG, "[::1]:1369", &addr, &port, 200); - test_assert(r == 0); + tt_int_op(r, ==, 0); tt_int_op(port,==,1369); done: @@ -1047,7 +1051,7 @@ test_addr_make_null(void *data) } #define ADDR_LEGACY(name) \ - { #name, legacy_test_helper, 0, &legacy_setup, test_addr_ ## name } + { #name, test_addr_ ## name , 0, NULL, NULL } struct testcase_t addr_tests[] = { ADDR_LEGACY(basic), diff --git a/src/test/test_buffers.c b/src/test/test_buffers.c index f24b80f0b0..3ab3d8d8c0 100644 --- a/src/test/test_buffers.c +++ b/src/test/test_buffers.c @@ -27,10 +27,10 @@ test_buffers_basic(void *arg) * buf_new ****/ if (!(buf = buf_new())) - test_fail(); + TT_DIE(("Assertion failed.")); //test_eq(buf_capacity(buf), 4096); - test_eq(buf_datalen(buf), 0); + tt_int_op(buf_datalen(buf),==, 0); /**** * General pointer frobbing @@ -40,16 +40,16 @@ test_buffers_basic(void *arg) } write_to_buf(str, 256, buf); write_to_buf(str, 256, buf); - test_eq(buf_datalen(buf), 512); + tt_int_op(buf_datalen(buf),==, 512); fetch_from_buf(str2, 200, buf); - test_memeq(str, str2, 200); - test_eq(buf_datalen(buf), 312); + tt_mem_op(str,==, str2, 200); + tt_int_op(buf_datalen(buf),==, 312); memset(str2, 0, sizeof(str2)); fetch_from_buf(str2, 256, buf); - test_memeq(str+200, str2, 56); - test_memeq(str, str2+56, 200); - test_eq(buf_datalen(buf), 56); + tt_mem_op(str+200,==, str2, 56); + tt_mem_op(str,==, str2+56, 200); + tt_int_op(buf_datalen(buf),==, 56); memset(str2, 0, sizeof(str2)); /* Okay, now we should be 512 bytes into the 4096-byte buffer. If we add * another 3584 bytes, we hit the end. */ @@ -57,16 +57,16 @@ test_buffers_basic(void *arg) write_to_buf(str, 256, buf); } assert_buf_ok(buf); - test_eq(buf_datalen(buf), 3896); + tt_int_op(buf_datalen(buf),==, 3896); fetch_from_buf(str2, 56, buf); - test_eq(buf_datalen(buf), 3840); - test_memeq(str+200, str2, 56); + tt_int_op(buf_datalen(buf),==, 3840); + tt_mem_op(str+200,==, str2, 56); for (j=0;j<15;++j) { memset(str2, 0, sizeof(str2)); fetch_from_buf(str2, 256, buf); - test_memeq(str, str2, 256); + tt_mem_op(str,==, str2, 256); } - test_eq(buf_datalen(buf), 0); + tt_int_op(buf_datalen(buf),==, 0); buf_free(buf); buf = NULL; @@ -76,7 +76,7 @@ test_buffers_basic(void *arg) write_to_buf(str+1, 255, buf); //test_eq(buf_capacity(buf), 256); fetch_from_buf(str2, 254, buf); - test_memeq(str+1, str2, 254); + tt_mem_op(str+1,==, str2, 254); //test_eq(buf_capacity(buf), 256); assert_buf_ok(buf); write_to_buf(str, 32, buf); @@ -85,15 +85,15 @@ test_buffers_basic(void *arg) write_to_buf(str, 256, buf); assert_buf_ok(buf); //test_eq(buf_capacity(buf), 512); - test_eq(buf_datalen(buf), 33+256); + tt_int_op(buf_datalen(buf),==, 33+256); fetch_from_buf(str2, 33, buf); - test_eq(*str2, str[255]); + tt_int_op(*str2,==, str[255]); - test_memeq(str2+1, str, 32); + tt_mem_op(str2+1,==, str, 32); //test_eq(buf_capacity(buf), 512); - test_eq(buf_datalen(buf), 256); + tt_int_op(buf_datalen(buf),==, 256); fetch_from_buf(str2, 256, buf); - test_memeq(str, str2, 256); + tt_mem_op(str,==, str2, 256); /* now try shrinking: case 1. */ buf_free(buf); @@ -102,10 +102,10 @@ test_buffers_basic(void *arg) write_to_buf(str,255, buf); } //test_eq(buf_capacity(buf), 33668); - test_eq(buf_datalen(buf), 17085); + tt_int_op(buf_datalen(buf),==, 17085); for (j=0; j < 40; ++j) { fetch_from_buf(str2, 255,buf); - test_memeq(str2, str, 255); + tt_mem_op(str2,==, str, 255); } /* now try shrinking: case 2. */ @@ -116,7 +116,7 @@ test_buffers_basic(void *arg) } for (j=0; j < 20; ++j) { fetch_from_buf(str2, 255,buf); - test_memeq(str2, str, 255); + tt_mem_op(str2,==, str, 255); } for (j=0;j<80;++j) { write_to_buf(str,255, buf); @@ -124,7 +124,7 @@ test_buffers_basic(void *arg) //test_eq(buf_capacity(buf),33668); for (j=0; j < 120; ++j) { fetch_from_buf(str2, 255,buf); - test_memeq(str2, str, 255); + tt_mem_op(str2,==, str, 255); } /* Move from buf to buf. */ @@ -133,27 +133,27 @@ test_buffers_basic(void *arg) buf2 = buf_new_with_capacity(4096); for (j=0;j<100;++j) write_to_buf(str, 255, buf); - test_eq(buf_datalen(buf), 25500); + tt_int_op(buf_datalen(buf),==, 25500); for (j=0;j<100;++j) { r = 10; move_buf_to_buf(buf2, buf, &r); - test_eq(r, 0); + tt_int_op(r,==, 0); } - test_eq(buf_datalen(buf), 24500); - test_eq(buf_datalen(buf2), 1000); + tt_int_op(buf_datalen(buf),==, 24500); + tt_int_op(buf_datalen(buf2),==, 1000); for (j=0;j<3;++j) { fetch_from_buf(str2, 255, buf2); - test_memeq(str2, str, 255); + tt_mem_op(str2,==, str, 255); } r = 8192; /*big move*/ move_buf_to_buf(buf2, buf, &r); - test_eq(r, 0); + tt_int_op(r,==, 0); r = 30000; /* incomplete move */ move_buf_to_buf(buf2, buf, &r); - test_eq(r, 13692); + tt_int_op(r,==, 13692); for (j=0;j<97;++j) { fetch_from_buf(str2, 255, buf2); - test_memeq(str2, str, 255); + tt_mem_op(str2,==, str, 255); } buf_free(buf); buf_free(buf2); @@ -163,16 +163,16 @@ test_buffers_basic(void *arg) cp = "Testing. This is a moderately long Testing string."; for (j = 0; cp[j]; j++) write_to_buf(cp+j, 1, buf); - test_eq(0, buf_find_string_offset(buf, "Testing", 7)); - test_eq(1, buf_find_string_offset(buf, "esting", 6)); - test_eq(1, buf_find_string_offset(buf, "est", 3)); - test_eq(39, buf_find_string_offset(buf, "ing str", 7)); - test_eq(35, buf_find_string_offset(buf, "Testing str", 11)); - test_eq(32, buf_find_string_offset(buf, "ng ", 3)); - test_eq(43, buf_find_string_offset(buf, "string.", 7)); - test_eq(-1, buf_find_string_offset(buf, "shrdlu", 6)); - test_eq(-1, buf_find_string_offset(buf, "Testing thing", 13)); - test_eq(-1, buf_find_string_offset(buf, "ngx", 3)); + tt_int_op(0,==, buf_find_string_offset(buf, "Testing", 7)); + tt_int_op(1,==, buf_find_string_offset(buf, "esting", 6)); + tt_int_op(1,==, buf_find_string_offset(buf, "est", 3)); + tt_int_op(39,==, buf_find_string_offset(buf, "ing str", 7)); + tt_int_op(35,==, buf_find_string_offset(buf, "Testing str", 11)); + tt_int_op(32,==, buf_find_string_offset(buf, "ng ", 3)); + tt_int_op(43,==, buf_find_string_offset(buf, "string.", 7)); + tt_int_op(-1,==, buf_find_string_offset(buf, "shrdlu", 6)); + tt_int_op(-1,==, buf_find_string_offset(buf, "Testing thing", 13)); + tt_int_op(-1,==, buf_find_string_offset(buf, "ngx", 3)); buf_free(buf); buf = NULL; @@ -240,16 +240,16 @@ test_buffer_pullup(void *arg) /* Make room for 3000 bytes in the first chunk, so that the pullup-move code * can get tested. */ tt_int_op(fetch_from_buf(tmp, 3000, buf), ==, 3000); - test_memeq(tmp, stuff, 3000); + tt_mem_op(tmp,==, stuff, 3000); buf_pullup(buf, 2048, 0); assert_buf_ok(buf); buf_get_first_chunk_data(buf, &cp, &sz); tt_ptr_op(cp, !=, NULL); tt_int_op(sz, >=, 2048); - test_memeq(cp, stuff+3000, 2048); + tt_mem_op(cp,==, stuff+3000, 2048); tt_int_op(3000, ==, buf_datalen(buf)); tt_int_op(fetch_from_buf(tmp, 3000, buf), ==, 0); - test_memeq(tmp, stuff+3000, 2048); + tt_mem_op(tmp,==, stuff+3000, 2048); buf_free(buf); @@ -269,16 +269,16 @@ test_buffer_pullup(void *arg) buf_get_first_chunk_data(buf, &cp, &sz); tt_ptr_op(cp, !=, NULL); tt_int_op(sz, >=, 12500); - test_memeq(cp, stuff, 12500); + tt_mem_op(cp,==, stuff, 12500); tt_int_op(buf_datalen(buf), ==, 16000); fetch_from_buf(tmp, 12400, buf); - test_memeq(tmp, stuff, 12400); + tt_mem_op(tmp,==, stuff, 12400); tt_int_op(buf_datalen(buf), ==, 3600); fetch_from_buf(tmp, 3500, buf); - test_memeq(tmp, stuff+12400, 3500); + tt_mem_op(tmp,==, stuff+12400, 3500); fetch_from_buf(tmp, 100, buf); - test_memeq(tmp, stuff+15900, 10); + tt_mem_op(tmp,==, stuff+15900, 10); buf_free(buf); @@ -292,7 +292,7 @@ test_buffer_pullup(void *arg) buf_get_first_chunk_data(buf, &cp, &sz); tt_ptr_op(cp, !=, NULL); tt_int_op(sz, ==, 7900); - test_memeq(cp, stuff+100, 7900); + tt_mem_op(cp,==, stuff+100, 7900); buf_free(buf); buf = NULL; @@ -335,14 +335,14 @@ test_buffer_copy(void *arg) tt_int_op(0, ==, generic_buffer_set_to_copy(&buf2, buf)); tt_int_op(len, ==, generic_buffer_len(buf2)); generic_buffer_get(buf2, b, len); - test_mem_op(b, ==, s, len); + tt_mem_op(b, ==, s, len); /* Now free buf2 and retry so we can test allocating */ generic_buffer_free(buf2); buf2 = NULL; tt_int_op(0, ==, generic_buffer_set_to_copy(&buf2, buf)); tt_int_op(len, ==, generic_buffer_len(buf2)); generic_buffer_get(buf2, b, len); - test_mem_op(b, ==, s, len); + tt_mem_op(b, ==, s, len); /* Clear buf for next test */ generic_buffer_get(buf, b, len); tt_int_op(generic_buffer_len(buf),==,0); @@ -362,7 +362,7 @@ test_buffer_copy(void *arg) for (i = 0; i < 256; ++i) { generic_buffer_get(buf2, b, len+1); tt_int_op((unsigned char)b[0],==,i); - test_mem_op(b+1, ==, s, len); + tt_mem_op(b+1, ==, s, len); } done: @@ -410,7 +410,7 @@ test_buffer_ext_or_cmd(void *arg) tt_ptr_op(NULL, !=, cmd); tt_int_op(0x1021, ==, cmd->cmd); tt_int_op(6, ==, cmd->len); - test_mem_op("abcdef", ==, cmd->body, 6); + tt_mem_op("abcdef", ==, cmd->body, 6); tt_int_op(0, ==, generic_buffer_len(buf)); ext_or_cmd_free(cmd); cmd = NULL; @@ -422,7 +422,7 @@ test_buffer_ext_or_cmd(void *arg) tt_ptr_op(NULL, !=, cmd); tt_int_op(0xffff, ==, cmd->cmd); tt_int_op(10, ==, cmd->len); - test_mem_op("loremipsum", ==, cmd->body, 10); + tt_mem_op("loremipsum", ==, cmd->body, 10); tt_int_op(4, ==, generic_buffer_len(buf)); ext_or_cmd_free(cmd); cmd = NULL; @@ -436,7 +436,7 @@ test_buffer_ext_or_cmd(void *arg) tt_ptr_op(NULL, !=, cmd); tt_int_op(0x1000, ==, cmd->cmd); tt_int_op(0xffff, ==, cmd->len); - test_mem_op(tmp, ==, cmd->body, 65535); + tt_mem_op(tmp, ==, cmd->body, 65535); tt_int_op(0, ==, generic_buffer_len(buf)); ext_or_cmd_free(cmd); cmd = NULL; diff --git a/src/test/test_cell_formats.c b/src/test/test_cell_formats.c index d7f60680c2..995e519163 100644 --- a/src/test/test_cell_formats.c +++ b/src/test/test_cell_formats.c @@ -35,11 +35,11 @@ test_cfmt_relay_header(void *arg) tt_int_op(rh.command, ==, 3); tt_int_op(rh.recognized, ==, 0); tt_int_op(rh.stream_id, ==, 0x2122); - test_mem_op(rh.integrity, ==, "ABCD", 4); + tt_mem_op(rh.integrity, ==, "ABCD", 4); tt_int_op(rh.length, ==, 0x103); relay_header_pack(hdr_out, &rh); - test_mem_op(hdr_out, ==, hdr_1, RELAY_HEADER_SIZE); + tt_mem_op(hdr_out, ==, hdr_1, RELAY_HEADER_SIZE); done: ; @@ -402,10 +402,10 @@ test_cfmt_create_cells(void *arg) tt_int_op(CELL_CREATE, ==, cc.cell_type); tt_int_op(ONION_HANDSHAKE_TYPE_TAP, ==, cc.handshake_type); tt_int_op(TAP_ONIONSKIN_CHALLENGE_LEN, ==, cc.handshake_len); - test_memeq(cc.onionskin, b, TAP_ONIONSKIN_CHALLENGE_LEN + 10); + tt_mem_op(cc.onionskin,==, b, TAP_ONIONSKIN_CHALLENGE_LEN + 10); tt_int_op(0, ==, create_cell_format(&cell2, &cc)); tt_int_op(cell.command, ==, cell2.command); - test_memeq(cell.payload, cell2.payload, CELL_PAYLOAD_SIZE); + tt_mem_op(cell.payload,==, cell2.payload, CELL_PAYLOAD_SIZE); /* A valid create_fast cell. */ memset(&cell, 0, sizeof(cell)); @@ -417,10 +417,10 @@ test_cfmt_create_cells(void *arg) tt_int_op(CELL_CREATE_FAST, ==, cc.cell_type); tt_int_op(ONION_HANDSHAKE_TYPE_FAST, ==, cc.handshake_type); tt_int_op(CREATE_FAST_LEN, ==, cc.handshake_len); - test_memeq(cc.onionskin, b, CREATE_FAST_LEN + 10); + tt_mem_op(cc.onionskin,==, b, CREATE_FAST_LEN + 10); tt_int_op(0, ==, create_cell_format(&cell2, &cc)); tt_int_op(cell.command, ==, cell2.command); - test_memeq(cell.payload, cell2.payload, CELL_PAYLOAD_SIZE); + tt_mem_op(cell.payload,==, cell2.payload, CELL_PAYLOAD_SIZE); /* A valid create2 cell with a TAP payload */ memset(&cell, 0, sizeof(cell)); @@ -433,10 +433,10 @@ test_cfmt_create_cells(void *arg) tt_int_op(CELL_CREATE2, ==, cc.cell_type); tt_int_op(ONION_HANDSHAKE_TYPE_TAP, ==, cc.handshake_type); tt_int_op(TAP_ONIONSKIN_CHALLENGE_LEN, ==, cc.handshake_len); - test_memeq(cc.onionskin, b, TAP_ONIONSKIN_CHALLENGE_LEN + 10); + tt_mem_op(cc.onionskin,==, b, TAP_ONIONSKIN_CHALLENGE_LEN + 10); tt_int_op(0, ==, create_cell_format(&cell2, &cc)); tt_int_op(cell.command, ==, cell2.command); - test_memeq(cell.payload, cell2.payload, CELL_PAYLOAD_SIZE); + tt_mem_op(cell.payload,==, cell2.payload, CELL_PAYLOAD_SIZE); /* A valid create2 cell with an ntor payload */ memset(&cell, 0, sizeof(cell)); @@ -450,10 +450,10 @@ test_cfmt_create_cells(void *arg) tt_int_op(CELL_CREATE2, ==, cc.cell_type); tt_int_op(ONION_HANDSHAKE_TYPE_NTOR, ==, cc.handshake_type); tt_int_op(NTOR_ONIONSKIN_LEN, ==, cc.handshake_len); - test_memeq(cc.onionskin, b, NTOR_ONIONSKIN_LEN + 10); + tt_mem_op(cc.onionskin,==, b, NTOR_ONIONSKIN_LEN + 10); tt_int_op(0, ==, create_cell_format(&cell2, &cc)); tt_int_op(cell.command, ==, cell2.command); - test_memeq(cell.payload, cell2.payload, CELL_PAYLOAD_SIZE); + tt_mem_op(cell.payload,==, cell2.payload, CELL_PAYLOAD_SIZE); #else tt_int_op(-1, ==, create_cell_parse(&cc, &cell)); #endif @@ -470,10 +470,10 @@ test_cfmt_create_cells(void *arg) tt_int_op(CELL_CREATE, ==, cc.cell_type); tt_int_op(ONION_HANDSHAKE_TYPE_NTOR, ==, cc.handshake_type); tt_int_op(NTOR_ONIONSKIN_LEN, ==, cc.handshake_len); - test_memeq(cc.onionskin, b, NTOR_ONIONSKIN_LEN + 10); + tt_mem_op(cc.onionskin,==, b, NTOR_ONIONSKIN_LEN + 10); tt_int_op(0, ==, create_cell_format(&cell2, &cc)); tt_int_op(cell.command, ==, cell2.command); - test_memeq(cell.payload, cell2.payload, CELL_PAYLOAD_SIZE); + tt_mem_op(cell.payload,==, cell2.payload, CELL_PAYLOAD_SIZE); #else tt_int_op(-1, ==, create_cell_parse(&cc, &cell)); #endif @@ -527,10 +527,10 @@ test_cfmt_created_cells(void *arg) tt_int_op(0, ==, created_cell_parse(&cc, &cell)); tt_int_op(CELL_CREATED, ==, cc.cell_type); tt_int_op(TAP_ONIONSKIN_REPLY_LEN, ==, cc.handshake_len); - test_memeq(cc.reply, b, TAP_ONIONSKIN_REPLY_LEN + 10); + tt_mem_op(cc.reply,==, b, TAP_ONIONSKIN_REPLY_LEN + 10); tt_int_op(0, ==, created_cell_format(&cell2, &cc)); tt_int_op(cell.command, ==, cell2.command); - test_memeq(cell.payload, cell2.payload, CELL_PAYLOAD_SIZE); + tt_mem_op(cell.payload,==, cell2.payload, CELL_PAYLOAD_SIZE); /* A good CREATED_FAST cell */ memset(&cell, 0, sizeof(cell)); @@ -541,10 +541,10 @@ test_cfmt_created_cells(void *arg) tt_int_op(0, ==, created_cell_parse(&cc, &cell)); tt_int_op(CELL_CREATED_FAST, ==, cc.cell_type); tt_int_op(CREATED_FAST_LEN, ==, cc.handshake_len); - test_memeq(cc.reply, b, CREATED_FAST_LEN + 10); + tt_mem_op(cc.reply,==, b, CREATED_FAST_LEN + 10); tt_int_op(0, ==, created_cell_format(&cell2, &cc)); tt_int_op(cell.command, ==, cell2.command); - test_memeq(cell.payload, cell2.payload, CELL_PAYLOAD_SIZE); + tt_mem_op(cell.payload,==, cell2.payload, CELL_PAYLOAD_SIZE); /* A good CREATED2 cell with short reply */ memset(&cell, 0, sizeof(cell)); @@ -556,10 +556,10 @@ test_cfmt_created_cells(void *arg) tt_int_op(0, ==, created_cell_parse(&cc, &cell)); tt_int_op(CELL_CREATED2, ==, cc.cell_type); tt_int_op(64, ==, cc.handshake_len); - test_memeq(cc.reply, b, 80); + tt_mem_op(cc.reply,==, b, 80); tt_int_op(0, ==, created_cell_format(&cell2, &cc)); tt_int_op(cell.command, ==, cell2.command); - test_memeq(cell.payload, cell2.payload, CELL_PAYLOAD_SIZE); + tt_mem_op(cell.payload,==, cell2.payload, CELL_PAYLOAD_SIZE); /* A good CREATED2 cell with maximal reply */ memset(&cell, 0, sizeof(cell)); @@ -571,10 +571,10 @@ test_cfmt_created_cells(void *arg) tt_int_op(0, ==, created_cell_parse(&cc, &cell)); tt_int_op(CELL_CREATED2, ==, cc.cell_type); tt_int_op(496, ==, cc.handshake_len); - test_memeq(cc.reply, b, 496); + tt_mem_op(cc.reply,==, b, 496); tt_int_op(0, ==, created_cell_format(&cell2, &cc)); tt_int_op(cell.command, ==, cell2.command); - test_memeq(cell.payload, cell2.payload, CELL_PAYLOAD_SIZE); + tt_mem_op(cell.payload,==, cell2.payload, CELL_PAYLOAD_SIZE); /* Bogus CREATED2 cell: too long! */ memset(&cell, 0, sizeof(cell)); @@ -620,15 +620,15 @@ test_cfmt_extend_cells(void *arg) tt_str_op("18.244.0.1", ==, fmt_addr(&ec.orport_ipv4.addr)); tt_int_op(258, ==, ec.orport_ipv4.port); tt_int_op(AF_UNSPEC, ==, tor_addr_family(&ec.orport_ipv6.addr)); - test_memeq(ec.node_id, "electroencephalogram", 20); + tt_mem_op(ec.node_id,==, "electroencephalogram", 20); tt_int_op(cc->cell_type, ==, CELL_CREATE); tt_int_op(cc->handshake_type, ==, ONION_HANDSHAKE_TYPE_TAP); tt_int_op(cc->handshake_len, ==, TAP_ONIONSKIN_CHALLENGE_LEN); - test_memeq(cc->onionskin, b, TAP_ONIONSKIN_CHALLENGE_LEN+20); + tt_mem_op(cc->onionskin,==, b, TAP_ONIONSKIN_CHALLENGE_LEN+20); tt_int_op(0, ==, extend_cell_format(&p2_cmd, &p2_len, p2, &ec)); tt_int_op(p2_cmd, ==, RELAY_COMMAND_EXTEND); tt_int_op(p2_len, ==, 26+TAP_ONIONSKIN_CHALLENGE_LEN); - test_memeq(p2, p, RELAY_PAYLOAD_SIZE); + tt_mem_op(p2,==, p, RELAY_PAYLOAD_SIZE); /* Let's do an ntor stuffed in a legacy EXTEND cell */ memset(p, 0, sizeof(p)); @@ -644,15 +644,15 @@ test_cfmt_extend_cells(void *arg) tt_str_op("18.244.0.1", ==, fmt_addr(&ec.orport_ipv4.addr)); tt_int_op(258, ==, ec.orport_ipv4.port); tt_int_op(AF_UNSPEC, ==, tor_addr_family(&ec.orport_ipv6.addr)); - test_memeq(ec.node_id, "electroencephalogram", 20); + tt_mem_op(ec.node_id,==, "electroencephalogram", 20); tt_int_op(cc->cell_type, ==, CELL_CREATE2); tt_int_op(cc->handshake_type, ==, ONION_HANDSHAKE_TYPE_NTOR); tt_int_op(cc->handshake_len, ==, NTOR_ONIONSKIN_LEN); - test_memeq(cc->onionskin, b, NTOR_ONIONSKIN_LEN+20); + tt_mem_op(cc->onionskin,==, b, NTOR_ONIONSKIN_LEN+20); tt_int_op(0, ==, extend_cell_format(&p2_cmd, &p2_len, p2, &ec)); tt_int_op(p2_cmd, ==, RELAY_COMMAND_EXTEND); tt_int_op(p2_len, ==, 26+TAP_ONIONSKIN_CHALLENGE_LEN); - test_memeq(p2, p, RELAY_PAYLOAD_SIZE); + tt_mem_op(p2,==, p, RELAY_PAYLOAD_SIZE); tt_int_op(0, ==, create_cell_format_relayed(&cell, cc)); /* Now let's do a minimal ntor EXTEND2 cell. */ @@ -673,15 +673,15 @@ test_cfmt_extend_cells(void *arg) tt_str_op("18.244.0.1", ==, fmt_addr(&ec.orport_ipv4.addr)); tt_int_op(61681, ==, ec.orport_ipv4.port); tt_int_op(AF_UNSPEC, ==, tor_addr_family(&ec.orport_ipv6.addr)); - test_memeq(ec.node_id, "anarchoindividualist", 20); + tt_mem_op(ec.node_id,==, "anarchoindividualist", 20); tt_int_op(cc->cell_type, ==, CELL_CREATE2); tt_int_op(cc->handshake_type, ==, ONION_HANDSHAKE_TYPE_NTOR); tt_int_op(cc->handshake_len, ==, NTOR_ONIONSKIN_LEN); - test_memeq(cc->onionskin, b, NTOR_ONIONSKIN_LEN+20); + tt_mem_op(cc->onionskin,==, b, NTOR_ONIONSKIN_LEN+20); tt_int_op(0, ==, extend_cell_format(&p2_cmd, &p2_len, p2, &ec)); tt_int_op(p2_cmd, ==, RELAY_COMMAND_EXTEND2); tt_int_op(p2_len, ==, 35+NTOR_ONIONSKIN_LEN); - test_memeq(p2, p, RELAY_PAYLOAD_SIZE); + tt_mem_op(p2,==, p, RELAY_PAYLOAD_SIZE); /* Now let's do a fanciful EXTEND2 cell. */ memset(&ec, 0xff, sizeof(ec)); @@ -706,11 +706,11 @@ test_cfmt_extend_cells(void *arg) tt_int_op(61681, ==, ec.orport_ipv4.port); tt_str_op("2002::f0:c51e", ==, fmt_addr(&ec.orport_ipv6.addr)); tt_int_op(4370, ==, ec.orport_ipv6.port); - test_memeq(ec.node_id, "anthropomorphization", 20); + tt_mem_op(ec.node_id,==, "anthropomorphization", 20); tt_int_op(cc->cell_type, ==, CELL_CREATE2); tt_int_op(cc->handshake_type, ==, 0x105); tt_int_op(cc->handshake_len, ==, 99); - test_memeq(cc->onionskin, b, 99+20); + tt_mem_op(cc->onionskin,==, b, 99+20); tt_int_op(0, ==, extend_cell_format(&p2_cmd, &p2_len, p2, &ec)); tt_int_op(p2_cmd, ==, RELAY_COMMAND_EXTEND2); /* We'll generate it minus the IPv6 address and minus the konami code */ @@ -722,7 +722,7 @@ test_cfmt_extend_cells(void *arg) "0214616e7468726f706f6d6f727068697a6174696f6e" /* Now the handshake prologue */ "01050063"); - test_memeq(p2+1+8+22+4, b, 99+20); + tt_mem_op(p2+1+8+22+4,==, b, 99+20); tt_int_op(0, ==, create_cell_format_relayed(&cell, cc)); /* == Now try parsing some junk */ @@ -836,11 +836,11 @@ test_cfmt_extended_cells(void *arg) tt_int_op(RELAY_COMMAND_EXTENDED, ==, ec.cell_type); tt_int_op(cc->cell_type, ==, CELL_CREATED); tt_int_op(cc->handshake_len, ==, TAP_ONIONSKIN_REPLY_LEN); - test_memeq(cc->reply, b, TAP_ONIONSKIN_REPLY_LEN); + tt_mem_op(cc->reply,==, b, TAP_ONIONSKIN_REPLY_LEN); tt_int_op(0, ==, extended_cell_format(&p2_cmd, &p2_len, p2, &ec)); tt_int_op(RELAY_COMMAND_EXTENDED, ==, p2_cmd); tt_int_op(TAP_ONIONSKIN_REPLY_LEN, ==, p2_len); - test_memeq(p2, p, sizeof(p2)); + tt_mem_op(p2,==, p, sizeof(p2)); /* Try an EXTENDED2 cell */ memset(&ec, 0xff, sizeof(ec)); @@ -853,11 +853,11 @@ test_cfmt_extended_cells(void *arg) tt_int_op(RELAY_COMMAND_EXTENDED2, ==, ec.cell_type); tt_int_op(cc->cell_type, ==, CELL_CREATED2); tt_int_op(cc->handshake_len, ==, 42); - test_memeq(cc->reply, b, 42+10); + tt_mem_op(cc->reply,==, b, 42+10); tt_int_op(0, ==, extended_cell_format(&p2_cmd, &p2_len, p2, &ec)); tt_int_op(RELAY_COMMAND_EXTENDED2, ==, p2_cmd); tt_int_op(2+42, ==, p2_len); - test_memeq(p2, p, sizeof(p2)); + tt_mem_op(p2,==, p, sizeof(p2)); /* Try an almost-too-long EXTENDED2 cell */ memcpy(p, "\x01\xf0", 2); diff --git a/src/test/test_cell_queue.c b/src/test/test_cell_queue.c index 92629823ec..3226f7b973 100644 --- a/src/test/test_cell_queue.c +++ b/src/test/test_cell_queue.c @@ -69,15 +69,15 @@ test_cq_manip(void *arg) pc_tmp = cell_queue_pop(&cq); tt_int_op(cq.n, ==, 1); tt_ptr_op(pc_tmp, !=, NULL); - test_mem_op(pc_tmp->body, ==, "\x12\x34\x56\x78\x0a", 5); - test_mem_op(pc_tmp->body+5, ==, cell.payload, sizeof(cell.payload)); + tt_mem_op(pc_tmp->body, ==, "\x12\x34\x56\x78\x0a", 5); + tt_mem_op(pc_tmp->body+5, ==, cell.payload, sizeof(cell.payload)); packed_cell_free(pc_tmp); pc_tmp = cell_queue_pop(&cq); tt_int_op(cq.n, ==, 0); tt_ptr_op(pc_tmp, !=, NULL); - test_mem_op(pc_tmp->body, ==, "\x20\x13\x0a", 3); - test_mem_op(pc_tmp->body+3, ==, cell.payload, sizeof(cell.payload)); + tt_mem_op(pc_tmp->body, ==, "\x20\x13\x0a", 3); + tt_mem_op(pc_tmp->body+3, ==, cell.payload, sizeof(cell.payload)); packed_cell_free(pc_tmp); pc_tmp = NULL; diff --git a/src/test/test_circuitlist.c b/src/test/test_circuitlist.c index 53dcab3302..e752eaf62a 100644 --- a/src/test/test_circuitlist.c +++ b/src/test/test_circuitlist.c @@ -251,7 +251,7 @@ test_rend_token_maps(void *arg) tt_ptr_op(c3->rendinfo, ==, NULL); tt_ptr_op(c4->rendinfo, !=, NULL); - test_mem_op(c4->rendinfo, ==, tok3, REND_TOKEN_LEN); + tt_mem_op(c4->rendinfo, ==, tok3, REND_TOKEN_LEN); /* Now clear c4's cookie. */ circuit_set_intro_point_digest(c4, NULL); diff --git a/src/test/test_circuitmux.c b/src/test/test_circuitmux.c index b9c0436ebf..a3cacc4cc7 100644 --- a/src/test/test_circuitmux.c +++ b/src/test/test_circuitmux.c @@ -65,7 +65,7 @@ test_cmux_destroy_cell_queue(void *arg) pc = cell_queue_pop(cq); tt_assert(pc); - test_mem_op(pc->body, ==, "\x00\x00\x00\x64\x04\x0a\x00\x00\x00", 9); + tt_mem_op(pc->body, ==, "\x00\x00\x00\x64\x04\x0a\x00\x00\x00", 9); packed_cell_free(pc); pc = NULL; diff --git a/src/test/test_config.c b/src/test/test_config.c index b35984f761..6a91453e8c 100644 --- a/src/test/test_config.c +++ b/src/test/test_config.c @@ -53,57 +53,57 @@ test_config_addressmap(void *arg) /* MapAddress .invalidwildcard.com .torserver.exit - no match */ strlcpy(address, "www.invalidwildcard.com", sizeof(address)); - test_assert(!addressmap_rewrite(address, sizeof(address), &expires, NULL)); + tt_assert(!addressmap_rewrite(address, sizeof(address), &expires, NULL)); /* MapAddress *invalidasterisk.com .torserver.exit - no match */ strlcpy(address, "www.invalidasterisk.com", sizeof(address)); - test_assert(!addressmap_rewrite(address, sizeof(address), &expires, NULL)); + tt_assert(!addressmap_rewrite(address, sizeof(address), &expires, NULL)); /* Where no mapping for FQDN match on top-level domain */ /* MapAddress .google.com .torserver.exit */ strlcpy(address, "reader.google.com", sizeof(address)); - test_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL)); - test_streq(address, "reader.torserver.exit"); + tt_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL)); + tt_str_op(address,==, "reader.torserver.exit"); /* MapAddress *.yahoo.com *.google.com.torserver.exit */ strlcpy(address, "reader.yahoo.com", sizeof(address)); - test_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL)); - test_streq(address, "reader.google.com.torserver.exit"); + tt_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL)); + tt_str_op(address,==, "reader.google.com.torserver.exit"); /*MapAddress *.cnn.com www.cnn.com */ strlcpy(address, "cnn.com", sizeof(address)); - test_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL)); - test_streq(address, "www.cnn.com"); + tt_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL)); + tt_str_op(address,==, "www.cnn.com"); /* MapAddress .cn.com www.cnn.com */ strlcpy(address, "www.cn.com", sizeof(address)); - test_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL)); - test_streq(address, "www.cnn.com"); + tt_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL)); + tt_str_op(address,==, "www.cnn.com"); /* MapAddress ex.com www.cnn.com - no match */ strlcpy(address, "www.ex.com", sizeof(address)); - test_assert(!addressmap_rewrite(address, sizeof(address), &expires, NULL)); + tt_assert(!addressmap_rewrite(address, sizeof(address), &expires, NULL)); /* MapAddress ey.com *.cnn.com - invalid expression */ strlcpy(address, "ey.com", sizeof(address)); - test_assert(!addressmap_rewrite(address, sizeof(address), &expires, NULL)); + tt_assert(!addressmap_rewrite(address, sizeof(address), &expires, NULL)); /* Where mapping for FQDN match on FQDN */ strlcpy(address, "www.google.com", sizeof(address)); - test_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL)); - test_streq(address, "3.3.3.3"); + tt_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL)); + tt_str_op(address,==, "3.3.3.3"); strlcpy(address, "www.torproject.org", sizeof(address)); - test_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL)); - test_streq(address, "1.1.1.1"); + tt_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL)); + tt_str_op(address,==, "1.1.1.1"); strlcpy(address, "other.torproject.org", sizeof(address)); - test_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL)); - test_streq(address, "this.torproject.org.otherserver.exit"); + tt_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL)); + tt_str_op(address,==, "this.torproject.org.otherserver.exit"); strlcpy(address, "test.torproject.org", sizeof(address)); - test_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL)); - test_streq(address, "2.2.2.2"); + tt_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL)); + tt_str_op(address,==, "2.2.2.2"); /* Test a chain of address mappings and the order in which they were added: "MapAddress www.example.org 4.4.4.4" @@ -111,17 +111,17 @@ test_config_addressmap(void *arg) "MapAddress 4.4.4.4 5.5.5.5" */ strlcpy(address, "www.example.org", sizeof(address)); - test_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL)); - test_streq(address, "5.5.5.5"); + tt_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL)); + tt_str_op(address,==, "5.5.5.5"); /* Test infinite address mapping results in no change */ strlcpy(address, "www.infiniteloop.org", sizeof(address)); - test_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL)); - test_streq(address, "www.infiniteloop.org"); + tt_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL)); + tt_str_op(address,==, "www.infiniteloop.org"); /* Test we don't find false positives */ strlcpy(address, "www.example.com", sizeof(address)); - test_assert(!addressmap_rewrite(address, sizeof(address), &expires, NULL)); + tt_assert(!addressmap_rewrite(address, sizeof(address), &expires, NULL)); /* Test top-level-domain matching a bit harder */ config_free_lines(get_options_mutable()->AddressMap); @@ -134,24 +134,24 @@ test_config_addressmap(void *arg) config_register_addressmaps(get_options()); strlcpy(address, "www.abc.com", sizeof(address)); - test_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL)); - test_streq(address, "www.abc.torserver.exit"); + tt_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL)); + tt_str_op(address,==, "www.abc.torserver.exit"); strlcpy(address, "www.def.com", sizeof(address)); - test_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL)); - test_streq(address, "www.def.torserver.exit"); + tt_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL)); + tt_str_op(address,==, "www.def.torserver.exit"); strlcpy(address, "www.torproject.org", sizeof(address)); - test_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL)); - test_streq(address, "1.1.1.1"); + tt_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL)); + tt_str_op(address,==, "1.1.1.1"); strlcpy(address, "test.torproject.org", sizeof(address)); - test_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL)); - test_streq(address, "1.1.1.1"); + tt_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL)); + tt_str_op(address,==, "1.1.1.1"); strlcpy(address, "torproject.net", sizeof(address)); - test_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL)); - test_streq(address, "2.2.2.2"); + tt_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL)); + tt_str_op(address,==, "2.2.2.2"); /* We don't support '*' as a mapping directive */ config_free_lines(get_options_mutable()->AddressMap); @@ -161,13 +161,13 @@ test_config_addressmap(void *arg) config_register_addressmaps(get_options()); strlcpy(address, "www.abc.com", sizeof(address)); - test_assert(!addressmap_rewrite(address, sizeof(address), &expires, NULL)); + tt_assert(!addressmap_rewrite(address, sizeof(address), &expires, NULL)); strlcpy(address, "www.def.net", sizeof(address)); - test_assert(!addressmap_rewrite(address, sizeof(address), &expires, NULL)); + tt_assert(!addressmap_rewrite(address, sizeof(address), &expires, NULL)); strlcpy(address, "www.torproject.org", sizeof(address)); - test_assert(!addressmap_rewrite(address, sizeof(address), &expires, NULL)); + tt_assert(!addressmap_rewrite(address, sizeof(address), &expires, NULL)); #undef addressmap_rewrite @@ -220,13 +220,13 @@ test_config_check_or_create_data_subdir(void *arg) // The subdirectory shouldn't exist yet, // but should be created by the call to check_or_create_data_subdir. - test_assert(r && (errno == ENOENT)); - test_assert(!check_or_create_data_subdir(subdir)); - test_assert(is_private_dir(subpath)); + tt_assert(r && (errno == ENOENT)); + tt_assert(!check_or_create_data_subdir(subdir)); + tt_assert(is_private_dir(subpath)); // The check should return 0, if the directory already exists // and is private to the user. - test_assert(!check_or_create_data_subdir(subdir)); + tt_assert(!check_or_create_data_subdir(subdir)); r = stat(subpath, &st); if (r) { @@ -243,9 +243,9 @@ test_config_check_or_create_data_subdir(void *arg) // If the directory exists, but its mode is too permissive // a call to check_or_create_data_subdir should reset the mode. - test_assert(!is_private_dir(subpath)); - test_assert(!check_or_create_data_subdir(subdir)); - test_assert(is_private_dir(subpath)); + tt_assert(!is_private_dir(subpath)); + tt_assert(!check_or_create_data_subdir(subdir)); + tt_assert(is_private_dir(subpath)); #endif done: @@ -291,20 +291,20 @@ test_config_write_to_data_subdir(void *arg) #endif // Write attempt shoudl fail, if subdirectory doesn't exist. - test_assert(write_to_data_subdir(subdir, fname, str, NULL)); - test_assert(! check_or_create_data_subdir(subdir)); + tt_assert(write_to_data_subdir(subdir, fname, str, NULL)); + tt_assert(! check_or_create_data_subdir(subdir)); // Content of file after write attempt should be // equal to the original string. - test_assert(!write_to_data_subdir(subdir, fname, str, NULL)); + tt_assert(!write_to_data_subdir(subdir, fname, str, NULL)); cp = read_file_to_str(filepath, 0, NULL); - test_streq(cp, str); + tt_str_op(cp,==, str); tor_free(cp); // A second write operation should overwrite the old content. - test_assert(!write_to_data_subdir(subdir, fname, str, NULL)); + tt_assert(!write_to_data_subdir(subdir, fname, str, NULL)); cp = read_file_to_str(filepath, 0, NULL); - test_streq(cp, str); + tt_str_op(cp,==, str); tor_free(cp); done: @@ -325,48 +325,48 @@ good_bridge_line_test(const char *string, const char *test_addrport, { char *tmp = NULL; bridge_line_t *bridge_line = parse_bridge_line(string); - test_assert(bridge_line); + tt_assert(bridge_line); /* test addrport */ tmp = tor_strdup(fmt_addrport(&bridge_line->addr, bridge_line->port)); - test_streq(test_addrport, tmp); + tt_str_op(test_addrport,==, tmp); tor_free(tmp); /* If we were asked to validate a digest, but we did not get a digest after parsing, we failed. */ if (test_digest && tor_digest_is_zero(bridge_line->digest)) - test_assert(0); + tt_assert(0); /* If we were not asked to validate a digest, and we got a digest after parsing, we failed again. */ if (!test_digest && !tor_digest_is_zero(bridge_line->digest)) - test_assert(0); + tt_assert(0); /* If we were asked to validate a digest, and we got a digest after parsing, make sure it's correct. */ if (test_digest) { tmp = tor_strdup(hex_str(bridge_line->digest, DIGEST_LEN)); tor_strlower(tmp); - test_streq(test_digest, tmp); + tt_str_op(test_digest,==, tmp); tor_free(tmp); } /* If we were asked to validate a transport name, make sure tha it matches with the transport name that was parsed. */ if (test_transport && !bridge_line->transport_name) - test_assert(0); + tt_assert(0); if (!test_transport && bridge_line->transport_name) - test_assert(0); + tt_assert(0); if (test_transport) - test_streq(test_transport, bridge_line->transport_name); + tt_str_op(test_transport,==, bridge_line->transport_name); /* Validate the SOCKS argument smartlist. */ if (test_socks_args && !bridge_line->socks_args) - test_assert(0); + tt_assert(0); if (!test_socks_args && bridge_line->socks_args) - test_assert(0); + tt_assert(0); if (test_socks_args) - test_assert(smartlist_strings_eq(test_socks_args, + tt_assert(smartlist_strings_eq(test_socks_args, bridge_line->socks_args)); done: @@ -382,7 +382,7 @@ bad_bridge_line_test(const char *string) bridge_line_t *bridge_line = parse_bridge_line(string); if (bridge_line) TT_FAIL(("%s was supposed to fail, but it didn't.", string)); - test_assert(!bridge_line); + tt_assert(!bridge_line); done: bridge_line_free(bridge_line); @@ -490,18 +490,18 @@ test_config_parse_transport_options_line(void *arg) { /* too small line */ options_sl = get_options_from_transport_options_line("valley", NULL); - test_assert(!options_sl); + tt_assert(!options_sl); } { /* no k=v values */ options_sl = get_options_from_transport_options_line("hit it!", NULL); - test_assert(!options_sl); + tt_assert(!options_sl); } { /* correct line, but wrong transport specified */ options_sl = get_options_from_transport_options_line("trebuchet k=v", "rook"); - test_assert(!options_sl); + tt_assert(!options_sl); } { /* correct -- no transport specified */ @@ -512,8 +512,8 @@ test_config_parse_transport_options_line(void *arg) options_sl = get_options_from_transport_options_line("rook ladi=dadi weliketo=party", NULL); - test_assert(options_sl); - test_assert(smartlist_strings_eq(options_sl, sl_tmp)); + tt_assert(options_sl); + tt_assert(smartlist_strings_eq(options_sl, sl_tmp)); SMARTLIST_FOREACH(sl_tmp, char *, s, tor_free(s)); smartlist_free(sl_tmp); @@ -531,8 +531,8 @@ test_config_parse_transport_options_line(void *arg) options_sl = get_options_from_transport_options_line("rook ladi=dadi weliketo=party", "rook"); - test_assert(options_sl); - test_assert(smartlist_strings_eq(options_sl, sl_tmp)); + tt_assert(options_sl); + tt_assert(smartlist_strings_eq(options_sl, sl_tmp)); SMARTLIST_FOREACH(sl_tmp, char *, s, tor_free(s)); smartlist_free(sl_tmp); sl_tmp = NULL; @@ -576,7 +576,7 @@ test_config_fix_my_family(void *arg) TT_FAIL(("options_validate failed: %s", err)); } - test_streq(options->MyFamily, "$1111111111111111111111111111111111111111, " + tt_str_op(options->MyFamily,==, "$1111111111111111111111111111111111111111, " "$1111111111111111111111111111111111111112, " "$1111111111111111111111111111111111111113"); diff --git a/src/test/test_containers.c b/src/test/test_containers.c index d7b7b3cfee..24211dd580 100644 --- a/src/test/test_containers.c +++ b/src/test/test_containers.c @@ -29,7 +29,7 @@ compare_strs_for_bsearch_(const void *a, const void **b) /** Helper: return a tristate based on comparing the strings in *<b>a</b> and * *<b>b</b>, excluding a's first character, and ignoring case. */ static int -compare_without_first_ch_(const void *a, const void **b) +cmp_without_first_(const void *a, const void **b) { const char *s1 = a, *s2 = *b; return strcasecmp(s1+1, s2); @@ -37,7 +37,7 @@ compare_without_first_ch_(const void *a, const void **b) /** Run unit tests for basic dynamic-sized array functionality. */ static void -test_container_smartlist_basic(void) +test_container_smartlist_basic(void *arg) { smartlist_t *sl; char *v0 = tor_strdup("v0"); @@ -52,6 +52,7 @@ test_container_smartlist_basic(void) /* XXXX test sort_digests, uniq_strings, uniq_digests */ /* Test smartlist add, del_keeporder, insert, get. */ + (void)arg; sl = smartlist_new(); smartlist_add(sl, v1); smartlist_add(sl, v2); @@ -61,22 +62,22 @@ test_container_smartlist_basic(void) smartlist_insert(sl, 1, v22); smartlist_insert(sl, 0, v0); smartlist_insert(sl, 5, v555); - test_eq_ptr(v0, smartlist_get(sl,0)); - test_eq_ptr(v1, smartlist_get(sl,1)); - test_eq_ptr(v22, smartlist_get(sl,2)); - test_eq_ptr(v3, smartlist_get(sl,3)); - test_eq_ptr(v4, smartlist_get(sl,4)); - test_eq_ptr(v555, smartlist_get(sl,5)); + tt_ptr_op(v0,==, smartlist_get(sl,0)); + tt_ptr_op(v1,==, smartlist_get(sl,1)); + tt_ptr_op(v22,==, smartlist_get(sl,2)); + tt_ptr_op(v3,==, smartlist_get(sl,3)); + tt_ptr_op(v4,==, smartlist_get(sl,4)); + tt_ptr_op(v555,==, smartlist_get(sl,5)); /* Try deleting in the middle. */ smartlist_del(sl, 1); - test_eq_ptr(v555, smartlist_get(sl, 1)); + tt_ptr_op(v555,==, smartlist_get(sl, 1)); /* Try deleting at the end. */ smartlist_del(sl, 4); - test_eq(4, smartlist_len(sl)); + tt_int_op(4,==, smartlist_len(sl)); /* test isin. */ - test_assert(smartlist_contains(sl, v3)); - test_assert(!smartlist_contains(sl, v99)); + tt_assert(smartlist_contains(sl, v3)); + tt_assert(!smartlist_contains(sl, v99)); done: smartlist_free(sl); @@ -92,198 +93,200 @@ test_container_smartlist_basic(void) /** Run unit tests for smartlist-of-strings functionality. */ static void -test_container_smartlist_strings(void) +test_container_smartlist_strings(void *arg) { smartlist_t *sl = smartlist_new(); char *cp=NULL, *cp_alloc=NULL; size_t sz; /* Test split and join */ - test_eq(0, smartlist_len(sl)); + (void)arg; + tt_int_op(0,==, smartlist_len(sl)); smartlist_split_string(sl, "abc", ":", 0, 0); - test_eq(1, smartlist_len(sl)); - test_streq("abc", smartlist_get(sl, 0)); + tt_int_op(1,==, smartlist_len(sl)); + tt_str_op("abc",==, smartlist_get(sl, 0)); smartlist_split_string(sl, "a::bc::", "::", 0, 0); - test_eq(4, smartlist_len(sl)); - test_streq("a", smartlist_get(sl, 1)); - test_streq("bc", smartlist_get(sl, 2)); - test_streq("", smartlist_get(sl, 3)); + tt_int_op(4,==, smartlist_len(sl)); + tt_str_op("a",==, smartlist_get(sl, 1)); + tt_str_op("bc",==, smartlist_get(sl, 2)); + tt_str_op("",==, smartlist_get(sl, 3)); cp_alloc = smartlist_join_strings(sl, "", 0, NULL); - test_streq(cp_alloc, "abcabc"); + tt_str_op(cp_alloc,==, "abcabc"); tor_free(cp_alloc); cp_alloc = smartlist_join_strings(sl, "!", 0, NULL); - test_streq(cp_alloc, "abc!a!bc!"); + tt_str_op(cp_alloc,==, "abc!a!bc!"); tor_free(cp_alloc); cp_alloc = smartlist_join_strings(sl, "XY", 0, NULL); - test_streq(cp_alloc, "abcXYaXYbcXY"); + tt_str_op(cp_alloc,==, "abcXYaXYbcXY"); tor_free(cp_alloc); cp_alloc = smartlist_join_strings(sl, "XY", 1, NULL); - test_streq(cp_alloc, "abcXYaXYbcXYXY"); + tt_str_op(cp_alloc,==, "abcXYaXYbcXYXY"); tor_free(cp_alloc); cp_alloc = smartlist_join_strings(sl, "", 1, NULL); - test_streq(cp_alloc, "abcabc"); + tt_str_op(cp_alloc,==, "abcabc"); tor_free(cp_alloc); smartlist_split_string(sl, "/def/ /ghijk", "/", 0, 0); - test_eq(8, smartlist_len(sl)); - test_streq("", smartlist_get(sl, 4)); - test_streq("def", smartlist_get(sl, 5)); - test_streq(" ", smartlist_get(sl, 6)); - test_streq("ghijk", smartlist_get(sl, 7)); + tt_int_op(8,==, smartlist_len(sl)); + tt_str_op("",==, smartlist_get(sl, 4)); + tt_str_op("def",==, smartlist_get(sl, 5)); + tt_str_op(" ",==, smartlist_get(sl, 6)); + tt_str_op("ghijk",==, smartlist_get(sl, 7)); SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp)); smartlist_clear(sl); smartlist_split_string(sl, "a,bbd,cdef", ",", SPLIT_SKIP_SPACE, 0); - test_eq(3, smartlist_len(sl)); - test_streq("a", smartlist_get(sl,0)); - test_streq("bbd", smartlist_get(sl,1)); - test_streq("cdef", smartlist_get(sl,2)); + tt_int_op(3,==, smartlist_len(sl)); + tt_str_op("a",==, smartlist_get(sl,0)); + tt_str_op("bbd",==, smartlist_get(sl,1)); + tt_str_op("cdef",==, smartlist_get(sl,2)); smartlist_split_string(sl, " z <> zhasd <> <> bnud<> ", "<>", SPLIT_SKIP_SPACE, 0); - test_eq(8, smartlist_len(sl)); - test_streq("z", smartlist_get(sl,3)); - test_streq("zhasd", smartlist_get(sl,4)); - test_streq("", smartlist_get(sl,5)); - test_streq("bnud", smartlist_get(sl,6)); - test_streq("", smartlist_get(sl,7)); + tt_int_op(8,==, smartlist_len(sl)); + tt_str_op("z",==, smartlist_get(sl,3)); + tt_str_op("zhasd",==, smartlist_get(sl,4)); + tt_str_op("",==, smartlist_get(sl,5)); + tt_str_op("bnud",==, smartlist_get(sl,6)); + tt_str_op("",==, smartlist_get(sl,7)); SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp)); smartlist_clear(sl); smartlist_split_string(sl, " ab\tc \td ef ", NULL, SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0); - test_eq(4, smartlist_len(sl)); - test_streq("ab", smartlist_get(sl,0)); - test_streq("c", smartlist_get(sl,1)); - test_streq("d", smartlist_get(sl,2)); - test_streq("ef", smartlist_get(sl,3)); + tt_int_op(4,==, smartlist_len(sl)); + tt_str_op("ab",==, smartlist_get(sl,0)); + tt_str_op("c",==, smartlist_get(sl,1)); + tt_str_op("d",==, smartlist_get(sl,2)); + tt_str_op("ef",==, smartlist_get(sl,3)); smartlist_split_string(sl, "ghi\tj", NULL, SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0); - test_eq(6, smartlist_len(sl)); - test_streq("ghi", smartlist_get(sl,4)); - test_streq("j", smartlist_get(sl,5)); + tt_int_op(6,==, smartlist_len(sl)); + tt_str_op("ghi",==, smartlist_get(sl,4)); + tt_str_op("j",==, smartlist_get(sl,5)); SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp)); smartlist_clear(sl); cp_alloc = smartlist_join_strings(sl, "XY", 0, NULL); - test_streq(cp_alloc, ""); + tt_str_op(cp_alloc,==, ""); tor_free(cp_alloc); cp_alloc = smartlist_join_strings(sl, "XY", 1, NULL); - test_streq(cp_alloc, "XY"); + tt_str_op(cp_alloc,==, "XY"); tor_free(cp_alloc); smartlist_split_string(sl, " z <> zhasd <> <> bnud<> ", "<>", SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0); - test_eq(3, smartlist_len(sl)); - test_streq("z", smartlist_get(sl, 0)); - test_streq("zhasd", smartlist_get(sl, 1)); - test_streq("bnud", smartlist_get(sl, 2)); + tt_int_op(3,==, smartlist_len(sl)); + tt_str_op("z",==, smartlist_get(sl, 0)); + tt_str_op("zhasd",==, smartlist_get(sl, 1)); + tt_str_op("bnud",==, smartlist_get(sl, 2)); smartlist_split_string(sl, " z <> zhasd <> <> bnud<> ", "<>", SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 2); - test_eq(5, smartlist_len(sl)); - test_streq("z", smartlist_get(sl, 3)); - test_streq("zhasd <> <> bnud<>", smartlist_get(sl, 4)); + tt_int_op(5,==, smartlist_len(sl)); + tt_str_op("z",==, smartlist_get(sl, 3)); + tt_str_op("zhasd <> <> bnud<>",==, smartlist_get(sl, 4)); SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp)); smartlist_clear(sl); smartlist_split_string(sl, "abcd\n", "\n", SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0); - test_eq(1, smartlist_len(sl)); - test_streq("abcd", smartlist_get(sl, 0)); + tt_int_op(1,==, smartlist_len(sl)); + tt_str_op("abcd",==, smartlist_get(sl, 0)); smartlist_split_string(sl, "efgh", "\n", SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0); - test_eq(2, smartlist_len(sl)); - test_streq("efgh", smartlist_get(sl, 1)); + tt_int_op(2,==, smartlist_len(sl)); + tt_str_op("efgh",==, smartlist_get(sl, 1)); SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp)); smartlist_clear(sl); /* Test swapping, shuffling, and sorting. */ smartlist_split_string(sl, "the,onion,router,by,arma,and,nickm", ",", 0, 0); - test_eq(7, smartlist_len(sl)); + tt_int_op(7,==, smartlist_len(sl)); smartlist_sort(sl, compare_strs_); cp_alloc = smartlist_join_strings(sl, ",", 0, NULL); - test_streq(cp_alloc,"and,arma,by,nickm,onion,router,the"); + tt_str_op(cp_alloc,==, "and,arma,by,nickm,onion,router,the"); tor_free(cp_alloc); smartlist_swap(sl, 1, 5); cp_alloc = smartlist_join_strings(sl, ",", 0, NULL); - test_streq(cp_alloc,"and,router,by,nickm,onion,arma,the"); + tt_str_op(cp_alloc,==, "and,router,by,nickm,onion,arma,the"); tor_free(cp_alloc); smartlist_shuffle(sl); - test_eq(7, smartlist_len(sl)); - test_assert(smartlist_contains_string(sl, "and")); - test_assert(smartlist_contains_string(sl, "router")); - test_assert(smartlist_contains_string(sl, "by")); - test_assert(smartlist_contains_string(sl, "nickm")); - test_assert(smartlist_contains_string(sl, "onion")); - test_assert(smartlist_contains_string(sl, "arma")); - test_assert(smartlist_contains_string(sl, "the")); + tt_int_op(7,==, smartlist_len(sl)); + tt_assert(smartlist_contains_string(sl, "and")); + tt_assert(smartlist_contains_string(sl, "router")); + tt_assert(smartlist_contains_string(sl, "by")); + tt_assert(smartlist_contains_string(sl, "nickm")); + tt_assert(smartlist_contains_string(sl, "onion")); + tt_assert(smartlist_contains_string(sl, "arma")); + tt_assert(smartlist_contains_string(sl, "the")); /* Test bsearch. */ smartlist_sort(sl, compare_strs_); - test_streq("nickm", smartlist_bsearch(sl, "zNicKM", - compare_without_first_ch_)); - test_streq("and", smartlist_bsearch(sl, " AND", compare_without_first_ch_)); - test_eq_ptr(NULL, smartlist_bsearch(sl, " ANz", compare_without_first_ch_)); + tt_str_op("nickm",==, smartlist_bsearch(sl, "zNicKM", + cmp_without_first_)); + tt_str_op("and",==, + smartlist_bsearch(sl, " AND", cmp_without_first_)); + tt_ptr_op(NULL,==, smartlist_bsearch(sl, " ANz", cmp_without_first_)); /* Test bsearch_idx */ { int f; smartlist_t *tmp = NULL; - test_eq(0, smartlist_bsearch_idx(sl," aaa",compare_without_first_ch_,&f)); - test_eq(f, 0); - test_eq(0, smartlist_bsearch_idx(sl," and",compare_without_first_ch_,&f)); - test_eq(f, 1); - test_eq(1, smartlist_bsearch_idx(sl," arm",compare_without_first_ch_,&f)); - test_eq(f, 0); - test_eq(1, smartlist_bsearch_idx(sl," arma",compare_without_first_ch_,&f)); - test_eq(f, 1); - test_eq(2, smartlist_bsearch_idx(sl," armb",compare_without_first_ch_,&f)); - test_eq(f, 0); - test_eq(7, smartlist_bsearch_idx(sl," zzzz",compare_without_first_ch_,&f)); - test_eq(f, 0); + tt_int_op(0,==,smartlist_bsearch_idx(sl," aaa",cmp_without_first_,&f)); + tt_int_op(f,==, 0); + tt_int_op(0,==, smartlist_bsearch_idx(sl," and",cmp_without_first_,&f)); + tt_int_op(f,==, 1); + tt_int_op(1,==, smartlist_bsearch_idx(sl," arm",cmp_without_first_,&f)); + tt_int_op(f,==, 0); + tt_int_op(1,==, smartlist_bsearch_idx(sl," arma",cmp_without_first_,&f)); + tt_int_op(f,==, 1); + tt_int_op(2,==, smartlist_bsearch_idx(sl," armb",cmp_without_first_,&f)); + tt_int_op(f,==, 0); + tt_int_op(7,==, smartlist_bsearch_idx(sl," zzzz",cmp_without_first_,&f)); + tt_int_op(f,==, 0); /* Test trivial cases for list of length 0 or 1 */ tmp = smartlist_new(); - test_eq(0, smartlist_bsearch_idx(tmp, "foo", + tt_int_op(0,==, smartlist_bsearch_idx(tmp, "foo", compare_strs_for_bsearch_, &f)); - test_eq(f, 0); + tt_int_op(f,==, 0); smartlist_insert(tmp, 0, (void *)("bar")); - test_eq(1, smartlist_bsearch_idx(tmp, "foo", + tt_int_op(1,==, smartlist_bsearch_idx(tmp, "foo", compare_strs_for_bsearch_, &f)); - test_eq(f, 0); - test_eq(0, smartlist_bsearch_idx(tmp, "aaa", + tt_int_op(f,==, 0); + tt_int_op(0,==, smartlist_bsearch_idx(tmp, "aaa", compare_strs_for_bsearch_, &f)); - test_eq(f, 0); - test_eq(0, smartlist_bsearch_idx(tmp, "bar", + tt_int_op(f,==, 0); + tt_int_op(0,==, smartlist_bsearch_idx(tmp, "bar", compare_strs_for_bsearch_, &f)); - test_eq(f, 1); + tt_int_op(f,==, 1); /* ... and one for length 2 */ smartlist_insert(tmp, 1, (void *)("foo")); - test_eq(1, smartlist_bsearch_idx(tmp, "foo", + tt_int_op(1,==, smartlist_bsearch_idx(tmp, "foo", compare_strs_for_bsearch_, &f)); - test_eq(f, 1); - test_eq(2, smartlist_bsearch_idx(tmp, "goo", + tt_int_op(f,==, 1); + tt_int_op(2,==, smartlist_bsearch_idx(tmp, "goo", compare_strs_for_bsearch_, &f)); - test_eq(f, 0); + tt_int_op(f,==, 0); smartlist_free(tmp); } /* Test reverse() and pop_last() */ smartlist_reverse(sl); cp_alloc = smartlist_join_strings(sl, ",", 0, NULL); - test_streq(cp_alloc,"the,router,onion,nickm,by,arma,and"); + tt_str_op(cp_alloc,==, "the,router,onion,nickm,by,arma,and"); tor_free(cp_alloc); cp_alloc = smartlist_pop_last(sl); - test_streq(cp_alloc, "and"); + tt_str_op(cp_alloc,==, "and"); tor_free(cp_alloc); - test_eq(smartlist_len(sl), 6); + tt_int_op(smartlist_len(sl),==, 6); SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp)); smartlist_clear(sl); cp_alloc = smartlist_pop_last(sl); - test_eq_ptr(cp_alloc, NULL); + tt_ptr_op(cp_alloc,==, NULL); /* Test uniq() */ smartlist_split_string(sl, @@ -292,16 +295,16 @@ test_container_smartlist_strings(void) smartlist_sort(sl, compare_strs_); smartlist_uniq(sl, compare_strs_, tor_free_); cp_alloc = smartlist_join_strings(sl, ",", 0, NULL); - test_streq(cp_alloc, "50,a,canal,man,noon,panama,plan,radar"); + tt_str_op(cp_alloc,==, "50,a,canal,man,noon,panama,plan,radar"); tor_free(cp_alloc); /* Test contains_string, contains_string_case and contains_int_as_string */ - test_assert(smartlist_contains_string(sl, "noon")); - test_assert(!smartlist_contains_string(sl, "noonoon")); - test_assert(smartlist_contains_string_case(sl, "nOOn")); - test_assert(!smartlist_contains_string_case(sl, "nooNooN")); - test_assert(smartlist_contains_int_as_string(sl, 50)); - test_assert(!smartlist_contains_int_as_string(sl, 60)); + tt_assert(smartlist_contains_string(sl, "noon")); + tt_assert(!smartlist_contains_string(sl, "noonoon")); + tt_assert(smartlist_contains_string_case(sl, "nOOn")); + tt_assert(!smartlist_contains_string_case(sl, "nooNooN")); + tt_assert(smartlist_contains_int_as_string(sl, 50)); + tt_assert(!smartlist_contains_int_as_string(sl, 60)); /* Test smartlist_choose */ { @@ -309,7 +312,7 @@ test_container_smartlist_strings(void) int allsame = 1; int allin = 1; void *first = smartlist_choose(sl); - test_assert(smartlist_contains(sl, first)); + tt_assert(smartlist_contains(sl, first)); for (i = 0; i < 100; ++i) { void *second = smartlist_choose(sl); if (second != first) @@ -317,8 +320,8 @@ test_container_smartlist_strings(void) if (!smartlist_contains(sl, second)) allin = 0; } - test_assert(!allsame); - test_assert(allin); + tt_assert(!allsame); + tt_assert(allin); } SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp)); smartlist_clear(sl); @@ -328,17 +331,17 @@ test_container_smartlist_strings(void) "Some say the Earth will end in ice and some in fire", " ", 0, 0); cp = smartlist_get(sl, 4); - test_streq(cp, "will"); + tt_str_op(cp,==, "will"); smartlist_add(sl, cp); smartlist_remove(sl, cp); tor_free(cp); cp_alloc = smartlist_join_strings(sl, ",", 0, NULL); - test_streq(cp_alloc, "Some,say,the,Earth,fire,end,in,ice,and,some,in"); + tt_str_op(cp_alloc,==, "Some,say,the,Earth,fire,end,in,ice,and,some,in"); tor_free(cp_alloc); smartlist_string_remove(sl, "in"); cp_alloc = smartlist_join_strings2(sl, "+XX", 1, 0, &sz); - test_streq(cp_alloc, "Some+say+the+Earth+fire+end+some+ice+and"); - test_eq((int)sz, 40); + tt_str_op(cp_alloc,==, "Some+say+the+Earth+fire+end+some+ice+and"); + tt_int_op((int)sz,==, 40); done: @@ -349,7 +352,7 @@ test_container_smartlist_strings(void) /** Run unit tests for smartlist set manipulation functions. */ static void -test_container_smartlist_overlap(void) +test_container_smartlist_overlap(void *arg) { smartlist_t *sl = smartlist_new(); smartlist_t *ints = smartlist_new(); @@ -357,6 +360,7 @@ test_container_smartlist_overlap(void) smartlist_t *evens = smartlist_new(); smartlist_t *primes = smartlist_new(); int i; + (void)arg; for (i=1; i < 10; i += 2) smartlist_add(odds, (void*)(uintptr_t)i); for (i=0; i < 10; i += 2) @@ -365,7 +369,7 @@ test_container_smartlist_overlap(void) /* add_all */ smartlist_add_all(ints, odds); smartlist_add_all(ints, evens); - test_eq(smartlist_len(ints), 10); + tt_int_op(smartlist_len(ints),==, 10); smartlist_add(primes, (void*)2); smartlist_add(primes, (void*)3); @@ -373,24 +377,24 @@ test_container_smartlist_overlap(void) smartlist_add(primes, (void*)7); /* overlap */ - test_assert(smartlist_overlap(ints, odds)); - test_assert(smartlist_overlap(odds, primes)); - test_assert(smartlist_overlap(evens, primes)); - test_assert(!smartlist_overlap(odds, evens)); + tt_assert(smartlist_overlap(ints, odds)); + tt_assert(smartlist_overlap(odds, primes)); + tt_assert(smartlist_overlap(evens, primes)); + tt_assert(!smartlist_overlap(odds, evens)); /* intersect */ smartlist_add_all(sl, odds); smartlist_intersect(sl, primes); - test_eq(smartlist_len(sl), 3); - test_assert(smartlist_contains(sl, (void*)3)); - test_assert(smartlist_contains(sl, (void*)5)); - test_assert(smartlist_contains(sl, (void*)7)); + tt_int_op(smartlist_len(sl),==, 3); + tt_assert(smartlist_contains(sl, (void*)3)); + tt_assert(smartlist_contains(sl, (void*)5)); + tt_assert(smartlist_contains(sl, (void*)7)); /* subtract */ smartlist_add_all(sl, primes); smartlist_subtract(sl, odds); - test_eq(smartlist_len(sl), 1); - test_assert(smartlist_contains(sl, (void*)2)); + tt_int_op(smartlist_len(sl),==, 1); + tt_assert(smartlist_contains(sl, (void*)2)); done: smartlist_free(odds); @@ -402,31 +406,32 @@ test_container_smartlist_overlap(void) /** Run unit tests for smartlist-of-digests functions. */ static void -test_container_smartlist_digests(void) +test_container_smartlist_digests(void *arg) { smartlist_t *sl = smartlist_new(); /* contains_digest */ + (void)arg; smartlist_add(sl, tor_memdup("AAAAAAAAAAAAAAAAAAAA", DIGEST_LEN)); smartlist_add(sl, tor_memdup("\00090AAB2AAAAaasdAAAAA", DIGEST_LEN)); smartlist_add(sl, tor_memdup("\00090AAB2AAAAaasdAAAAA", DIGEST_LEN)); - test_eq(0, smartlist_contains_digest(NULL, "AAAAAAAAAAAAAAAAAAAA")); - test_assert(smartlist_contains_digest(sl, "AAAAAAAAAAAAAAAAAAAA")); - test_assert(smartlist_contains_digest(sl, "\00090AAB2AAAAaasdAAAAA")); - test_eq(0, smartlist_contains_digest(sl, "\00090AAB2AAABaasdAAAAA")); + tt_int_op(0,==, smartlist_contains_digest(NULL, "AAAAAAAAAAAAAAAAAAAA")); + tt_assert(smartlist_contains_digest(sl, "AAAAAAAAAAAAAAAAAAAA")); + tt_assert(smartlist_contains_digest(sl, "\00090AAB2AAAAaasdAAAAA")); + tt_int_op(0,==, smartlist_contains_digest(sl, "\00090AAB2AAABaasdAAAAA")); /* sort digests */ smartlist_sort_digests(sl); - test_memeq(smartlist_get(sl, 0), "\00090AAB2AAAAaasdAAAAA", DIGEST_LEN); - test_memeq(smartlist_get(sl, 1), "\00090AAB2AAAAaasdAAAAA", DIGEST_LEN); - test_memeq(smartlist_get(sl, 2), "AAAAAAAAAAAAAAAAAAAA", DIGEST_LEN); - test_eq(3, smartlist_len(sl)); + tt_mem_op(smartlist_get(sl, 0),==, "\00090AAB2AAAAaasdAAAAA", DIGEST_LEN); + tt_mem_op(smartlist_get(sl, 1),==, "\00090AAB2AAAAaasdAAAAA", DIGEST_LEN); + tt_mem_op(smartlist_get(sl, 2),==, "AAAAAAAAAAAAAAAAAAAA", DIGEST_LEN); + tt_int_op(3,==, smartlist_len(sl)); /* uniq_digests */ smartlist_uniq_digests(sl); - test_eq(2, smartlist_len(sl)); - test_memeq(smartlist_get(sl, 0), "\00090AAB2AAAAaasdAAAAA", DIGEST_LEN); - test_memeq(smartlist_get(sl, 1), "AAAAAAAAAAAAAAAAAAAA", DIGEST_LEN); + tt_int_op(2,==, smartlist_len(sl)); + tt_mem_op(smartlist_get(sl, 0),==, "\00090AAB2AAAAaasdAAAAA", DIGEST_LEN); + tt_mem_op(smartlist_get(sl, 1),==, "AAAAAAAAAAAAAAAAAAAA", DIGEST_LEN); done: SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp)); @@ -435,13 +440,14 @@ test_container_smartlist_digests(void) /** Run unit tests for concatenate-a-smartlist-of-strings functions. */ static void -test_container_smartlist_join(void) +test_container_smartlist_join(void *arg) { smartlist_t *sl = smartlist_new(); smartlist_t *sl2 = smartlist_new(), *sl3 = smartlist_new(), *sl4 = smartlist_new(); char *joined=NULL; /* unique, sorted. */ + (void)arg; smartlist_split_string(sl, "Abashments Ambush Anchorman Bacon Banks Borscht " "Bunks Inhumane Insurance Knish Know Manners " @@ -457,21 +463,21 @@ test_container_smartlist_join(void) sl2, char *, cp2, strcmp(cp1,cp2), smartlist_add(sl3, cp2)) { - test_streq(cp1, cp2); + tt_str_op(cp1,==, cp2); smartlist_add(sl4, cp1); } SMARTLIST_FOREACH_JOIN_END(cp1, cp2); SMARTLIST_FOREACH(sl3, const char *, cp, - test_assert(smartlist_contains(sl2, cp) && + tt_assert(smartlist_contains(sl2, cp) && !smartlist_contains_string(sl, cp))); SMARTLIST_FOREACH(sl4, const char *, cp, - test_assert(smartlist_contains(sl, cp) && + tt_assert(smartlist_contains(sl, cp) && smartlist_contains_string(sl2, cp))); joined = smartlist_join_strings(sl3, ",", 0, NULL); - test_streq(joined, "Anemias,Anemias,Crossbowmen,Work"); + tt_str_op(joined,==, "Anemias,Anemias,Crossbowmen,Work"); tor_free(joined); joined = smartlist_join_strings(sl4, ",", 0, NULL); - test_streq(joined, "Ambush,Anchorman,Anchorman,Bacon,Inhumane,Insurance," + tt_str_op(joined,==, "Ambush,Anchorman,Anchorman,Bacon,Inhumane,Insurance," "Knish,Know,Manners,Manners,Maraschinos,Wombats,Wombats"); tor_free(joined); @@ -532,18 +538,19 @@ test_container_smartlist_ints_eq(void *arg) /** Run unit tests for bitarray code */ static void -test_container_bitarray(void) +test_container_bitarray(void *arg) { bitarray_t *ba = NULL; int i, j, ok=1; + (void)arg; ba = bitarray_init_zero(1); - test_assert(ba); - test_assert(! bitarray_is_set(ba, 0)); + tt_assert(ba); + tt_assert(! bitarray_is_set(ba, 0)); bitarray_set(ba, 0); - test_assert(bitarray_is_set(ba, 0)); + tt_assert(bitarray_is_set(ba, 0)); bitarray_clear(ba, 0); - test_assert(! bitarray_is_set(ba, 0)); + tt_assert(! bitarray_is_set(ba, 0)); bitarray_free(ba); ba = bitarray_init_zero(1023); @@ -558,7 +565,7 @@ test_container_bitarray(void) if (!bool_eq(bitarray_is_set(ba, j), j%i)) ok = 0; } - test_assert(ok); + tt_assert(ok); if (i < 7) ++i; else if (i == 28) @@ -575,7 +582,7 @@ test_container_bitarray(void) /** Run unit tests for digest set code (implemented as a hashtable or as a * bloom filter) */ static void -test_container_digestset(void) +test_container_digestset(void *arg) { smartlist_t *included = smartlist_new(); char d[DIGEST_LEN]; @@ -584,6 +591,7 @@ test_container_digestset(void) int false_positives = 0; digestset_t *set = NULL; + (void)arg; for (i = 0; i < 1000; ++i) { crypto_rand(d, DIGEST_LEN); smartlist_add(included, tor_memdup(d, DIGEST_LEN)); @@ -592,19 +600,19 @@ test_container_digestset(void) SMARTLIST_FOREACH(included, const char *, cp, if (digestset_contains(set, cp)) ok = 0); - test_assert(ok); + tt_assert(ok); SMARTLIST_FOREACH(included, const char *, cp, digestset_add(set, cp)); SMARTLIST_FOREACH(included, const char *, cp, if (!digestset_contains(set, cp)) ok = 0); - test_assert(ok); + tt_assert(ok); for (i = 0; i < 1000; ++i) { crypto_rand(d, DIGEST_LEN); if (digestset_contains(set, d)) ++false_positives; } - test_assert(false_positives < 50); /* Should be far lower. */ + tt_int_op(50, >, false_positives); /* Should be far lower. */ done: if (set) @@ -628,7 +636,7 @@ compare_strings_for_pqueue_(const void *p1, const void *p2) /** Run unit tests for heap-based priority queue functions. */ static void -test_container_pqueue(void) +test_container_pqueue(void *arg) { smartlist_t *sl = smartlist_new(); int (*cmp)(const void *, const void*); @@ -650,6 +658,8 @@ test_container_pqueue(void) #define OK() smartlist_pqueue_assert_ok(sl, cmp, offset) + (void)arg; + cmp = compare_strings_for_pqueue_; smartlist_pqueue_add(sl, cmp, offset, &cows); smartlist_pqueue_add(sl, cmp, offset, &zebras); @@ -665,31 +675,31 @@ test_container_pqueue(void) OK(); - test_eq(smartlist_len(sl), 11); - test_eq_ptr(smartlist_get(sl, 0), &apples); - test_eq_ptr(smartlist_pqueue_pop(sl, cmp, offset), &apples); - test_eq(smartlist_len(sl), 10); + tt_int_op(smartlist_len(sl),==, 11); + tt_ptr_op(smartlist_get(sl, 0),==, &apples); + tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),==, &apples); + tt_int_op(smartlist_len(sl),==, 10); OK(); - test_eq_ptr(smartlist_pqueue_pop(sl, cmp, offset), &cows); - test_eq_ptr(smartlist_pqueue_pop(sl, cmp, offset), &daschunds); + tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),==, &cows); + tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),==, &daschunds); smartlist_pqueue_add(sl, cmp, offset, &chinchillas); OK(); smartlist_pqueue_add(sl, cmp, offset, &fireflies); OK(); - test_eq_ptr(smartlist_pqueue_pop(sl, cmp, offset), &chinchillas); - test_eq_ptr(smartlist_pqueue_pop(sl, cmp, offset), &eggplants); - test_eq_ptr(smartlist_pqueue_pop(sl, cmp, offset), &fireflies); + tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),==, &chinchillas); + tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),==, &eggplants); + tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),==, &fireflies); OK(); - test_eq_ptr(smartlist_pqueue_pop(sl, cmp, offset), &fish); - test_eq_ptr(smartlist_pqueue_pop(sl, cmp, offset), &frogs); - test_eq_ptr(smartlist_pqueue_pop(sl, cmp, offset), &lobsters); - test_eq_ptr(smartlist_pqueue_pop(sl, cmp, offset), &roquefort); + tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),==, &fish); + tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),==, &frogs); + tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),==, &lobsters); + tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),==, &roquefort); OK(); - test_eq(smartlist_len(sl), 3); - test_eq_ptr(smartlist_pqueue_pop(sl, cmp, offset), &squid); - test_eq_ptr(smartlist_pqueue_pop(sl, cmp, offset), &weissbier); - test_eq_ptr(smartlist_pqueue_pop(sl, cmp, offset), &zebras); - test_eq(smartlist_len(sl), 0); + tt_int_op(smartlist_len(sl),==, 3); + tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),==, &squid); + tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),==, &weissbier); + tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),==, &zebras); + tt_int_op(smartlist_len(sl),==, 0); OK(); /* Now test remove. */ @@ -699,21 +709,21 @@ test_container_pqueue(void) smartlist_pqueue_add(sl, cmp, offset, &apples); smartlist_pqueue_add(sl, cmp, offset, &squid); smartlist_pqueue_add(sl, cmp, offset, &zebras); - test_eq(smartlist_len(sl), 6); + tt_int_op(smartlist_len(sl),==, 6); OK(); smartlist_pqueue_remove(sl, cmp, offset, &zebras); - test_eq(smartlist_len(sl), 5); + tt_int_op(smartlist_len(sl),==, 5); OK(); smartlist_pqueue_remove(sl, cmp, offset, &cows); - test_eq(smartlist_len(sl), 4); + tt_int_op(smartlist_len(sl),==, 4); OK(); smartlist_pqueue_remove(sl, cmp, offset, &apples); - test_eq(smartlist_len(sl), 3); + tt_int_op(smartlist_len(sl),==, 3); OK(); - test_eq_ptr(smartlist_pqueue_pop(sl, cmp, offset), &fish); - test_eq_ptr(smartlist_pqueue_pop(sl, cmp, offset), &frogs); - test_eq_ptr(smartlist_pqueue_pop(sl, cmp, offset), &squid); - test_eq(smartlist_len(sl), 0); + tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),==, &fish); + tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),==, &frogs); + tt_ptr_op(smartlist_pqueue_pop(sl, cmp, offset),==, &squid); + tt_int_op(smartlist_len(sl),==, 0); OK(); #undef OK @@ -725,7 +735,7 @@ test_container_pqueue(void) /** Run unit tests for string-to-void* map functions */ static void -test_container_strmap(void) +test_container_strmap(void *arg) { strmap_t *map; strmap_iter_t *iter; @@ -742,32 +752,33 @@ test_container_strmap(void) char *v104 = tor_strdup("v104"); char *v105 = tor_strdup("v105"); + (void)arg; map = strmap_new(); - test_assert(map); - test_eq(strmap_size(map), 0); - test_assert(strmap_isempty(map)); + tt_assert(map); + tt_int_op(strmap_size(map),==, 0); + tt_assert(strmap_isempty(map)); v = strmap_set(map, "K1", v99); - test_eq_ptr(v, NULL); - test_assert(!strmap_isempty(map)); + tt_ptr_op(v,==, NULL); + tt_assert(!strmap_isempty(map)); v = strmap_set(map, "K2", v101); - test_eq_ptr(v, NULL); + tt_ptr_op(v,==, NULL); v = strmap_set(map, "K1", v100); - test_eq_ptr(v, v99); - test_eq_ptr(strmap_get(map,"K1"), v100); - test_eq_ptr(strmap_get(map,"K2"), v101); - test_eq_ptr(strmap_get(map,"K-not-there"), NULL); + tt_ptr_op(v,==, v99); + tt_ptr_op(strmap_get(map,"K1"),==, v100); + tt_ptr_op(strmap_get(map,"K2"),==, v101); + tt_ptr_op(strmap_get(map,"K-not-there"),==, NULL); strmap_assert_ok(map); v = strmap_remove(map,"K2"); strmap_assert_ok(map); - test_eq_ptr(v, v101); - test_eq_ptr(strmap_get(map,"K2"), NULL); - test_eq_ptr(strmap_remove(map,"K2"), NULL); + tt_ptr_op(v,==, v101); + tt_ptr_op(strmap_get(map,"K2"),==, NULL); + tt_ptr_op(strmap_remove(map,"K2"),==, NULL); strmap_set(map, "K2", v101); strmap_set(map, "K3", v102); strmap_set(map, "K4", v103); - test_eq(strmap_size(map), 4); + tt_int_op(strmap_size(map),==, 4); strmap_assert_ok(map); strmap_set(map, "K5", v104); strmap_set(map, "K6", v105); @@ -779,7 +790,7 @@ test_container_strmap(void) while (!strmap_iter_done(iter)) { strmap_iter_get(iter,&k,&v); smartlist_add(found_keys, tor_strdup(k)); - test_eq_ptr(v, strmap_get(map, k)); + tt_ptr_op(v,==, strmap_get(map, k)); if (!strcmp(k, "K2")) { iter = strmap_iter_next_rmv(map,iter); @@ -789,12 +800,12 @@ test_container_strmap(void) } /* Make sure we removed K2, but not the others. */ - test_eq_ptr(strmap_get(map, "K2"), NULL); - test_eq_ptr(strmap_get(map, "K5"), v104); + tt_ptr_op(strmap_get(map, "K2"),==, NULL); + tt_ptr_op(strmap_get(map, "K5"),==, v104); /* Make sure we visited everyone once */ smartlist_sort_strings(found_keys); visited = smartlist_join_strings(found_keys, ":", 0, NULL); - test_streq(visited, "K1:K2:K3:K4:K5:K6"); + tt_str_op(visited,==, "K1:K2:K3:K4:K5:K6"); strmap_assert_ok(map); /* Clean up after ourselves. */ @@ -804,13 +815,13 @@ test_container_strmap(void) /* Now try some lc functions. */ map = strmap_new(); strmap_set_lc(map,"Ab.C", v1); - test_eq_ptr(strmap_get(map,"ab.c"), v1); + tt_ptr_op(strmap_get(map,"ab.c"),==, v1); strmap_assert_ok(map); - test_eq_ptr(strmap_get_lc(map,"AB.C"), v1); - test_eq_ptr(strmap_get(map,"AB.C"), NULL); - test_eq_ptr(strmap_remove_lc(map,"aB.C"), v1); + tt_ptr_op(strmap_get_lc(map,"AB.C"),==, v1); + tt_ptr_op(strmap_get(map,"AB.C"),==, NULL); + tt_ptr_op(strmap_remove_lc(map,"aB.C"),==, v1); strmap_assert_ok(map); - test_eq_ptr(strmap_get_lc(map,"AB.C"), NULL); + tt_ptr_op(strmap_get_lc(map,"AB.C"),==, NULL); done: if (map) @@ -832,7 +843,7 @@ test_container_strmap(void) /** Run unit tests for getting the median of a list. */ static void -test_container_order_functions(void) +test_container_order_functions(void *arg) { int lst[25], n = 0; unsigned int lst2[25]; @@ -840,42 +851,43 @@ test_container_order_functions(void) #define median() median_int(lst, n) + (void)arg; lst[n++] = 12; - test_eq(12, median()); /* 12 */ + tt_int_op(12,==, median()); /* 12 */ lst[n++] = 77; //smartlist_shuffle(sl); - test_eq(12, median()); /* 12, 77 */ + tt_int_op(12,==, median()); /* 12, 77 */ lst[n++] = 77; //smartlist_shuffle(sl); - test_eq(77, median()); /* 12, 77, 77 */ + tt_int_op(77,==, median()); /* 12, 77, 77 */ lst[n++] = 24; - test_eq(24, median()); /* 12,24,77,77 */ + tt_int_op(24,==, median()); /* 12,24,77,77 */ lst[n++] = 60; lst[n++] = 12; lst[n++] = 25; //smartlist_shuffle(sl); - test_eq(25, median()); /* 12,12,24,25,60,77,77 */ + tt_int_op(25,==, median()); /* 12,12,24,25,60,77,77 */ #undef median #define third_quartile() third_quartile_uint32(lst2, n) n = 0; lst2[n++] = 1; - test_eq(1, third_quartile()); /* ~1~ */ + tt_int_op(1,==, third_quartile()); /* ~1~ */ lst2[n++] = 2; - test_eq(2, third_quartile()); /* 1, ~2~ */ + tt_int_op(2,==, third_quartile()); /* 1, ~2~ */ lst2[n++] = 3; lst2[n++] = 4; lst2[n++] = 5; - test_eq(4, third_quartile()); /* 1, 2, 3, ~4~, 5 */ + tt_int_op(4,==, third_quartile()); /* 1, 2, 3, ~4~, 5 */ lst2[n++] = 6; lst2[n++] = 7; lst2[n++] = 8; lst2[n++] = 9; - test_eq(7, third_quartile()); /* 1, 2, 3, 4, 5, 6, ~7~, 8, 9 */ + tt_int_op(7,==, third_quartile()); /* 1, 2, 3, 4, 5, 6, ~7~, 8, 9 */ lst2[n++] = 10; lst2[n++] = 11; - test_eq(9, third_quartile()); /* 1, 2, 3, 4, 5, 6, 7, 8, ~9~, 10, 11 */ + tt_int_op(9,==, third_quartile()); /* 1, 2, 3, 4, 5, 6, 7, 8, ~9~, 10, 11 */ #undef third_quartile @@ -929,7 +941,7 @@ test_container_di_map(void *arg) /** Run unit tests for fp_pair-to-void* map functions */ static void -test_container_fp_pair_map(void) +test_container_fp_pair_map(void *arg) { fp_pair_map_t *map; fp_pair_t fp1, fp2, fp3, fp4, fp5, fp6; @@ -944,10 +956,11 @@ test_container_fp_pair_map(void) char *v104 = tor_strdup("v104"); char *v105 = tor_strdup("v105"); + (void)arg; map = fp_pair_map_new(); - test_assert(map); - test_eq(fp_pair_map_size(map), 0); - test_assert(fp_pair_map_isempty(map)); + tt_assert(map); + tt_int_op(fp_pair_map_size(map),==, 0); + tt_assert(fp_pair_map_isempty(map)); memset(fp1.first, 0x11, DIGEST_LEN); memset(fp1.second, 0x12, DIGEST_LEN); @@ -964,26 +977,26 @@ test_container_fp_pair_map(void) v = fp_pair_map_set(map, &fp1, v99); tt_ptr_op(v, ==, NULL); - test_assert(!fp_pair_map_isempty(map)); + tt_assert(!fp_pair_map_isempty(map)); v = fp_pair_map_set(map, &fp2, v101); tt_ptr_op(v, ==, NULL); v = fp_pair_map_set(map, &fp1, v100); tt_ptr_op(v, ==, v99); - test_eq_ptr(fp_pair_map_get(map, &fp1), v100); - test_eq_ptr(fp_pair_map_get(map, &fp2), v101); - test_eq_ptr(fp_pair_map_get(map, &fp3), NULL); + tt_ptr_op(fp_pair_map_get(map, &fp1),==, v100); + tt_ptr_op(fp_pair_map_get(map, &fp2),==, v101); + tt_ptr_op(fp_pair_map_get(map, &fp3),==, NULL); fp_pair_map_assert_ok(map); v = fp_pair_map_remove(map, &fp2); fp_pair_map_assert_ok(map); - test_eq_ptr(v, v101); - test_eq_ptr(fp_pair_map_get(map, &fp2), NULL); - test_eq_ptr(fp_pair_map_remove(map, &fp2), NULL); + tt_ptr_op(v,==, v101); + tt_ptr_op(fp_pair_map_get(map, &fp2),==, NULL); + tt_ptr_op(fp_pair_map_remove(map, &fp2),==, NULL); fp_pair_map_set(map, &fp2, v101); fp_pair_map_set(map, &fp3, v102); fp_pair_map_set(map, &fp4, v103); - test_eq(fp_pair_map_size(map), 4); + tt_int_op(fp_pair_map_size(map),==, 4); fp_pair_map_assert_ok(map); fp_pair_map_set(map, &fp5, v104); fp_pair_map_set(map, &fp6, v105); @@ -993,7 +1006,7 @@ test_container_fp_pair_map(void) iter = fp_pair_map_iter_init(map); while (!fp_pair_map_iter_done(iter)) { fp_pair_map_iter_get(iter, &k, &v); - test_eq_ptr(v, fp_pair_map_get(map, &k)); + tt_ptr_op(v,==, fp_pair_map_get(map, &k)); if (tor_memeq(&fp2, &k, sizeof(fp2))) { iter = fp_pair_map_iter_next_rmv(map, iter); @@ -1003,8 +1016,8 @@ test_container_fp_pair_map(void) } /* Make sure we removed fp2, but not the others. */ - test_eq_ptr(fp_pair_map_get(map, &fp2), NULL); - test_eq_ptr(fp_pair_map_get(map, &fp5), v104); + tt_ptr_op(fp_pair_map_get(map, &fp2),==, NULL); + tt_ptr_op(fp_pair_map_get(map, &fp5),==, v104); fp_pair_map_assert_ok(map); /* Clean up after ourselves. */ @@ -1024,7 +1037,7 @@ test_container_fp_pair_map(void) } #define CONTAINER_LEGACY(name) \ - { #name, legacy_test_helper, 0, &legacy_setup, test_container_ ## name } + { #name, test_container_ ## name , 0, NULL, NULL } #define CONTAINER(name, flags) \ { #name, test_container_ ## name, (flags), NULL, NULL } diff --git a/src/test/test_crypto.c b/src/test/test_crypto.c index 5d8edb6550..795c603fd4 100644 --- a/src/test/test_crypto.c +++ b/src/test/test_crypto.c @@ -5,6 +5,7 @@ #include "orconfig.h" #define CRYPTO_CURVE25519_PRIVATE +#define CRYPTO_S2K_PRIVATE #include "or.h" #include "test.h" #include "aes.h" @@ -13,6 +14,10 @@ #ifdef CURVE25519_ENABLED #include "crypto_curve25519.h" #endif +#include "crypto_ed25519.h" +#include "ed25519_vectors.inc" +#include "crypto_s2k.h" +#include "crypto_pwbox.h" extern const char AUTHORITY_SIGNKEY_3[]; extern const char AUTHORITY_SIGNKEY_A_DIGEST[]; @@ -20,7 +25,7 @@ extern const char AUTHORITY_SIGNKEY_A_DIGEST256[]; /** Run unit tests for Diffie-Hellman functionality. */ static void -test_crypto_dh(void) +test_crypto_dh(void *arg) { crypto_dh_t *dh1 = crypto_dh_new(DH_TYPE_CIRCUIT); crypto_dh_t *dh2 = crypto_dh_new(DH_TYPE_CIRCUIT); @@ -30,24 +35,25 @@ test_crypto_dh(void) char s2[DH_BYTES]; ssize_t s1len, s2len; - test_eq(crypto_dh_get_bytes(dh1), DH_BYTES); - test_eq(crypto_dh_get_bytes(dh2), DH_BYTES); + (void)arg; + tt_int_op(crypto_dh_get_bytes(dh1),==, DH_BYTES); + tt_int_op(crypto_dh_get_bytes(dh2),==, DH_BYTES); memset(p1, 0, DH_BYTES); memset(p2, 0, DH_BYTES); - test_memeq(p1, p2, DH_BYTES); - test_assert(! crypto_dh_get_public(dh1, p1, DH_BYTES)); - test_memneq(p1, p2, DH_BYTES); - test_assert(! crypto_dh_get_public(dh2, p2, DH_BYTES)); - test_memneq(p1, p2, DH_BYTES); + tt_mem_op(p1,==, p2, DH_BYTES); + tt_assert(! crypto_dh_get_public(dh1, p1, DH_BYTES)); + tt_mem_op(p1,!=, p2, DH_BYTES); + tt_assert(! crypto_dh_get_public(dh2, p2, DH_BYTES)); + tt_mem_op(p1,!=, p2, DH_BYTES); memset(s1, 0, DH_BYTES); memset(s2, 0xFF, DH_BYTES); s1len = crypto_dh_compute_secret(LOG_WARN, dh1, p2, DH_BYTES, s1, 50); s2len = crypto_dh_compute_secret(LOG_WARN, dh2, p1, DH_BYTES, s2, 50); - test_assert(s1len > 0); - test_eq(s1len, s2len); - test_memeq(s1, s2, s1len); + tt_assert(s1len > 0); + tt_int_op(s1len,==, s2len); + tt_mem_op(s1,==, s2, s1len); { /* XXXX Now fabricate some bad values and make sure they get caught, @@ -63,17 +69,18 @@ test_crypto_dh(void) /** Run unit tests for our random number generation function and its wrappers. */ static void -test_crypto_rng(void) +test_crypto_rng(void *arg) { int i, j, allok; char data1[100], data2[100]; double d; /* Try out RNG. */ - test_assert(! crypto_seed_rng(0)); + (void)arg; + tt_assert(! crypto_seed_rng(0)); crypto_rand(data1, 100); crypto_rand(data2, 100); - test_memneq(data1,data2,100); + tt_mem_op(data1,!=, data2,100); allok = 1; for (i = 0; i < 100; ++i) { uint64_t big; @@ -88,8 +95,8 @@ test_crypto_rng(void) if (big >= 5) allok = 0; d = crypto_rand_double(); - test_assert(d >= 0); - test_assert(d < 1.0); + tt_assert(d >= 0); + tt_assert(d < 1.0); host = crypto_random_hostname(3,8,"www.",".onion"); if (strcmpstart(host,"www.") || strcmpend(host,".onion") || @@ -98,7 +105,7 @@ test_crypto_rng(void) allok = 0; tor_free(host); } - test_assert(allok); + tt_assert(allok); done: ; } @@ -128,15 +135,15 @@ test_crypto_aes(void *arg) memset(data2, 0, 1024); memset(data3, 0, 1024); env1 = crypto_cipher_new(NULL); - test_neq_ptr(env1, 0); + tt_ptr_op(env1, !=, NULL); env2 = crypto_cipher_new(crypto_cipher_get_key(env1)); - test_neq_ptr(env2, 0); + tt_ptr_op(env2, !=, NULL); /* Try encrypting 512 chars. */ crypto_cipher_encrypt(env1, data2, data1, 512); crypto_cipher_decrypt(env2, data3, data2, 512); - test_memeq(data1, data3, 512); - test_memneq(data1, data2, 512); + tt_mem_op(data1,==, data3, 512); + tt_mem_op(data1,!=, data2, 512); /* Now encrypt 1 at a time, and get 1 at a time. */ for (j = 512; j < 560; ++j) { @@ -145,7 +152,7 @@ test_crypto_aes(void *arg) for (j = 512; j < 560; ++j) { crypto_cipher_decrypt(env2, data3+j, data2+j, 1); } - test_memeq(data1, data3, 560); + tt_mem_op(data1,==, data3, 560); /* Now encrypt 3 at a time, and get 5 at a time. */ for (j = 560; j < 1024-5; j += 3) { crypto_cipher_encrypt(env1, data2+j, data1+j, 3); @@ -153,7 +160,7 @@ test_crypto_aes(void *arg) for (j = 560; j < 1024-5; j += 5) { crypto_cipher_decrypt(env2, data3+j, data2+j, 5); } - test_memeq(data1, data3, 1024-5); + tt_mem_op(data1,==, data3, 1024-5); /* Now make sure that when we encrypt with different chunk sizes, we get the same results. */ crypto_cipher_free(env2); @@ -161,7 +168,7 @@ test_crypto_aes(void *arg) memset(data3, 0, 1024); env2 = crypto_cipher_new(crypto_cipher_get_key(env1)); - test_neq_ptr(env2, NULL); + tt_ptr_op(env2, !=, NULL); for (j = 0; j < 1024-16; j += 17) { crypto_cipher_encrypt(env2, data3+j, data1+j, 17); } @@ -170,7 +177,7 @@ test_crypto_aes(void *arg) printf("%d: %d\t%d\n", j, (int) data2[j], (int) data3[j]); } } - test_memeq(data2, data3, 1024-16); + tt_mem_op(data2,==, data3, 1024-16); crypto_cipher_free(env1); env1 = NULL; crypto_cipher_free(env2); @@ -237,7 +244,7 @@ test_crypto_aes(void *arg) "\xff\xff\xff\xff\xff\xff\xff\xff" "\xff\xff\xff\xff\xff\xff\xff\xff"); crypto_cipher_crypt_inplace(env1, data2, 64); - test_assert(tor_mem_is_zero(data2, 64)); + tt_assert(tor_mem_is_zero(data2, 64)); done: tor_free(mem_op_hex_tmp); @@ -252,7 +259,7 @@ test_crypto_aes(void *arg) /** Run unit tests for our SHA-1 functionality */ static void -test_crypto_sha(void) +test_crypto_sha(void *arg) { crypto_digest_t *d1 = NULL, *d2 = NULL; int i; @@ -263,6 +270,7 @@ test_crypto_sha(void) char *mem_op_hex_tmp=NULL; /* Test SHA-1 with a test vector from the specification. */ + (void)arg; i = crypto_digest(data, "abc", 3); test_memeq_hex(data, "A9993E364706816ABA3E25717850C26C9CD0D89D"); tt_int_op(i, ==, 0); @@ -277,13 +285,13 @@ test_crypto_sha(void) /* Case empty (wikipedia) */ crypto_hmac_sha256(digest, "", 0, "", 0); - test_streq(hex_str(digest, 32), + tt_str_op(hex_str(digest, 32),==, "B613679A0814D9EC772F95D778C35FC5FF1697C493715653C6C712144292C5AD"); /* Case quick-brown (wikipedia) */ crypto_hmac_sha256(digest, "key", 3, "The quick brown fox jumps over the lazy dog", 43); - test_streq(hex_str(digest, 32), + tt_str_op(hex_str(digest, 32),==, "F7BC83F430538424B13298E6AA6FB143EF4D59A14946175997479DBC2D1A3CD8"); /* "Test Case 1" from RFC 4231 */ @@ -344,43 +352,43 @@ test_crypto_sha(void) /* Incremental digest code. */ d1 = crypto_digest_new(); - test_assert(d1); + tt_assert(d1); crypto_digest_add_bytes(d1, "abcdef", 6); d2 = crypto_digest_dup(d1); - test_assert(d2); + tt_assert(d2); crypto_digest_add_bytes(d2, "ghijkl", 6); crypto_digest_get_digest(d2, d_out1, sizeof(d_out1)); crypto_digest(d_out2, "abcdefghijkl", 12); - test_memeq(d_out1, d_out2, DIGEST_LEN); + tt_mem_op(d_out1,==, d_out2, DIGEST_LEN); crypto_digest_assign(d2, d1); crypto_digest_add_bytes(d2, "mno", 3); crypto_digest_get_digest(d2, d_out1, sizeof(d_out1)); crypto_digest(d_out2, "abcdefmno", 9); - test_memeq(d_out1, d_out2, DIGEST_LEN); + tt_mem_op(d_out1,==, d_out2, DIGEST_LEN); crypto_digest_get_digest(d1, d_out1, sizeof(d_out1)); crypto_digest(d_out2, "abcdef", 6); - test_memeq(d_out1, d_out2, DIGEST_LEN); + tt_mem_op(d_out1,==, d_out2, DIGEST_LEN); crypto_digest_free(d1); crypto_digest_free(d2); /* Incremental digest code with sha256 */ d1 = crypto_digest256_new(DIGEST_SHA256); - test_assert(d1); + tt_assert(d1); crypto_digest_add_bytes(d1, "abcdef", 6); d2 = crypto_digest_dup(d1); - test_assert(d2); + tt_assert(d2); crypto_digest_add_bytes(d2, "ghijkl", 6); crypto_digest_get_digest(d2, d_out1, sizeof(d_out1)); crypto_digest256(d_out2, "abcdefghijkl", 12, DIGEST_SHA256); - test_memeq(d_out1, d_out2, DIGEST_LEN); + tt_mem_op(d_out1,==, d_out2, DIGEST_LEN); crypto_digest_assign(d2, d1); crypto_digest_add_bytes(d2, "mno", 3); crypto_digest_get_digest(d2, d_out1, sizeof(d_out1)); crypto_digest256(d_out2, "abcdefmno", 9, DIGEST_SHA256); - test_memeq(d_out1, d_out2, DIGEST_LEN); + tt_mem_op(d_out1,==, d_out2, DIGEST_LEN); crypto_digest_get_digest(d1, d_out1, sizeof(d_out1)); crypto_digest256(d_out2, "abcdef", 6, DIGEST_SHA256); - test_memeq(d_out1, d_out2, DIGEST_LEN); + tt_mem_op(d_out1,==, d_out2, DIGEST_LEN); done: if (d1) @@ -392,7 +400,7 @@ test_crypto_sha(void) /** Run unit tests for our public key crypto functions */ static void -test_crypto_pk(void) +test_crypto_pk(void *arg) { crypto_pk_t *pk1 = NULL, *pk2 = NULL; char *encoded = NULL; @@ -401,74 +409,83 @@ test_crypto_pk(void) int i, len; /* Public-key ciphers */ + (void)arg; pk1 = pk_generate(0); pk2 = crypto_pk_new(); - test_assert(pk1 && pk2); - test_assert(! crypto_pk_write_public_key_to_string(pk1, &encoded, &size)); - test_assert(! crypto_pk_read_public_key_from_string(pk2, encoded, size)); - test_eq(0, crypto_pk_cmp_keys(pk1, pk2)); + tt_assert(pk1 && pk2); + tt_assert(! crypto_pk_write_public_key_to_string(pk1, &encoded, &size)); + tt_assert(! crypto_pk_read_public_key_from_string(pk2, encoded, size)); + tt_int_op(0,==, crypto_pk_cmp_keys(pk1, pk2)); /* comparison between keys and NULL */ tt_int_op(crypto_pk_cmp_keys(NULL, pk1), <, 0); tt_int_op(crypto_pk_cmp_keys(NULL, NULL), ==, 0); tt_int_op(crypto_pk_cmp_keys(pk1, NULL), >, 0); - test_eq(128, crypto_pk_keysize(pk1)); - test_eq(1024, crypto_pk_num_bits(pk1)); - test_eq(128, crypto_pk_keysize(pk2)); - test_eq(1024, crypto_pk_num_bits(pk2)); + tt_int_op(128,==, crypto_pk_keysize(pk1)); + tt_int_op(1024,==, crypto_pk_num_bits(pk1)); + tt_int_op(128,==, crypto_pk_keysize(pk2)); + tt_int_op(1024,==, crypto_pk_num_bits(pk2)); - test_eq(128, crypto_pk_public_encrypt(pk2, data1, sizeof(data1), + tt_int_op(128,==, crypto_pk_public_encrypt(pk2, data1, sizeof(data1), "Hello whirled.", 15, PK_PKCS1_OAEP_PADDING)); - test_eq(128, crypto_pk_public_encrypt(pk1, data2, sizeof(data1), + tt_int_op(128,==, crypto_pk_public_encrypt(pk1, data2, sizeof(data1), "Hello whirled.", 15, PK_PKCS1_OAEP_PADDING)); /* oaep padding should make encryption not match */ - test_memneq(data1, data2, 128); - test_eq(15, crypto_pk_private_decrypt(pk1, data3, sizeof(data3), data1, 128, + tt_mem_op(data1,!=, data2, 128); + tt_int_op(15,==, + crypto_pk_private_decrypt(pk1, data3, sizeof(data3), data1, 128, PK_PKCS1_OAEP_PADDING,1)); - test_streq(data3, "Hello whirled."); + tt_str_op(data3,==, "Hello whirled."); memset(data3, 0, 1024); - test_eq(15, crypto_pk_private_decrypt(pk1, data3, sizeof(data3), data2, 128, + tt_int_op(15,==, + crypto_pk_private_decrypt(pk1, data3, sizeof(data3), data2, 128, PK_PKCS1_OAEP_PADDING,1)); - test_streq(data3, "Hello whirled."); + tt_str_op(data3,==, "Hello whirled."); /* Can't decrypt with public key. */ - test_eq(-1, crypto_pk_private_decrypt(pk2, data3, sizeof(data3), data2, 128, + tt_int_op(-1,==, + crypto_pk_private_decrypt(pk2, data3, sizeof(data3), data2, 128, PK_PKCS1_OAEP_PADDING,1)); /* Try again with bad padding */ memcpy(data2+1, "XYZZY", 5); /* This has fails ~ once-in-2^40 */ - test_eq(-1, crypto_pk_private_decrypt(pk1, data3, sizeof(data3), data2, 128, + tt_int_op(-1,==, + crypto_pk_private_decrypt(pk1, data3, sizeof(data3), data2, 128, PK_PKCS1_OAEP_PADDING,1)); /* File operations: save and load private key */ - test_assert(! crypto_pk_write_private_key_to_filename(pk1, + tt_assert(! crypto_pk_write_private_key_to_filename(pk1, get_fname("pkey1"))); /* failing case for read: can't read. */ - test_assert(crypto_pk_read_private_key_from_filename(pk2, + tt_assert(crypto_pk_read_private_key_from_filename(pk2, get_fname("xyzzy")) < 0); write_str_to_file(get_fname("xyzzy"), "foobar", 6); /* Failing case for read: no key. */ - test_assert(crypto_pk_read_private_key_from_filename(pk2, + tt_assert(crypto_pk_read_private_key_from_filename(pk2, get_fname("xyzzy")) < 0); - test_assert(! crypto_pk_read_private_key_from_filename(pk2, + tt_assert(! crypto_pk_read_private_key_from_filename(pk2, get_fname("pkey1"))); - test_eq(15, crypto_pk_private_decrypt(pk2, data3, sizeof(data3), data1, 128, + tt_int_op(15,==, + crypto_pk_private_decrypt(pk2, data3, sizeof(data3), data1, 128, PK_PKCS1_OAEP_PADDING,1)); /* Now try signing. */ strlcpy(data1, "Ossifrage", 1024); - test_eq(128, crypto_pk_private_sign(pk1, data2, sizeof(data2), data1, 10)); - test_eq(10, + tt_int_op(128,==, + crypto_pk_private_sign(pk1, data2, sizeof(data2), data1, 10)); + tt_int_op(10,==, crypto_pk_public_checksig(pk1, data3, sizeof(data3), data2, 128)); - test_streq(data3, "Ossifrage"); + tt_str_op(data3,==, "Ossifrage"); /* Try signing digests. */ - test_eq(128, crypto_pk_private_sign_digest(pk1, data2, sizeof(data2), + tt_int_op(128,==, crypto_pk_private_sign_digest(pk1, data2, sizeof(data2), data1, 10)); - test_eq(20, + tt_int_op(20,==, crypto_pk_public_checksig(pk1, data3, sizeof(data3), data2, 128)); - test_eq(0, crypto_pk_public_checksig_digest(pk1, data1, 10, data2, 128)); - test_eq(-1, crypto_pk_public_checksig_digest(pk1, data1, 11, data2, 128)); + tt_int_op(0,==, + crypto_pk_public_checksig_digest(pk1, data1, 10, data2, 128)); + tt_int_op(-1,==, + crypto_pk_public_checksig_digest(pk1, data1, 11, data2, 128)); /*XXXX test failed signing*/ @@ -476,9 +493,9 @@ test_crypto_pk(void) crypto_pk_free(pk2); pk2 = NULL; i = crypto_pk_asn1_encode(pk1, data1, 1024); - test_assert(i>0); + tt_int_op(i, >, 0); pk2 = crypto_pk_asn1_decode(data1, i); - test_assert(crypto_pk_cmp_keys(pk1,pk2) == 0); + tt_assert(crypto_pk_cmp_keys(pk1,pk2) == 0); /* Try with hybrid encryption wrappers. */ crypto_rand(data1, 1024); @@ -487,19 +504,19 @@ test_crypto_pk(void) memset(data3,0,1024); len = crypto_pk_public_hybrid_encrypt(pk1,data2,sizeof(data2), data1,i,PK_PKCS1_OAEP_PADDING,0); - test_assert(len>=0); + tt_int_op(len, >=, 0); len = crypto_pk_private_hybrid_decrypt(pk1,data3,sizeof(data3), data2,len,PK_PKCS1_OAEP_PADDING,1); - test_eq(len,i); - test_memeq(data1,data3,i); + tt_int_op(len,==, i); + tt_mem_op(data1,==, data3,i); } /* Try copy_full */ crypto_pk_free(pk2); pk2 = crypto_pk_copy_full(pk1); - test_assert(pk2 != NULL); - test_neq_ptr(pk1, pk2); - test_assert(crypto_pk_cmp_keys(pk1,pk2) == 0); + tt_assert(pk2 != NULL); + tt_ptr_op(pk1, !=, pk2); + tt_assert(crypto_pk_cmp_keys(pk1,pk2) == 0); done: if (pk1) @@ -532,7 +549,7 @@ test_crypto_pk_fingerprints(void *arg) /* Is digest as expected? */ crypto_digest(d, encoded, n); tt_int_op(0, ==, crypto_pk_get_digest(pk, d2)); - test_memeq(d, d2, DIGEST_LEN); + tt_mem_op(d,==, d2, DIGEST_LEN); /* Is fingerprint right? */ tt_int_op(0, ==, crypto_pk_get_fingerprint(pk, fingerprint, 0)); @@ -561,28 +578,29 @@ test_crypto_pk_fingerprints(void *arg) /** Sanity check for crypto pk digests */ static void -test_crypto_digests(void) +test_crypto_digests(void *arg) { crypto_pk_t *k = NULL; ssize_t r; digests_t pkey_digests; char digest[DIGEST_LEN]; + (void)arg; k = crypto_pk_new(); - test_assert(k); + tt_assert(k); r = crypto_pk_read_private_key_from_string(k, AUTHORITY_SIGNKEY_3, -1); - test_assert(!r); + tt_assert(!r); r = crypto_pk_get_digest(k, digest); - test_assert(r == 0); - test_memeq(hex_str(digest, DIGEST_LEN), + tt_assert(r == 0); + tt_mem_op(hex_str(digest, DIGEST_LEN),==, AUTHORITY_SIGNKEY_A_DIGEST, HEX_DIGEST_LEN); r = crypto_pk_get_all_digests(k, &pkey_digests); - test_memeq(hex_str(pkey_digests.d[DIGEST_SHA1], DIGEST_LEN), + tt_mem_op(hex_str(pkey_digests.d[DIGEST_SHA1], DIGEST_LEN),==, AUTHORITY_SIGNKEY_A_DIGEST, HEX_DIGEST_LEN); - test_memeq(hex_str(pkey_digests.d[DIGEST_SHA256], DIGEST256_LEN), + tt_mem_op(hex_str(pkey_digests.d[DIGEST_SHA256], DIGEST256_LEN),==, AUTHORITY_SIGNKEY_A_DIGEST256, HEX_DIGEST256_LEN); done: crypto_pk_free(k); @@ -591,58 +609,59 @@ test_crypto_digests(void) /** Run unit tests for misc crypto formatting functionality (base64, base32, * fingerprints, etc) */ static void -test_crypto_formats(void) +test_crypto_formats(void *arg) { char *data1 = NULL, *data2 = NULL, *data3 = NULL; int i, j, idx; + (void)arg; data1 = tor_malloc(1024); data2 = tor_malloc(1024); data3 = tor_malloc(1024); - test_assert(data1 && data2 && data3); + tt_assert(data1 && data2 && data3); /* Base64 tests */ memset(data1, 6, 1024); for (idx = 0; idx < 10; ++idx) { i = base64_encode(data2, 1024, data1, idx); - test_assert(i >= 0); + tt_int_op(i, >=, 0); j = base64_decode(data3, 1024, data2, i); - test_eq(j,idx); - test_memeq(data3, data1, idx); + tt_int_op(j,==, idx); + tt_mem_op(data3,==, data1, idx); } strlcpy(data1, "Test string that contains 35 chars.", 1024); strlcat(data1, " 2nd string that contains 35 chars.", 1024); i = base64_encode(data2, 1024, data1, 71); - test_assert(i >= 0); + tt_int_op(i, >=, 0); j = base64_decode(data3, 1024, data2, i); - test_eq(j, 71); - test_streq(data3, data1); - test_assert(data2[i] == '\0'); + tt_int_op(j,==, 71); + tt_str_op(data3,==, data1); + tt_int_op(data2[i], ==, '\0'); crypto_rand(data1, DIGEST_LEN); memset(data2, 100, 1024); digest_to_base64(data2, data1); - test_eq(BASE64_DIGEST_LEN, strlen(data2)); - test_eq(100, data2[BASE64_DIGEST_LEN+2]); + tt_int_op(BASE64_DIGEST_LEN,==, strlen(data2)); + tt_int_op(100,==, data2[BASE64_DIGEST_LEN+2]); memset(data3, 99, 1024); - test_eq(digest_from_base64(data3, data2), 0); - test_memeq(data1, data3, DIGEST_LEN); - test_eq(99, data3[DIGEST_LEN+1]); + tt_int_op(digest_from_base64(data3, data2),==, 0); + tt_mem_op(data1,==, data3, DIGEST_LEN); + tt_int_op(99,==, data3[DIGEST_LEN+1]); - test_assert(digest_from_base64(data3, "###") < 0); + tt_assert(digest_from_base64(data3, "###") < 0); /* Encoding SHA256 */ crypto_rand(data2, DIGEST256_LEN); memset(data2, 100, 1024); digest256_to_base64(data2, data1); - test_eq(BASE64_DIGEST256_LEN, strlen(data2)); - test_eq(100, data2[BASE64_DIGEST256_LEN+2]); + tt_int_op(BASE64_DIGEST256_LEN,==, strlen(data2)); + tt_int_op(100,==, data2[BASE64_DIGEST256_LEN+2]); memset(data3, 99, 1024); - test_eq(digest256_from_base64(data3, data2), 0); - test_memeq(data1, data3, DIGEST256_LEN); - test_eq(99, data3[DIGEST256_LEN+1]); + tt_int_op(digest256_from_base64(data3, data2),==, 0); + tt_mem_op(data1,==, data3, DIGEST256_LEN); + tt_int_op(99,==, data3[DIGEST256_LEN+1]); /* Base32 tests */ strlcpy(data1, "5chrs", 1024); @@ -651,27 +670,27 @@ test_crypto_formats(void) * By 5s: [00110 10101 10001 10110 10000 11100 10011 10011] */ base32_encode(data2, 9, data1, 5); - test_streq(data2, "gvrwq4tt"); + tt_str_op(data2,==, "gvrwq4tt"); strlcpy(data1, "\xFF\xF5\x6D\x44\xAE\x0D\x5C\xC9\x62\xC4", 1024); base32_encode(data2, 30, data1, 10); - test_streq(data2, "772w2rfobvomsywe"); + tt_str_op(data2,==, "772w2rfobvomsywe"); /* Base16 tests */ strlcpy(data1, "6chrs\xff", 1024); base16_encode(data2, 13, data1, 6); - test_streq(data2, "3663687273FF"); + tt_str_op(data2,==, "3663687273FF"); strlcpy(data1, "f0d678affc000100", 1024); i = base16_decode(data2, 8, data1, 16); - test_eq(i,0); - test_memeq(data2, "\xf0\xd6\x78\xaf\xfc\x00\x01\x00",8); + tt_int_op(i,==, 0); + tt_mem_op(data2,==, "\xf0\xd6\x78\xaf\xfc\x00\x01\x00",8); /* now try some failing base16 decodes */ - test_eq(-1, base16_decode(data2, 8, data1, 15)); /* odd input len */ - test_eq(-1, base16_decode(data2, 7, data1, 16)); /* dest too short */ + tt_int_op(-1,==, base16_decode(data2, 8, data1, 15)); /* odd input len */ + tt_int_op(-1,==, base16_decode(data2, 7, data1, 16)); /* dest too short */ strlcpy(data1, "f0dz!8affc000100", 1024); - test_eq(-1, base16_decode(data2, 8, data1, 16)); + tt_int_op(-1,==, base16_decode(data2, 8, data1, 16)); tor_free(data1); tor_free(data2); @@ -680,10 +699,10 @@ test_crypto_formats(void) /* Add spaces to fingerprint */ { data1 = tor_strdup("ABCD1234ABCD56780000ABCD1234ABCD56780000"); - test_eq(strlen(data1), 40); + tt_int_op(strlen(data1),==, 40); data2 = tor_malloc(FINGERPRINT_LEN+1); crypto_add_spaces_to_fp(data2, FINGERPRINT_LEN+1, data1); - test_streq(data2, "ABCD 1234 ABCD 5678 0000 ABCD 1234 ABCD 5678 0000"); + tt_str_op(data2,==, "ABCD 1234 ABCD 5678 0000 ABCD 1234 ABCD 5678 0000"); tor_free(data1); tor_free(data2); } @@ -696,37 +715,377 @@ test_crypto_formats(void) /** Run unit tests for our secret-to-key passphrase hashing functionality. */ static void -test_crypto_s2k(void) +test_crypto_s2k_rfc2440(void *arg) { char buf[29]; char buf2[29]; char *buf3 = NULL; int i; + (void)arg; memset(buf, 0, sizeof(buf)); memset(buf2, 0, sizeof(buf2)); buf3 = tor_malloc(65536); memset(buf3, 0, 65536); - secret_to_key(buf+9, 20, "", 0, buf); + secret_to_key_rfc2440(buf+9, 20, "", 0, buf); crypto_digest(buf2+9, buf3, 1024); - test_memeq(buf, buf2, 29); + tt_mem_op(buf,==, buf2, 29); memcpy(buf,"vrbacrda",8); memcpy(buf2,"vrbacrda",8); buf[8] = 96; buf2[8] = 96; - secret_to_key(buf+9, 20, "12345678", 8, buf); + secret_to_key_rfc2440(buf+9, 20, "12345678", 8, buf); for (i = 0; i < 65536; i += 16) { memcpy(buf3+i, "vrbacrda12345678", 16); } crypto_digest(buf2+9, buf3, 65536); - test_memeq(buf, buf2, 29); + tt_mem_op(buf,==, buf2, 29); done: tor_free(buf3); } +static void +run_s2k_tests(const unsigned flags, const unsigned type, + int speclen, const int keylen, int legacy) +{ + uint8_t buf[S2K_MAXLEN], buf2[S2K_MAXLEN], buf3[S2K_MAXLEN]; + int r; + size_t sz; + const char pw1[] = "You can't come in here unless you say swordfish!"; + const char pw2[] = "Now, I give you one more guess."; + + r = secret_to_key_new(buf, sizeof(buf), &sz, + pw1, strlen(pw1), flags); + tt_int_op(r, ==, S2K_OKAY); + tt_int_op(buf[0], ==, type); + + tt_int_op(sz, ==, keylen + speclen); + + if (legacy) { + memmove(buf, buf+1, sz-1); + --sz; + --speclen; + } + + tt_int_op(S2K_OKAY, ==, + secret_to_key_check(buf, sz, pw1, strlen(pw1))); + + tt_int_op(S2K_BAD_SECRET, ==, + secret_to_key_check(buf, sz, pw2, strlen(pw2))); + + /* Move key to buf2, and clear it. */ + memset(buf3, 0, sizeof(buf3)); + memcpy(buf2, buf+speclen, keylen); + memset(buf+speclen, 0, sz - speclen); + + /* Derivekey should produce the same results. */ + tt_int_op(S2K_OKAY, ==, + secret_to_key_derivekey(buf3, keylen, buf, speclen, pw1, strlen(pw1))); + + tt_mem_op(buf2, ==, buf3, keylen); + + /* Derivekey with a longer output should fill the output. */ + memset(buf2, 0, sizeof(buf2)); + tt_int_op(S2K_OKAY, ==, + secret_to_key_derivekey(buf2, sizeof(buf2), buf, speclen, + pw1, strlen(pw1))); + + tt_mem_op(buf2, !=, buf3, sizeof(buf2)); + + memset(buf3, 0, sizeof(buf3)); + tt_int_op(S2K_OKAY, ==, + secret_to_key_derivekey(buf3, sizeof(buf3), buf, speclen, + pw1, strlen(pw1))); + tt_mem_op(buf2, ==, buf3, sizeof(buf3)); + tt_assert(!tor_mem_is_zero((char*)buf2+keylen, sizeof(buf2)-keylen)); + + done: + ; +} + +static void +test_crypto_s2k_general(void *arg) +{ + const char *which = arg; + + if (!strcmp(which, "scrypt")) { + run_s2k_tests(0, 2, 19, 32, 0); + } else if (!strcmp(which, "scrypt-low")) { + run_s2k_tests(S2K_FLAG_LOW_MEM, 2, 19, 32, 0); + } else if (!strcmp(which, "pbkdf2")) { + run_s2k_tests(S2K_FLAG_USE_PBKDF2, 1, 18, 20, 0); + } else if (!strcmp(which, "rfc2440")) { + run_s2k_tests(S2K_FLAG_NO_SCRYPT, 0, 10, 20, 0); + } else if (!strcmp(which, "rfc2440-legacy")) { + run_s2k_tests(S2K_FLAG_NO_SCRYPT, 0, 10, 20, 1); + } else { + tt_fail(); + } +} + +static void +test_crypto_s2k_errors(void *arg) +{ + uint8_t buf[S2K_MAXLEN], buf2[S2K_MAXLEN]; + size_t sz; + + (void)arg; + + /* Bogus specifiers: simple */ + tt_int_op(S2K_BAD_LEN, ==, + secret_to_key_derivekey(buf, sizeof(buf), + (const uint8_t*)"", 0, "ABC", 3)); + tt_int_op(S2K_BAD_ALGORITHM, ==, + secret_to_key_derivekey(buf, sizeof(buf), + (const uint8_t*)"\x10", 1, "ABC", 3)); + tt_int_op(S2K_BAD_LEN, ==, + secret_to_key_derivekey(buf, sizeof(buf), + (const uint8_t*)"\x01\x02", 2, "ABC", 3)); + + tt_int_op(S2K_BAD_LEN, ==, + secret_to_key_check((const uint8_t*)"", 0, "ABC", 3)); + tt_int_op(S2K_BAD_ALGORITHM, ==, + secret_to_key_check((const uint8_t*)"\x10", 1, "ABC", 3)); + tt_int_op(S2K_BAD_LEN, ==, + secret_to_key_check((const uint8_t*)"\x01\x02", 2, "ABC", 3)); + + /* too long gets "BAD_LEN" too */ + memset(buf, 0, sizeof(buf)); + buf[0] = 2; + tt_int_op(S2K_BAD_LEN, ==, + secret_to_key_derivekey(buf2, sizeof(buf2), + buf, sizeof(buf), "ABC", 3)); + + /* Truncated output */ +#ifdef HAVE_LIBSCRYPT_H + tt_int_op(S2K_TRUNCATED, ==, secret_to_key_new(buf, 50, &sz, + "ABC", 3, 0)); + tt_int_op(S2K_TRUNCATED, ==, secret_to_key_new(buf, 50, &sz, + "ABC", 3, S2K_FLAG_LOW_MEM)); +#endif + tt_int_op(S2K_TRUNCATED, ==, secret_to_key_new(buf, 37, &sz, + "ABC", 3, S2K_FLAG_USE_PBKDF2)); + tt_int_op(S2K_TRUNCATED, ==, secret_to_key_new(buf, 29, &sz, + "ABC", 3, S2K_FLAG_NO_SCRYPT)); + +#ifdef HAVE_LIBSCRYPT_H + tt_int_op(S2K_TRUNCATED, ==, secret_to_key_make_specifier(buf, 18, 0)); + tt_int_op(S2K_TRUNCATED, ==, secret_to_key_make_specifier(buf, 18, + S2K_FLAG_LOW_MEM)); +#endif + tt_int_op(S2K_TRUNCATED, ==, secret_to_key_make_specifier(buf, 17, + S2K_FLAG_USE_PBKDF2)); + tt_int_op(S2K_TRUNCATED, ==, secret_to_key_make_specifier(buf, 9, + S2K_FLAG_NO_SCRYPT)); + + /* Now try using type-specific bogus specifiers. */ + + /* It's a bad pbkdf2 buffer if it has an iteration count that would overflow + * int32_t. */ + memset(buf, 0, sizeof(buf)); + buf[0] = 1; /* pbkdf2 */ + buf[17] = 100; /* 1<<100 is much bigger than INT32_MAX */ + tt_int_op(S2K_BAD_PARAMS, ==, + secret_to_key_derivekey(buf2, sizeof(buf2), + buf, 18, "ABC", 3)); + +#ifdef HAVE_LIBSCRYPT_H + /* It's a bad scrypt buffer if N would overflow uint64 */ + memset(buf, 0, sizeof(buf)); + buf[0] = 2; /* scrypt */ + buf[17] = 100; /* 1<<100 is much bigger than UINT64_MAX */ + tt_int_op(S2K_BAD_PARAMS, ==, + secret_to_key_derivekey(buf2, sizeof(buf2), + buf, 19, "ABC", 3)); +#endif + + done: + ; +} + +static void +test_crypto_scrypt_vectors(void *arg) +{ + char *mem_op_hex_tmp = NULL; + uint8_t spec[64], out[64]; + + (void)arg; +#ifndef HAVE_LIBSCRYPT_H + if (1) + tt_skip(); +#endif + + /* Test vectors from + http://tools.ietf.org/html/draft-josefsson-scrypt-kdf-00 section 11. + + Note that the names of 'r' and 'N' are switched in that section. Or + possibly in libscrypt. + */ + + base16_decode((char*)spec, sizeof(spec), + "0400", 4); + memset(out, 0x00, sizeof(out)); + tt_int_op(64, ==, + secret_to_key_compute_key(out, 64, spec, 2, "", 0, 2)); + test_memeq_hex(out, + "77d6576238657b203b19ca42c18a0497" + "f16b4844e3074ae8dfdffa3fede21442" + "fcd0069ded0948f8326a753a0fc81f17" + "e8d3e0fb2e0d3628cf35e20c38d18906"); + + base16_decode((char*)spec, sizeof(spec), + "4e61436c" "0A34", 12); + memset(out, 0x00, sizeof(out)); + tt_int_op(64, ==, + secret_to_key_compute_key(out, 64, spec, 6, "password", 8, 2)); + test_memeq_hex(out, + "fdbabe1c9d3472007856e7190d01e9fe" + "7c6ad7cbc8237830e77376634b373162" + "2eaf30d92e22a3886ff109279d9830da" + "c727afb94a83ee6d8360cbdfa2cc0640"); + + base16_decode((char*)spec, sizeof(spec), + "536f6469756d43686c6f72696465" "0e30", 32); + memset(out, 0x00, sizeof(out)); + tt_int_op(64, ==, + secret_to_key_compute_key(out, 64, spec, 16, + "pleaseletmein", 13, 2)); + test_memeq_hex(out, + "7023bdcb3afd7348461c06cd81fd38eb" + "fda8fbba904f8e3ea9b543f6545da1f2" + "d5432955613f0fcf62d49705242a9af9" + "e61e85dc0d651e40dfcf017b45575887"); + + base16_decode((char*)spec, sizeof(spec), + "536f6469756d43686c6f72696465" "1430", 32); + memset(out, 0x00, sizeof(out)); + tt_int_op(64, ==, + secret_to_key_compute_key(out, 64, spec, 16, + "pleaseletmein", 13, 2)); + test_memeq_hex(out, + "2101cb9b6a511aaeaddbbe09cf70f881" + "ec568d574a2ffd4dabe5ee9820adaa47" + "8e56fd8f4ba5d09ffa1c6d927c40f4c3" + "37304049e8a952fbcbf45c6fa77a41a4"); + + done: + tor_free(mem_op_hex_tmp); +} + +static void +test_crypto_pbkdf2_vectors(void *arg) +{ + char *mem_op_hex_tmp = NULL; + uint8_t spec[64], out[64]; + (void)arg; + + /* Test vectors from RFC6070, section 2 */ + base16_decode((char*)spec, sizeof(spec), + "73616c74" "00" , 10); + memset(out, 0x00, sizeof(out)); + tt_int_op(20, ==, + secret_to_key_compute_key(out, 20, spec, 5, "password", 8, 1)); + test_memeq_hex(out, "0c60c80f961f0e71f3a9b524af6012062fe037a6"); + + base16_decode((char*)spec, sizeof(spec), + "73616c74" "01" , 10); + memset(out, 0x00, sizeof(out)); + tt_int_op(20, ==, + secret_to_key_compute_key(out, 20, spec, 5, "password", 8, 1)); + test_memeq_hex(out, "ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957"); + + base16_decode((char*)spec, sizeof(spec), + "73616c74" "0C" , 10); + memset(out, 0x00, sizeof(out)); + tt_int_op(20, ==, + secret_to_key_compute_key(out, 20, spec, 5, "password", 8, 1)); + test_memeq_hex(out, "4b007901b765489abead49d926f721d065a429c1"); + + base16_decode((char*)spec, sizeof(spec), + "73616c74" "18" , 10); + memset(out, 0x00, sizeof(out)); + tt_int_op(20, ==, + secret_to_key_compute_key(out, 20, spec, 5, "password", 8, 1)); + test_memeq_hex(out, "eefe3d61cd4da4e4e9945b3d6ba2158c2634e984"); + + base16_decode((char*)spec, sizeof(spec), + "73616c7453414c5473616c7453414c5473616c745" + "3414c5473616c7453414c5473616c74" "0C" , 74); + memset(out, 0x00, sizeof(out)); + tt_int_op(25, ==, + secret_to_key_compute_key(out, 25, spec, 37, + "passwordPASSWORDpassword", 24, 1)); + test_memeq_hex(out, "3d2eec4fe41c849b80c8d83662c0e44a8b291a964cf2f07038"); + + base16_decode((char*)spec, sizeof(spec), + "7361006c74" "0c" , 12); + memset(out, 0x00, sizeof(out)); + tt_int_op(16, ==, + secret_to_key_compute_key(out, 16, spec, 6, "pass\0word", 9, 1)); + test_memeq_hex(out, "56fa6aa75548099dcc37d7f03425e0c3"); + + done: + tor_free(mem_op_hex_tmp); +} + +static void +test_crypto_pwbox(void *arg) +{ + uint8_t *boxed=NULL, *decoded=NULL; + size_t len, dlen; + unsigned i; + const char msg[] = "This bunny reminds you that you still have a " + "salamander in your sylladex. She is holding the bunny Dave got you. " + "It’s sort of uncanny how similar they are, aside from the knitted " + "enhancements. Seriously, what are the odds?? So weird."; + const char pw[] = "I'm a night owl and a wise bird too"; + + const unsigned flags[] = { 0, + S2K_FLAG_NO_SCRYPT, + S2K_FLAG_LOW_MEM, + S2K_FLAG_NO_SCRYPT|S2K_FLAG_LOW_MEM, + S2K_FLAG_USE_PBKDF2 }; + (void)arg; + + for (i = 0; i < ARRAY_LENGTH(flags); ++i) { + tt_int_op(0, ==, crypto_pwbox(&boxed, &len, + (const uint8_t*)msg, strlen(msg), + pw, strlen(pw), flags[i])); + tt_assert(boxed); + tt_assert(len > 128+32); + + tt_int_op(0, ==, crypto_unpwbox(&decoded, &dlen, boxed, len, + pw, strlen(pw))); + + tt_assert(decoded); + tt_uint_op(dlen, ==, strlen(msg)); + tt_mem_op(decoded, ==, msg, dlen); + + tor_free(decoded); + + tt_int_op(UNPWBOX_BAD_SECRET, ==, crypto_unpwbox(&decoded, &dlen, + boxed, len, + pw, strlen(pw)-1)); + boxed[len-1] ^= 1; + tt_int_op(UNPWBOX_BAD_SECRET, ==, crypto_unpwbox(&decoded, &dlen, + boxed, len, + pw, strlen(pw))); + boxed[0] = 255; + tt_int_op(UNPWBOX_CORRUPTED, ==, crypto_unpwbox(&decoded, &dlen, + boxed, len, + pw, strlen(pw))); + + tor_free(boxed); + } + + done: + tor_free(boxed); + tor_free(decoded); +} + /** Test AES-CTR encryption and decryption with IV. */ static void test_crypto_aes_iv(void *arg) @@ -757,79 +1116,79 @@ test_crypto_aes_iv(void *arg) encrypted_size = crypto_cipher_encrypt_with_iv(key1, encrypted1, 16 + 4095, plain, 4095); - test_eq(encrypted_size, 16 + 4095); + tt_int_op(encrypted_size,==, 16 + 4095); tt_assert(encrypted_size > 0); /* This is obviously true, since 4111 is * greater than 0, but its truth is not * obvious to all analysis tools. */ decrypted_size = crypto_cipher_decrypt_with_iv(key1, decrypted1, 4095, encrypted1, encrypted_size); - test_eq(decrypted_size, 4095); + tt_int_op(decrypted_size,==, 4095); tt_assert(decrypted_size > 0); - test_memeq(plain, decrypted1, 4095); + tt_mem_op(plain,==, decrypted1, 4095); /* Encrypt a second time (with a new random initialization vector). */ encrypted_size = crypto_cipher_encrypt_with_iv(key1, encrypted2, 16 + 4095, plain, 4095); - test_eq(encrypted_size, 16 + 4095); + tt_int_op(encrypted_size,==, 16 + 4095); tt_assert(encrypted_size > 0); decrypted_size = crypto_cipher_decrypt_with_iv(key1, decrypted2, 4095, encrypted2, encrypted_size); - test_eq(decrypted_size, 4095); + tt_int_op(decrypted_size,==, 4095); tt_assert(decrypted_size > 0); - test_memeq(plain, decrypted2, 4095); - test_memneq(encrypted1, encrypted2, encrypted_size); + tt_mem_op(plain,==, decrypted2, 4095); + tt_mem_op(encrypted1,!=, encrypted2, encrypted_size); /* Decrypt with the wrong key. */ decrypted_size = crypto_cipher_decrypt_with_iv(key2, decrypted2, 4095, encrypted1, encrypted_size); - test_eq(decrypted_size, 4095); - test_memneq(plain, decrypted2, decrypted_size); + tt_int_op(decrypted_size,==, 4095); + tt_mem_op(plain,!=, decrypted2, decrypted_size); /* Alter the initialization vector. */ encrypted1[0] += 42; decrypted_size = crypto_cipher_decrypt_with_iv(key1, decrypted1, 4095, encrypted1, encrypted_size); - test_eq(decrypted_size, 4095); - test_memneq(plain, decrypted2, 4095); + tt_int_op(decrypted_size,==, 4095); + tt_mem_op(plain,!=, decrypted2, 4095); /* Special length case: 1. */ encrypted_size = crypto_cipher_encrypt_with_iv(key1, encrypted1, 16 + 1, plain_1, 1); - test_eq(encrypted_size, 16 + 1); + tt_int_op(encrypted_size,==, 16 + 1); tt_assert(encrypted_size > 0); decrypted_size = crypto_cipher_decrypt_with_iv(key1, decrypted1, 1, encrypted1, encrypted_size); - test_eq(decrypted_size, 1); + tt_int_op(decrypted_size,==, 1); tt_assert(decrypted_size > 0); - test_memeq(plain_1, decrypted1, 1); + tt_mem_op(plain_1,==, decrypted1, 1); /* Special length case: 15. */ encrypted_size = crypto_cipher_encrypt_with_iv(key1, encrypted1, 16 + 15, plain_15, 15); - test_eq(encrypted_size, 16 + 15); + tt_int_op(encrypted_size,==, 16 + 15); tt_assert(encrypted_size > 0); decrypted_size = crypto_cipher_decrypt_with_iv(key1, decrypted1, 15, encrypted1, encrypted_size); - test_eq(decrypted_size, 15); + tt_int_op(decrypted_size,==, 15); tt_assert(decrypted_size > 0); - test_memeq(plain_15, decrypted1, 15); + tt_mem_op(plain_15,==, decrypted1, 15); /* Special length case: 16. */ encrypted_size = crypto_cipher_encrypt_with_iv(key1, encrypted1, 16 + 16, plain_16, 16); - test_eq(encrypted_size, 16 + 16); + tt_int_op(encrypted_size,==, 16 + 16); tt_assert(encrypted_size > 0); decrypted_size = crypto_cipher_decrypt_with_iv(key1, decrypted1, 16, encrypted1, encrypted_size); - test_eq(decrypted_size, 16); + tt_int_op(decrypted_size,==, 16); tt_assert(decrypted_size > 0); - test_memeq(plain_16, decrypted1, 16); + tt_mem_op(plain_16,==, decrypted1, 16); /* Special length case: 17. */ encrypted_size = crypto_cipher_encrypt_with_iv(key1, encrypted1, 16 + 17, plain_17, 17); - test_eq(encrypted_size, 16 + 17); + tt_int_op(encrypted_size,==, 16 + 17); tt_assert(encrypted_size > 0); decrypted_size = crypto_cipher_decrypt_with_iv(key1, decrypted1, 17, encrypted1, encrypted_size); - test_eq(decrypted_size, 17); + tt_int_op(decrypted_size,==, 17); tt_assert(decrypted_size > 0); - test_memeq(plain_17, decrypted1, 17); + tt_mem_op(plain_17,==, decrypted1, 17); done: /* Free memory. */ @@ -842,34 +1201,35 @@ test_crypto_aes_iv(void *arg) /** Test base32 decoding. */ static void -test_crypto_base32_decode(void) +test_crypto_base32_decode(void *arg) { char plain[60], encoded[96 + 1], decoded[60]; int res; + (void)arg; crypto_rand(plain, 60); /* Encode and decode a random string. */ base32_encode(encoded, 96 + 1, plain, 60); res = base32_decode(decoded, 60, encoded, 96); - test_eq(res, 0); - test_memeq(plain, decoded, 60); + tt_int_op(res,==, 0); + tt_mem_op(plain,==, decoded, 60); /* Encode, uppercase, and decode a random string. */ base32_encode(encoded, 96 + 1, plain, 60); tor_strupper(encoded); res = base32_decode(decoded, 60, encoded, 96); - test_eq(res, 0); - test_memeq(plain, decoded, 60); + tt_int_op(res,==, 0); + tt_mem_op(plain,==, decoded, 60); /* Change encoded string and decode. */ if (encoded[0] == 'A' || encoded[0] == 'a') encoded[0] = 'B'; else encoded[0] = 'A'; res = base32_decode(decoded, 60, encoded, 96); - test_eq(res, 0); - test_memneq(plain, decoded, 60); + tt_int_op(res,==, 0); + tt_mem_op(plain,!=, decoded, 60); /* Bad encodings. */ encoded[0] = '!'; res = base32_decode(decoded, 60, encoded, 96); - test_assert(res < 0); + tt_int_op(0, >, res); done: ; @@ -1024,7 +1384,7 @@ test_crypto_curve25519_impl(void *arg) e2k[31] |= (byte & 0x80); } curve25519_impl(e1e2k,e1,e2k); - test_memeq(e1e2k, e2e1k, 32); + tt_mem_op(e1e2k,==, e2e1k, 32); if (loop == loop_max-1) { break; } @@ -1056,11 +1416,11 @@ test_crypto_curve25519_wrappers(void *arg) curve25519_secret_key_generate(&seckey2, 1); curve25519_public_key_generate(&pubkey1, &seckey1); curve25519_public_key_generate(&pubkey2, &seckey2); - test_assert(curve25519_public_key_is_ok(&pubkey1)); - test_assert(curve25519_public_key_is_ok(&pubkey2)); + tt_assert(curve25519_public_key_is_ok(&pubkey1)); + tt_assert(curve25519_public_key_is_ok(&pubkey2)); curve25519_handshake(output1, &seckey1, &pubkey2); curve25519_handshake(output2, &seckey2, &pubkey1); - test_memeq(output1, output2, sizeof(output1)); + tt_mem_op(output1,==, output2, sizeof(output1)); done: ; @@ -1081,12 +1441,12 @@ test_crypto_curve25519_encode(void *arg) tt_int_op(CURVE25519_BASE64_PADDED_LEN, ==, strlen(buf)); tt_int_op(0, ==, curve25519_public_from_base64(&key2, buf)); - test_memeq(key1.public_key, key2.public_key, CURVE25519_PUBKEY_LEN); + tt_mem_op(key1.public_key,==, key2.public_key, CURVE25519_PUBKEY_LEN); buf[CURVE25519_BASE64_PADDED_LEN - 1] = '\0'; tt_int_op(CURVE25519_BASE64_PADDED_LEN-1, ==, strlen(buf)); tt_int_op(0, ==, curve25519_public_from_base64(&key3, buf)); - test_memeq(key1.public_key, key3.public_key, CURVE25519_PUBKEY_LEN); + tt_mem_op(key1.public_key,==, key3.public_key, CURVE25519_PUBKEY_LEN); /* Now try bogus parses. */ strlcpy(buf, "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$=", sizeof(buf)); @@ -1122,10 +1482,10 @@ test_crypto_curve25519_persist(void *arg) tt_str_op(tag,==,"testing"); tor_free(tag); - test_memeq(keypair.pubkey.public_key, + tt_mem_op(keypair.pubkey.public_key,==, keypair2.pubkey.public_key, CURVE25519_PUBKEY_LEN); - test_memeq(keypair.seckey.secret_key, + tt_mem_op(keypair.seckey.secret_key,==, keypair2.seckey.secret_key, CURVE25519_SECKEY_LEN); @@ -1137,11 +1497,11 @@ test_crypto_curve25519_persist(void *arg) tt_assert(fast_memeq(content, "== c25519v1: testing ==", taglen)); tt_assert(tor_mem_is_zero(content+taglen, 32-taglen)); cp = content + 32; - test_memeq(keypair.seckey.secret_key, + tt_mem_op(keypair.seckey.secret_key,==, cp, CURVE25519_SECKEY_LEN); cp += CURVE25519_SECKEY_LEN; - test_memeq(keypair.pubkey.public_key, + tt_mem_op(keypair.pubkey.public_key,==, cp, CURVE25519_SECKEY_LEN); @@ -1161,7 +1521,362 @@ test_crypto_curve25519_persist(void *arg) tor_free(tag); } -#endif +static void +test_crypto_ed25519_simple(void *arg) +{ + ed25519_keypair_t kp1, kp2; + ed25519_public_key_t pub1, pub2; + ed25519_secret_key_t sec1, sec2; + ed25519_signature_t sig1, sig2; + const uint8_t msg[] = + "GNU will be able to run Unix programs, " + "but will not be identical to Unix."; + const uint8_t msg2[] = + "Microsoft Windows extends the features of the DOS operating system, " + "yet is compatible with most existing applications that run under DOS."; + size_t msg_len = strlen((const char*)msg); + size_t msg2_len = strlen((const char*)msg2); + + (void)arg; + + tt_int_op(0, ==, ed25519_secret_key_generate(&sec1, 0)); + tt_int_op(0, ==, ed25519_secret_key_generate(&sec2, 1)); + + tt_int_op(0, ==, ed25519_public_key_generate(&pub1, &sec1)); + tt_int_op(0, ==, ed25519_public_key_generate(&pub2, &sec1)); + + tt_mem_op(pub1.pubkey, ==, pub2.pubkey, sizeof(pub1.pubkey)); + + memcpy(&kp1.pubkey, &pub1, sizeof(pub1)); + memcpy(&kp1.seckey, &sec1, sizeof(sec1)); + tt_int_op(0, ==, ed25519_sign(&sig1, msg, msg_len, &kp1)); + tt_int_op(0, ==, ed25519_sign(&sig2, msg, msg_len, &kp1)); + + /* Ed25519 signatures are deterministic */ + tt_mem_op(sig1.sig, ==, sig2.sig, sizeof(sig1.sig)); + + /* Basic signature is valid. */ + tt_int_op(0, ==, ed25519_checksig(&sig1, msg, msg_len, &pub1)); + + /* Altered signature doesn't work. */ + sig1.sig[0] ^= 3; + tt_int_op(-1, ==, ed25519_checksig(&sig1, msg, msg_len, &pub1)); + + /* Wrong public key doesn't work. */ + tt_int_op(0, ==, ed25519_public_key_generate(&pub2, &sec2)); + tt_int_op(-1, ==, ed25519_checksig(&sig2, msg, msg_len, &pub2)); + + /* Wrong message doesn't work. */ + tt_int_op(0, ==, ed25519_checksig(&sig2, msg, msg_len, &pub1)); + tt_int_op(-1, ==, ed25519_checksig(&sig2, msg, msg_len-1, &pub1)); + tt_int_op(-1, ==, ed25519_checksig(&sig2, msg2, msg2_len, &pub1)); + + /* Batch signature checking works with some bad. */ + tt_int_op(0, ==, ed25519_keypair_generate(&kp2, 0)); + tt_int_op(0, ==, ed25519_sign(&sig1, msg, msg_len, &kp2)); + { + ed25519_checkable_t ch[] = { + { &pub1, sig2, msg, msg_len }, /*ok*/ + { &pub1, sig2, msg, msg_len-1 }, /*bad*/ + { &kp2.pubkey, sig2, msg2, msg2_len }, /*bad*/ + { &kp2.pubkey, sig1, msg, msg_len }, /*ok*/ + }; + int okay[4]; + tt_int_op(-2, ==, ed25519_checksig_batch(okay, ch, 4)); + tt_int_op(okay[0], ==, 1); + tt_int_op(okay[1], ==, 0); + tt_int_op(okay[2], ==, 0); + tt_int_op(okay[3], ==, 1); + tt_int_op(-2, ==, ed25519_checksig_batch(NULL, ch, 4)); + } + + /* Batch signature checking works with all good. */ + { + ed25519_checkable_t ch[] = { + { &pub1, sig2, msg, msg_len }, /*ok*/ + { &kp2.pubkey, sig1, msg, msg_len }, /*ok*/ + }; + int okay[2]; + tt_int_op(0, ==, ed25519_checksig_batch(okay, ch, 2)); + tt_int_op(okay[0], ==, 1); + tt_int_op(okay[1], ==, 1); + tt_int_op(0, ==, ed25519_checksig_batch(NULL, ch, 2)); + } + + done: + ; +} + +static void +test_crypto_ed25519_test_vectors(void *arg) +{ + char *mem_op_hex_tmp=NULL; + int i; + struct { + const char *sk; + const char *pk; + const char *sig; + const char *msg; + } items[] = { + /* These test vectors were generated with the "ref" implementation of + * ed25519 from SUPERCOP-20130419 */ + { "4c6574277320686f706520746865726520617265206e6f206275677320696e20", + "f3e0e493b30f56e501aeb868fc912fe0c8b76621efca47a78f6d75875193dd87", + "b5d7fd6fd3adf643647ce1fe87a2931dedd1a4e38e6c662bedd35cdd80bfac51" + "1b2c7d1ee6bd929ac213014e1a8dc5373854c7b25dbe15ec96bf6c94196fae06", + "506c6561736520657863757365206d7920667269656e642e2048652069736e2774" + "204e554c2d7465726d696e617465642e" + }, + + { "74686520696d706c656d656e746174696f6e20776869636820617265206e6f74", + "407f0025a1e1351a4cb68e92f5c0ebaf66e7aaf93a4006a4d1a66e3ede1cfeac", + "02884fde1c3c5944d0ecf2d133726fc820c303aae695adceabf3a1e01e95bf28" + "da88c0966f5265e9c6f8edc77b3b96b5c91baec3ca993ccd21a3f64203600601", + "506c6561736520657863757365206d7920667269656e642e2048652069736e2774" + "204e554c2d7465726d696e617465642e" + }, + { "6578706f73656420627920456e676c697368207465787420617320696e707574", + "61681cb5fbd69f9bc5a462a21a7ab319011237b940bc781cdc47fcbe327e7706", + "6a127d0414de7510125d4bc214994ffb9b8857a46330832d05d1355e882344ad" + "f4137e3ca1f13eb9cc75c887ef2309b98c57528b4acd9f6376c6898889603209", + "506c6561736520657863757365206d7920667269656e642e2048652069736e2774" + "204e554c2d7465726d696e617465642e" + }, + + /* These come from "sign.input" in ed25519's page */ + { "5b5a619f8ce1c66d7ce26e5a2ae7b0c04febcd346d286c929e19d0d5973bfef9", + "6fe83693d011d111131c4f3fbaaa40a9d3d76b30012ff73bb0e39ec27ab18257", + "0f9ad9793033a2fa06614b277d37381e6d94f65ac2a5a94558d09ed6ce922258" + "c1a567952e863ac94297aec3c0d0c8ddf71084e504860bb6ba27449b55adc40e", + "5a8d9d0a22357e6655f9c785" + }, + { "940c89fe40a81dafbdb2416d14ae469119869744410c3303bfaa0241dac57800", + "a2eb8c0501e30bae0cf842d2bde8dec7386f6b7fc3981b8c57c9792bb94cf2dd", + "d8bb64aad8c9955a115a793addd24f7f2b077648714f49c4694ec995b330d09d" + "640df310f447fd7b6cb5c14f9fe9f490bcf8cfadbfd2169c8ac20d3b8af49a0c", + "b87d3813e03f58cf19fd0b6395" + }, + { "9acad959d216212d789a119252ebfe0c96512a23c73bd9f3b202292d6916a738", + "cf3af898467a5b7a52d33d53bc037e2642a8da996903fc252217e9c033e2f291", + "6ee3fe81e23c60eb2312b2006b3b25e6838e02106623f844c44edb8dafd66ab0" + "671087fd195df5b8f58a1d6e52af42908053d55c7321010092748795ef94cf06", + "55c7fa434f5ed8cdec2b7aeac173", + }, + { "d5aeee41eeb0e9d1bf8337f939587ebe296161e6bf5209f591ec939e1440c300", + "fd2a565723163e29f53c9de3d5e8fbe36a7ab66e1439ec4eae9c0a604af291a5", + "f68d04847e5b249737899c014d31c805c5007a62c0a10d50bb1538c5f3550395" + "1fbc1e08682f2cc0c92efe8f4985dec61dcbd54d4b94a22547d24451271c8b00", + "0a688e79be24f866286d4646b5d81c" + }, + + { NULL, NULL, NULL, NULL} + }; + + (void)arg; + + for (i = 0; items[i].pk; ++i) { + ed25519_keypair_t kp; + ed25519_signature_t sig; + uint8_t sk_seed[32]; + uint8_t *msg; + size_t msg_len; + base16_decode((char*)sk_seed, sizeof(sk_seed), + items[i].sk, 64); + ed25519_secret_key_from_seed(&kp.seckey, sk_seed); + tt_int_op(0, ==, ed25519_public_key_generate(&kp.pubkey, &kp.seckey)); + test_memeq_hex(kp.pubkey.pubkey, items[i].pk); + + msg_len = strlen(items[i].msg) / 2; + msg = tor_malloc(msg_len); + base16_decode((char*)msg, msg_len, items[i].msg, strlen(items[i].msg)); + + tt_int_op(0, ==, ed25519_sign(&sig, msg, msg_len, &kp)); + test_memeq_hex(sig.sig, items[i].sig); + + tor_free(msg); + } + + done: + tor_free(mem_op_hex_tmp); +} + +static void +test_crypto_ed25519_encode(void *arg) +{ + char buf[ED25519_BASE64_LEN+1]; + ed25519_keypair_t kp; + ed25519_public_key_t pk; + char *mem_op_hex_tmp = NULL; + (void) arg; + + /* Test roundtrip. */ + tt_int_op(0, ==, ed25519_keypair_generate(&kp, 0)); + tt_int_op(0, ==, ed25519_public_to_base64(buf, &kp.pubkey)); + tt_int_op(ED25519_BASE64_LEN, ==, strlen(buf)); + tt_int_op(0, ==, ed25519_public_from_base64(&pk, buf)); + tt_mem_op(kp.pubkey.pubkey, ==, pk.pubkey, ED25519_PUBKEY_LEN); + + /* Test known value. */ + tt_int_op(0, ==, ed25519_public_from_base64(&pk, + "lVIuIctLjbGZGU5wKMNXxXlSE3cW4kaqkqm04u6pxvM")); + test_memeq_hex(pk.pubkey, + "95522e21cb4b8db199194e7028c357c57952137716e246aa92a9b4e2eea9c6f3"); + + done: + tor_free(mem_op_hex_tmp); +} + +static void +test_crypto_ed25519_convert(void *arg) +{ + const uint8_t msg[] = + "The eyes are not here / There are no eyes here."; + const int N = 30; + int i; + (void)arg; + + for (i = 0; i < N; ++i) { + curve25519_keypair_t curve25519_keypair; + ed25519_keypair_t ed25519_keypair; + ed25519_public_key_t ed25519_pubkey; + + int bit=0; + ed25519_signature_t sig; + + tt_int_op(0,==,curve25519_keypair_generate(&curve25519_keypair, i&1)); + tt_int_op(0,==,ed25519_keypair_from_curve25519_keypair( + &ed25519_keypair, &bit, &curve25519_keypair)); + tt_int_op(0,==,ed25519_public_key_from_curve25519_public_key( + &ed25519_pubkey, &curve25519_keypair.pubkey, bit)); + tt_mem_op(ed25519_pubkey.pubkey, ==, ed25519_keypair.pubkey.pubkey, 32); + + tt_int_op(0,==,ed25519_sign(&sig, msg, sizeof(msg), &ed25519_keypair)); + tt_int_op(0,==,ed25519_checksig(&sig, msg, sizeof(msg), + &ed25519_pubkey)); + + tt_int_op(-1,==,ed25519_checksig(&sig, msg, sizeof(msg)-1, + &ed25519_pubkey)); + sig.sig[0] ^= 15; + tt_int_op(-1,==,ed25519_checksig(&sig, msg, sizeof(msg), + &ed25519_pubkey)); + } + + done: + ; +} + +static void +test_crypto_ed25519_blinding(void *arg) +{ + const uint8_t msg[] = + "Eyes I dare not meet in dreams / In death's dream kingdom"; + + const int N = 30; + int i; + (void)arg; + + for (i = 0; i < N; ++i) { + uint8_t blinding[32]; + ed25519_keypair_t ed25519_keypair; + ed25519_keypair_t ed25519_keypair_blinded; + ed25519_public_key_t ed25519_pubkey_blinded; + + ed25519_signature_t sig; + + crypto_rand((char*) blinding, sizeof(blinding)); + + tt_int_op(0,==,ed25519_keypair_generate(&ed25519_keypair, 0)); + tt_int_op(0,==,ed25519_keypair_blind(&ed25519_keypair_blinded, + &ed25519_keypair, blinding)); + + tt_int_op(0,==,ed25519_public_blind(&ed25519_pubkey_blinded, + &ed25519_keypair.pubkey, blinding)); + + tt_mem_op(ed25519_pubkey_blinded.pubkey, ==, + ed25519_keypair_blinded.pubkey.pubkey, 32); + + tt_int_op(0,==,ed25519_sign(&sig, msg, sizeof(msg), + &ed25519_keypair_blinded)); + + tt_int_op(0,==,ed25519_checksig(&sig, msg, sizeof(msg), + &ed25519_pubkey_blinded)); + + tt_int_op(-1,==,ed25519_checksig(&sig, msg, sizeof(msg)-1, + &ed25519_pubkey_blinded)); + sig.sig[0] ^= 15; + tt_int_op(-1,==,ed25519_checksig(&sig, msg, sizeof(msg), + &ed25519_pubkey_blinded)); + } + + done: + ; +} + +static void +test_crypto_ed25519_testvectors(void *arg) +{ + unsigned i; + char *mem_op_hex_tmp = NULL; + (void)arg; + + for (i = 0; i < ARRAY_LENGTH(ED25519_SECRET_KEYS); ++i) { + uint8_t sk[32]; + ed25519_secret_key_t esk; + ed25519_public_key_t pk, blind_pk, pkfromcurve; + ed25519_keypair_t keypair, blind_keypair; + curve25519_keypair_t curvekp; + uint8_t blinding_param[32]; + ed25519_signature_t sig; + int sign; + +#define DECODE(p,s) base16_decode((char*)(p),sizeof(p),(s),strlen(s)) +#define EQ(a,h) test_memeq_hex((const char*)(a), (h)) + + tt_int_op(0, ==, DECODE(sk, ED25519_SECRET_KEYS[i])); + tt_int_op(0, ==, DECODE(blinding_param, ED25519_BLINDING_PARAMS[i])); + + tt_int_op(0, ==, ed25519_secret_key_from_seed(&esk, sk)); + EQ(esk.seckey, ED25519_EXPANDED_SECRET_KEYS[i]); + + tt_int_op(0, ==, ed25519_public_key_generate(&pk, &esk)); + EQ(pk.pubkey, ED25519_PUBLIC_KEYS[i]); + + memcpy(&curvekp.seckey.secret_key, esk.seckey, 32); + curve25519_public_key_generate(&curvekp.pubkey, &curvekp.seckey); + + tt_int_op(0, ==, + ed25519_keypair_from_curve25519_keypair(&keypair, &sign, &curvekp)); + tt_int_op(0, ==, ed25519_public_key_from_curve25519_public_key( + &pkfromcurve, &curvekp.pubkey, sign)); + tt_mem_op(keypair.pubkey.pubkey, ==, pkfromcurve.pubkey, 32); + EQ(curvekp.pubkey.public_key, ED25519_CURVE25519_PUBLIC_KEYS[i]); + + /* Self-signing */ + memcpy(&keypair.seckey, &esk, sizeof(esk)); + memcpy(&keypair.pubkey, &pk, sizeof(pk)); + + tt_int_op(0, ==, ed25519_sign(&sig, pk.pubkey, 32, &keypair)); + + EQ(sig.sig, ED25519_SELF_SIGNATURES[i]); + + /* Blinding */ + tt_int_op(0, ==, + ed25519_keypair_blind(&blind_keypair, &keypair, blinding_param)); + tt_int_op(0, ==, + ed25519_public_blind(&blind_pk, &pk, blinding_param)); + + EQ(blind_keypair.seckey.seckey, ED25519_BLINDED_SECRET_KEYS[i]); + EQ(blind_pk.pubkey, ED25519_BLINDED_PUBLIC_KEYS[i]); + + tt_mem_op(blind_pk.pubkey, ==, blind_keypair.pubkey.pubkey, 32); + +#undef DECODE +#undef EQ + } + done: + tor_free(mem_op_hex_tmp); +} +#endif /* CURVE25519_ENABLED */ static void test_crypto_siphash(void *arg) @@ -1276,7 +1991,7 @@ static const struct testcase_setup_t pass_data = { }; #define CRYPTO_LEGACY(name) \ - { #name, legacy_test_helper, 0, &legacy_setup, test_crypto_ ## name } + { #name, test_crypto_ ## name , 0, NULL, NULL } struct testcase_t crypto_tests[] = { CRYPTO_LEGACY(formats), @@ -1288,7 +2003,23 @@ struct testcase_t crypto_tests[] = { { "pk_fingerprints", test_crypto_pk_fingerprints, TT_FORK, NULL, NULL }, CRYPTO_LEGACY(digests), CRYPTO_LEGACY(dh), - CRYPTO_LEGACY(s2k), + CRYPTO_LEGACY(s2k_rfc2440), +#ifdef HAVE_LIBSCRYPT_H + { "s2k_scrypt", test_crypto_s2k_general, 0, &pass_data, + (void*)"scrypt" }, + { "s2k_scrypt_low", test_crypto_s2k_general, 0, &pass_data, + (void*)"scrypt-low" }, +#endif + { "s2k_pbkdf2", test_crypto_s2k_general, 0, &pass_data, + (void*)"pbkdf2" }, + { "s2k_rfc2440_general", test_crypto_s2k_general, 0, &pass_data, + (void*)"rfc2440" }, + { "s2k_rfc2440_legacy", test_crypto_s2k_general, 0, &pass_data, + (void*)"rfc2440-legacy" }, + { "s2k_errors", test_crypto_s2k_errors, 0, NULL, NULL }, + { "scrypt_vectors", test_crypto_scrypt_vectors, 0, NULL, NULL }, + { "pbkdf2_vectors", test_crypto_pbkdf2_vectors, 0, NULL, NULL }, + { "pwbox", test_crypto_pwbox, 0, NULL, NULL }, { "aes_iv_AES", test_crypto_aes_iv, TT_FORK, &pass_data, (void*)"aes" }, { "aes_iv_EVP", test_crypto_aes_iv, TT_FORK, &pass_data, (void*)"evp" }, CRYPTO_LEGACY(base32_decode), @@ -1300,6 +2031,12 @@ struct testcase_t crypto_tests[] = { { "curve25519_wrappers", test_crypto_curve25519_wrappers, 0, NULL, NULL }, { "curve25519_encode", test_crypto_curve25519_encode, 0, NULL, NULL }, { "curve25519_persist", test_crypto_curve25519_persist, 0, NULL, NULL }, + { "ed25519_simple", test_crypto_ed25519_simple, 0, NULL, NULL }, + { "ed25519_test_vectors", test_crypto_ed25519_test_vectors, 0, NULL, NULL }, + { "ed25519_encode", test_crypto_ed25519_encode, 0, NULL, NULL }, + { "ed25519_convert", test_crypto_ed25519_convert, 0, NULL, NULL }, + { "ed25519_blinding", test_crypto_ed25519_blinding, 0, NULL, NULL }, + { "ed25519_testvectors", test_crypto_ed25519_testvectors, 0, NULL, NULL }, #endif { "siphash", test_crypto_siphash, 0, NULL, NULL }, END_OF_TESTCASES diff --git a/src/test/test_dir.c b/src/test/test_dir.c index c5eee46979..e03efbeff5 100644 --- a/src/test/test_dir.c +++ b/src/test/test_dir.c @@ -25,55 +25,56 @@ #include "test.h" static void -test_dir_nicknames(void) +test_dir_nicknames(void *arg) { - test_assert( is_legal_nickname("a")); - test_assert(!is_legal_nickname("")); - test_assert(!is_legal_nickname("abcdefghijklmnopqrst")); /* 20 chars */ - test_assert(!is_legal_nickname("hyphen-")); /* bad char */ - test_assert( is_legal_nickname("abcdefghijklmnopqrs")); /* 19 chars */ - test_assert(!is_legal_nickname("$AAAAAAAA01234AAAAAAAAAAAAAAAAAAAAAAAAAAA")); + (void)arg; + tt_assert( is_legal_nickname("a")); + tt_assert(!is_legal_nickname("")); + tt_assert(!is_legal_nickname("abcdefghijklmnopqrst")); /* 20 chars */ + tt_assert(!is_legal_nickname("hyphen-")); /* bad char */ + tt_assert( is_legal_nickname("abcdefghijklmnopqrs")); /* 19 chars */ + tt_assert(!is_legal_nickname("$AAAAAAAA01234AAAAAAAAAAAAAAAAAAAAAAAAAAA")); /* valid */ - test_assert( is_legal_nickname_or_hexdigest( + tt_assert( is_legal_nickname_or_hexdigest( "$AAAAAAAA01234AAAAAAAAAAAAAAAAAAAAAAAAAAA")); - test_assert( is_legal_nickname_or_hexdigest( + tt_assert( is_legal_nickname_or_hexdigest( "$AAAAAAAA01234AAAAAAAAAAAAAAAAAAAAAAAAAAA=fred")); - test_assert( is_legal_nickname_or_hexdigest( + tt_assert( is_legal_nickname_or_hexdigest( "$AAAAAAAA01234AAAAAAAAAAAAAAAAAAAAAAAAAAA~fred")); /* too short */ - test_assert(!is_legal_nickname_or_hexdigest( + tt_assert(!is_legal_nickname_or_hexdigest( "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA")); /* illegal char */ - test_assert(!is_legal_nickname_or_hexdigest( + tt_assert(!is_legal_nickname_or_hexdigest( "$AAAAAAzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA")); /* hex part too long */ - test_assert(!is_legal_nickname_or_hexdigest( + tt_assert(!is_legal_nickname_or_hexdigest( "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA")); - test_assert(!is_legal_nickname_or_hexdigest( + tt_assert(!is_legal_nickname_or_hexdigest( "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=fred")); /* Bad nickname */ - test_assert(!is_legal_nickname_or_hexdigest( + tt_assert(!is_legal_nickname_or_hexdigest( "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=")); - test_assert(!is_legal_nickname_or_hexdigest( + tt_assert(!is_legal_nickname_or_hexdigest( "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~")); - test_assert(!is_legal_nickname_or_hexdigest( + tt_assert(!is_legal_nickname_or_hexdigest( "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~hyphen-")); - test_assert(!is_legal_nickname_or_hexdigest( + tt_assert(!is_legal_nickname_or_hexdigest( "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~" "abcdefghijklmnoppqrst")); /* Bad extra char. */ - test_assert(!is_legal_nickname_or_hexdigest( + tt_assert(!is_legal_nickname_or_hexdigest( "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA!")); - test_assert(is_legal_nickname_or_hexdigest("xyzzy")); - test_assert(is_legal_nickname_or_hexdigest("abcdefghijklmnopqrs")); - test_assert(!is_legal_nickname_or_hexdigest("abcdefghijklmnopqrst")); + tt_assert(is_legal_nickname_or_hexdigest("xyzzy")); + tt_assert(is_legal_nickname_or_hexdigest("abcdefghijklmnopqrs")); + tt_assert(!is_legal_nickname_or_hexdigest("abcdefghijklmnopqrst")); done: ; } /** Run unit tests for router descriptor generation logic. */ static void -test_dir_formats(void) +test_dir_formats(void *arg) { char *buf = NULL; char buf2[8192]; @@ -89,10 +90,11 @@ test_dir_formats(void) or_options_t *options = get_options_mutable(); const addr_policy_t *p; + (void)arg; pk1 = pk_generate(0); pk2 = pk_generate(1); - test_assert(pk1 && pk2); + tt_assert(pk1 && pk2); hibernate_set_state_for_testing_(HIBERNATE_STATE_LIVE); @@ -140,9 +142,9 @@ test_dir_formats(void) smartlist_add(r2->exit_policy, ex2); r2->nickname = tor_strdup("Fred"); - test_assert(!crypto_pk_write_public_key_to_string(pk1, &pk1_str, + tt_assert(!crypto_pk_write_public_key_to_string(pk1, &pk1_str, &pk1_str_len)); - test_assert(!crypto_pk_write_public_key_to_string(pk2 , &pk2_str, + tt_assert(!crypto_pk_write_public_key_to_string(pk2 , &pk2_str, &pk2_str_len)); /* XXXX025 router_dump_to_string should really take this from ri.*/ @@ -150,7 +152,7 @@ test_dir_formats(void) "<magri@elsewhere.example.com>"); buf = router_dump_router_to_string(r1, pk2); tor_free(options->ContactInfo); - test_assert(buf); + tt_assert(buf); strlcpy(buf2, "router Magri 192.168.0.1 9000 0 9003\n" "or-address [1:2:3:4::]:9999\n" @@ -160,7 +162,7 @@ test_dir_formats(void) "protocols Link 1 2 Circuit 1\n" "published 1970-01-01 00:00:00\n" "fingerprint ", sizeof(buf2)); - test_assert(!crypto_pk_get_fingerprint(pk2, fingerprint, 1)); + tt_assert(!crypto_pk_get_fingerprint(pk2, fingerprint, 1)); strlcat(buf2, fingerprint, sizeof(buf2)); strlcat(buf2, "\nuptime 0\n" /* XXX the "0" above is hard-coded, but even if we made it reflect @@ -178,23 +180,23 @@ test_dir_formats(void) buf[strlen(buf2)] = '\0'; /* Don't compare the sig; it's never the same * twice */ - test_streq(buf, buf2); + tt_str_op(buf,==, buf2); tor_free(buf); buf = router_dump_router_to_string(r1, pk2); - test_assert(buf); + tt_assert(buf); cp = buf; - rp1 = router_parse_entry_from_string((const char*)cp,NULL,1,0,NULL); - test_assert(rp1); - test_eq(rp1->addr, r1->addr); - test_eq(rp1->or_port, r1->or_port); + rp1 = router_parse_entry_from_string((const char*)cp,NULL,1,0,NULL,NULL); + tt_assert(rp1); + tt_int_op(rp1->addr,==, r1->addr); + tt_int_op(rp1->or_port,==, r1->or_port); //test_eq(rp1->dir_port, r1->dir_port); - test_eq(rp1->bandwidthrate, r1->bandwidthrate); - test_eq(rp1->bandwidthburst, r1->bandwidthburst); - test_eq(rp1->bandwidthcapacity, r1->bandwidthcapacity); - test_assert(crypto_pk_cmp_keys(rp1->onion_pkey, pk1) == 0); - test_assert(crypto_pk_cmp_keys(rp1->identity_pkey, pk2) == 0); - //test_assert(rp1->exit_policy == NULL); + tt_int_op(rp1->bandwidthrate,==, r1->bandwidthrate); + tt_int_op(rp1->bandwidthburst,==, r1->bandwidthburst); + tt_int_op(rp1->bandwidthcapacity,==, r1->bandwidthcapacity); + tt_assert(crypto_pk_cmp_keys(rp1->onion_pkey, pk1) == 0); + tt_assert(crypto_pk_cmp_keys(rp1->identity_pkey, pk2) == 0); + //tt_assert(rp1->exit_policy == NULL); tor_free(buf); strlcpy(buf2, @@ -205,7 +207,7 @@ test_dir_formats(void) "protocols Link 1 2 Circuit 1\n" "published 1970-01-01 00:00:05\n" "fingerprint ", sizeof(buf2)); - test_assert(!crypto_pk_get_fingerprint(pk1, fingerprint, 1)); + tt_assert(!crypto_pk_get_fingerprint(pk1, fingerprint, 1)); strlcat(buf2, fingerprint, sizeof(buf2)); strlcat(buf2, "\nuptime 0\n" "bandwidth 3000 3000 3000\n", sizeof(buf2)); @@ -224,42 +226,42 @@ test_dir_formats(void) buf = router_dump_router_to_string(r2, pk1); buf[strlen(buf2)] = '\0'; /* Don't compare the sig; it's never the same * twice */ - test_streq(buf, buf2); + tt_str_op(buf,==, buf2); tor_free(buf); buf = router_dump_router_to_string(r2, pk1); cp = buf; - rp2 = router_parse_entry_from_string((const char*)cp,NULL,1,0,NULL); - test_assert(rp2); - test_eq(rp2->addr, r2->addr); - test_eq(rp2->or_port, r2->or_port); - test_eq(rp2->dir_port, r2->dir_port); - test_eq(rp2->bandwidthrate, r2->bandwidthrate); - test_eq(rp2->bandwidthburst, r2->bandwidthburst); - test_eq(rp2->bandwidthcapacity, r2->bandwidthcapacity); + rp2 = router_parse_entry_from_string((const char*)cp,NULL,1,0,NULL,NULL); + tt_assert(rp2); + tt_int_op(rp2->addr,==, r2->addr); + tt_int_op(rp2->or_port,==, r2->or_port); + tt_int_op(rp2->dir_port,==, r2->dir_port); + tt_int_op(rp2->bandwidthrate,==, r2->bandwidthrate); + tt_int_op(rp2->bandwidthburst,==, r2->bandwidthburst); + tt_int_op(rp2->bandwidthcapacity,==, r2->bandwidthcapacity); #ifdef CURVE25519_ENABLED - test_memeq(rp2->onion_curve25519_pkey->public_key, + tt_mem_op(rp2->onion_curve25519_pkey->public_key,==, r2->onion_curve25519_pkey->public_key, CURVE25519_PUBKEY_LEN); #endif - test_assert(crypto_pk_cmp_keys(rp2->onion_pkey, pk2) == 0); - test_assert(crypto_pk_cmp_keys(rp2->identity_pkey, pk1) == 0); + tt_assert(crypto_pk_cmp_keys(rp2->onion_pkey, pk2) == 0); + tt_assert(crypto_pk_cmp_keys(rp2->identity_pkey, pk1) == 0); - test_eq(smartlist_len(rp2->exit_policy), 2); + tt_int_op(smartlist_len(rp2->exit_policy),==, 2); p = smartlist_get(rp2->exit_policy, 0); - test_eq(p->policy_type, ADDR_POLICY_ACCEPT); - test_assert(tor_addr_is_null(&p->addr)); - test_eq(p->maskbits, 0); - test_eq(p->prt_min, 80); - test_eq(p->prt_max, 80); + tt_int_op(p->policy_type,==, ADDR_POLICY_ACCEPT); + tt_assert(tor_addr_is_null(&p->addr)); + tt_int_op(p->maskbits,==, 0); + tt_int_op(p->prt_min,==, 80); + tt_int_op(p->prt_max,==, 80); p = smartlist_get(rp2->exit_policy, 1); - test_eq(p->policy_type, ADDR_POLICY_REJECT); - test_assert(tor_addr_eq(&p->addr, &ex2->addr)); - test_eq(p->maskbits, 8); - test_eq(p->prt_min, 24); - test_eq(p->prt_max, 24); + tt_int_op(p->policy_type,==, ADDR_POLICY_REJECT); + tt_assert(tor_addr_eq(&p->addr, &ex2->addr)); + tt_int_op(p->maskbits,==, 8); + tt_int_op(p->prt_min,==, 24); + tt_int_op(p->prt_max,==, 24); #if 0 /* Okay, now for the directories. */ @@ -292,50 +294,551 @@ test_dir_formats(void) tor_free(dir2); /* And more !*/ } +#include "failing_routerdescs.inc" + +static void +test_dir_routerparse_bad(void *arg) +{ + (void) arg; + + int again; + routerinfo_t *ri = NULL; + +#define CHECK_OK(s) \ + do { \ + routerinfo_free(ri); \ + ri = router_parse_entry_from_string((s), NULL, 0, 0, NULL, NULL); \ + tt_assert(ri); \ + } while (0) +#define CHECK_FAIL(s, againval) \ + do { \ + routerinfo_free(ri); \ + again = 999; \ + ri = router_parse_entry_from_string((s), NULL, 0, 0, NULL, &again); \ + tt_assert(ri == NULL); \ + tt_int_op(again, ==, (againval)); \ + } while (0) + + CHECK_OK(EX_RI_MINIMAL); + CHECK_OK(EX_RI_MAXIMAL); + + /* good annotations prepended */ + routerinfo_free(ri); + ri = router_parse_entry_from_string(EX_RI_MINIMAL, NULL, 0, 0, + "@purpose bridge\n", NULL); + tt_assert(ri != NULL); + tt_assert(ri->purpose == ROUTER_PURPOSE_BRIDGE); + routerinfo_free(ri); + + /* bad annotations prepended. */ + ri = router_parse_entry_from_string(EX_RI_MINIMAL, + NULL, 0, 0, "@purpose\n", NULL); + tt_assert(ri == NULL); + + /* bad annotations on router. */ + ri = router_parse_entry_from_string("@purpose\nrouter x\n", NULL, 0, 1, + NULL, NULL); + tt_assert(ri == NULL); + + /* unwanted annotations on router. */ + ri = router_parse_entry_from_string("@purpose foo\nrouter x\n", NULL, 0, 0, + NULL, NULL); + tt_assert(ri == NULL); + + /* No signature. */ + ri = router_parse_entry_from_string("router x\n", NULL, 0, 0, + NULL, NULL); + tt_assert(ri == NULL); + + /* Not a router */ + routerinfo_free(ri); + ri = router_parse_entry_from_string("hello\n", NULL, 0, 0, NULL, NULL); + tt_assert(ri == NULL); + + CHECK_FAIL(EX_RI_BAD_SIG1, 1); + CHECK_FAIL(EX_RI_BAD_SIG2, 1); + CHECK_FAIL(EX_RI_BAD_TOKENS, 0); + CHECK_FAIL(EX_RI_BAD_PUBLISHED, 0); + CHECK_FAIL(EX_RI_NEG_BANDWIDTH, 0); + CHECK_FAIL(EX_RI_BAD_BANDWIDTH, 0); + CHECK_FAIL(EX_RI_BAD_BANDWIDTH2, 0); + CHECK_FAIL(EX_RI_BAD_ONIONKEY1, 0); + CHECK_FAIL(EX_RI_BAD_ONIONKEY2, 0); + CHECK_FAIL(EX_RI_BAD_PORTS, 0); + CHECK_FAIL(EX_RI_BAD_IP, 0); + CHECK_FAIL(EX_RI_BAD_DIRPORT, 0); + CHECK_FAIL(EX_RI_BAD_NAME2, 0); + CHECK_FAIL(EX_RI_BAD_UPTIME, 0); + + CHECK_FAIL(EX_RI_BAD_BANDWIDTH3, 0); + CHECK_FAIL(EX_RI_BAD_NTOR_KEY, 0); + CHECK_FAIL(EX_RI_BAD_FINGERPRINT, 0); + CHECK_FAIL(EX_RI_MISMATCHED_FINGERPRINT, 0); + CHECK_FAIL(EX_RI_BAD_HAS_ACCEPT6, 0); + CHECK_FAIL(EX_RI_BAD_NO_EXIT_POLICY, 0); + CHECK_FAIL(EX_RI_BAD_IPV6_EXIT_POLICY, 0); + CHECK_FAIL(EX_RI_BAD_FAMILY, 0); + CHECK_FAIL(EX_RI_ZERO_ORPORT, 0); + + /* This is allowed; we just ignore it. */ + CHECK_OK(EX_RI_BAD_EI_DIGEST); + +#undef CHECK_FAIL +#undef CHECK_OK + done: + routerinfo_free(ri); +} + +#include "example_extrainfo.inc" + +static void +test_dir_extrainfo_parsing(void *arg) +{ + (void) arg; + +#define CHECK_OK(s) \ + do { \ + extrainfo_free(ei); \ + ei = extrainfo_parse_entry_from_string((s), NULL, 0, map, NULL); \ + tt_assert(ei); \ + } while (0) +#define CHECK_FAIL(s, againval) \ + do { \ + extrainfo_free(ei); \ + again = 999; \ + ei = extrainfo_parse_entry_from_string((s), NULL, 0, map, &again); \ + tt_assert(ei == NULL); \ + tt_int_op(again, ==, (againval)); \ + } while (0) +#define ADD(name) \ + do { \ + ri = tor_malloc_zero(sizeof(routerinfo_t)); \ + crypto_pk_t *pk = ri->identity_pkey = crypto_pk_new(); \ + tt_assert(! crypto_pk_read_public_key_from_string(pk, \ + name##_KEY, strlen(name##_KEY))); \ + tt_int_op(0,==,base16_decode(d, 20, name##_FP, strlen(name##_FP))); \ + digestmap_set((digestmap_t*)map, d, ri); \ + ri = NULL; \ + } while (0) + + routerinfo_t *ri = NULL; + char d[20]; + struct digest_ri_map_t *map = NULL; + extrainfo_t *ei = NULL; + int again; + + CHECK_OK(EX_EI_MINIMAL); + tt_assert(ei->pending_sig); + CHECK_OK(EX_EI_MAXIMAL); + tt_assert(ei->pending_sig); + + map = (struct digest_ri_map_t *)digestmap_new(); + ADD(EX_EI_MINIMAL); + ADD(EX_EI_MAXIMAL); + ADD(EX_EI_BAD_FP); + ADD(EX_EI_BAD_NICKNAME); + ADD(EX_EI_BAD_TOKENS); + ADD(EX_EI_BAD_START); + ADD(EX_EI_BAD_PUBLISHED); + + CHECK_OK(EX_EI_MINIMAL); + tt_assert(!ei->pending_sig); + CHECK_OK(EX_EI_MAXIMAL); + tt_assert(!ei->pending_sig); + + CHECK_FAIL(EX_EI_BAD_SIG1,1); + CHECK_FAIL(EX_EI_BAD_SIG2,1); + CHECK_FAIL(EX_EI_BAD_SIG3,1); + CHECK_FAIL(EX_EI_BAD_FP,0); + CHECK_FAIL(EX_EI_BAD_NICKNAME,0); + CHECK_FAIL(EX_EI_BAD_TOKENS,0); + CHECK_FAIL(EX_EI_BAD_START,0); + CHECK_FAIL(EX_EI_BAD_PUBLISHED,0); + +#undef CHECK_OK +#undef CHECK_FAIL + + done: + routerinfo_free(ri); + /* XXXX elements should get freed too */ + digestmap_free((digestmap_t*)map, NULL); +} + +static void +test_dir_parse_router_list(void *arg) +{ + (void) arg; + smartlist_t *invalid = smartlist_new(); + smartlist_t *dest = smartlist_new(); + smartlist_t *chunks = smartlist_new(); + int dest_has_ri = 1; + char *list = NULL; + const char *cp; + digestmap_t *map = NULL; + char *mem_op_hex_tmp = NULL; + routerinfo_t *ri = NULL; + char d[DIGEST_LEN]; + + smartlist_add(chunks, tor_strdup(EX_RI_MINIMAL)); // ri 0 + smartlist_add(chunks, tor_strdup(EX_RI_BAD_PORTS)); // bad ri 0 + smartlist_add(chunks, tor_strdup(EX_EI_MAXIMAL)); // ei 0 + smartlist_add(chunks, tor_strdup(EX_EI_BAD_SIG2)); // bad ei -- + smartlist_add(chunks, tor_strdup(EX_EI_BAD_NICKNAME));// bad ei 0 + smartlist_add(chunks, tor_strdup(EX_RI_BAD_SIG1)); // bad ri -- + smartlist_add(chunks, tor_strdup(EX_EI_BAD_PUBLISHED)); // bad ei 1 + smartlist_add(chunks, tor_strdup(EX_RI_MAXIMAL)); // ri 1 + smartlist_add(chunks, tor_strdup(EX_RI_BAD_FAMILY)); // bad ri 1 + smartlist_add(chunks, tor_strdup(EX_EI_MINIMAL)); // ei 1 + + list = smartlist_join_strings(chunks, "", 0, NULL); + + /* First, parse the routers. */ + cp = list; + tt_int_op(0,==, + router_parse_list_from_string(&cp, NULL, dest, SAVED_NOWHERE, + 0, 0, NULL, invalid)); + tt_int_op(2, ==, smartlist_len(dest)); + tt_ptr_op(cp, ==, list + strlen(list)); + + routerinfo_t *r = smartlist_get(dest, 0); + tt_mem_op(r->cache_info.signed_descriptor_body, ==, + EX_RI_MINIMAL, strlen(EX_RI_MINIMAL)); + r = smartlist_get(dest, 1); + tt_mem_op(r->cache_info.signed_descriptor_body, ==, + EX_RI_MAXIMAL, strlen(EX_RI_MAXIMAL)); + + tt_int_op(2, ==, smartlist_len(invalid)); + test_memeq_hex(smartlist_get(invalid, 0), + "ab9eeaa95e7d45740185b4e519c76ead756277a9"); + test_memeq_hex(smartlist_get(invalid, 1), + "9a651ee03b64325959e8f1b46f2b689b30750b4c"); + + /* Now tidy up */ + SMARTLIST_FOREACH(dest, routerinfo_t *, ri, routerinfo_free(ri)); + SMARTLIST_FOREACH(invalid, uint8_t *, d, tor_free(d)); + smartlist_clear(dest); + smartlist_clear(invalid); + + /* And check extrainfos. */ + dest_has_ri = 0; + map = (digestmap_t*)router_get_routerlist()->identity_map; + ADD(EX_EI_MINIMAL); + ADD(EX_EI_MAXIMAL); + ADD(EX_EI_BAD_NICKNAME); + ADD(EX_EI_BAD_PUBLISHED); + cp = list; + tt_int_op(0,==, + router_parse_list_from_string(&cp, NULL, dest, SAVED_NOWHERE, + 1, 0, NULL, invalid)); + tt_int_op(2, ==, smartlist_len(dest)); + extrainfo_t *e = smartlist_get(dest, 0); + tt_mem_op(e->cache_info.signed_descriptor_body, ==, + EX_EI_MAXIMAL, strlen(EX_EI_MAXIMAL)); + e = smartlist_get(dest, 1); + tt_mem_op(e->cache_info.signed_descriptor_body, ==, + EX_EI_MINIMAL, strlen(EX_EI_MINIMAL)); + + tt_int_op(2, ==, smartlist_len(invalid)); + test_memeq_hex(smartlist_get(invalid, 0), + "d5df4aa62ee9ffc9543d41150c9864908e0390af"); + test_memeq_hex(smartlist_get(invalid, 1), + "f61efd2a7f4531f3687a9043e0de90a862ec64ba"); + + done: + tor_free(list); + if (dest_has_ri) + SMARTLIST_FOREACH(dest, routerinfo_t *, rt, routerinfo_free(rt)); + else + SMARTLIST_FOREACH(dest, extrainfo_t *, ei, extrainfo_free(ei)); + smartlist_free(dest); + SMARTLIST_FOREACH(invalid, uint8_t *, d, tor_free(d)); + smartlist_free(invalid); + SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp)); + smartlist_free(chunks); + routerinfo_free(ri); + /* XXXX this leaks: */ + if (map) { + digestmap_free((digestmap_t*)map, NULL); + router_get_routerlist()->identity_map = + (struct digest_ri_map_t*)digestmap_new(); + } + tor_free(mem_op_hex_tmp); + +#undef ADD +} + +static download_status_t dls_minimal; +static download_status_t dls_maximal; +static download_status_t dls_bad_fingerprint; +static download_status_t dls_bad_sig2; +static download_status_t dls_bad_ports; +static download_status_t dls_bad_tokens; + +static int mock_router_get_dl_status_unrecognized = 0; +static int mock_router_get_dl_status_calls = 0; + +static download_status_t * +mock_router_get_dl_status(const char *d) +{ + ++mock_router_get_dl_status_calls; + char hex[HEX_DIGEST_LEN+1]; + base16_encode(hex, sizeof(hex), d, DIGEST_LEN); + if (!strcmp(hex, "3E31D19A69EB719C00B02EC60D13356E3F7A3452")) { + return &dls_minimal; + } else if (!strcmp(hex, "581D8A368A0FA854ECDBFAB841D88B3F1B004038")) { + return &dls_maximal; + } else if (!strcmp(hex, "2578AE227C6116CDE29B3F0E95709B9872DEE5F1")) { + return &dls_bad_fingerprint; + } else if (!strcmp(hex, "16D387D3A58F7DB3CF46638F8D0B90C45C7D769C")) { + return &dls_bad_sig2; + } else if (!strcmp(hex, "AB9EEAA95E7D45740185B4E519C76EAD756277A9")) { + return &dls_bad_ports; + } else if (!strcmp(hex, "A0CC2CEFAD59DBF19F468BFEE60E0868C804B422")) { + return &dls_bad_tokens; + } else { + ++mock_router_get_dl_status_unrecognized; + return NULL; + } +} + +static void +test_dir_load_routers(void *arg) +{ + (void) arg; + smartlist_t *chunks = smartlist_new(); + smartlist_t *wanted = smartlist_new(); + char buf[DIGEST_LEN]; + char *mem_op_hex_tmp = NULL; + +#define ADD(str) \ + do { \ + tt_int_op(0,==,router_get_router_hash(str, strlen(str), buf)); \ + smartlist_add(wanted, tor_strdup(hex_str(buf, DIGEST_LEN))); \ + } while (0) + + MOCK(router_get_dl_status_by_descriptor_digest, mock_router_get_dl_status); + + update_approx_time(1412510400); + + smartlist_add(chunks, tor_strdup(EX_RI_MINIMAL)); + smartlist_add(chunks, tor_strdup(EX_RI_BAD_FINGERPRINT)); + smartlist_add(chunks, tor_strdup(EX_RI_BAD_SIG2)); + smartlist_add(chunks, tor_strdup(EX_RI_MAXIMAL)); + smartlist_add(chunks, tor_strdup(EX_RI_BAD_PORTS)); + smartlist_add(chunks, tor_strdup(EX_RI_BAD_TOKENS)); + + /* not ADDing MINIMIAL */ + ADD(EX_RI_MAXIMAL); + ADD(EX_RI_BAD_FINGERPRINT); + ADD(EX_RI_BAD_SIG2); + /* Not ADDing BAD_PORTS */ + ADD(EX_RI_BAD_TOKENS); + + char *list = smartlist_join_strings(chunks, "", 0, NULL); + tt_int_op(1, ==, + router_load_routers_from_string(list, NULL, SAVED_IN_JOURNAL, + wanted, 1, NULL)); + + /* The "maximal" router was added. */ + /* "minimal" was not. */ + tt_int_op(smartlist_len(router_get_routerlist()->routers),==,1); + routerinfo_t *r = smartlist_get(router_get_routerlist()->routers, 0); + test_memeq_hex(r->cache_info.signed_descriptor_digest, + "581D8A368A0FA854ECDBFAB841D88B3F1B004038"); + tt_int_op(dls_minimal.n_download_failures, ==, 0); + tt_int_op(dls_maximal.n_download_failures, ==, 0); + + /* "Bad fingerprint" and "Bad tokens" should have gotten marked + * non-retriable. */ + tt_want_int_op(mock_router_get_dl_status_calls, ==, 2); + tt_want_int_op(mock_router_get_dl_status_unrecognized, ==, 0); + tt_int_op(dls_bad_fingerprint.n_download_failures, ==, 255); + tt_int_op(dls_bad_tokens.n_download_failures, ==, 255); + + /* bad_sig2 and bad ports" are retriable -- one since only the signature + * was bad, and one because we didn't ask for it. */ + tt_int_op(dls_bad_sig2.n_download_failures, ==, 0); + tt_int_op(dls_bad_ports.n_download_failures, ==, 0); + + /* Wanted still contains "BAD_SIG2" */ + tt_int_op(smartlist_len(wanted), ==, 1); + tt_str_op(smartlist_get(wanted, 0), ==, + "E0A3753CEFD54128EAB239F294954121DB23D2EF"); + +#undef ADD + + done: + tor_free(mem_op_hex_tmp); + UNMOCK(router_get_dl_status_by_descriptor_digest); + SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp)); + smartlist_free(chunks); + SMARTLIST_FOREACH(wanted, char *, cp, tor_free(cp)); + smartlist_free(wanted); +} + +static int mock_get_by_ei_dd_calls = 0; +static int mock_get_by_ei_dd_unrecognized = 0; + +static signed_descriptor_t sd_ei_minimal; +static signed_descriptor_t sd_ei_bad_nickname; +static signed_descriptor_t sd_ei_maximal; +static signed_descriptor_t sd_ei_bad_tokens; +static signed_descriptor_t sd_ei_bad_sig2; + +static signed_descriptor_t * +mock_get_by_ei_desc_digest(const char *d) +{ + + ++mock_get_by_ei_dd_calls; + char hex[HEX_DIGEST_LEN+1]; + base16_encode(hex, sizeof(hex), d, DIGEST_LEN); + + if (!strcmp(hex, "11E0EDF526950739F7769810FCACAB8C882FAEEE")) { + return &sd_ei_minimal; + } else if (!strcmp(hex, "47803B02A0E70E9E8BDA226CB1D74DE354D67DFF")) { + return &sd_ei_maximal; + } else if (!strcmp(hex, "D5DF4AA62EE9FFC9543D41150C9864908E0390AF")) { + return &sd_ei_bad_nickname; + } else if (!strcmp(hex, "16D387D3A58F7DB3CF46638F8D0B90C45C7D769C")) { + return &sd_ei_bad_sig2; + } else if (!strcmp(hex, "9D90F8C42955BBC57D54FB05E54A3F083AF42E8B")) { + return &sd_ei_bad_tokens; + } else { + ++mock_get_by_ei_dd_unrecognized; + return NULL; + } +} + +static smartlist_t *mock_ei_insert_list = NULL; +static was_router_added_t +mock_ei_insert(routerlist_t *rl, extrainfo_t *ei) +{ + (void) rl; + smartlist_add(mock_ei_insert_list, ei); + return ROUTER_ADDED_SUCCESSFULLY; +} + static void -test_dir_versions(void) +test_dir_load_extrainfo(void *arg) +{ + (void) arg; + smartlist_t *chunks = smartlist_new(); + smartlist_t *wanted = smartlist_new(); + char buf[DIGEST_LEN]; + char *mem_op_hex_tmp = NULL; + +#define ADD(str) \ + do { \ + tt_int_op(0,==,router_get_extrainfo_hash(str, strlen(str), buf)); \ + smartlist_add(wanted, tor_strdup(hex_str(buf, DIGEST_LEN))); \ + } while (0) + + mock_ei_insert_list = smartlist_new(); + MOCK(router_get_by_extrainfo_digest, mock_get_by_ei_desc_digest); + MOCK(extrainfo_insert, mock_ei_insert); + + smartlist_add(chunks, tor_strdup(EX_EI_MINIMAL)); + smartlist_add(chunks, tor_strdup(EX_EI_BAD_NICKNAME)); + smartlist_add(chunks, tor_strdup(EX_EI_MAXIMAL)); + smartlist_add(chunks, tor_strdup(EX_EI_BAD_PUBLISHED)); + smartlist_add(chunks, tor_strdup(EX_EI_BAD_TOKENS)); + + /* not ADDing MINIMIAL */ + ADD(EX_EI_MAXIMAL); + ADD(EX_EI_BAD_NICKNAME); + /* Not ADDing BAD_PUBLISHED */ + ADD(EX_EI_BAD_TOKENS); + ADD(EX_EI_BAD_SIG2); + + char *list = smartlist_join_strings(chunks, "", 0, NULL); + router_load_extrainfo_from_string(list, NULL, SAVED_IN_JOURNAL, wanted, 1); + + /* The "maximal" router was added. */ + /* "minimal" was also added, even though we didn't ask for it, since + * that's what we do with extrainfos. */ + tt_int_op(smartlist_len(mock_ei_insert_list),==,2); + + extrainfo_t *e = smartlist_get(mock_ei_insert_list, 0); + test_memeq_hex(e->cache_info.signed_descriptor_digest, + "11E0EDF526950739F7769810FCACAB8C882FAEEE"); + + e = smartlist_get(mock_ei_insert_list, 1); + test_memeq_hex(e->cache_info.signed_descriptor_digest, + "47803B02A0E70E9E8BDA226CB1D74DE354D67DFF"); + tt_int_op(dls_minimal.n_download_failures, ==, 0); + tt_int_op(dls_maximal.n_download_failures, ==, 0); + + /* "Bad nickname" and "Bad tokens" should have gotten marked + * non-retriable. */ + tt_want_int_op(mock_get_by_ei_dd_calls, ==, 2); + tt_want_int_op(mock_get_by_ei_dd_unrecognized, ==, 0); + tt_int_op(sd_ei_bad_nickname.ei_dl_status.n_download_failures, ==, 255); + tt_int_op(sd_ei_bad_tokens.ei_dl_status.n_download_failures, ==, 255); + + /* bad_ports is retriable -- because we didn't ask for it. */ + tt_int_op(dls_bad_ports.n_download_failures, ==, 0); + + /* Wanted still contains "BAD_SIG2" */ + tt_int_op(smartlist_len(wanted), ==, 1); + tt_str_op(smartlist_get(wanted, 0), ==, + "16D387D3A58F7DB3CF46638F8D0B90C45C7D769C"); + +#undef ADD + + done: + tor_free(mem_op_hex_tmp); + UNMOCK(router_get_by_extrainfo_digest); + SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp)); + smartlist_free(chunks); + SMARTLIST_FOREACH(wanted, char *, cp, tor_free(cp)); + smartlist_free(wanted); +} + +static void +test_dir_versions(void *arg) { tor_version_t ver1; /* Try out version parsing functionality */ - test_eq(0, tor_version_parse("0.3.4pre2-cvs", &ver1)); - test_eq(0, ver1.major); - test_eq(3, ver1.minor); - test_eq(4, ver1.micro); - test_eq(VER_PRE, ver1.status); - test_eq(2, ver1.patchlevel); - test_eq(0, tor_version_parse("0.3.4rc1", &ver1)); - test_eq(0, ver1.major); - test_eq(3, ver1.minor); - test_eq(4, ver1.micro); - test_eq(VER_RC, ver1.status); - test_eq(1, ver1.patchlevel); - test_eq(0, tor_version_parse("1.3.4", &ver1)); - test_eq(1, ver1.major); - test_eq(3, ver1.minor); - test_eq(4, ver1.micro); - test_eq(VER_RELEASE, ver1.status); - test_eq(0, ver1.patchlevel); - test_eq(0, tor_version_parse("1.3.4.999", &ver1)); - test_eq(1, ver1.major); - test_eq(3, ver1.minor); - test_eq(4, ver1.micro); - test_eq(VER_RELEASE, ver1.status); - test_eq(999, ver1.patchlevel); - test_eq(0, tor_version_parse("0.1.2.4-alpha", &ver1)); - test_eq(0, ver1.major); - test_eq(1, ver1.minor); - test_eq(2, ver1.micro); - test_eq(4, ver1.patchlevel); - test_eq(VER_RELEASE, ver1.status); - test_streq("alpha", ver1.status_tag); - test_eq(0, tor_version_parse("0.1.2.4", &ver1)); - test_eq(0, ver1.major); - test_eq(1, ver1.minor); - test_eq(2, ver1.micro); - test_eq(4, ver1.patchlevel); - test_eq(VER_RELEASE, ver1.status); - test_streq("", ver1.status_tag); + (void)arg; + tt_int_op(0,==, tor_version_parse("0.3.4pre2-cvs", &ver1)); + tt_int_op(0,==, ver1.major); + tt_int_op(3,==, ver1.minor); + tt_int_op(4,==, ver1.micro); + tt_int_op(VER_PRE,==, ver1.status); + tt_int_op(2,==, ver1.patchlevel); + tt_int_op(0,==, tor_version_parse("0.3.4rc1", &ver1)); + tt_int_op(0,==, ver1.major); + tt_int_op(3,==, ver1.minor); + tt_int_op(4,==, ver1.micro); + tt_int_op(VER_RC,==, ver1.status); + tt_int_op(1,==, ver1.patchlevel); + tt_int_op(0,==, tor_version_parse("1.3.4", &ver1)); + tt_int_op(1,==, ver1.major); + tt_int_op(3,==, ver1.minor); + tt_int_op(4,==, ver1.micro); + tt_int_op(VER_RELEASE,==, ver1.status); + tt_int_op(0,==, ver1.patchlevel); + tt_int_op(0,==, tor_version_parse("1.3.4.999", &ver1)); + tt_int_op(1,==, ver1.major); + tt_int_op(3,==, ver1.minor); + tt_int_op(4,==, ver1.micro); + tt_int_op(VER_RELEASE,==, ver1.status); + tt_int_op(999,==, ver1.patchlevel); + tt_int_op(0,==, tor_version_parse("0.1.2.4-alpha", &ver1)); + tt_int_op(0,==, ver1.major); + tt_int_op(1,==, ver1.minor); + tt_int_op(2,==, ver1.micro); + tt_int_op(4,==, ver1.patchlevel); + tt_int_op(VER_RELEASE,==, ver1.status); + tt_str_op("alpha",==, ver1.status_tag); + tt_int_op(0,==, tor_version_parse("0.1.2.4", &ver1)); + tt_int_op(0,==, ver1.major); + tt_int_op(1,==, ver1.minor); + tt_int_op(2,==, ver1.micro); + tt_int_op(4,==, ver1.patchlevel); + tt_int_op(VER_RELEASE,==, ver1.status); + tt_str_op("",==, ver1.status_tag); #define tt_versionstatus_op(vs1, op, vs2) \ tt_assert_test_type(vs1,vs2,#vs1" "#op" "#vs2,version_status_t, \ @@ -368,53 +871,54 @@ test_dir_versions(void) /* On list, not newer than any on same series. */ test_v_i_o(VS_UNRECOMMENDED, "0.1.0.1", "Tor 0.1.0.2,Tor 0.0.9.5,Tor 0.1.1.0"); - test_eq(0, tor_version_as_new_as("Tor 0.0.5", "0.0.9pre1-cvs")); - test_eq(1, tor_version_as_new_as( + tt_int_op(0,==, tor_version_as_new_as("Tor 0.0.5", "0.0.9pre1-cvs")); + tt_int_op(1,==, tor_version_as_new_as( "Tor 0.0.8 on Darwin 64-121-192-100.c3-0." "sfpo-ubr1.sfrn-sfpo.ca.cable.rcn.com Power Macintosh", "0.0.8rc2")); - test_eq(0, tor_version_as_new_as( + tt_int_op(0,==, tor_version_as_new_as( "Tor 0.0.8 on Darwin 64-121-192-100.c3-0." "sfpo-ubr1.sfrn-sfpo.ca.cable.rcn.com Power Macintosh", "0.0.8.2")); /* Now try svn revisions. */ - test_eq(1, tor_version_as_new_as("Tor 0.2.1.0-dev (r100)", + tt_int_op(1,==, tor_version_as_new_as("Tor 0.2.1.0-dev (r100)", "Tor 0.2.1.0-dev (r99)")); - test_eq(1, tor_version_as_new_as("Tor 0.2.1.0-dev (r100) on Banana Jr", + tt_int_op(1,==, tor_version_as_new_as("Tor 0.2.1.0-dev (r100) on Banana Jr", "Tor 0.2.1.0-dev (r99) on Hal 9000")); - test_eq(1, tor_version_as_new_as("Tor 0.2.1.0-dev (r100)", + tt_int_op(1,==, tor_version_as_new_as("Tor 0.2.1.0-dev (r100)", "Tor 0.2.1.0-dev on Colossus")); - test_eq(0, tor_version_as_new_as("Tor 0.2.1.0-dev (r99)", + tt_int_op(0,==, tor_version_as_new_as("Tor 0.2.1.0-dev (r99)", "Tor 0.2.1.0-dev (r100)")); - test_eq(0, tor_version_as_new_as("Tor 0.2.1.0-dev (r99) on MCP", + tt_int_op(0,==, tor_version_as_new_as("Tor 0.2.1.0-dev (r99) on MCP", "Tor 0.2.1.0-dev (r100) on AM")); - test_eq(0, tor_version_as_new_as("Tor 0.2.1.0-dev", + tt_int_op(0,==, tor_version_as_new_as("Tor 0.2.1.0-dev", "Tor 0.2.1.0-dev (r99)")); - test_eq(1, tor_version_as_new_as("Tor 0.2.1.1", + tt_int_op(1,==, tor_version_as_new_as("Tor 0.2.1.1", "Tor 0.2.1.0-dev (r99)")); /* Now try git revisions */ - test_eq(0, tor_version_parse("0.5.6.7 (git-ff00ff)", &ver1)); - test_eq(0, ver1.major); - test_eq(5, ver1.minor); - test_eq(6, ver1.micro); - test_eq(7, ver1.patchlevel); - test_eq(3, ver1.git_tag_len); - test_memeq(ver1.git_tag, "\xff\x00\xff", 3); - test_eq(-1, tor_version_parse("0.5.6.7 (git-ff00xx)", &ver1)); - test_eq(-1, tor_version_parse("0.5.6.7 (git-ff00fff)", &ver1)); - test_eq(0, tor_version_parse("0.5.6.7 (git ff00fff)", &ver1)); + tt_int_op(0,==, tor_version_parse("0.5.6.7 (git-ff00ff)", &ver1)); + tt_int_op(0,==, ver1.major); + tt_int_op(5,==, ver1.minor); + tt_int_op(6,==, ver1.micro); + tt_int_op(7,==, ver1.patchlevel); + tt_int_op(3,==, ver1.git_tag_len); + tt_mem_op(ver1.git_tag,==, "\xff\x00\xff", 3); + tt_int_op(-1,==, tor_version_parse("0.5.6.7 (git-ff00xx)", &ver1)); + tt_int_op(-1,==, tor_version_parse("0.5.6.7 (git-ff00fff)", &ver1)); + tt_int_op(0,==, tor_version_parse("0.5.6.7 (git ff00fff)", &ver1)); done: ; } /** Run unit tests for directory fp_pair functions. */ static void -test_dir_fp_pairs(void) +test_dir_fp_pairs(void *arg) { smartlist_t *sl = smartlist_new(); fp_pair_t *pair; + (void)arg; dir_split_resource_into_fingerprint_pairs( /* Two pairs, out of order, with one duplicate. */ "73656372657420646174612E0000000000FFFFFF-" @@ -424,13 +928,13 @@ test_dir_fp_pairs(void) "48657861646563696d616c2069736e277420736f-" "676f6f6420666f7220686964696e6720796f7572.z", sl); - test_eq(smartlist_len(sl), 2); + tt_int_op(smartlist_len(sl),==, 2); pair = smartlist_get(sl, 0); - test_memeq(pair->first, "Hexadecimal isn't so", DIGEST_LEN); - test_memeq(pair->second, "good for hiding your", DIGEST_LEN); + tt_mem_op(pair->first,==, "Hexadecimal isn't so", DIGEST_LEN); + tt_mem_op(pair->second,==, "good for hiding your", DIGEST_LEN); pair = smartlist_get(sl, 1); - test_memeq(pair->first, "secret data.\0\0\0\0\0\xff\xff\xff", DIGEST_LEN); - test_memeq(pair->second, "Use AES-256 instead.", DIGEST_LEN); + tt_mem_op(pair->first,==, "secret data.\0\0\0\0\0\xff\xff\xff", DIGEST_LEN); + tt_mem_op(pair->second,==, "Use AES-256 instead.", DIGEST_LEN); done: SMARTLIST_FOREACH(sl, fp_pair_t *, pair, tor_free(pair)); @@ -557,7 +1061,7 @@ test_dir_split_fps(void *testdata) } static void -test_dir_measured_bw_kb(void) +test_dir_measured_bw_kb(void *arg) { measured_bw_line_t mbwl; int i; @@ -605,16 +1109,17 @@ test_dir_measured_bw_kb(void) "end" }; + (void)arg; for (i = 0; strcmp(lines_fail[i], "end"); i++) { //fprintf(stderr, "Testing: %s\n", lines_fail[i]); - test_assert(measured_bw_line_parse(&mbwl, lines_fail[i]) == -1); + tt_assert(measured_bw_line_parse(&mbwl, lines_fail[i]) == -1); } for (i = 0; strcmp(lines_pass[i], "end"); i++) { //fprintf(stderr, "Testing: %s %d\n", lines_pass[i], TOR_ISSPACE('\n')); - test_assert(measured_bw_line_parse(&mbwl, lines_pass[i]) == 0); - test_assert(mbwl.bw_kb == 1024); - test_assert(strcmp(mbwl.node_hex, + tt_assert(measured_bw_line_parse(&mbwl, lines_pass[i]) == 0); + tt_assert(mbwl.bw_kb == 1024); + tt_assert(strcmp(mbwl.node_hex, "557365204145532d32353620696e73746561642e") == 0); } @@ -626,7 +1131,7 @@ test_dir_measured_bw_kb(void) /** Do the measured bandwidth cache unit test */ static void -test_dir_measured_bw_kb_cache(void) +test_dir_measured_bw_kb_cache(void *arg) { /* Initial fake time_t for testing */ time_t curr = MBWC_INIT_TIME; @@ -637,8 +1142,9 @@ test_dir_measured_bw_kb_cache(void) time_t as_of; /* First, clear the cache and assert that it's empty */ + (void)arg; dirserv_clear_measured_bw_cache(); - test_eq(dirserv_get_measured_bw_cache_size(), 0); + tt_int_op(dirserv_get_measured_bw_cache_size(),==, 0); /* * Set up test mbwls; none of the dirserv_cache_*() functions care about * the node_hex field. @@ -651,56 +1157,56 @@ test_dir_measured_bw_kb_cache(void) mbwl[2].bw_kb = 80; /* Try caching something */ dirserv_cache_measured_bw(&(mbwl[0]), curr); - test_eq(dirserv_get_measured_bw_cache_size(), 1); + tt_int_op(dirserv_get_measured_bw_cache_size(),==, 1); /* Okay, let's see if we can retrieve it */ - test_assert(dirserv_query_measured_bw_cache_kb(mbwl[0].node_id,&bw, &as_of)); - test_eq(bw, 20); - test_eq(as_of, MBWC_INIT_TIME); + tt_assert(dirserv_query_measured_bw_cache_kb(mbwl[0].node_id,&bw, &as_of)); + tt_int_op(bw,==, 20); + tt_int_op(as_of,==, MBWC_INIT_TIME); /* Try retrieving it without some outputs */ - test_assert(dirserv_query_measured_bw_cache_kb(mbwl[0].node_id,NULL, NULL)); - test_assert(dirserv_query_measured_bw_cache_kb(mbwl[0].node_id,&bw, NULL)); - test_eq(bw, 20); - test_assert(dirserv_query_measured_bw_cache_kb(mbwl[0].node_id,NULL,&as_of)); - test_eq(as_of, MBWC_INIT_TIME); + tt_assert(dirserv_query_measured_bw_cache_kb(mbwl[0].node_id,NULL, NULL)); + tt_assert(dirserv_query_measured_bw_cache_kb(mbwl[0].node_id,&bw, NULL)); + tt_int_op(bw,==, 20); + tt_assert(dirserv_query_measured_bw_cache_kb(mbwl[0].node_id,NULL,&as_of)); + tt_int_op(as_of,==, MBWC_INIT_TIME); /* Now expire it */ curr += MAX_MEASUREMENT_AGE + 1; dirserv_expire_measured_bw_cache(curr); /* Check that the cache is empty */ - test_eq(dirserv_get_measured_bw_cache_size(), 0); + tt_int_op(dirserv_get_measured_bw_cache_size(),==, 0); /* Check that we can't retrieve it */ - test_assert(!dirserv_query_measured_bw_cache_kb(mbwl[0].node_id, NULL,NULL)); + tt_assert(!dirserv_query_measured_bw_cache_kb(mbwl[0].node_id, NULL,NULL)); /* Try caching a few things now */ dirserv_cache_measured_bw(&(mbwl[0]), curr); - test_eq(dirserv_get_measured_bw_cache_size(), 1); + tt_int_op(dirserv_get_measured_bw_cache_size(),==, 1); curr += MAX_MEASUREMENT_AGE / 4; dirserv_cache_measured_bw(&(mbwl[1]), curr); - test_eq(dirserv_get_measured_bw_cache_size(), 2); + tt_int_op(dirserv_get_measured_bw_cache_size(),==, 2); curr += MAX_MEASUREMENT_AGE / 4; dirserv_cache_measured_bw(&(mbwl[2]), curr); - test_eq(dirserv_get_measured_bw_cache_size(), 3); + tt_int_op(dirserv_get_measured_bw_cache_size(),==, 3); curr += MAX_MEASUREMENT_AGE / 4 + 1; /* Do an expire that's too soon to get any of them */ dirserv_expire_measured_bw_cache(curr); - test_eq(dirserv_get_measured_bw_cache_size(), 3); + tt_int_op(dirserv_get_measured_bw_cache_size(),==, 3); /* Push the oldest one off the cliff */ curr += MAX_MEASUREMENT_AGE / 4; dirserv_expire_measured_bw_cache(curr); - test_eq(dirserv_get_measured_bw_cache_size(), 2); + tt_int_op(dirserv_get_measured_bw_cache_size(),==, 2); /* And another... */ curr += MAX_MEASUREMENT_AGE / 4; dirserv_expire_measured_bw_cache(curr); - test_eq(dirserv_get_measured_bw_cache_size(), 1); + tt_int_op(dirserv_get_measured_bw_cache_size(),==, 1); /* This should empty it out again */ curr += MAX_MEASUREMENT_AGE / 4; dirserv_expire_measured_bw_cache(curr); - test_eq(dirserv_get_measured_bw_cache_size(), 0); + tt_int_op(dirserv_get_measured_bw_cache_size(),==, 0); done: return; } static void -test_dir_param_voting(void) +test_dir_param_voting(void *arg) { networkstatus_t vote1, vote2, vote3, vote4; smartlist_t *votes = smartlist_new(); @@ -709,6 +1215,7 @@ test_dir_param_voting(void) /* dirvote_compute_params only looks at the net_params field of the votes, so that's all we need to set. */ + (void)arg; memset(&vote1, 0, sizeof(vote1)); memset(&vote2, 0, sizeof(vote2)); memset(&vote3, 0, sizeof(vote3)); @@ -725,11 +1232,11 @@ test_dir_param_voting(void) "abcd=20 c=60 cw=500 x-yz=-9 zzzzz=101", NULL, 0, 0); smartlist_split_string(vote4.net_params, "ab=900 abcd=200 c=1 cw=51 x-yz=100", NULL, 0, 0); - test_eq(100, networkstatus_get_param(&vote4, "x-yz", 50, 0, 300)); - test_eq(222, networkstatus_get_param(&vote4, "foobar", 222, 0, 300)); - test_eq(80, networkstatus_get_param(&vote4, "ab", 12, 0, 80)); - test_eq(-8, networkstatus_get_param(&vote4, "ab", -12, -100, -8)); - test_eq(0, networkstatus_get_param(&vote4, "foobar", 0, -100, 8)); + tt_int_op(100,==, networkstatus_get_param(&vote4, "x-yz", 50, 0, 300)); + tt_int_op(222,==, networkstatus_get_param(&vote4, "foobar", 222, 0, 300)); + tt_int_op(80,==, networkstatus_get_param(&vote4, "ab", 12, 0, 80)); + tt_int_op(-8,==, networkstatus_get_param(&vote4, "ab", -12, -100, -8)); + tt_int_op(0,==, networkstatus_get_param(&vote4, "foobar", 0, -100, 8)); smartlist_add(votes, &vote1); @@ -737,59 +1244,59 @@ test_dir_param_voting(void) * networks without many dirauths. */ res = dirvote_compute_params(votes, 12, 2); - test_streq(res, ""); + tt_str_op(res,==, ""); tor_free(res); res = dirvote_compute_params(votes, 12, 1); - test_streq(res, "ab=90 abcd=20 cw=50 x-yz=-99"); + tt_str_op(res,==, "ab=90 abcd=20 cw=50 x-yz=-99"); tor_free(res); smartlist_add(votes, &vote2); res = dirvote_compute_params(votes, 12, 2); - test_streq(res, "ab=27 cw=5 x-yz=-99"); + tt_str_op(res,==, "ab=27 cw=5 x-yz=-99"); tor_free(res); res = dirvote_compute_params(votes, 12, 3); - test_streq(res, "ab=27 cw=5 x-yz=-99"); + tt_str_op(res,==, "ab=27 cw=5 x-yz=-99"); tor_free(res); res = dirvote_compute_params(votes, 12, 6); - test_streq(res, ""); + tt_str_op(res,==, ""); tor_free(res); smartlist_add(votes, &vote3); res = dirvote_compute_params(votes, 12, 3); - test_streq(res, "ab=27 abcd=20 cw=50 x-yz=-9"); + tt_str_op(res,==, "ab=27 abcd=20 cw=50 x-yz=-9"); tor_free(res); res = dirvote_compute_params(votes, 12, 5); - test_streq(res, "cw=50 x-yz=-9"); + tt_str_op(res,==, "cw=50 x-yz=-9"); tor_free(res); res = dirvote_compute_params(votes, 12, 9); - test_streq(res, "cw=50 x-yz=-9"); + tt_str_op(res,==, "cw=50 x-yz=-9"); tor_free(res); smartlist_add(votes, &vote4); res = dirvote_compute_params(votes, 12, 4); - test_streq(res, "ab=90 abcd=20 cw=50 x-yz=-9"); + tt_str_op(res,==, "ab=90 abcd=20 cw=50 x-yz=-9"); tor_free(res); res = dirvote_compute_params(votes, 12, 5); - test_streq(res, "ab=90 abcd=20 cw=50 x-yz=-9"); + tt_str_op(res,==, "ab=90 abcd=20 cw=50 x-yz=-9"); tor_free(res); /* Test that the special-cased "at least three dirauths voted for * this param" logic works as expected. */ res = dirvote_compute_params(votes, 12, 6); - test_streq(res, "ab=90 abcd=20 cw=50 x-yz=-9"); + tt_str_op(res,==, "ab=90 abcd=20 cw=50 x-yz=-9"); tor_free(res); res = dirvote_compute_params(votes, 12, 10); - test_streq(res, "ab=90 abcd=20 cw=50 x-yz=-9"); + tt_str_op(res,==, "ab=90 abcd=20 cw=50 x-yz=-9"); tor_free(res); done: @@ -821,14 +1328,14 @@ static void test_same_voter(networkstatus_voter_info_t *v1, networkstatus_voter_info_t *v2) { - test_streq(v1->nickname, v2->nickname); - test_memeq(v1->identity_digest, v2->identity_digest, DIGEST_LEN); - test_streq(v1->address, v2->address); - test_eq(v1->addr, v2->addr); - test_eq(v1->dir_port, v2->dir_port); - test_eq(v1->or_port, v2->or_port); - test_streq(v1->contact, v2->contact); - test_memeq(v1->vote_digest, v2->vote_digest, DIGEST_LEN); + tt_str_op(v1->nickname,==, v2->nickname); + tt_mem_op(v1->identity_digest,==, v2->identity_digest, DIGEST_LEN); + tt_str_op(v1->address,==, v2->address); + tt_int_op(v1->addr,==, v2->addr); + tt_int_op(v1->dir_port,==, v2->dir_port); + tt_int_op(v1->or_port,==, v2->or_port); + tt_str_op(v1->contact,==, v2->contact); + tt_mem_op(v1->vote_digest,==, v2->vote_digest, DIGEST_LEN); done: ; } @@ -965,7 +1472,7 @@ gen_routerstatus_for_v3ns(int idx, time_t now) break; default: /* Shouldn't happen */ - test_assert(0); + tt_assert(0); } if (vrs) { vrs->microdesc = tor_malloc_zero(sizeof(vote_microdesc_hash_t)); @@ -986,14 +1493,14 @@ vote_tweaks_for_v3ns(networkstatus_t *v, int voter, time_t now) vote_routerstatus_t *vrs; const char *msg = NULL; - test_assert(v); + tt_assert(v); (void)now; if (voter == 1) { measured_bw_line_t mbw; memset(mbw.node_id, 33, sizeof(mbw.node_id)); mbw.bw_kb = 1024; - test_assert(measured_bw_line_apply(&mbw, + tt_assert(measured_bw_line_apply(&mbw, v->routerstatus_list) == 1); } else if (voter == 2 || voter == 3) { /* Monkey around with the list a bit */ @@ -1009,7 +1516,7 @@ vote_tweaks_for_v3ns(networkstatus_t *v, int voter, time_t now) vote_routerstatus_free(vrs); vrs = smartlist_get(v->routerstatus_list, 0); memset(vrs->status.descriptor_digest, (int)'Z', DIGEST_LEN); - test_assert(router_add_to_routerlist( + tt_assert(router_add_to_routerlist( generate_ri_from_rs(vrs), &msg,0,0) >= 0); } } @@ -1027,9 +1534,9 @@ test_vrs_for_v3ns(vote_routerstatus_t *vrs, int voter, time_t now) routerstatus_t *rs; tor_addr_t addr_ipv6; - test_assert(vrs); + tt_assert(vrs); rs = &(vrs->status); - test_assert(rs); + tt_assert(rs); /* Split out by digests to test */ if (tor_memeq(rs->identity_digest, @@ -1038,17 +1545,17 @@ test_vrs_for_v3ns(vote_routerstatus_t *vrs, int voter, time_t now) DIGEST_LEN) && (voter == 1)) { /* Check the first routerstatus. */ - test_streq(vrs->version, "0.1.2.14"); - test_eq(rs->published_on, now-1500); - test_streq(rs->nickname, "router2"); - test_memeq(rs->identity_digest, + tt_str_op(vrs->version,==, "0.1.2.14"); + tt_int_op(rs->published_on,==, now-1500); + tt_str_op(rs->nickname,==, "router2"); + tt_mem_op(rs->identity_digest,==, "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3" "\x3\x3\x3\x3", DIGEST_LEN); - test_memeq(rs->descriptor_digest, "NNNNNNNNNNNNNNNNNNNN", DIGEST_LEN); - test_eq(rs->addr, 0x99008801); - test_eq(rs->or_port, 443); - test_eq(rs->dir_port, 8000); + tt_mem_op(rs->descriptor_digest,==, "NNNNNNNNNNNNNNNNNNNN", DIGEST_LEN); + tt_int_op(rs->addr,==, 0x99008801); + tt_int_op(rs->or_port,==, 443); + tt_int_op(rs->dir_port,==, 8000); /* no flags except "running" (16) and "v2dir" (64) */ tt_u64_op(vrs->flags, ==, U64_LITERAL(80)); } else if (tor_memeq(rs->identity_digest, @@ -1056,24 +1563,24 @@ test_vrs_for_v3ns(vote_routerstatus_t *vrs, int voter, time_t now) "\x5\x5\x5\x5", DIGEST_LEN) && (voter == 1 || voter == 2)) { - test_memeq(rs->identity_digest, + tt_mem_op(rs->identity_digest,==, "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5" "\x5\x5\x5\x5", DIGEST_LEN); if (voter == 1) { /* Check the second routerstatus. */ - test_streq(vrs->version, "0.2.0.5"); - test_eq(rs->published_on, now-1000); - test_streq(rs->nickname, "router1"); + tt_str_op(vrs->version,==, "0.2.0.5"); + tt_int_op(rs->published_on,==, now-1000); + tt_str_op(rs->nickname,==, "router1"); } - test_memeq(rs->descriptor_digest, "MMMMMMMMMMMMMMMMMMMM", DIGEST_LEN); - test_eq(rs->addr, 0x99009901); - test_eq(rs->or_port, 443); - test_eq(rs->dir_port, 0); + tt_mem_op(rs->descriptor_digest,==, "MMMMMMMMMMMMMMMMMMMM", DIGEST_LEN); + tt_int_op(rs->addr,==, 0x99009901); + tt_int_op(rs->or_port,==, 443); + tt_int_op(rs->dir_port,==, 0); tor_addr_parse(&addr_ipv6, "[1:2:3::4]"); - test_assert(tor_addr_eq(&rs->ipv6_addr, &addr_ipv6)); - test_eq(rs->ipv6_orport, 4711); + tt_assert(tor_addr_eq(&rs->ipv6_addr, &addr_ipv6)); + tt_int_op(rs->ipv6_orport,==, 4711); if (voter == 1) { /* all except "authority" (1) and "v2dir" (64) */ tt_u64_op(vrs->flags, ==, U64_LITERAL(190)); @@ -1087,14 +1594,14 @@ test_vrs_for_v3ns(vote_routerstatus_t *vrs, int voter, time_t now) DIGEST_LEN) && (voter == 1 || voter == 2)) { /* Check the measured bandwidth bits */ - test_assert(vrs->has_measured_bw && + tt_assert(vrs->has_measured_bw && vrs->measured_bw_kb == 1024); } else { /* * Didn't expect this, but the old unit test only checked some of them, * so don't assert. */ - /* test_assert(0); */ + /* tt_assert(0); */ } done: @@ -1109,9 +1616,9 @@ test_consensus_for_v3ns(networkstatus_t *con, time_t now) { (void)now; - test_assert(con); - test_assert(!con->cert); - test_eq(2, smartlist_len(con->routerstatus_list)); + tt_assert(con); + tt_assert(!con->cert); + tt_int_op(2,==, smartlist_len(con->routerstatus_list)); /* There should be two listed routers: one with identity 3, one with * identity 5. */ @@ -1127,7 +1634,7 @@ test_routerstatus_for_v3ns(routerstatus_t *rs, time_t now) { tor_addr_t addr_ipv6; - test_assert(rs); + tt_assert(rs); /* There should be two listed routers: one with identity 3, one with * identity 5. */ @@ -1136,49 +1643,49 @@ test_routerstatus_for_v3ns(routerstatus_t *rs, time_t now) "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3" "\x3\x3", DIGEST_LEN)) { - test_memeq(rs->identity_digest, + tt_mem_op(rs->identity_digest,==, "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3", DIGEST_LEN); - test_memeq(rs->descriptor_digest, "NNNNNNNNNNNNNNNNNNNN", DIGEST_LEN); - test_assert(!rs->is_authority); - test_assert(!rs->is_exit); - test_assert(!rs->is_fast); - test_assert(!rs->is_possible_guard); - test_assert(!rs->is_stable); + tt_mem_op(rs->descriptor_digest,==, "NNNNNNNNNNNNNNNNNNNN", DIGEST_LEN); + tt_assert(!rs->is_authority); + tt_assert(!rs->is_exit); + tt_assert(!rs->is_fast); + tt_assert(!rs->is_possible_guard); + tt_assert(!rs->is_stable); /* (If it wasn't running it wouldn't be here) */ - test_assert(rs->is_flagged_running); - test_assert(!rs->is_valid); - test_assert(!rs->is_named); + tt_assert(rs->is_flagged_running); + tt_assert(!rs->is_valid); + tt_assert(!rs->is_named); /* XXXX check version */ } else if (tor_memeq(rs->identity_digest, "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5" "\x5\x5\x5\x5", DIGEST_LEN)) { /* This one showed up in 3 digests. Twice with ID 'M', once with 'Z'. */ - test_memeq(rs->identity_digest, + tt_mem_op(rs->identity_digest,==, "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5", DIGEST_LEN); - test_streq(rs->nickname, "router1"); - test_memeq(rs->descriptor_digest, "MMMMMMMMMMMMMMMMMMMM", DIGEST_LEN); - test_eq(rs->published_on, now-1000); - test_eq(rs->addr, 0x99009901); - test_eq(rs->or_port, 443); - test_eq(rs->dir_port, 0); + tt_str_op(rs->nickname,==, "router1"); + tt_mem_op(rs->descriptor_digest,==, "MMMMMMMMMMMMMMMMMMMM", DIGEST_LEN); + tt_int_op(rs->published_on,==, now-1000); + tt_int_op(rs->addr,==, 0x99009901); + tt_int_op(rs->or_port,==, 443); + tt_int_op(rs->dir_port,==, 0); tor_addr_parse(&addr_ipv6, "[1:2:3::4]"); - test_assert(tor_addr_eq(&rs->ipv6_addr, &addr_ipv6)); - test_eq(rs->ipv6_orport, 4711); - test_assert(!rs->is_authority); - test_assert(rs->is_exit); - test_assert(rs->is_fast); - test_assert(rs->is_possible_guard); - test_assert(rs->is_stable); - test_assert(rs->is_flagged_running); - test_assert(rs->is_valid); - test_assert(!rs->is_named); + tt_assert(tor_addr_eq(&rs->ipv6_addr, &addr_ipv6)); + tt_int_op(rs->ipv6_orport,==, 4711); + tt_assert(!rs->is_authority); + tt_assert(rs->is_exit); + tt_assert(rs->is_fast); + tt_assert(rs->is_possible_guard); + tt_assert(rs->is_stable); + tt_assert(rs->is_flagged_running); + tt_assert(rs->is_valid); + tt_assert(!rs->is_named); /* XXXX check version */ } else { /* Weren't expecting this... */ - test_assert(0); + tt_assert(0); } done: @@ -1226,31 +1733,31 @@ test_a_networkstatus( networkstatus_t *con2=NULL, *con_md2=NULL, *con3=NULL, *con_md3=NULL; ns_detached_signatures_t *dsig1=NULL, *dsig2=NULL; - test_assert(vrs_gen); - test_assert(rs_test); - test_assert(vrs_test); + tt_assert(vrs_gen); + tt_assert(rs_test); + tt_assert(vrs_test); /* Parse certificates and keys. */ cert1 = authority_cert_parse_from_string(AUTHORITY_CERT_1, NULL); - test_assert(cert1); + tt_assert(cert1); cert2 = authority_cert_parse_from_string(AUTHORITY_CERT_2, NULL); - test_assert(cert2); + tt_assert(cert2); cert3 = authority_cert_parse_from_string(AUTHORITY_CERT_3, NULL); - test_assert(cert3); + tt_assert(cert3); sign_skey_1 = crypto_pk_new(); sign_skey_2 = crypto_pk_new(); sign_skey_3 = crypto_pk_new(); sign_skey_leg1 = pk_generate(4); - test_assert(!crypto_pk_read_private_key_from_string(sign_skey_1, + tt_assert(!crypto_pk_read_private_key_from_string(sign_skey_1, AUTHORITY_SIGNKEY_1, -1)); - test_assert(!crypto_pk_read_private_key_from_string(sign_skey_2, + tt_assert(!crypto_pk_read_private_key_from_string(sign_skey_2, AUTHORITY_SIGNKEY_2, -1)); - test_assert(!crypto_pk_read_private_key_from_string(sign_skey_3, + tt_assert(!crypto_pk_read_private_key_from_string(sign_skey_3, AUTHORITY_SIGNKEY_3, -1)); - test_assert(!crypto_pk_cmp_keys(sign_skey_1, cert1->signing_key)); - test_assert(!crypto_pk_cmp_keys(sign_skey_2, cert2->signing_key)); + tt_assert(!crypto_pk_cmp_keys(sign_skey_1, cert1->signing_key)); + tt_assert(!crypto_pk_cmp_keys(sign_skey_2, cert2->signing_key)); /* * Set up a vote; generate it; try to parse it. @@ -1292,7 +1799,7 @@ test_a_networkstatus( vrs = vrs_gen(idx, now); if (vrs) { smartlist_add(vote->routerstatus_list, vrs); - test_assert(router_add_to_routerlist(generate_ri_from_rs(vrs), + tt_assert(router_add_to_routerlist(generate_ri_from_rs(vrs), &msg,0,0)>=0); ++idx; } @@ -1301,41 +1808,41 @@ test_a_networkstatus( /* dump the vote and try to parse it. */ v1_text = format_networkstatus_vote(sign_skey_1, vote); - test_assert(v1_text); + tt_assert(v1_text); v1 = networkstatus_parse_vote_from_string(v1_text, NULL, NS_TYPE_VOTE); - test_assert(v1); + tt_assert(v1); /* Make sure the parsed thing was right. */ - test_eq(v1->type, NS_TYPE_VOTE); - test_eq(v1->published, vote->published); - test_eq(v1->valid_after, vote->valid_after); - test_eq(v1->fresh_until, vote->fresh_until); - test_eq(v1->valid_until, vote->valid_until); - test_eq(v1->vote_seconds, vote->vote_seconds); - test_eq(v1->dist_seconds, vote->dist_seconds); - test_streq(v1->client_versions, vote->client_versions); - test_streq(v1->server_versions, vote->server_versions); - test_assert(v1->voters && smartlist_len(v1->voters)); + tt_int_op(v1->type,==, NS_TYPE_VOTE); + tt_int_op(v1->published,==, vote->published); + tt_int_op(v1->valid_after,==, vote->valid_after); + tt_int_op(v1->fresh_until,==, vote->fresh_until); + tt_int_op(v1->valid_until,==, vote->valid_until); + tt_int_op(v1->vote_seconds,==, vote->vote_seconds); + tt_int_op(v1->dist_seconds,==, vote->dist_seconds); + tt_str_op(v1->client_versions,==, vote->client_versions); + tt_str_op(v1->server_versions,==, vote->server_versions); + tt_assert(v1->voters && smartlist_len(v1->voters)); voter = smartlist_get(v1->voters, 0); - test_streq(voter->nickname, "Voter1"); - test_streq(voter->address, "1.2.3.4"); - test_eq(voter->addr, 0x01020304); - test_eq(voter->dir_port, 80); - test_eq(voter->or_port, 9000); - test_streq(voter->contact, "voter@example.com"); - test_assert(v1->cert); - test_assert(!crypto_pk_cmp_keys(sign_skey_1, v1->cert->signing_key)); + tt_str_op(voter->nickname,==, "Voter1"); + tt_str_op(voter->address,==, "1.2.3.4"); + tt_int_op(voter->addr,==, 0x01020304); + tt_int_op(voter->dir_port,==, 80); + tt_int_op(voter->or_port,==, 9000); + tt_str_op(voter->contact,==, "voter@example.com"); + tt_assert(v1->cert); + tt_assert(!crypto_pk_cmp_keys(sign_skey_1, v1->cert->signing_key)); cp = smartlist_join_strings(v1->known_flags, ":", 0, NULL); - test_streq(cp, "Authority:Exit:Fast:Guard:Running:Stable:V2Dir:Valid"); + tt_str_op(cp,==, "Authority:Exit:Fast:Guard:Running:Stable:V2Dir:Valid"); tor_free(cp); - test_eq(smartlist_len(v1->routerstatus_list), n_vrs); + tt_int_op(smartlist_len(v1->routerstatus_list),==, n_vrs); if (vote_tweaks) params_tweaked += vote_tweaks(v1, 1, now); /* Check the routerstatuses. */ for (idx = 0; idx < n_vrs; ++idx) { vrs = smartlist_get(v1->routerstatus_list, idx); - test_assert(vrs); + tt_assert(vrs); vrs_test(vrs, 1, now); } @@ -1365,15 +1872,15 @@ test_a_networkstatus( /* generate and parse v2. */ v2_text = format_networkstatus_vote(sign_skey_2, vote); - test_assert(v2_text); + tt_assert(v2_text); v2 = networkstatus_parse_vote_from_string(v2_text, NULL, NS_TYPE_VOTE); - test_assert(v2); + tt_assert(v2); if (vote_tweaks) params_tweaked += vote_tweaks(v2, 2, now); /* Check that flags come out right.*/ cp = smartlist_join_strings(v2->known_flags, ":", 0, NULL); - test_streq(cp, "Authority:Exit:Fast:Guard:MadeOfCheese:MadeOfTin:" + tt_str_op(cp,==, "Authority:Exit:Fast:Guard:MadeOfCheese:MadeOfTin:" "Running:Stable:V2Dir:Valid"); tor_free(cp); @@ -1381,7 +1888,7 @@ test_a_networkstatus( n_vrs = smartlist_len(v2->routerstatus_list); for (idx = 0; idx < n_vrs; ++idx) { vrs = smartlist_get(v2->routerstatus_list, idx); - test_assert(vrs); + tt_assert(vrs); vrs_test(vrs, 2, now); } @@ -1409,10 +1916,10 @@ test_a_networkstatus( memset(voter->legacy_id_digest, (int)'A', DIGEST_LEN); v3_text = format_networkstatus_vote(sign_skey_3, vote); - test_assert(v3_text); + tt_assert(v3_text); v3 = networkstatus_parse_vote_from_string(v3_text, NULL, NS_TYPE_VOTE); - test_assert(v3); + tt_assert(v3); if (vote_tweaks) params_tweaked += vote_tweaks(v3, 3, now); @@ -1426,10 +1933,10 @@ test_a_networkstatus( "AAAAAAAAAAAAAAAAAAAA", sign_skey_leg1, FLAV_NS); - test_assert(consensus_text); + tt_assert(consensus_text); con = networkstatus_parse_vote_from_string(consensus_text, NULL, NS_TYPE_CONSENSUS); - test_assert(con); + tt_assert(con); //log_notice(LD_GENERAL, "<<%s>>\n<<%s>>\n<<%s>>\n", // v1_text, v2_text, v3_text); consensus_text_md = networkstatus_compute_consensus(votes, 3, @@ -1438,38 +1945,38 @@ test_a_networkstatus( "AAAAAAAAAAAAAAAAAAAA", sign_skey_leg1, FLAV_MICRODESC); - test_assert(consensus_text_md); + tt_assert(consensus_text_md); con_md = networkstatus_parse_vote_from_string(consensus_text_md, NULL, NS_TYPE_CONSENSUS); - test_assert(con_md); - test_eq(con_md->flavor, FLAV_MICRODESC); + tt_assert(con_md); + tt_int_op(con_md->flavor,==, FLAV_MICRODESC); /* Check consensus contents. */ - test_assert(con->type == NS_TYPE_CONSENSUS); - test_eq(con->published, 0); /* this field only appears in votes. */ - test_eq(con->valid_after, now+1000); - test_eq(con->fresh_until, now+2003); /* median */ - test_eq(con->valid_until, now+3000); - test_eq(con->vote_seconds, 100); - test_eq(con->dist_seconds, 250); /* median */ - test_streq(con->client_versions, "0.1.2.14"); - test_streq(con->server_versions, "0.1.2.15,0.1.2.16"); + tt_assert(con->type == NS_TYPE_CONSENSUS); + tt_int_op(con->published,==, 0); /* this field only appears in votes. */ + tt_int_op(con->valid_after,==, now+1000); + tt_int_op(con->fresh_until,==, now+2003); /* median */ + tt_int_op(con->valid_until,==, now+3000); + tt_int_op(con->vote_seconds,==, 100); + tt_int_op(con->dist_seconds,==, 250); /* median */ + tt_str_op(con->client_versions,==, "0.1.2.14"); + tt_str_op(con->server_versions,==, "0.1.2.15,0.1.2.16"); cp = smartlist_join_strings(v2->known_flags, ":", 0, NULL); - test_streq(cp, "Authority:Exit:Fast:Guard:MadeOfCheese:MadeOfTin:" + tt_str_op(cp,==, "Authority:Exit:Fast:Guard:MadeOfCheese:MadeOfTin:" "Running:Stable:V2Dir:Valid"); tor_free(cp); if (!params_tweaked) { /* Skip this one if vote_tweaks() messed with the param lists */ cp = smartlist_join_strings(con->net_params, ":", 0, NULL); - test_streq(cp, "circuitwindow=80:foo=660"); + tt_str_op(cp,==, "circuitwindow=80:foo=660"); tor_free(cp); } - test_eq(4, smartlist_len(con->voters)); /*3 voters, 1 legacy key.*/ + tt_int_op(4,==, smartlist_len(con->voters)); /*3 voters, 1 legacy key.*/ /* The voter id digests should be in this order. */ - test_assert(memcmp(cert2->cache_info.identity_digest, + tt_assert(memcmp(cert2->cache_info.identity_digest, cert1->cache_info.identity_digest,DIGEST_LEN)<0); - test_assert(memcmp(cert1->cache_info.identity_digest, + tt_assert(memcmp(cert1->cache_info.identity_digest, cert3->cache_info.identity_digest,DIGEST_LEN)<0); test_same_voter(smartlist_get(con->voters, 1), smartlist_get(v2->voters, 0)); @@ -1484,26 +1991,26 @@ test_a_networkstatus( n_rs = smartlist_len(con->routerstatus_list); for (idx = 0; idx < n_rs; ++idx) { rs = smartlist_get(con->routerstatus_list, idx); - test_assert(rs); + tt_assert(rs); rs_test(rs, now); } /* Check signatures. the first voter is a pseudo-entry with a legacy key. * The second one hasn't signed. The fourth one has signed: validate it. */ voter = smartlist_get(con->voters, 1); - test_eq(smartlist_len(voter->sigs), 0); + tt_int_op(smartlist_len(voter->sigs),==, 0); voter = smartlist_get(con->voters, 3); - test_eq(smartlist_len(voter->sigs), 1); + tt_int_op(smartlist_len(voter->sigs),==, 1); sig = smartlist_get(voter->sigs, 0); - test_assert(sig->signature); - test_assert(!sig->good_signature); - test_assert(!sig->bad_signature); + tt_assert(sig->signature); + tt_assert(!sig->good_signature); + tt_assert(!sig->bad_signature); - test_assert(!networkstatus_check_document_signature(con, sig, cert3)); - test_assert(sig->signature); - test_assert(sig->good_signature); - test_assert(!sig->bad_signature); + tt_assert(!networkstatus_check_document_signature(con, sig, cert3)); + tt_assert(sig->signature); + tt_assert(sig->good_signature); + tt_assert(!sig->bad_signature); { const char *msg=NULL; @@ -1526,10 +2033,10 @@ test_a_networkstatus( cert1->identity_key, sign_skey_1, NULL,NULL, FLAV_MICRODESC); - test_assert(consensus_text2); - test_assert(consensus_text3); - test_assert(consensus_text_md2); - test_assert(consensus_text_md3); + tt_assert(consensus_text2); + tt_assert(consensus_text3); + tt_assert(consensus_text_md2); + tt_assert(consensus_text_md3); con2 = networkstatus_parse_vote_from_string(consensus_text2, NULL, NS_TYPE_CONSENSUS); con3 = networkstatus_parse_vote_from_string(consensus_text3, NULL, @@ -1538,17 +2045,17 @@ test_a_networkstatus( NS_TYPE_CONSENSUS); con_md3 = networkstatus_parse_vote_from_string(consensus_text_md3, NULL, NS_TYPE_CONSENSUS); - test_assert(con2); - test_assert(con3); - test_assert(con_md2); - test_assert(con_md3); + tt_assert(con2); + tt_assert(con3); + tt_assert(con_md2); + tt_assert(con_md3); /* All three should have the same digest. */ - test_memeq(&con->digests, &con2->digests, sizeof(digests_t)); - test_memeq(&con->digests, &con3->digests, sizeof(digests_t)); + tt_mem_op(&con->digests,==, &con2->digests, sizeof(digests_t)); + tt_mem_op(&con->digests,==, &con3->digests, sizeof(digests_t)); - test_memeq(&con_md->digests, &con_md2->digests, sizeof(digests_t)); - test_memeq(&con_md->digests, &con_md3->digests, sizeof(digests_t)); + tt_mem_op(&con_md->digests,==, &con_md2->digests, sizeof(digests_t)); + tt_mem_op(&con_md->digests,==, &con_md3->digests, sizeof(digests_t)); /* Extract a detached signature from con3. */ detached_text1 = get_detached_sigs(con3, con_md3); @@ -1558,50 +2065,51 @@ test_a_networkstatus( tt_assert(dsig1); /* Are parsed values as expected? */ - test_eq(dsig1->valid_after, con3->valid_after); - test_eq(dsig1->fresh_until, con3->fresh_until); - test_eq(dsig1->valid_until, con3->valid_until); + tt_int_op(dsig1->valid_after,==, con3->valid_after); + tt_int_op(dsig1->fresh_until,==, con3->fresh_until); + tt_int_op(dsig1->valid_until,==, con3->valid_until); { digests_t *dsig_digests = strmap_get(dsig1->digests, "ns"); - test_assert(dsig_digests); - test_memeq(dsig_digests->d[DIGEST_SHA1], con3->digests.d[DIGEST_SHA1], + tt_assert(dsig_digests); + tt_mem_op(dsig_digests->d[DIGEST_SHA1],==, con3->digests.d[DIGEST_SHA1], DIGEST_LEN); dsig_digests = strmap_get(dsig1->digests, "microdesc"); - test_assert(dsig_digests); - test_memeq(dsig_digests->d[DIGEST_SHA256], + tt_assert(dsig_digests); + tt_mem_op(dsig_digests->d[DIGEST_SHA256],==, con_md3->digests.d[DIGEST_SHA256], DIGEST256_LEN); } { smartlist_t *dsig_signatures = strmap_get(dsig1->signatures, "ns"); - test_assert(dsig_signatures); - test_eq(1, smartlist_len(dsig_signatures)); + tt_assert(dsig_signatures); + tt_int_op(1,==, smartlist_len(dsig_signatures)); sig = smartlist_get(dsig_signatures, 0); - test_memeq(sig->identity_digest, cert1->cache_info.identity_digest, + tt_mem_op(sig->identity_digest,==, cert1->cache_info.identity_digest, DIGEST_LEN); - test_eq(sig->alg, DIGEST_SHA1); + tt_int_op(sig->alg,==, DIGEST_SHA1); dsig_signatures = strmap_get(dsig1->signatures, "microdesc"); - test_assert(dsig_signatures); - test_eq(1, smartlist_len(dsig_signatures)); + tt_assert(dsig_signatures); + tt_int_op(1,==, smartlist_len(dsig_signatures)); sig = smartlist_get(dsig_signatures, 0); - test_memeq(sig->identity_digest, cert1->cache_info.identity_digest, + tt_mem_op(sig->identity_digest,==, cert1->cache_info.identity_digest, DIGEST_LEN); - test_eq(sig->alg, DIGEST_SHA256); + tt_int_op(sig->alg,==, DIGEST_SHA256); } /* Try adding it to con2. */ detached_text2 = get_detached_sigs(con2,con_md2); - test_eq(1, networkstatus_add_detached_signatures(con2, dsig1, "test", + tt_int_op(1,==, networkstatus_add_detached_signatures(con2, dsig1, "test", LOG_INFO, &msg)); tor_free(detached_text2); - test_eq(1, networkstatus_add_detached_signatures(con_md2, dsig1, "test", + tt_int_op(1,==, + networkstatus_add_detached_signatures(con_md2, dsig1, "test", LOG_INFO, &msg)); tor_free(detached_text2); detached_text2 = get_detached_sigs(con2,con_md2); //printf("\n<%s>\n", detached_text2); dsig2 = networkstatus_parse_detached_signatures(detached_text2, NULL); - test_assert(dsig2); + tt_assert(dsig2); /* printf("\n"); SMARTLIST_FOREACH(dsig2->signatures, networkstatus_voter_info_t *, vi, { @@ -1610,28 +2118,28 @@ test_a_networkstatus( printf("%s\n", hd); }); */ - test_eq(2, + tt_int_op(2,==, smartlist_len((smartlist_t*)strmap_get(dsig2->signatures, "ns"))); - test_eq(2, + tt_int_op(2,==, smartlist_len((smartlist_t*)strmap_get(dsig2->signatures, "microdesc"))); /* Try adding to con2 twice; verify that nothing changes. */ - test_eq(0, networkstatus_add_detached_signatures(con2, dsig1, "test", + tt_int_op(0,==, networkstatus_add_detached_signatures(con2, dsig1, "test", LOG_INFO, &msg)); /* Add to con. */ - test_eq(2, networkstatus_add_detached_signatures(con, dsig2, "test", + tt_int_op(2,==, networkstatus_add_detached_signatures(con, dsig2, "test", LOG_INFO, &msg)); /* Check signatures */ voter = smartlist_get(con->voters, 1); sig = smartlist_get(voter->sigs, 0); - test_assert(sig); - test_assert(!networkstatus_check_document_signature(con, sig, cert2)); + tt_assert(sig); + tt_assert(!networkstatus_check_document_signature(con, sig, cert2)); voter = smartlist_get(con->voters, 2); sig = smartlist_get(voter->sigs, 0); - test_assert(sig); - test_assert(!networkstatus_check_document_signature(con, sig, cert1)); + tt_assert(sig); + tt_assert(!networkstatus_check_document_signature(con, sig, cert1)); } done: @@ -1693,8 +2201,9 @@ test_a_networkstatus( /** Run unit tests for generating and parsing V3 consensus networkstatus * documents. */ static void -test_dir_v3_networkstatus(void) +test_dir_v3_networkstatus(void *arg) { + (void)arg; test_a_networkstatus(gen_routerstatus_for_v3ns, vote_tweaks_for_v3ns, test_vrs_for_v3ns, @@ -1733,10 +2242,37 @@ test_dir_scale_bw(void *testdata) tt_assert(total <= (U64_LITERAL(1)<<62)); for (i=0; i<8; ++i) { + /* vals[2].u64 is the scaled value of 1.0 */ double ratio = ((double)vals[i].u64) / vals[2].u64; tt_double_op(fabs(ratio - v[i]), <, .00001); } + /* test handling of no entries */ + total = 1; + scale_array_elements_to_u64(vals, 0, &total); + tt_assert(total == 0); + + /* make sure we don't read the array when we have no entries + * may require compiler flags to catch NULL dereferences */ + total = 1; + scale_array_elements_to_u64(NULL, 0, &total); + tt_assert(total == 0); + + scale_array_elements_to_u64(NULL, 0, NULL); + + /* test handling of zero totals */ + total = 1; + vals[0].dbl = 0.0; + scale_array_elements_to_u64(vals, 1, &total); + tt_assert(total == 0); + tt_assert(vals[0].u64 == 0); + + vals[0].dbl = 0.0; + vals[1].dbl = 0.0; + scale_array_elements_to_u64(vals, 2, NULL); + tt_assert(vals[0].u64 == 0); + tt_assert(vals[1].u64 == 0); + done: ; } @@ -1942,7 +2478,7 @@ gen_routerstatus_for_umbw(int idx, time_t now) break; default: /* Shouldn't happen */ - test_assert(0); + tt_assert(0); } if (vrs) { vrs->microdesc = tor_malloc_zero(sizeof(vote_microdesc_hash_t)); @@ -1964,11 +2500,11 @@ vote_tweaks_for_umbw(networkstatus_t *v, int voter, time_t now) char *maxbw_param = NULL; int rv = 0; - test_assert(v); + tt_assert(v); (void)voter; (void)now; - test_assert(v->supported_methods); + tt_assert(v->supported_methods); SMARTLIST_FOREACH(v->supported_methods, char *, c, tor_free(c)); smartlist_clear(v->supported_methods); /* Method 17 is MIN_METHOD_TO_CLIP_UNMEASURED_BW_KB */ @@ -1978,7 +2514,7 @@ vote_tweaks_for_umbw(networkstatus_t *v, int voter, time_t now) /* If we're using a non-default clip bandwidth, add it to net_params */ if (alternate_clip_bw > 0) { tor_asprintf(&maxbw_param, "maxunmeasuredbw=%u", alternate_clip_bw); - test_assert(maxbw_param); + tt_assert(maxbw_param); if (maxbw_param) { smartlist_add(v->net_params, maxbw_param); rv = 1; @@ -2001,9 +2537,9 @@ test_vrs_for_umbw(vote_routerstatus_t *vrs, int voter, time_t now) alternate_clip_bw : DEFAULT_MAX_UNMEASURED_BW_KB; (void)voter; - test_assert(vrs); + tt_assert(vrs); rs = &(vrs->status); - test_assert(rs); + tt_assert(rs); /* Split out by digests to test */ if (tor_memeq(rs->identity_digest, @@ -2014,21 +2550,21 @@ test_vrs_for_umbw(vote_routerstatus_t *vrs, int voter, time_t now) * Check the first routerstatus - measured bandwidth below the clip * cutoff. */ - test_streq(vrs->version, "0.1.2.14"); - test_eq(rs->published_on, now-1500); - test_streq(rs->nickname, "router2"); - test_memeq(rs->identity_digest, + tt_str_op(vrs->version,==, "0.1.2.14"); + tt_int_op(rs->published_on,==, now-1500); + tt_str_op(rs->nickname,==, "router2"); + tt_mem_op(rs->identity_digest,==, "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3" "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3", DIGEST_LEN); - test_memeq(rs->descriptor_digest, "NNNNNNNNNNNNNNNNNNNN", DIGEST_LEN); - test_eq(rs->addr, 0x99008801); - test_eq(rs->or_port, 443); - test_eq(rs->dir_port, 8000); - test_assert(rs->has_bandwidth); - test_assert(vrs->has_measured_bw); - test_eq(rs->bandwidth_kb, max_unmeasured_bw_kb / 2); - test_eq(vrs->measured_bw_kb, max_unmeasured_bw_kb / 2); + tt_mem_op(rs->descriptor_digest,==, "NNNNNNNNNNNNNNNNNNNN", DIGEST_LEN); + tt_int_op(rs->addr,==, 0x99008801); + tt_int_op(rs->or_port,==, 443); + tt_int_op(rs->dir_port,==, 8000); + tt_assert(rs->has_bandwidth); + tt_assert(vrs->has_measured_bw); + tt_int_op(rs->bandwidth_kb,==, max_unmeasured_bw_kb / 2); + tt_int_op(vrs->measured_bw_kb,==, max_unmeasured_bw_kb / 2); } else if (tor_memeq(rs->identity_digest, "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5" "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5", @@ -2038,24 +2574,24 @@ test_vrs_for_umbw(vote_routerstatus_t *vrs, int voter, time_t now) * Check the second routerstatus - measured bandwidth above the clip * cutoff. */ - test_streq(vrs->version, "0.2.0.5"); - test_eq(rs->published_on, now-1000); - test_streq(rs->nickname, "router1"); - test_memeq(rs->identity_digest, + tt_str_op(vrs->version,==, "0.2.0.5"); + tt_int_op(rs->published_on,==, now-1000); + tt_str_op(rs->nickname,==, "router1"); + tt_mem_op(rs->identity_digest,==, "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5" "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5", DIGEST_LEN); - test_memeq(rs->descriptor_digest, "MMMMMMMMMMMMMMMMMMMM", DIGEST_LEN); - test_eq(rs->addr, 0x99009901); - test_eq(rs->or_port, 443); - test_eq(rs->dir_port, 0); + tt_mem_op(rs->descriptor_digest,==, "MMMMMMMMMMMMMMMMMMMM", DIGEST_LEN); + tt_int_op(rs->addr,==, 0x99009901); + tt_int_op(rs->or_port,==, 443); + tt_int_op(rs->dir_port,==, 0); tor_addr_parse(&addr_ipv6, "[1:2:3::4]"); - test_assert(tor_addr_eq(&rs->ipv6_addr, &addr_ipv6)); - test_eq(rs->ipv6_orport, 4711); - test_assert(rs->has_bandwidth); - test_assert(vrs->has_measured_bw); - test_eq(rs->bandwidth_kb, max_unmeasured_bw_kb * 2); - test_eq(vrs->measured_bw_kb, max_unmeasured_bw_kb * 2); + tt_assert(tor_addr_eq(&rs->ipv6_addr, &addr_ipv6)); + tt_int_op(rs->ipv6_orport,==, 4711); + tt_assert(rs->has_bandwidth); + tt_assert(vrs->has_measured_bw); + tt_int_op(rs->bandwidth_kb,==, max_unmeasured_bw_kb * 2); + tt_int_op(vrs->measured_bw_kb,==, max_unmeasured_bw_kb * 2); } else if (tor_memeq(rs->identity_digest, "\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33" "\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33", @@ -2065,10 +2601,10 @@ test_vrs_for_umbw(vote_routerstatus_t *vrs, int voter, time_t now) * cutoff; this one should be clipped later on in the consensus, but * appears unclipped in the vote. */ - test_assert(rs->has_bandwidth); - test_assert(!(vrs->has_measured_bw)); - test_eq(rs->bandwidth_kb, max_unmeasured_bw_kb * 2); - test_eq(vrs->measured_bw_kb, 0); + tt_assert(rs->has_bandwidth); + tt_assert(!(vrs->has_measured_bw)); + tt_int_op(rs->bandwidth_kb,==, max_unmeasured_bw_kb * 2); + tt_int_op(vrs->measured_bw_kb,==, 0); } else if (tor_memeq(rs->identity_digest, "\x34\x34\x34\x34\x34\x34\x34\x34\x34\x34" "\x34\x34\x34\x34\x34\x34\x34\x34\x34\x34", @@ -2077,12 +2613,12 @@ test_vrs_for_umbw(vote_routerstatus_t *vrs, int voter, time_t now) * Check the fourth routerstatus - unmeasured bandwidth below the clip * cutoff; this one should not be clipped. */ - test_assert(rs->has_bandwidth); - test_assert(!(vrs->has_measured_bw)); - test_eq(rs->bandwidth_kb, max_unmeasured_bw_kb / 2); - test_eq(vrs->measured_bw_kb, 0); + tt_assert(rs->has_bandwidth); + tt_assert(!(vrs->has_measured_bw)); + tt_int_op(rs->bandwidth_kb,==, max_unmeasured_bw_kb / 2); + tt_int_op(vrs->measured_bw_kb,==, 0); } else { - test_assert(0); + tt_assert(0); } done: @@ -2097,11 +2633,11 @@ test_consensus_for_umbw(networkstatus_t *con, time_t now) { (void)now; - test_assert(con); - test_assert(!con->cert); - // test_assert(con->consensus_method >= MIN_METHOD_TO_CLIP_UNMEASURED_BW_KB); - test_assert(con->consensus_method >= 16); - test_eq(4, smartlist_len(con->routerstatus_list)); + tt_assert(con); + tt_assert(!con->cert); + // tt_assert(con->consensus_method >= MIN_METHOD_TO_CLIP_UNMEASURED_BW_KB); + tt_assert(con->consensus_method >= 16); + tt_int_op(4,==, smartlist_len(con->routerstatus_list)); /* There should be four listed routers; all voters saw the same in this */ done: @@ -2118,61 +2654,61 @@ test_routerstatus_for_umbw(routerstatus_t *rs, time_t now) uint32_t max_unmeasured_bw_kb = (alternate_clip_bw > 0) ? alternate_clip_bw : DEFAULT_MAX_UNMEASURED_BW_KB; - test_assert(rs); + tt_assert(rs); /* There should be four listed routers, as constructed above */ if (tor_memeq(rs->identity_digest, "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3" "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3", DIGEST_LEN)) { - test_memeq(rs->identity_digest, + tt_mem_op(rs->identity_digest,==, "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3" "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3", DIGEST_LEN); - test_memeq(rs->descriptor_digest, "NNNNNNNNNNNNNNNNNNNN", DIGEST_LEN); - test_assert(!rs->is_authority); - test_assert(!rs->is_exit); - test_assert(!rs->is_fast); - test_assert(!rs->is_possible_guard); - test_assert(!rs->is_stable); + tt_mem_op(rs->descriptor_digest,==, "NNNNNNNNNNNNNNNNNNNN", DIGEST_LEN); + tt_assert(!rs->is_authority); + tt_assert(!rs->is_exit); + tt_assert(!rs->is_fast); + tt_assert(!rs->is_possible_guard); + tt_assert(!rs->is_stable); /* (If it wasn't running it wouldn't be here) */ - test_assert(rs->is_flagged_running); - test_assert(!rs->is_valid); - test_assert(!rs->is_named); + tt_assert(rs->is_flagged_running); + tt_assert(!rs->is_valid); + tt_assert(!rs->is_named); /* This one should have measured bandwidth below the clip cutoff */ - test_assert(rs->has_bandwidth); - test_eq(rs->bandwidth_kb, max_unmeasured_bw_kb / 2); - test_assert(!(rs->bw_is_unmeasured)); + tt_assert(rs->has_bandwidth); + tt_int_op(rs->bandwidth_kb,==, max_unmeasured_bw_kb / 2); + tt_assert(!(rs->bw_is_unmeasured)); } else if (tor_memeq(rs->identity_digest, "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5" "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5", DIGEST_LEN)) { /* This one showed up in 3 digests. Twice with ID 'M', once with 'Z'. */ - test_memeq(rs->identity_digest, + tt_mem_op(rs->identity_digest,==, "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5" "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5", DIGEST_LEN); - test_streq(rs->nickname, "router1"); - test_memeq(rs->descriptor_digest, "MMMMMMMMMMMMMMMMMMMM", DIGEST_LEN); - test_eq(rs->published_on, now-1000); - test_eq(rs->addr, 0x99009901); - test_eq(rs->or_port, 443); - test_eq(rs->dir_port, 0); + tt_str_op(rs->nickname,==, "router1"); + tt_mem_op(rs->descriptor_digest,==, "MMMMMMMMMMMMMMMMMMMM", DIGEST_LEN); + tt_int_op(rs->published_on,==, now-1000); + tt_int_op(rs->addr,==, 0x99009901); + tt_int_op(rs->or_port,==, 443); + tt_int_op(rs->dir_port,==, 0); tor_addr_parse(&addr_ipv6, "[1:2:3::4]"); - test_assert(tor_addr_eq(&rs->ipv6_addr, &addr_ipv6)); - test_eq(rs->ipv6_orport, 4711); - test_assert(!rs->is_authority); - test_assert(rs->is_exit); - test_assert(rs->is_fast); - test_assert(rs->is_possible_guard); - test_assert(rs->is_stable); - test_assert(rs->is_flagged_running); - test_assert(rs->is_valid); - test_assert(!rs->is_named); + tt_assert(tor_addr_eq(&rs->ipv6_addr, &addr_ipv6)); + tt_int_op(rs->ipv6_orport,==, 4711); + tt_assert(!rs->is_authority); + tt_assert(rs->is_exit); + tt_assert(rs->is_fast); + tt_assert(rs->is_possible_guard); + tt_assert(rs->is_stable); + tt_assert(rs->is_flagged_running); + tt_assert(rs->is_valid); + tt_assert(!rs->is_named); /* This one should have measured bandwidth above the clip cutoff */ - test_assert(rs->has_bandwidth); - test_eq(rs->bandwidth_kb, max_unmeasured_bw_kb * 2); - test_assert(!(rs->bw_is_unmeasured)); + tt_assert(rs->has_bandwidth); + tt_int_op(rs->bandwidth_kb,==, max_unmeasured_bw_kb * 2); + tt_assert(!(rs->bw_is_unmeasured)); } else if (tor_memeq(rs->identity_digest, "\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33" "\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33", @@ -2181,9 +2717,9 @@ test_routerstatus_for_umbw(routerstatus_t *rs, time_t now) * This one should have unmeasured bandwidth above the clip cutoff, * and so should be clipped */ - test_assert(rs->has_bandwidth); - test_eq(rs->bandwidth_kb, max_unmeasured_bw_kb); - test_assert(rs->bw_is_unmeasured); + tt_assert(rs->has_bandwidth); + tt_int_op(rs->bandwidth_kb,==, max_unmeasured_bw_kb); + tt_assert(rs->bw_is_unmeasured); } else if (tor_memeq(rs->identity_digest, "\x34\x34\x34\x34\x34\x34\x34\x34\x34\x34" "\x34\x34\x34\x34\x34\x34\x34\x34\x34\x34", @@ -2192,12 +2728,12 @@ test_routerstatus_for_umbw(routerstatus_t *rs, time_t now) * This one should have unmeasured bandwidth below the clip cutoff, * and so should not be clipped */ - test_assert(rs->has_bandwidth); - test_eq(rs->bandwidth_kb, max_unmeasured_bw_kb / 2); - test_assert(rs->bw_is_unmeasured); + tt_assert(rs->has_bandwidth); + tt_int_op(rs->bandwidth_kb,==, max_unmeasured_bw_kb / 2); + tt_assert(rs->bw_is_unmeasured); } else { /* Weren't expecting this... */ - test_assert(0); + tt_assert(0); } done: @@ -2211,9 +2747,10 @@ test_routerstatus_for_umbw(routerstatus_t *rs, time_t now) */ static void -test_dir_clip_unmeasured_bw_kb(void) +test_dir_clip_unmeasured_bw_kb(void *arg) { /* Run the test with the default clip bandwidth */ + (void)arg; alternate_clip_bw = 0; test_a_networkstatus(gen_routerstatus_for_umbw, vote_tweaks_for_umbw, @@ -2228,7 +2765,7 @@ test_dir_clip_unmeasured_bw_kb(void) */ static void -test_dir_clip_unmeasured_bw_kb_alt(void) +test_dir_clip_unmeasured_bw_kb_alt(void *arg) { /* * Try a different one; this value is chosen so that the below-the-cutoff @@ -2236,6 +2773,7 @@ test_dir_clip_unmeasured_bw_kb_alt(void) * DEFAULT_MAX_UNMEASURED_BW_KB and if the consensus incorrectly uses that * cutoff it will fail the test. */ + (void)arg; alternate_clip_bw = 3 * DEFAULT_MAX_UNMEASURED_BW_KB; test_a_networkstatus(gen_routerstatus_for_umbw, vote_tweaks_for_umbw, @@ -2286,60 +2824,60 @@ test_dir_http_handling(void *args) /* Parse http url tests: */ /* Good headers */ - test_eq(parse_http_url("GET /tor/a/b/c.txt HTTP/1.1\r\n" + tt_int_op(parse_http_url("GET /tor/a/b/c.txt HTTP/1.1\r\n" "Host: example.com\r\n" "User-Agent: Mozilla/5.0 (Windows;" " U; Windows NT 6.1; en-US; rv:1.9.1.5)\r\n", - &url), 0); - test_streq(url, "/tor/a/b/c.txt"); + &url),==, 0); + tt_str_op(url,==, "/tor/a/b/c.txt"); tor_free(url); - test_eq(parse_http_url("GET /tor/a/b/c.txt HTTP/1.0\r\n", &url), 0); - test_streq(url, "/tor/a/b/c.txt"); + tt_int_op(parse_http_url("GET /tor/a/b/c.txt HTTP/1.0\r\n", &url),==, 0); + tt_str_op(url,==, "/tor/a/b/c.txt"); tor_free(url); - test_eq(parse_http_url("GET /tor/a/b/c.txt HTTP/1.600\r\n", &url), 0); - test_streq(url, "/tor/a/b/c.txt"); + tt_int_op(parse_http_url("GET /tor/a/b/c.txt HTTP/1.600\r\n", &url),==, 0); + tt_str_op(url,==, "/tor/a/b/c.txt"); tor_free(url); /* Should prepend '/tor/' to url if required */ - test_eq(parse_http_url("GET /a/b/c.txt HTTP/1.1\r\n" + tt_int_op(parse_http_url("GET /a/b/c.txt HTTP/1.1\r\n" "Host: example.com\r\n" "User-Agent: Mozilla/5.0 (Windows;" " U; Windows NT 6.1; en-US; rv:1.9.1.5)\r\n", - &url), 0); - test_streq(url, "/tor/a/b/c.txt"); + &url),==, 0); + tt_str_op(url,==, "/tor/a/b/c.txt"); tor_free(url); /* Bad headers -- no HTTP/1.x*/ - test_eq(parse_http_url("GET /a/b/c.txt\r\n" + tt_int_op(parse_http_url("GET /a/b/c.txt\r\n" "Host: example.com\r\n" "User-Agent: Mozilla/5.0 (Windows;" " U; Windows NT 6.1; en-US; rv:1.9.1.5)\r\n", - &url), -1); + &url),==, -1); tt_assert(!url); /* Bad headers */ - test_eq(parse_http_url("GET /a/b/c.txt\r\n" + tt_int_op(parse_http_url("GET /a/b/c.txt\r\n" "Host: example.com\r\n" "User-Agent: Mozilla/5.0 (Windows;" " U; Windows NT 6.1; en-US; rv:1.9.1.5)\r\n", - &url), -1); + &url),==, -1); tt_assert(!url); - test_eq(parse_http_url("GET /tor/a/b/c.txt", &url), -1); + tt_int_op(parse_http_url("GET /tor/a/b/c.txt", &url),==, -1); tt_assert(!url); - test_eq(parse_http_url("GET /tor/a/b/c.txt HTTP/1.1", &url), -1); + tt_int_op(parse_http_url("GET /tor/a/b/c.txt HTTP/1.1", &url),==, -1); tt_assert(!url); - test_eq(parse_http_url("GET /tor/a/b/c.txt HTTP/1.1x\r\n", &url), -1); + tt_int_op(parse_http_url("GET /tor/a/b/c.txt HTTP/1.1x\r\n", &url),==, -1); tt_assert(!url); - test_eq(parse_http_url("GET /tor/a/b/c.txt HTTP/1.", &url), -1); + tt_int_op(parse_http_url("GET /tor/a/b/c.txt HTTP/1.", &url),==, -1); tt_assert(!url); - test_eq(parse_http_url("GET /tor/a/b/c.txt HTTP/1.\r", &url), -1); + tt_int_op(parse_http_url("GET /tor/a/b/c.txt HTTP/1.\r", &url),==, -1); tt_assert(!url); done: @@ -2347,7 +2885,7 @@ test_dir_http_handling(void *args) } #define DIR_LEGACY(name) \ - { #name, legacy_test_helper, TT_FORK, &legacy_setup, test_dir_ ## name } + { #name, test_dir_ ## name , TT_FORK, NULL, NULL } #define DIR(name,flags) \ { #name, test_dir_##name, (flags), NULL, NULL } @@ -2355,6 +2893,11 @@ test_dir_http_handling(void *args) struct testcase_t dir_tests[] = { DIR_LEGACY(nicknames), DIR_LEGACY(formats), + DIR(routerparse_bad, 0), + DIR(extrainfo_parsing, 0), + DIR(parse_router_list, TT_FORK), + DIR(load_routers, TT_FORK), + DIR(load_extrainfo, TT_FORK), DIR_LEGACY(versions), DIR_LEGACY(fp_pairs), DIR(split_fps, 0), diff --git a/src/test/test_entrynodes.c b/src/test/test_entrynodes.c index fab82c3446..bddc0f11e0 100644 --- a/src/test/test_entrynodes.c +++ b/src/test/test_entrynodes.c @@ -139,7 +139,7 @@ test_choose_random_entry_no_guards(void *arg) /* Unintuitively, we actually pick a random node as our entry, because router_choose_random_node() relaxes its constraints if it can't find a proper entry guard. */ - test_assert(chosen_entry); + tt_assert(chosen_entry); done: ; @@ -201,7 +201,7 @@ populate_live_entry_guards_test_helper(int num_needed) SMARTLIST_FOREACH_BEGIN(our_nodelist, const node_t *, node) { const node_t *node_tmp; node_tmp = add_an_entry_guard(node, 0, 1, 0, 0); - test_assert(node_tmp); + tt_assert(node_tmp); } SMARTLIST_FOREACH_END(node); /* Make sure the nodes were added as entry guards. */ @@ -650,7 +650,7 @@ test_entry_is_live(void *arg) SMARTLIST_FOREACH_BEGIN(our_nodelist, const node_t *, node) { const node_t *node_tmp; node_tmp = add_an_entry_guard(node, 0, 1, 0, 0); - test_assert(node_tmp); + tt_assert(node_tmp); tt_int_op(node->is_stable, ==, 0); tt_int_op(node->is_fast, ==, 0); @@ -670,22 +670,22 @@ test_entry_is_live(void *arg) test_node = entry_is_live(test_entry, ENTRY_NEED_UPTIME | ENTRY_ASSUME_REACHABLE, &msg); - test_assert(!test_node); + tt_assert(!test_node); /* Require the node to be fast, but it's not. Should fail. */ test_node = entry_is_live(test_entry, ENTRY_NEED_CAPACITY | ENTRY_ASSUME_REACHABLE, &msg); - test_assert(!test_node); + tt_assert(!test_node); /* Don't impose any restrictions on the node. Should succeed. */ test_node = entry_is_live(test_entry, 0, &msg); - test_assert(test_node); + tt_assert(test_node); tt_ptr_op(test_node, ==, node_get_by_id(test_entry->identity)); /* Require descriptor for this node. It has one so it should succeed. */ test_node = entry_is_live(test_entry, ENTRY_NEED_DESCRIPTOR, &msg); - test_assert(test_node); + tt_assert(test_node); tt_ptr_op(test_node, ==, node_get_by_id(test_entry->identity)); done: diff --git a/src/test/test_extorport.c b/src/test/test_extorport.c index 93c8f77d5b..35e7fe5ad9 100644 --- a/src/test/test_extorport.c +++ b/src/test/test_extorport.c @@ -42,7 +42,7 @@ test_ext_or_id_map(void *arg) /* Give c2 a new ID. */ connection_or_set_ext_or_identifier(c2); - test_mem_op(idp, !=, c2->ext_or_conn_id, EXT_OR_CONN_ID_LEN); + tt_mem_op(idp, !=, c2->ext_or_conn_id, EXT_OR_CONN_ID_LEN); idp2 = tor_memdup(c2->ext_or_conn_id, EXT_OR_CONN_ID_LEN); tt_assert(!tor_digest_is_zero(idp2)); @@ -119,7 +119,7 @@ test_ext_or_write_command(void *arg) ==, 0); cp = buf_get_contents(TO_CONN(c1)->outbuf, &sz); tt_int_op(sz, ==, 4); - test_mem_op(cp, ==, "\x00\x99\x00\x00", 4); + tt_mem_op(cp, ==, "\x00\x99\x00\x00", 4); tor_free(cp); /* Medium command. */ @@ -127,7 +127,7 @@ test_ext_or_write_command(void *arg) "Wai\0Hello", 9), ==, 0); cp = buf_get_contents(TO_CONN(c1)->outbuf, &sz); tt_int_op(sz, ==, 13); - test_mem_op(cp, ==, "\x00\x99\x00\x09Wai\x00Hello", 13); + tt_mem_op(cp, ==, "\x00\x99\x00\x09Wai\x00Hello", 13); tor_free(cp); /* Long command */ @@ -137,8 +137,8 @@ test_ext_or_write_command(void *arg) buf, 65535), ==, 0); cp = buf_get_contents(TO_CONN(c1)->outbuf, &sz); tt_int_op(sz, ==, 65539); - test_mem_op(cp, ==, "\xf0\x0d\xff\xff", 4); - test_mem_op(cp+4, ==, buf, 65535); + tt_mem_op(cp, ==, "\xf0\x0d\xff\xff", 4); + tt_mem_op(cp+4, ==, buf, 65535); tor_free(cp); done: @@ -181,7 +181,7 @@ test_ext_or_init_auth(void *arg) /* Shouldn't be initialized already, or our tests will be a bit * meaningless */ ext_or_auth_cookie = tor_malloc_zero(32); - test_assert(tor_mem_is_zero((char*)ext_or_auth_cookie, 32)); + tt_assert(tor_mem_is_zero((char*)ext_or_auth_cookie, 32)); /* Now make sure we use a temporary file */ fn = get_fname("ext_cookie_file"); @@ -203,14 +203,14 @@ test_ext_or_init_auth(void *arg) cp = read_file_to_str(fn, RFTS_BIN, &st); tt_ptr_op(cp, !=, NULL); tt_u64_op((uint64_t)st.st_size, ==, 64); - test_memeq(cp, "! Extended ORPort Auth Cookie !\x0a", 32); - test_memeq(cp+32, ext_or_auth_cookie, 32); + tt_mem_op(cp,==, "! Extended ORPort Auth Cookie !\x0a", 32); + tt_mem_op(cp+32,==, ext_or_auth_cookie, 32); memcpy(cookie0, ext_or_auth_cookie, 32); - test_assert(!tor_mem_is_zero((char*)ext_or_auth_cookie, 32)); + tt_assert(!tor_mem_is_zero((char*)ext_or_auth_cookie, 32)); /* Operation should be idempotent. */ tt_int_op(0, ==, init_ext_or_cookie_authentication(1)); - test_memeq(cookie0, ext_or_auth_cookie, 32); + tt_mem_op(cookie0,==, ext_or_auth_cookie, 32); done: tor_free(cp); @@ -280,15 +280,15 @@ test_ext_or_cookie_auth(void *arg) 46+32+32); crypto_hmac_sha256(hmac2, (char*)ext_or_auth_cookie, 32, client_hash_input, 46+32+32); - test_memeq(hmac1, reply, 32); - test_memeq(hmac2, client_hash, 32); + tt_mem_op(hmac1,==, reply, 32); + tt_mem_op(hmac2,==, client_hash, 32); /* Now do it again and make sure that the results are *different* */ tt_int_op(0, ==, handle_client_auth_nonce(client_nonce, 32, &client_hash2, &reply2, &reply_len)); - test_memneq(reply2, reply, reply_len); - test_memneq(client_hash2, client_hash, 32); + tt_mem_op(reply2,!=, reply, reply_len); + tt_mem_op(client_hash2,!=, client_hash, 32); /* But that this one checks out too. */ memcpy(server_hash_input+46+32, reply2+32, 32); memcpy(client_hash_input+46+32, reply2+32, 32); @@ -297,8 +297,8 @@ test_ext_or_cookie_auth(void *arg) 46+32+32); crypto_hmac_sha256(hmac2, (char*)ext_or_auth_cookie, 32, client_hash_input, 46+32+32); - test_memeq(hmac1, reply2, 32); - test_memeq(hmac2, client_hash2, 32); + tt_mem_op(hmac1,==, reply2, 32); + tt_mem_op(hmac2,==, client_hash2, 32); done: tor_free(reply); @@ -339,7 +339,7 @@ test_ext_or_cookie_auth_testvec(void *arg) &reply_len)); tt_ptr_op(reply, !=, NULL ); tt_uint_op(reply_len, ==, 64); - test_memeq(reply+32, "te road There is always another ", 32); + tt_mem_op(reply+32,==, "te road There is always another ", 32); /* HMACSHA256("Gliding wrapt in a brown mantle," * "ExtORPort authentication server-to-client hash" * "But when I look ahead up the write road There is always another "); @@ -406,7 +406,7 @@ handshake_start(or_connection_t *conn, int receiving) tt_int_op(buf_datalen(TO_CONN(conn)->outbuf), ==, (n)); \ if ((n)) { \ fetch_from_buf(b, (n), TO_CONN(conn)->outbuf); \ - test_memeq(b, (s), (n)); \ + tt_mem_op(b, ==, (s), (n)); \ } \ } while (0) diff --git a/src/test/test_hs.c b/src/test/test_hs.c index 99ef7dd570..0ee46c2a58 100644 --- a/src/test/test_hs.c +++ b/src/test/test_hs.c @@ -84,8 +84,8 @@ test_hs_desc_event(void *arg) STR_HS_ID); expected_msg = "650 HS_DESC REQUESTED "STR_HS_ADDR" NO_AUTH "\ STR_HSDIR_EXIST_LONGNAME" "STR_HS_ID"\r\n"; - test_assert(received_msg); - test_streq(received_msg, expected_msg); + tt_assert(received_msg); + tt_str_op(received_msg,==, expected_msg); tor_free(received_msg); /* test received event */ @@ -93,8 +93,8 @@ test_hs_desc_event(void *arg) control_event_hs_descriptor_received(&rend_query, HSDIR_EXIST_ID); expected_msg = "650 HS_DESC RECEIVED "STR_HS_ADDR" BASIC_AUTH "\ STR_HSDIR_EXIST_LONGNAME"\r\n"; - test_assert(received_msg); - test_streq(received_msg, expected_msg); + tt_assert(received_msg); + tt_str_op(received_msg,==, expected_msg); tor_free(received_msg); /* test failed event */ @@ -102,8 +102,8 @@ test_hs_desc_event(void *arg) control_event_hs_descriptor_failed(&rend_query, HSDIR_NONE_EXIST_ID); expected_msg = "650 HS_DESC FAILED "STR_HS_ADDR" STEALTH_AUTH "\ STR_HSDIR_NONE_EXIST_LONGNAME"\r\n"; - test_assert(received_msg); - test_streq(received_msg, expected_msg); + tt_assert(received_msg); + tt_str_op(received_msg,==, expected_msg); tor_free(received_msg); /* test invalid auth type */ @@ -111,8 +111,8 @@ test_hs_desc_event(void *arg) control_event_hs_descriptor_failed(&rend_query, HSDIR_EXIST_ID); expected_msg = "650 HS_DESC FAILED "STR_HS_ADDR" UNKNOWN "\ STR_HSDIR_EXIST_LONGNAME"\r\n"; - test_assert(received_msg); - test_streq(received_msg, expected_msg); + tt_assert(received_msg); + tt_str_op(received_msg,==, expected_msg); tor_free(received_msg); done: diff --git a/src/test/test_introduce.c b/src/test/test_introduce.c index 69c1152229..17ee01d9b8 100644 --- a/src/test/test_introduce.c +++ b/src/test/test_introduce.c @@ -290,48 +290,48 @@ do_parse_test(uint8_t *plaintext, size_t plaintext_len, int phase) /* Get a key */ k = crypto_pk_new(); - test_assert(k); + tt_assert(k); r = crypto_pk_read_private_key_from_string(k, AUTHORITY_SIGNKEY_1, -1); - test_assert(!r); + tt_assert(!r); /* Get digest for future comparison */ r = crypto_pk_get_digest(k, digest); - test_assert(r >= 0); + tt_assert(r >= 0); /* Make a cell out of it */ r = make_intro_from_plaintext( plaintext, plaintext_len, k, (void **)(&cell)); - test_assert(r > 0); - test_assert(cell); + tt_assert(r > 0); + tt_assert(cell); cell_len = r; /* Do early parsing */ parsed_req = rend_service_begin_parse_intro(cell, cell_len, 2, &err_msg); - test_assert(parsed_req); - test_assert(!err_msg); - test_memeq(parsed_req->pk, digest, DIGEST_LEN); - test_assert(parsed_req->ciphertext); - test_assert(parsed_req->ciphertext_len > 0); + tt_assert(parsed_req); + tt_assert(!err_msg); + tt_mem_op(parsed_req->pk,==, digest, DIGEST_LEN); + tt_assert(parsed_req->ciphertext); + tt_assert(parsed_req->ciphertext_len > 0); if (phase == EARLY_PARSE_ONLY) goto done; /* Do decryption */ r = rend_service_decrypt_intro(parsed_req, k, &err_msg); - test_assert(!r); - test_assert(!err_msg); - test_assert(parsed_req->plaintext); - test_assert(parsed_req->plaintext_len > 0); + tt_assert(!r); + tt_assert(!err_msg); + tt_assert(parsed_req->plaintext); + tt_assert(parsed_req->plaintext_len > 0); if (phase == DECRYPT_ONLY) goto done; /* Do late parsing */ r = rend_service_parse_intro_plaintext(parsed_req, &err_msg); - test_assert(!r); - test_assert(!err_msg); - test_assert(parsed_req->parsed); + tt_assert(!r); + tt_assert(!err_msg); + tt_assert(parsed_req->parsed); done: tor_free(cell); @@ -371,14 +371,14 @@ make_intro_from_plaintext( /* Compute key digest (will be first DIGEST_LEN octets of cell) */ r = crypto_pk_get_digest(key, cell); - test_assert(r >= 0); + tt_assert(r >= 0); /* Do encryption */ r = crypto_pk_public_hybrid_encrypt( key, cell + DIGEST_LEN, ciphertext_size, buf, len, PK_PKCS1_OAEP_PADDING, 0); - test_assert(r >= 0); + tt_assert(r >= 0); /* Figure out cell length */ cell_len = DIGEST_LEN + r; @@ -394,8 +394,9 @@ make_intro_from_plaintext( */ static void -test_introduce_decrypt_v0(void) +test_introduce_decrypt_v0(void *arg) { + (void)arg; do_decrypt_test(v0_test_plaintext, sizeof(v0_test_plaintext)); } @@ -403,8 +404,9 @@ test_introduce_decrypt_v0(void) */ static void -test_introduce_decrypt_v1(void) +test_introduce_decrypt_v1(void *arg) { + (void)arg; do_decrypt_test(v1_test_plaintext, sizeof(v1_test_plaintext)); } @@ -412,8 +414,9 @@ test_introduce_decrypt_v1(void) */ static void -test_introduce_decrypt_v2(void) +test_introduce_decrypt_v2(void *arg) { + (void)arg; do_decrypt_test(v2_test_plaintext, sizeof(v2_test_plaintext)); } @@ -421,8 +424,9 @@ test_introduce_decrypt_v2(void) */ static void -test_introduce_decrypt_v3(void) +test_introduce_decrypt_v3(void *arg) { + (void)arg; do_decrypt_test( v3_no_auth_test_plaintext, sizeof(v3_no_auth_test_plaintext)); do_decrypt_test( @@ -433,8 +437,9 @@ test_introduce_decrypt_v3(void) */ static void -test_introduce_early_parse_v0(void) +test_introduce_early_parse_v0(void *arg) { + (void)arg; do_early_parse_test(v0_test_plaintext, sizeof(v0_test_plaintext)); } @@ -442,8 +447,9 @@ test_introduce_early_parse_v0(void) */ static void -test_introduce_early_parse_v1(void) +test_introduce_early_parse_v1(void *arg) { + (void)arg; do_early_parse_test(v1_test_plaintext, sizeof(v1_test_plaintext)); } @@ -451,8 +457,9 @@ test_introduce_early_parse_v1(void) */ static void -test_introduce_early_parse_v2(void) +test_introduce_early_parse_v2(void *arg) { + (void)arg; do_early_parse_test(v2_test_plaintext, sizeof(v2_test_plaintext)); } @@ -460,8 +467,9 @@ test_introduce_early_parse_v2(void) */ static void -test_introduce_early_parse_v3(void) +test_introduce_early_parse_v3(void *arg) { + (void)arg; do_early_parse_test( v3_no_auth_test_plaintext, sizeof(v3_no_auth_test_plaintext)); do_early_parse_test( @@ -472,8 +480,9 @@ test_introduce_early_parse_v3(void) */ static void -test_introduce_late_parse_v0(void) +test_introduce_late_parse_v0(void *arg) { + (void)arg; do_late_parse_test(v0_test_plaintext, sizeof(v0_test_plaintext)); } @@ -481,8 +490,9 @@ test_introduce_late_parse_v0(void) */ static void -test_introduce_late_parse_v1(void) +test_introduce_late_parse_v1(void *arg) { + (void)arg; do_late_parse_test(v1_test_plaintext, sizeof(v1_test_plaintext)); } @@ -490,8 +500,9 @@ test_introduce_late_parse_v1(void) */ static void -test_introduce_late_parse_v2(void) +test_introduce_late_parse_v2(void *arg) { + (void)arg; do_late_parse_test(v2_test_plaintext, sizeof(v2_test_plaintext)); } @@ -499,8 +510,9 @@ test_introduce_late_parse_v2(void) */ static void -test_introduce_late_parse_v3(void) +test_introduce_late_parse_v3(void *arg) { + (void)arg; do_late_parse_test( v3_no_auth_test_plaintext, sizeof(v3_no_auth_test_plaintext)); do_late_parse_test( @@ -508,7 +520,7 @@ test_introduce_late_parse_v3(void) } #define INTRODUCE_LEGACY(name) \ - { #name, legacy_test_helper, 0, &legacy_setup, test_introduce_ ## name } + { #name, test_introduce_ ## name , 0, NULL, NULL } struct testcase_t introduce_tests[] = { INTRODUCE_LEGACY(early_parse_v0), diff --git a/src/test/test_microdesc.c b/src/test/test_microdesc.c index 78f4823b87..bc6755b93e 100644 --- a/src/test/test_microdesc.c +++ b/src/test/test_microdesc.c @@ -7,11 +7,16 @@ #include "config.h" #include "dirvote.h" #include "microdesc.h" +#include "networkstatus.h" #include "routerlist.h" #include "routerparse.h" #include "test.h" +#include <openssl/rsa.h> +#include <openssl/bn.h> +#include <openssl/pem.h> + #ifdef _WIN32 /* For mkdir() */ #include <direct.h> @@ -108,7 +113,7 @@ test_md_cache(void *data) md2 = smartlist_get(added, 0); /* And it should have gotten removed from 'wanted' */ tt_int_op(smartlist_len(wanted), ==, 1); - test_mem_op(smartlist_get(wanted, 0), ==, d3, DIGEST256_LEN); + tt_mem_op(smartlist_get(wanted, 0), ==, d3, DIGEST256_LEN); smartlist_free(added); added = NULL; @@ -144,18 +149,18 @@ test_md_cache(void *data) tt_int_op(md1->bodylen, ==, strlen(test_md1)); tt_int_op(md2->bodylen, ==, strlen(test_md2)); tt_int_op(md3->bodylen, ==, strlen(test_md3_noannotation)); - test_mem_op(md1->body, ==, test_md1, strlen(test_md1)); - test_mem_op(md2->body, ==, test_md2, strlen(test_md2)); - test_mem_op(md3->body, ==, test_md3_noannotation, + tt_mem_op(md1->body, ==, test_md1, strlen(test_md1)); + tt_mem_op(md2->body, ==, test_md2, strlen(test_md2)); + tt_mem_op(md3->body, ==, test_md3_noannotation, strlen(test_md3_noannotation)); tor_asprintf(&fn, "%s"PATH_SEPARATOR"cached-microdescs.new", options->DataDirectory); s = read_file_to_str(fn, RFTS_BIN, NULL); tt_assert(s); - test_mem_op(md1->body, ==, s + md1->off, md1->bodylen); - test_mem_op(md2->body, ==, s + md2->off, md2->bodylen); - test_mem_op(md3->body, ==, s + md3->off, md3->bodylen); + tt_mem_op(md1->body, ==, s + md1->off, md1->bodylen); + tt_mem_op(md2->body, ==, s + md2->off, md2->bodylen); + tt_mem_op(md3->body, ==, s + md3->off, md3->bodylen); tt_ptr_op(md1->family, ==, NULL); tt_ptr_op(md3->family, !=, NULL); @@ -180,9 +185,9 @@ test_md_cache(void *data) tor_asprintf(&fn, "%s"PATH_SEPARATOR"cached-microdescs", options->DataDirectory); s = read_file_to_str(fn, RFTS_BIN, NULL); - test_mem_op(md1->body, ==, s + md1->off, strlen(test_md1)); - test_mem_op(md2->body, ==, s + md2->off, strlen(test_md2)); - test_mem_op(md3->body, ==, s + md3->off, strlen(test_md3_noannotation)); + tt_mem_op(md1->body, ==, s + md1->off, strlen(test_md1)); + tt_mem_op(md2->body, ==, s + md2->off, strlen(test_md2)); + tt_mem_op(md3->body, ==, s + md3->off, strlen(test_md3_noannotation)); /* Okay, now we are going to forget about the cache entirely, and reload it * from the disk. */ @@ -191,12 +196,12 @@ test_md_cache(void *data) md1 = microdesc_cache_lookup_by_digest256(mc, d1); md2 = microdesc_cache_lookup_by_digest256(mc, d2); md3 = microdesc_cache_lookup_by_digest256(mc, d3); - test_assert(md1); - test_assert(md2); - test_assert(md3); - test_mem_op(md1->body, ==, s + md1->off, strlen(test_md1)); - test_mem_op(md2->body, ==, s + md2->off, strlen(test_md2)); - test_mem_op(md3->body, ==, s + md3->off, strlen(test_md3_noannotation)); + tt_assert(md1); + tt_assert(md2); + tt_assert(md3); + tt_mem_op(md1->body, ==, s + md1->off, strlen(test_md1)); + tt_mem_op(md2->body, ==, s + md2->off, strlen(test_md2)); + tt_mem_op(md3->body, ==, s + md3->off, strlen(test_md3_noannotation)); tt_int_op(md1->last_listed, ==, time1); tt_int_op(md2->last_listed, ==, time2); @@ -367,7 +372,7 @@ test_md_generate(void *arg) microdesc_t *md = NULL; (void)arg; - ri = router_parse_entry_from_string(test_ri, NULL, 0, 0, NULL); + ri = router_parse_entry_from_string(test_ri, NULL, 0, 0, NULL, NULL); tt_assert(ri); md = dirvote_create_microdescriptor(ri, 8); tt_str_op(md->body, ==, test_md_8); @@ -391,10 +396,330 @@ test_md_generate(void *arg) routerinfo_free(ri); } +/* Taken at random from my ~/.tor/cached-microdescs file and then + * hand-munged */ +static const char MD_PARSE_TEST_DATA[] = + /* Good 0 */ + "onion-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBANsKd1GRfOuSR1MkcwKqs6SVy4Gi/JXplt/bHDkIGm6Q96TeJ5uyVgUL\n" + "DBr/ij6+JqgVFeriuiMzHKREytzjdaTuKsKBFFpLwb+Ppcjr5nMIH/AR6/aHO8hW\n" + "T3B9lx5T6Kl7CqZ4yqXxYRHzn50EPTIZuz0y9se4J4gi9mLmL+pHAgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "p accept 20-23,43,53,79-81,88,110,143,194,220,443,464,531,543-544\n" + "id rsa1024 GEo59/iR1GWSIWZDzXTd5QxtqnU\n" + /* Bad 0: I've messed with the onion-key in the second one. */ + "onion-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBAMr4o/pflVwscx11vC1AKEADlKEqnhpvCIjAEzNEenMhvGQHRlA0EXLC\n" + "7G7O5bhnCwEHqK8Pvg8cuX/fD8v08TF1EVPhwPa0UI6ab8KnPP2F!!!!!!b92DG7EQIk3q\n" + "d68Uxp7E9/t3v1WWZjzDqvEe0par6ul+DKW6HMlTGebFo5Q4e8R1AgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "ntor-onion-key 761Dmm27via7lXygNHM3l+oJLrYU2Nye0Uz4pkpipyY=\n" + "p accept 53\n" + "id rsa1024 3Y4fwXhtgkdGDZ5ef5mtb6TJRQQ\n" + /* Good 1 */ + "onion-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBANsMSjVi3EX8ZHfm/dvPF6KdVR66k1tVul7Jp+dDbDajBYNhgKRzVCxy\n" + "Yac1CBuQjOqK89tKap9PQBnhF087eDrfaZDqYTLwB2W2sBJncVej15WEPXPRBifo\n" + "iFZ8337kgczkaY+IOfSuhtbOUyDOoDpRJheIKBNq0ZiTqtLbbadVAgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "ntor-onion-key ncfiHJjSgdDEW/gc6q6/7idac7j+x7ejQrRm6i75pGA=\n" + "p accept 443,6660-6669,6697,7000-7001\n" + "id rsa1024 XXuLzw3mfBELEq3veXoNhdehwD4\n" + /* Good 2 */ + "onion-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBANQfBlrHrh9F/CAOytrNFgi0ikWMW/HZxuoszF9X+AQ+MudR8bcxxOGl\n" + "1RFwb74s8E3uuzrCkNFvSw9Ar1L02F2DOX0gLsxEGuYC4Ave9NUteGqSqDyEJQUJ\n" + "KlfxCPn2qC9nvNT7wR/Dg2WRvAEKnJmkpb57N3+WSAOPLjKOFEz3AgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "ntor-onion-key AppBt6CSeb1kKid/36ototmFA24ddfW5JpjWPLuoJgs=\n" + "id rsa1024 6y60AEI9a1PUUlRPO0YQT9WzrjI\n" + /* Bad 1: Here I've messed with the ntor key */ + "onion-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBAPjy2HacU3jDNO5nTOFGSwNa0qKCNn4yhtrDVcAJ5alIQeBWZZGJLZ0q\n" + "Cqylw1vYqxu8E09g+QXXFbAgBv1U9TICaATxrIJhIJzc8TJPhqJemp1kq0DvHLDx\n" + "mxwlkNnCD/P5NS+JYB3EjOlU9EnSKUWNU61+Co344m2JqhEau40vAgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "ntor-onion-key 4i2Fp9JHTUr1uQs0pxD5j5spl4/RG56S2P0gQxU=\n" + "id rsa1024 nMRmNEGysA0NmlALVaUmI7D5jLU\n" + /* Good 3: I've added a weird token in this one. This shouldn't prevent + * it parsing */ + "onion-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBAKmosxudyNA/yJNz3S890VqV/ebylzoD11Sc0b/d5tyNNaNZjcYy5vRD\n" + "kwyxFRMbP2TLZQ1zRfNwY7IDnYjU2SbW0pxuM6M8WRtsmx/YOE3kHMVAFJNrTUqU\n" + "6D1zB3IiRDS5q5+NoRxwqo+hYUck60O3WTwEoqb+l3lvXeu7z9rFAgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "flux-capacitor 1.21 GW\n" + "ntor-onion-key MWBoEkl+RlBiGX44XKIvTSqbznTNZStOmUYtcYRQQyY=\n" + "id rsa1024 R+A5O9qRvRac4FT3C4L2QnFyxsc\n" + /* Good 4: Here I've made the 'id rsa' token odd. It should still parse + * just fine. */ + "onion-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBAOh+WMkdNe/Pkjb8UjQyfLOlFgpuVFrxAIGnJsmWWx0yBE97DQxGyh2n\n" + "h8G5OJZHRarJQyCIf7vpZQAi0oP0OkGGaCaDQsM+D8TnqhnU++RWGnMqY/cXxPrL\n" + "MEq+n6aGiLmzkO7ah8yorZpoREk4GqLUIN89/tHHGOhJL3c4CPGjAgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "p reject 25,119,135-139,445,563,1214,4661-4666,6346-6429,6699,6881-6999\n" + "id rsa1234 jlqAKFD2E7uMKv+8TmKSeo7NBho\n" + /* Good 5: Extra id type. */ + "onion-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBAMdgPPc5uaw4y/q+SUTN/I8Y+Gvdx9kKgWV4dmDGJ0mxsVZmo1v6+v3F\n" + "12M2f9m99G3WB8F8now29C+9XyEv8MBHj1lHRdUFHSQes3YTFvDNlgj+FjLqO5TJ\n" + "adOOmfu4DCUUtUEDyQKbNVL4EkMTXY73omTVsjcH3xxFjTx5wixhAgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "ntor-onion-key AAVnWZcnDbxasdZwKqb4fL6O9sZV+XsRNHTpNd1YMz8=\n" + "id rsa1024 72EfBL11QuwX2vU8y+p9ExGfGEg\n" + "id expolding hedgehog 0+A5O9qRvRac4FT3C4L2QnFyxsc\n" + /* Good 6: I've given this a bogus policy. It should parse. */ + "onion-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBALNuufwhPMF8BooxYMNvhYJMPqUB8hQDt8wGmPKphJcD1sVD1i4gAZM2\n" + "HIo+zUBlljDrRWL5NzVzd1yxUJAiQxvXS5dRRFY3B70M7wTVpXw53xe0/BM5t1AX\n" + "n0MFk7Jl6XIKMlzRalZvmMvE/odtyWXkP4Nd1MyZ1QcIwrQ2iwyrAgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "p condone 1-10\n" + "ntor-onion-key 2/nMJ+L4dd/2GpMyTYjz3zC59MvQy4MIzJZhdzKHekg=\n" + "id rsa1024 FHyh10glEMA6MCmBb5R9Y+X/MhQ\n" + /* Good 7: I've given this one another sort of odd policy. Should parse. */ + "onion-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBAKcd3FmQ8iAADghyvX8eca0ePqtJ2w1IDdUdTlf5Y/8+OMdp//sD01yC\n" + "YmiX45LK5ge1O3AzcakYCO6fb3pyIqvXdvm24OjyYZELQ40cmKSLjdhcSf4Fr/N9\n" + "uR/CkknR9cEePu1wZ5WBIGmGdXI6s7t3LB+e7XFyBYAx6wMGlnX7AgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "p accept frogs-mice\n" + "ntor-onion-key AMxvhaQ1Qg7jBJFoyHuPRgETvLbFmJ194hExV24FuAI=\n" + "family $D8CFEA0D996F5D1473D2063C041B7910DB23981E\n" + "id rsa1024 d0VVZC/cHh1P3y4MMbfKlQHFycc\n" + /* Good 8: This one has the ntor-onion-key without terminating =. That's + * allowed. */ + "onion-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBAL438YfjrJE2SPqkkXeQwICygu8KNO54Juj6sjqk5hgsiazIWMOBgbaX\n" + "LIRqPNGaiSq01xSqwjwCBCfwZYT/nSdDBqj1h9aoR8rnjxZjyQ+m3rWpdDqeCDMx\n" + "I3NgZ5w4bNX4poRb42lrV6NmQiFdjzpqszVbv5Lpn2CSKu32CwKVAgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "ntor-onion-key UKL6Dnj2KwYsFlkCvOkXVatxvOPB4MaxqwPQQgZMTwI\n" + "id rsa1024 FPIXc6k++JnKCtSKWUxaR6oXEKs\n" + /* Good 9: Another totally normal one.*/ + "onion-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBANNGIKRd8PFNXkJ2JPV1ohDMFNbJwKbwybeieaQFjtU9KWedHCbr+QD4\n" + "B6zNY5ysguNjHNnlq2f6D09+uhnfDBON8tAz0mPQH/6JqnOXm+EiUn+8bN0E8Nke\n" + "/i3GEgDeaxJJMNQcpsJvmmSmKFOlYy9Fy7ejAjTGqtAnqOte7BnTAgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "ntor-onion-key gUsq3e5iYgsQQvyxINtLzBpHxmIt5rtuFlEbKfI4gFk=\n" + "id rsa1024 jv+LdatDzsMfEW6pLBeL/5uzwCc\n" + /* Bad 2: RSA key has bad exponent of 3. */ + "onion-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGHAoGBAMMTWtvPxYnUNJ5Y7B+XENcpxzPoGstrdiUszCBS+/42xvluLJ+JDSdR\n" + "qJaMD6ax8vKAeLS5C6O17MNdG2VldlPRbtgl41MXsOoUqEJ+nY9e3WG9Snjp47xC\n" + "zmWIfeduXSavIsb3a43/MLIz/9qO0TkgAAiuQr79JlwKhLdzCqTLAgED\n" + "-----END RSA PUBLIC KEY-----\n" + "ntor-onion-key NkRB4wTUFogiVp5jYmjGORe2ffb/y5Kk8Itw8jdzMjA=\n" + "p reject 25,119,135-139,445,563,1214,4661-4666,6346-6429,6699,6881-6999\n" + "id rsa1024 fKvYjP7TAjCC1FzYee5bYAwYkoDg\n" + /* Bad 3: Bogus annotation */ + "@last-listed with strange aeons\n" + "onion-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBALcRBFNCZtpd2TFJysU77/fJMFzKisRQEBOtDGtTZ2Bg4aEGosssa0Id\n" + "YtUagRLYle08QVGvGB+EHBI5qf6Ah2yPH7k5QiN2a3Sq+nyh85dXKPazBGBBbM+C\n" + "DOfDauV02CAnADNMLJEf1voY3oBVvYyIsmHxn5i1R19ZYIiR8NX5AgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "ntor-onion-key m4xcFXMWMjCvZDXq8FT3XmS0EHYseGOeu+fV+6FYDlk=\n" + "p accept 20-23,43,53,79-81,88,110,143,194,220,389,443,464,531,543-544\n" + "id rsa1024 SSbfNE9vmaiwRKH+eqNAkiKQhds\n" + /* Good 10: Normal, with added ipv6 address and added other address */ + "onion-key\n" + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIGJAoGBAM7uUtq5F6h63QNYIvC+4NcWaD0DjtnrOORZMkdpJhinXUOwce3cD5Dj\n" + "sgdN1wJpWpTQMXJ2DssfSgmOVXETP7qJuZyRprxalQhaEATMDNJA/66Ml1jSO9mZ\n" + "+8Xb7m/4q778lNtkSbsvMaYD2Dq6k2QQ3kMhr9z8oUtX0XA23+pfAgMBAAE=\n" + "-----END RSA PUBLIC KEY-----\n" + "a [::1:2:3:4]:9090\n" + "a 18.0.0.1:9999\n" + "ntor-onion-key k2yFqTU2vzMCQDEiE/j9UcEHxKrXMLpB3IL0or09sik=\n" + "id rsa1024 2A8wYpHxnkKJ92orocvIQBzeHlE\n" + "p6 allow 80\n" + ; + +/** More tests for parsing different kinds of microdescriptors, and getting + * invalid digests trackd from them. */ +static void +test_md_parse(void *arg) +{ + (void) arg; + char *mem_op_hex_tmp = NULL; + smartlist_t *invalid = smartlist_new(); + + smartlist_t *mds = microdescs_parse_from_string(MD_PARSE_TEST_DATA, + NULL, 1, SAVED_NOWHERE, + invalid); + tt_int_op(smartlist_len(mds), ==, 11); + tt_int_op(smartlist_len(invalid), ==, 4); + + test_memeq_hex(smartlist_get(invalid,0), + "5d76bf1c6614e885614a1e0ad074e1ab" + "4ea14655ebeefb1736a71b5ed8a15a51"); + test_memeq_hex(smartlist_get(invalid,1), + "2fde0ee3343669c2444cd9d53cbd39c6" + "a7d1fc0513513e840ca7f6e68864b36c"); + test_memeq_hex(smartlist_get(invalid,2), + "20d1576c5ab11bbcff0dedb1db4a3cfc" + "c8bc8dd839d8cbfef92d00a1a7d7b294"); + test_memeq_hex(smartlist_get(invalid,3), + "074770f394c73dbde7b44412e9692add" + "691a478d4727f9804b77646c95420a96"); + + /* Spot-check the valid ones. */ + const microdesc_t *md = smartlist_get(mds, 5); + test_memeq_hex(md->digest, + "54bb6d733ddeb375d2456c79ae103961" + "da0cae29620375ac4cf13d54da4d92b3"); + tt_int_op(md->last_listed, ==, 0); + tt_int_op(md->saved_location, ==, SAVED_NOWHERE); + tt_int_op(md->no_save, ==, 0); + tt_uint_op(md->held_in_map, ==, 0); + tt_uint_op(md->held_by_nodes, ==, 0); + tt_assert(md->onion_curve25519_pkey); + + md = smartlist_get(mds, 6); + test_memeq_hex(md->digest, + "53f740bd222ab37f19f604b1d3759aa6" + "5eff1fbce9ac254bd0fa50d4af9b1bae"); + tt_assert(! md->exit_policy); + + md = smartlist_get(mds, 8); + test_memeq_hex(md->digest, + "a0a155562d8093d8fd0feb7b93b7226e" + "17f056c2142aab7a4ea8c5867a0376d5"); + tt_assert(md->onion_curve25519_pkey); + + md = smartlist_get(mds, 10); + test_memeq_hex(md->digest, + "409ebd87d23925a2732bd467a92813c9" + "21ca378fcb9ca193d354c51550b6d5e9"); + tt_assert(tor_addr_family(&md->ipv6_addr) == AF_INET6); + tt_int_op(md->ipv6_orport, ==, 9090); + + done: + SMARTLIST_FOREACH(mds, microdesc_t *, md, microdesc_free(md)); + smartlist_free(mds); + SMARTLIST_FOREACH(invalid, char *, cp, tor_free(cp)); + smartlist_free(invalid); + tor_free(mem_op_hex_tmp); +} + +static int mock_rgsbd_called = 0; +static routerstatus_t *mock_rgsbd_val_a = NULL; +static routerstatus_t *mock_rgsbd_val_b = NULL; +static routerstatus_t * +mock_router_get_status_by_digest(networkstatus_t *c, const char *d) +{ + (void) c; + ++mock_rgsbd_called; + + if (fast_memeq(d, "\x5d\x76", 2)) { + memcpy(mock_rgsbd_val_a->descriptor_digest, d, 32); + return mock_rgsbd_val_a; + } else if (fast_memeq(d, "\x20\xd1", 2)) { + memcpy(mock_rgsbd_val_b->descriptor_digest, d, 32); + return mock_rgsbd_val_b; + } else { + return NULL; + } +} + +static networkstatus_t *mock_ns_val = NULL; +static networkstatus_t * +mock_ns_get_by_flavor(consensus_flavor_t f) +{ + (void)f; + return mock_ns_val; +} + +static void +test_md_reject_cache(void *arg) +{ + (void) arg; + microdesc_cache_t *mc = NULL ; + smartlist_t *added = NULL, *wanted = smartlist_new(); + or_options_t *options = get_options_mutable(); + char buf[DIGEST256_LEN]; + + tor_free(options->DataDirectory); + options->DataDirectory = tor_strdup(get_fname("md_datadir_test_rej")); + mock_rgsbd_val_a = tor_malloc_zero(sizeof(routerstatus_t)); + mock_rgsbd_val_b = tor_malloc_zero(sizeof(routerstatus_t)); + mock_ns_val = tor_malloc_zero(sizeof(networkstatus_t)); + + mock_ns_val->valid_after = time(NULL) - 86400; + mock_ns_val->valid_until = time(NULL) + 86400; + mock_ns_val->flavor = FLAV_MICRODESC; + +#ifdef _WIN32 + tt_int_op(0, ==, mkdir(options->DataDirectory)); +#else + tt_int_op(0, ==, mkdir(options->DataDirectory, 0700)); +#endif + + MOCK(router_get_mutable_consensus_status_by_descriptor_digest, + mock_router_get_status_by_digest); + MOCK(networkstatus_get_latest_consensus_by_flavor, mock_ns_get_by_flavor); + + mc = get_microdesc_cache(); +#define ADD(hex) \ + do { \ + tt_int_op(0,==,base16_decode(buf,sizeof(buf),hex,strlen(hex))); \ + smartlist_add(wanted, tor_memdup(buf, DIGEST256_LEN)); \ + } while (0) + + /* invalid,0 */ + ADD("5d76bf1c6614e885614a1e0ad074e1ab4ea14655ebeefb1736a71b5ed8a15a51"); + /* invalid,2 */ + ADD("20d1576c5ab11bbcff0dedb1db4a3cfcc8bc8dd839d8cbfef92d00a1a7d7b294"); + /* valid, 6 */ + ADD("53f740bd222ab37f19f604b1d3759aa65eff1fbce9ac254bd0fa50d4af9b1bae"); + /* valid, 8 */ + ADD("a0a155562d8093d8fd0feb7b93b7226e17f056c2142aab7a4ea8c5867a0376d5"); + + added = microdescs_add_to_cache(mc, MD_PARSE_TEST_DATA, NULL, + SAVED_NOWHERE, 0, time(NULL), wanted); + + tt_int_op(smartlist_len(added), ==, 2); + tt_int_op(mock_rgsbd_called, ==, 2); + tt_int_op(mock_rgsbd_val_a->dl_status.n_download_failures, ==, 255); + tt_int_op(mock_rgsbd_val_b->dl_status.n_download_failures, ==, 255); + + done: + UNMOCK(networkstatus_get_latest_consensus_by_flavor); + UNMOCK(router_get_mutable_consensus_status_by_descriptor_digest); + if (options) + tor_free(options->DataDirectory); + microdesc_free_all(); + smartlist_free(added); + SMARTLIST_FOREACH(wanted, char *, cp, tor_free(cp)); + smartlist_free(wanted); + tor_free(mock_rgsbd_val_a); + tor_free(mock_rgsbd_val_b); + tor_free(mock_ns_val); +} + struct testcase_t microdesc_tests[] = { { "cache", test_md_cache, TT_FORK, NULL, NULL }, { "broken_cache", test_md_cache_broken, TT_FORK, NULL, NULL }, { "generate", test_md_generate, 0, NULL, NULL }, + { "parse", test_md_parse, 0, NULL, NULL }, + { "reject_cache", test_md_reject_cache, TT_FORK, NULL, NULL }, END_OF_TESTCASES }; diff --git a/src/test/test_nodelist.c b/src/test/test_nodelist.c index 600e6a89d4..6d270db960 100644 --- a/src/test/test_nodelist.c +++ b/src/test/test_nodelist.c @@ -23,9 +23,9 @@ test_nodelist_node_get_verbose_nickname_by_id_null_node(void *arg) (void) arg; /* make sure node_get_by_id returns NULL */ - test_assert(!node_get_by_id(ID)); + tt_assert(!node_get_by_id(ID)); node_get_verbose_nickname_by_id(ID, vname); - test_streq(vname, "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"); + tt_str_op(vname,==, "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"); done: return; } @@ -54,7 +54,7 @@ test_nodelist_node_get_verbose_nickname_not_named(void *arg) "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA", DIGEST_LEN); node_get_verbose_nickname(&mock_node, vname); - test_streq(vname, "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~TestOR"); + tt_str_op(vname,==, "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~TestOR"); done: return; diff --git a/src/test/test_policy.c b/src/test/test_policy.c index 4cdcd034bb..388251a61f 100644 --- a/src/test/test_policy.c +++ b/src/test/test_policy.c @@ -47,17 +47,20 @@ test_policy_summary_helper(const char *policy_str, line.value = (char *)policy_str; line.next = NULL; - r = policies_parse_exit_policy(&line, &policy, 1, 0, 0, 1); - test_eq(r, 0); + r = policies_parse_exit_policy(&line, &policy, + EXIT_POLICY_IPV6_ENABLED | + EXIT_POLICY_ADD_DEFAULT ,0); + tt_int_op(r,==, 0); + summary = policy_summarize(policy, AF_INET); - test_assert(summary != NULL); - test_streq(summary, expected_summary); + tt_assert(summary != NULL); + tt_str_op(summary,==, expected_summary); short_policy = parse_short_policy(summary); tt_assert(short_policy); summary_after = write_short_policy(short_policy); - test_streq(summary, summary_after); + tt_str_op(summary,==, summary_after); done: tor_free(summary_after); @@ -86,104 +89,108 @@ test_policies_general(void *arg) policy = smartlist_new(); p = router_parse_addr_policy_item_from_string("reject 192.168.0.0/16:*",-1); - test_assert(p != NULL); - test_eq(ADDR_POLICY_REJECT, p->policy_type); + tt_assert(p != NULL); + tt_int_op(ADDR_POLICY_REJECT,==, p->policy_type); tor_addr_from_ipv4h(&tar, 0xc0a80000u); - test_eq(0, tor_addr_compare(&p->addr, &tar, CMP_EXACT)); - test_eq(16, p->maskbits); - test_eq(1, p->prt_min); - test_eq(65535, p->prt_max); + tt_int_op(0,==, tor_addr_compare(&p->addr, &tar, CMP_EXACT)); + tt_int_op(16,==, p->maskbits); + tt_int_op(1,==, p->prt_min); + tt_int_op(65535,==, p->prt_max); smartlist_add(policy, p); tor_addr_from_ipv4h(&tar, 0x01020304u); - test_assert(ADDR_POLICY_ACCEPTED == + tt_assert(ADDR_POLICY_ACCEPTED == compare_tor_addr_to_addr_policy(&tar, 2, policy)); tor_addr_make_unspec(&tar); - test_assert(ADDR_POLICY_PROBABLY_ACCEPTED == + tt_assert(ADDR_POLICY_PROBABLY_ACCEPTED == compare_tor_addr_to_addr_policy(&tar, 2, policy)); tor_addr_from_ipv4h(&tar, 0xc0a80102); - test_assert(ADDR_POLICY_REJECTED == + tt_assert(ADDR_POLICY_REJECTED == compare_tor_addr_to_addr_policy(&tar, 2, policy)); - test_assert(0 == policies_parse_exit_policy(NULL, &policy2, 1, 1, 0, 1)); - test_assert(policy2); + tt_int_op(0, ==, policies_parse_exit_policy(NULL, &policy2, + EXIT_POLICY_IPV6_ENABLED | + EXIT_POLICY_REJECT_PRIVATE | + EXIT_POLICY_ADD_DEFAULT, 0)); + + tt_assert(policy2); policy3 = smartlist_new(); p = router_parse_addr_policy_item_from_string("reject *:*",-1); - test_assert(p != NULL); + tt_assert(p != NULL); smartlist_add(policy3, p); p = router_parse_addr_policy_item_from_string("accept *:*",-1); - test_assert(p != NULL); + tt_assert(p != NULL); smartlist_add(policy3, p); policy4 = smartlist_new(); p = router_parse_addr_policy_item_from_string("accept *:443",-1); - test_assert(p != NULL); + tt_assert(p != NULL); smartlist_add(policy4, p); p = router_parse_addr_policy_item_from_string("accept *:443",-1); - test_assert(p != NULL); + tt_assert(p != NULL); smartlist_add(policy4, p); policy5 = smartlist_new(); p = router_parse_addr_policy_item_from_string("reject 0.0.0.0/8:*",-1); - test_assert(p != NULL); + tt_assert(p != NULL); smartlist_add(policy5, p); p = router_parse_addr_policy_item_from_string("reject 169.254.0.0/16:*",-1); - test_assert(p != NULL); + tt_assert(p != NULL); smartlist_add(policy5, p); p = router_parse_addr_policy_item_from_string("reject 127.0.0.0/8:*",-1); - test_assert(p != NULL); + tt_assert(p != NULL); smartlist_add(policy5, p); p = router_parse_addr_policy_item_from_string("reject 192.168.0.0/16:*",-1); - test_assert(p != NULL); + tt_assert(p != NULL); smartlist_add(policy5, p); p = router_parse_addr_policy_item_from_string("reject 10.0.0.0/8:*",-1); - test_assert(p != NULL); + tt_assert(p != NULL); smartlist_add(policy5, p); p = router_parse_addr_policy_item_from_string("reject 172.16.0.0/12:*",-1); - test_assert(p != NULL); + tt_assert(p != NULL); smartlist_add(policy5, p); p = router_parse_addr_policy_item_from_string("reject 80.190.250.90:*",-1); - test_assert(p != NULL); + tt_assert(p != NULL); smartlist_add(policy5, p); p = router_parse_addr_policy_item_from_string("reject *:1-65534",-1); - test_assert(p != NULL); + tt_assert(p != NULL); smartlist_add(policy5, p); p = router_parse_addr_policy_item_from_string("reject *:65535",-1); - test_assert(p != NULL); + tt_assert(p != NULL); smartlist_add(policy5, p); p = router_parse_addr_policy_item_from_string("accept *:1-65535",-1); - test_assert(p != NULL); + tt_assert(p != NULL); smartlist_add(policy5, p); policy6 = smartlist_new(); p = router_parse_addr_policy_item_from_string("accept 43.3.0.0/9:*",-1); - test_assert(p != NULL); + tt_assert(p != NULL); smartlist_add(policy6, p); policy7 = smartlist_new(); p = router_parse_addr_policy_item_from_string("accept 0.0.0.0/8:*",-1); - test_assert(p != NULL); + tt_assert(p != NULL); smartlist_add(policy7, p); - test_assert(!exit_policy_is_general_exit(policy)); - test_assert(exit_policy_is_general_exit(policy2)); - test_assert(!exit_policy_is_general_exit(NULL)); - test_assert(!exit_policy_is_general_exit(policy3)); - test_assert(!exit_policy_is_general_exit(policy4)); - test_assert(!exit_policy_is_general_exit(policy5)); - test_assert(!exit_policy_is_general_exit(policy6)); - test_assert(!exit_policy_is_general_exit(policy7)); + tt_assert(!exit_policy_is_general_exit(policy)); + tt_assert(exit_policy_is_general_exit(policy2)); + tt_assert(!exit_policy_is_general_exit(NULL)); + tt_assert(!exit_policy_is_general_exit(policy3)); + tt_assert(!exit_policy_is_general_exit(policy4)); + tt_assert(!exit_policy_is_general_exit(policy5)); + tt_assert(!exit_policy_is_general_exit(policy6)); + tt_assert(!exit_policy_is_general_exit(policy7)); - test_assert(cmp_addr_policies(policy, policy2)); - test_assert(cmp_addr_policies(policy, NULL)); - test_assert(!cmp_addr_policies(policy2, policy2)); - test_assert(!cmp_addr_policies(NULL, NULL)); + tt_assert(cmp_addr_policies(policy, policy2)); + tt_assert(cmp_addr_policies(policy, NULL)); + tt_assert(!cmp_addr_policies(policy2, policy2)); + tt_assert(!cmp_addr_policies(NULL, NULL)); - test_assert(!policy_is_reject_star(policy2, AF_INET)); - test_assert(policy_is_reject_star(policy, AF_INET)); - test_assert(policy_is_reject_star(NULL, AF_INET)); + tt_assert(!policy_is_reject_star(policy2, AF_INET)); + tt_assert(policy_is_reject_star(policy, AF_INET)); + tt_assert(policy_is_reject_star(NULL, AF_INET)); addr_policy_list_free(policy); policy = NULL; @@ -193,11 +200,14 @@ test_policies_general(void *arg) line.key = (char*)"foo"; line.value = (char*)"accept *:80,reject private:*,reject *:*"; line.next = NULL; - test_assert(0 == policies_parse_exit_policy(&line, &policy, 1, 0, 0, 1)); - test_assert(policy); + tt_int_op(0, ==, policies_parse_exit_policy(&line,&policy, + EXIT_POLICY_IPV6_ENABLED | + EXIT_POLICY_ADD_DEFAULT,0)); + tt_assert(policy); + //test_streq(policy->string, "accept *:80"); //test_streq(policy->next->string, "reject *:*"); - test_eq(smartlist_len(policy), 4); + tt_int_op(smartlist_len(policy),==, 4); /* test policy summaries */ /* check if we properly ignore private IP addresses */ @@ -359,7 +369,7 @@ test_dump_exit_policy_to_string(void *arg) ri->exit_policy = NULL; // expecting "reject *:*" ep = router_dump_exit_policy_to_string(ri,1,1); - test_streq("reject *:*",ep); + tt_str_op("reject *:*",==, ep); tor_free(ep); @@ -372,7 +382,7 @@ test_dump_exit_policy_to_string(void *arg) ep = router_dump_exit_policy_to_string(ri,1,1); - test_streq("accept *:*",ep); + tt_str_op("accept *:*",==, ep); tor_free(ep); @@ -382,7 +392,7 @@ test_dump_exit_policy_to_string(void *arg) ep = router_dump_exit_policy_to_string(ri,1,1); - test_streq("accept *:*\nreject *:25",ep); + tt_str_op("accept *:*\nreject *:25",==, ep); tor_free(ep); @@ -393,7 +403,7 @@ test_dump_exit_policy_to_string(void *arg) ep = router_dump_exit_policy_to_string(ri,1,1); - test_streq("accept *:*\nreject *:25\nreject 8.8.8.8:*",ep); + tt_str_op("accept *:*\nreject *:25\nreject 8.8.8.8:*",==, ep); tor_free(ep); policy_entry = @@ -403,8 +413,8 @@ test_dump_exit_policy_to_string(void *arg) ep = router_dump_exit_policy_to_string(ri,1,1); - test_streq("accept *:*\nreject *:25\nreject 8.8.8.8:*\n" - "reject6 [fc00::]/7:*",ep); + tt_str_op("accept *:*\nreject *:25\nreject 8.8.8.8:*\n" + "reject6 [fc00::]/7:*",==, ep); tor_free(ep); policy_entry = @@ -414,8 +424,8 @@ test_dump_exit_policy_to_string(void *arg) ep = router_dump_exit_policy_to_string(ri,1,1); - test_streq("accept *:*\nreject *:25\nreject 8.8.8.8:*\n" - "reject6 [fc00::]/7:*\naccept6 [c000::]/3:*",ep); + tt_str_op("accept *:*\nreject *:25\nreject 8.8.8.8:*\n" + "reject6 [fc00::]/7:*\naccept6 [c000::]/3:*",==, ep); done: diff --git a/src/test/test_pt.c b/src/test/test_pt.c index f55c059580..61ade84e3a 100644 --- a/src/test/test_pt.c +++ b/src/test/test_pt.c @@ -27,75 +27,76 @@ reset_mp(managed_proxy_t *mp) } static void -test_pt_parsing(void) +test_pt_parsing(void *arg) { char line[200]; transport_t *transport = NULL; tor_addr_t test_addr; - managed_proxy_t *mp = tor_malloc(sizeof(managed_proxy_t)); + managed_proxy_t *mp = tor_malloc_zero(sizeof(managed_proxy_t)); + (void)arg; mp->conf_state = PT_PROTO_INFANT; mp->transports = smartlist_new(); /* incomplete cmethod */ strlcpy(line,"CMETHOD trebuchet",sizeof(line)); - test_assert(parse_cmethod_line(line, mp) < 0); + tt_assert(parse_cmethod_line(line, mp) < 0); reset_mp(mp); /* wrong proxy type */ strlcpy(line,"CMETHOD trebuchet dog 127.0.0.1:1999",sizeof(line)); - test_assert(parse_cmethod_line(line, mp) < 0); + tt_assert(parse_cmethod_line(line, mp) < 0); reset_mp(mp); /* wrong addrport */ strlcpy(line,"CMETHOD trebuchet socks4 abcd",sizeof(line)); - test_assert(parse_cmethod_line(line, mp) < 0); + tt_assert(parse_cmethod_line(line, mp) < 0); reset_mp(mp); /* correct line */ strlcpy(line,"CMETHOD trebuchet socks5 127.0.0.1:1999",sizeof(line)); - test_assert(parse_cmethod_line(line, mp) == 0); - test_assert(smartlist_len(mp->transports) == 1); + tt_assert(parse_cmethod_line(line, mp) == 0); + tt_assert(smartlist_len(mp->transports) == 1); transport = smartlist_get(mp->transports, 0); /* test registered address of transport */ tor_addr_parse(&test_addr, "127.0.0.1"); - test_assert(tor_addr_eq(&test_addr, &transport->addr)); + tt_assert(tor_addr_eq(&test_addr, &transport->addr)); /* test registered port of transport */ - test_assert(transport->port == 1999); + tt_assert(transport->port == 1999); /* test registered SOCKS version of transport */ - test_assert(transport->socks_version == PROXY_SOCKS5); + tt_assert(transport->socks_version == PROXY_SOCKS5); /* test registered name of transport */ - test_streq(transport->name, "trebuchet"); + tt_str_op(transport->name,==, "trebuchet"); reset_mp(mp); /* incomplete smethod */ strlcpy(line,"SMETHOD trebuchet",sizeof(line)); - test_assert(parse_smethod_line(line, mp) < 0); + tt_assert(parse_smethod_line(line, mp) < 0); reset_mp(mp); /* wrong addr type */ strlcpy(line,"SMETHOD trebuchet abcd",sizeof(line)); - test_assert(parse_smethod_line(line, mp) < 0); + tt_assert(parse_smethod_line(line, mp) < 0); reset_mp(mp); /* cowwect */ strlcpy(line,"SMETHOD trebuchy 127.0.0.2:2999",sizeof(line)); - test_assert(parse_smethod_line(line, mp) == 0); - test_assert(smartlist_len(mp->transports) == 1); + tt_assert(parse_smethod_line(line, mp) == 0); + tt_assert(smartlist_len(mp->transports) == 1); transport = smartlist_get(mp->transports, 0); /* test registered address of transport */ tor_addr_parse(&test_addr, "127.0.0.2"); - test_assert(tor_addr_eq(&test_addr, &transport->addr)); + tt_assert(tor_addr_eq(&test_addr, &transport->addr)); /* test registered port of transport */ - test_assert(transport->port == 2999); + tt_assert(transport->port == 2999); /* test registered name of transport */ - test_streq(transport->name, "trebuchy"); + tt_str_op(transport->name,==, "trebuchy"); reset_mp(mp); @@ -103,7 +104,7 @@ test_pt_parsing(void) strlcpy(line,"SMETHOD trebuchet 127.0.0.1:9999 " "ARGS:counterweight=3,sling=snappy", sizeof(line)); - test_assert(parse_smethod_line(line, mp) == 0); + tt_assert(parse_smethod_line(line, mp) == 0); tt_int_op(1, ==, smartlist_len(mp->transports)); { const transport_t *transport = smartlist_get(mp->transports, 0); @@ -118,15 +119,15 @@ test_pt_parsing(void) /* unsupported version */ strlcpy(line,"VERSION 666",sizeof(line)); - test_assert(parse_version(line, mp) < 0); + tt_assert(parse_version(line, mp) < 0); /* incomplete VERSION */ strlcpy(line,"VERSION ",sizeof(line)); - test_assert(parse_version(line, mp) < 0); + tt_assert(parse_version(line, mp) < 0); /* correct VERSION */ strlcpy(line,"VERSION 1",sizeof(line)); - test_assert(parse_version(line, mp) == 0); + tt_assert(parse_version(line, mp) == 0); done: reset_mp(mp); @@ -187,11 +188,12 @@ test_pt_get_transport_options(void *arg) } static void -test_pt_protocol(void) +test_pt_protocol(void *arg) { char line[200]; managed_proxy_t *mp = tor_malloc_zero(sizeof(managed_proxy_t)); + (void)arg; mp->conf_state = PT_PROTO_LAUNCHED; mp->transports = smartlist_new(); mp->argv = tor_calloc(sizeof(char *), 2); @@ -201,32 +203,32 @@ test_pt_protocol(void) strlcpy(line,"VERSION 1",sizeof(line)); handle_proxy_line(line, mp); - test_assert(mp->conf_state == PT_PROTO_ACCEPTING_METHODS); + tt_assert(mp->conf_state == PT_PROTO_ACCEPTING_METHODS); strlcpy(line,"VERSION 1",sizeof(line)); handle_proxy_line(line, mp); - test_assert(mp->conf_state == PT_PROTO_BROKEN); + tt_assert(mp->conf_state == PT_PROTO_BROKEN); reset_mp(mp); strlcpy(line,"CMETHOD trebuchet socks5 127.0.0.1:1999",sizeof(line)); handle_proxy_line(line, mp); - test_assert(mp->conf_state == PT_PROTO_BROKEN); + tt_assert(mp->conf_state == PT_PROTO_BROKEN); reset_mp(mp); /* correct protocol run: */ strlcpy(line,"VERSION 1",sizeof(line)); handle_proxy_line(line, mp); - test_assert(mp->conf_state == PT_PROTO_ACCEPTING_METHODS); + tt_assert(mp->conf_state == PT_PROTO_ACCEPTING_METHODS); strlcpy(line,"CMETHOD trebuchet socks5 127.0.0.1:1999",sizeof(line)); handle_proxy_line(line, mp); - test_assert(mp->conf_state == PT_PROTO_ACCEPTING_METHODS); + tt_assert(mp->conf_state == PT_PROTO_ACCEPTING_METHODS); strlcpy(line,"CMETHODS DONE",sizeof(line)); handle_proxy_line(line, mp); - test_assert(mp->conf_state == PT_PROTO_CONFIGURED); + tt_assert(mp->conf_state == PT_PROTO_CONFIGURED); done: reset_mp(mp); @@ -363,7 +365,7 @@ test_pt_configure_proxy(void *arg) control_testing_set_global_event_mask(EVENT_TRANSPORT_LAUNCHED); - mp = tor_malloc(sizeof(managed_proxy_t)); + mp = tor_malloc_zero(sizeof(managed_proxy_t)); mp->conf_state = PT_PROTO_ACCEPTING_METHODS; mp->transports = smartlist_new(); mp->transports_to_launch = smartlist_new(); @@ -378,19 +380,19 @@ test_pt_configure_proxy(void *arg) for (i = 0 ; i < 5 ; i++) { retval = configure_proxy(mp); /* retval should be zero because proxy hasn't finished configuring yet */ - test_assert(retval == 0); + tt_int_op(retval, ==, 0); /* check the number of registered transports */ - test_assert(smartlist_len(mp->transports) == i+1); + tt_assert(smartlist_len(mp->transports) == i+1); /* check that the mp is still waiting for transports */ - test_assert(mp->conf_state == PT_PROTO_ACCEPTING_METHODS); + tt_assert(mp->conf_state == PT_PROTO_ACCEPTING_METHODS); } /* this last configure_proxy() should finalize the proxy configuration. */ retval = configure_proxy(mp); /* retval should be 1 since the proxy finished configuring */ - test_assert(retval == 1); + tt_int_op(retval, ==, 1); /* check the mp state */ - test_assert(mp->conf_state == PT_PROTO_COMPLETED); + tt_assert(mp->conf_state == PT_PROTO_COMPLETED); tt_int_op(controlevent_n, ==, 5); tt_int_op(controlevent_event, ==, EVENT_TRANSPORT_LAUNCHED); @@ -416,7 +418,7 @@ test_pt_configure_proxy(void *arg) /* Get the bindaddr for "mock1" and check it against the bindaddr that the mocked tor_get_lines_from_handle() generated. */ transport_in_state = get_transport_in_state_by_name("mock1"); - test_assert(transport_in_state); + tt_assert(transport_in_state); smartlist_split_string(transport_info_sl, transport_in_state->value, NULL, 0, 0); name_of_transport = smartlist_get(transport_info_sl, 0); @@ -450,8 +452,86 @@ test_pt_configure_proxy(void *arg) tor_free(mp); } +/* Test the get_pt_proxy_uri() function. */ +static void +test_get_pt_proxy_uri(void *arg) +{ + or_options_t *options = get_options_mutable(); + char *uri = NULL; + int ret; + (void) arg; + + /* Test with no proxy. */ + uri = get_pt_proxy_uri(); + tt_assert(uri == NULL); + + /* Test with a SOCKS4 proxy. */ + options->Socks4Proxy = tor_strdup("192.0.2.1:1080"); + ret = tor_addr_port_lookup(options->Socks4Proxy, + &options->Socks4ProxyAddr, + &options->Socks4ProxyPort); + tt_int_op(ret, ==, 0); + uri = get_pt_proxy_uri(); + tt_str_op(uri, ==, "socks4a://192.0.2.1:1080"); + tor_free(uri); + tor_free(options->Socks4Proxy); + + /* Test with a SOCKS5 proxy, no username/password. */ + options->Socks5Proxy = tor_strdup("192.0.2.1:1080"); + ret = tor_addr_port_lookup(options->Socks5Proxy, + &options->Socks5ProxyAddr, + &options->Socks5ProxyPort); + tt_int_op(ret, ==, 0); + uri = get_pt_proxy_uri(); + tt_str_op(uri, ==, "socks5://192.0.2.1:1080"); + tor_free(uri); + + /* Test with a SOCKS5 proxy, with username/password. */ + options->Socks5ProxyUsername = tor_strdup("hwest"); + options->Socks5ProxyPassword = tor_strdup("r34n1m470r"); + uri = get_pt_proxy_uri(); + tt_str_op(uri, ==, "socks5://hwest:r34n1m470r@192.0.2.1:1080"); + tor_free(uri); + tor_free(options->Socks5Proxy); + tor_free(options->Socks5ProxyUsername); + tor_free(options->Socks5ProxyPassword); + + /* Test with a HTTPS proxy, no authenticator. */ + options->HTTPSProxy = tor_strdup("192.0.2.1:80"); + ret = tor_addr_port_lookup(options->HTTPSProxy, + &options->HTTPSProxyAddr, + &options->HTTPSProxyPort); + tt_int_op(ret, ==, 0); + uri = get_pt_proxy_uri(); + tt_str_op(uri, ==, "http://192.0.2.1:80"); + tor_free(uri); + + /* Test with a HTTPS proxy, with authenticator. */ + options->HTTPSProxyAuthenticator = tor_strdup("hwest:r34n1m470r"); + uri = get_pt_proxy_uri(); + tt_str_op(uri, ==, "http://hwest:r34n1m470r@192.0.2.1:80"); + tor_free(uri); + tor_free(options->HTTPSProxy); + tor_free(options->HTTPSProxyAuthenticator); + + /* Token nod to the fact that IPv6 exists. */ + options->Socks4Proxy = tor_strdup("[2001:db8::1]:1080"); + ret = tor_addr_port_lookup(options->Socks4Proxy, + &options->Socks4ProxyAddr, + &options->Socks4ProxyPort); + tt_int_op(ret, ==, 0); + uri = get_pt_proxy_uri(); + tt_str_op(uri, ==, "socks4a://[2001:db8::1]:1080"); + tor_free(uri); + tor_free(options->Socks4Proxy); + + done: + if (uri) + tor_free(uri); +} + #define PT_LEGACY(name) \ - { #name, legacy_test_helper, 0, &legacy_setup, test_pt_ ## name } + { #name, test_pt_ ## name , 0, NULL, NULL } struct testcase_t pt_tests[] = { PT_LEGACY(parsing), @@ -462,6 +542,8 @@ struct testcase_t pt_tests[] = { NULL, NULL }, { "configure_proxy",test_pt_configure_proxy, TT_FORK, NULL, NULL }, + { "get_pt_proxy_uri", test_get_pt_proxy_uri, TT_FORK, + NULL, NULL }, END_OF_TESTCASES }; diff --git a/src/test/test_replay.c b/src/test/test_replay.c index b48f582f5e..2f543512b0 100644 --- a/src/test/test_replay.c +++ b/src/test/test_replay.c @@ -18,12 +18,13 @@ static const char *test_buffer = " mollit anim id est laborum."; static void -test_replaycache_alloc(void) +test_replaycache_alloc(void *arg) { replaycache_t *r = NULL; + (void)arg; r = replaycache_new(600, 300); - test_assert(r != NULL); + tt_assert(r != NULL); done: if (r) replaycache_free(r); @@ -32,21 +33,22 @@ test_replaycache_alloc(void) } static void -test_replaycache_badalloc(void) +test_replaycache_badalloc(void *arg) { replaycache_t *r = NULL; /* Negative horizon should fail */ + (void)arg; r = replaycache_new(-600, 300); - test_assert(r == NULL); + tt_assert(r == NULL); /* Negative interval should get adjusted to zero */ r = replaycache_new(600, -300); - test_assert(r != NULL); - test_eq(r->scrub_interval, 0); + tt_assert(r != NULL); + tt_int_op(r->scrub_interval,==, 0); replaycache_free(r); /* Negative horizon and negative interval should still fail */ r = replaycache_new(-600, -300); - test_assert(r == NULL); + tt_assert(r == NULL); done: if (r) replaycache_free(r); @@ -55,35 +57,37 @@ test_replaycache_badalloc(void) } static void -test_replaycache_free_null(void) +test_replaycache_free_null(void *arg) { + (void)arg; replaycache_free(NULL); /* Assert that we're here without horrible death */ - test_assert(1); + tt_assert(1); done: return; } static void -test_replaycache_miss(void) +test_replaycache_miss(void *arg) { replaycache_t *r = NULL; int result; + (void)arg; r = replaycache_new(600, 300); - test_assert(r != NULL); + tt_assert(r != NULL); result = replaycache_add_and_test_internal(1200, r, test_buffer, strlen(test_buffer), NULL); - test_eq(result, 0); + tt_int_op(result,==, 0); /* poke the bad-parameter error case too */ result = replaycache_add_and_test_internal(1200, NULL, test_buffer, strlen(test_buffer), NULL); - test_eq(result, 0); + tt_int_op(result,==, 0); done: if (r) replaycache_free(r); @@ -92,23 +96,24 @@ test_replaycache_miss(void) } static void -test_replaycache_hit(void) +test_replaycache_hit(void *arg) { replaycache_t *r = NULL; int result; + (void)arg; r = replaycache_new(600, 300); - test_assert(r != NULL); + tt_assert(r != NULL); result = replaycache_add_and_test_internal(1200, r, test_buffer, strlen(test_buffer), NULL); - test_eq(result, 0); + tt_int_op(result,==, 0); result = replaycache_add_and_test_internal(1300, r, test_buffer, strlen(test_buffer), NULL); - test_eq(result, 1); + tt_int_op(result,==, 1); done: if (r) replaycache_free(r); @@ -117,28 +122,29 @@ test_replaycache_hit(void) } static void -test_replaycache_age(void) +test_replaycache_age(void *arg) { replaycache_t *r = NULL; int result; + (void)arg; r = replaycache_new(600, 300); - test_assert(r != NULL); + tt_assert(r != NULL); result = replaycache_add_and_test_internal(1200, r, test_buffer, strlen(test_buffer), NULL); - test_eq(result, 0); + tt_int_op(result,==, 0); result = replaycache_add_and_test_internal(1300, r, test_buffer, strlen(test_buffer), NULL); - test_eq(result, 1); + tt_int_op(result,==, 1); result = replaycache_add_and_test_internal(3000, r, test_buffer, strlen(test_buffer), NULL); - test_eq(result, 0); + tt_int_op(result,==, 0); done: if (r) replaycache_free(r); @@ -147,25 +153,26 @@ test_replaycache_age(void) } static void -test_replaycache_elapsed(void) +test_replaycache_elapsed(void *arg) { replaycache_t *r = NULL; int result; time_t elapsed; + (void)arg; r = replaycache_new(600, 300); - test_assert(r != NULL); + tt_assert(r != NULL); result = replaycache_add_and_test_internal(1200, r, test_buffer, strlen(test_buffer), NULL); - test_eq(result, 0); + tt_int_op(result,==, 0); result = replaycache_add_and_test_internal(1300, r, test_buffer, strlen(test_buffer), &elapsed); - test_eq(result, 1); - test_eq(elapsed, 100); + tt_int_op(result,==, 1); + tt_int_op(elapsed,==, 100); done: if (r) replaycache_free(r); @@ -174,28 +181,29 @@ test_replaycache_elapsed(void) } static void -test_replaycache_noexpire(void) +test_replaycache_noexpire(void *arg) { replaycache_t *r = NULL; int result; + (void)arg; r = replaycache_new(0, 0); - test_assert(r != NULL); + tt_assert(r != NULL); result = replaycache_add_and_test_internal(1200, r, test_buffer, strlen(test_buffer), NULL); - test_eq(result, 0); + tt_int_op(result,==, 0); result = replaycache_add_and_test_internal(1300, r, test_buffer, strlen(test_buffer), NULL); - test_eq(result, 1); + tt_int_op(result,==, 1); result = replaycache_add_and_test_internal(3000, r, test_buffer, strlen(test_buffer), NULL); - test_eq(result, 1); + tt_int_op(result,==, 1); done: if (r) replaycache_free(r); @@ -204,24 +212,25 @@ test_replaycache_noexpire(void) } static void -test_replaycache_scrub(void) +test_replaycache_scrub(void *arg) { replaycache_t *r = NULL; int result; + (void)arg; r = replaycache_new(600, 300); - test_assert(r != NULL); + tt_assert(r != NULL); /* Set up like in test_replaycache_hit() */ result = replaycache_add_and_test_internal(100, r, test_buffer, strlen(test_buffer), NULL); - test_eq(result, 0); + tt_int_op(result,==, 0); result = replaycache_add_and_test_internal(200, r, test_buffer, strlen(test_buffer), NULL); - test_eq(result, 1); + tt_int_op(result,==, 1); /* * Poke a few replaycache_scrub_if_needed_internal() error cases that @@ -231,12 +240,12 @@ test_replaycache_scrub(void) /* Null cache */ replaycache_scrub_if_needed_internal(300, NULL); /* Assert we're still here */ - test_assert(1); + tt_assert(1); /* Make sure we hit the aging-out case too */ replaycache_scrub_if_needed_internal(1500, r); /* Assert that we aged it */ - test_eq(digestmap_size(r->digests_seen), 0); + tt_int_op(digestmap_size(r->digests_seen),==, 0); done: if (r) replaycache_free(r); @@ -245,29 +254,30 @@ test_replaycache_scrub(void) } static void -test_replaycache_future(void) +test_replaycache_future(void *arg) { replaycache_t *r = NULL; int result; time_t elapsed = 0; + (void)arg; r = replaycache_new(600, 300); - test_assert(r != NULL); + tt_assert(r != NULL); /* Set up like in test_replaycache_hit() */ result = replaycache_add_and_test_internal(100, r, test_buffer, strlen(test_buffer), &elapsed); - test_eq(result, 0); + tt_int_op(result,==, 0); /* elapsed should still be 0, since it wasn't written */ - test_eq(elapsed, 0); + tt_int_op(elapsed,==, 0); result = replaycache_add_and_test_internal(200, r, test_buffer, strlen(test_buffer), &elapsed); - test_eq(result, 1); + tt_int_op(result,==, 1); /* elapsed should be the time since the last hit */ - test_eq(elapsed, 100); + tt_int_op(elapsed,==, 100); /* * Now let's turn the clock back to get coverage on the cache entry from the @@ -277,9 +287,9 @@ test_replaycache_future(void) replaycache_add_and_test_internal(150, r, test_buffer, strlen(test_buffer), &elapsed); /* We should still get a hit */ - test_eq(result, 1); + tt_int_op(result,==, 1); /* ...but it shouldn't let us see a negative elapsed time */ - test_eq(elapsed, 0); + tt_int_op(elapsed,==, 0); done: if (r) replaycache_free(r); @@ -288,7 +298,7 @@ test_replaycache_future(void) } static void -test_replaycache_realtime(void) +test_replaycache_realtime(void *arg) { replaycache_t *r = NULL; /* @@ -299,26 +309,27 @@ test_replaycache_realtime(void) int result; /* Test the realtime as well as *_internal() entry points */ + (void)arg; r = replaycache_new(600, 300); - test_assert(r != NULL); + tt_assert(r != NULL); /* This should miss */ result = replaycache_add_and_test(r, test_buffer, strlen(test_buffer)); - test_eq(result, 0); + tt_int_op(result,==, 0); /* This should hit */ result = replaycache_add_and_test(r, test_buffer, strlen(test_buffer)); - test_eq(result, 1); + tt_int_op(result,==, 1); /* This should hit and return a small elapsed time */ result = replaycache_add_test_and_elapsed(r, test_buffer, strlen(test_buffer), &elapsed); - test_eq(result, 1); - test_assert(elapsed >= 0); - test_assert(elapsed <= 5); + tt_int_op(result,==, 1); + tt_assert(elapsed >= 0); + tt_assert(elapsed <= 5); /* Scrub it to exercise that entry point too */ replaycache_scrub_if_needed(r); @@ -329,7 +340,7 @@ test_replaycache_realtime(void) } #define REPLAYCACHE_LEGACY(name) \ - { #name, legacy_test_helper, 0, &legacy_setup, test_replaycache_ ## name } + { #name, test_replaycache_ ## name , 0, NULL, NULL } struct testcase_t replaycache_tests[] = { REPLAYCACHE_LEGACY(alloc), diff --git a/src/test/test_routerset.c b/src/test/test_routerset.c index 0ea1ef2d89..81e4dbb1eb 100644 --- a/src/test/test_routerset.c +++ b/src/test/test_routerset.c @@ -775,10 +775,11 @@ NS(test_main)(void *arg) { routerset_t *set = routerset_new(); int contains; + uint8_t foo[20] = { 2, 3, 4 }; (void)arg; - digestmap_set(set->digests, "foo", (void *)1); - contains = routerset_contains(set, NULL, 0, NULL, "foo", 0); + digestmap_set(set->digests, (const char*)foo, (void *)1); + contains = routerset_contains(set, NULL, 0, NULL, (const char*)foo, 0); routerset_free(set); tt_int_op(contains, ==, 4); @@ -799,10 +800,12 @@ NS(test_main)(void *arg) { routerset_t *set = routerset_new(); int contains; + uint8_t bar[20] = { 9, 10, 11, 55 }; + uint8_t foo[20] = { 1, 2, 3, 4}; (void)arg; - digestmap_set(set->digests, "bar", (void *)1); - contains = routerset_contains(set, NULL, 0, NULL, "foo", 0); + digestmap_set(set->digests, (const char*)bar, (void *)1); + contains = routerset_contains(set, NULL, 0, NULL, (const char*)foo, 0); routerset_free(set); tt_int_op(contains, ==, 0); @@ -823,9 +826,10 @@ NS(test_main)(void *arg) { routerset_t *set = routerset_new(); int contains; + uint8_t bar[20] = { 9, 10, 11, 55 }; (void)arg; - digestmap_set(set->digests, "bar", (void *)1); + digestmap_set(set->digests, (const char*)bar, (void *)1); contains = routerset_contains(set, NULL, 0, NULL, NULL, 0); routerset_free(set); diff --git a/src/test/test_socks.c b/src/test/test_socks.c index 4ce61e068b..9aaa16e081 100644 --- a/src/test/test_socks.c +++ b/src/test/test_socks.c @@ -61,10 +61,10 @@ test_socks_4_unsupported_commands(void *ptr) /* SOCKS 4 Send BIND [02] to IP address 2.2.2.2:4369 */ ADD_DATA(buf, "\x04\x02\x11\x11\x02\x02\x02\x02\x00"); - test_assert(fetch_from_buf_socks(buf, socks, get_options()->TestSocks, + tt_assert(fetch_from_buf_socks(buf, socks, get_options()->TestSocks, get_options()->SafeSocks) == -1); - test_eq(4, socks->socks_version); - test_eq(0, socks->replylen); /* XXX: shouldn't tor reply? */ + tt_int_op(4,==, socks->socks_version); + tt_int_op(0,==, socks->replylen); /* XXX: shouldn't tor reply? */ done: ; @@ -76,49 +76,49 @@ test_socks_4_supported_commands(void *ptr) { SOCKS_TEST_INIT(); - test_eq(0, buf_datalen(buf)); + tt_int_op(0,==, buf_datalen(buf)); /* SOCKS 4 Send CONNECT [01] to IP address 2.2.2.2:4370 */ ADD_DATA(buf, "\x04\x01\x11\x12\x02\x02\x02\x03\x00"); - test_assert(fetch_from_buf_socks(buf, socks, get_options()->TestSocks, + tt_assert(fetch_from_buf_socks(buf, socks, get_options()->TestSocks, get_options()->SafeSocks) == 1); - test_eq(4, socks->socks_version); - test_eq(0, socks->replylen); /* XXX: shouldn't tor reply? */ - test_eq(SOCKS_COMMAND_CONNECT, socks->command); - test_streq("2.2.2.3", socks->address); - test_eq(4370, socks->port); - test_assert(socks->got_auth == 0); - test_assert(! socks->username); - - test_eq(0, buf_datalen(buf)); + tt_int_op(4,==, socks->socks_version); + tt_int_op(0,==, socks->replylen); /* XXX: shouldn't tor reply? */ + tt_int_op(SOCKS_COMMAND_CONNECT,==, socks->command); + tt_str_op("2.2.2.3",==, socks->address); + tt_int_op(4370,==, socks->port); + tt_assert(socks->got_auth == 0); + tt_assert(! socks->username); + + tt_int_op(0,==, buf_datalen(buf)); socks_request_clear(socks); /* SOCKS 4 Send CONNECT [01] to IP address 2.2.2.2:4369 with userid*/ ADD_DATA(buf, "\x04\x01\x11\x12\x02\x02\x02\x04me\x00"); - test_assert(fetch_from_buf_socks(buf, socks, get_options()->TestSocks, + tt_assert(fetch_from_buf_socks(buf, socks, get_options()->TestSocks, get_options()->SafeSocks) == 1); - test_eq(4, socks->socks_version); - test_eq(0, socks->replylen); /* XXX: shouldn't tor reply? */ - test_eq(SOCKS_COMMAND_CONNECT, socks->command); - test_streq("2.2.2.4", socks->address); - test_eq(4370, socks->port); - test_assert(socks->got_auth == 1); - test_assert(socks->username); - test_eq(2, socks->usernamelen); - test_memeq("me", socks->username, 2); - - test_eq(0, buf_datalen(buf)); + tt_int_op(4,==, socks->socks_version); + tt_int_op(0,==, socks->replylen); /* XXX: shouldn't tor reply? */ + tt_int_op(SOCKS_COMMAND_CONNECT,==, socks->command); + tt_str_op("2.2.2.4",==, socks->address); + tt_int_op(4370,==, socks->port); + tt_assert(socks->got_auth == 1); + tt_assert(socks->username); + tt_int_op(2,==, socks->usernamelen); + tt_mem_op("me",==, socks->username, 2); + + tt_int_op(0,==, buf_datalen(buf)); socks_request_clear(socks); /* SOCKS 4a Send RESOLVE [F0] request for torproject.org */ ADD_DATA(buf, "\x04\xF0\x01\x01\x00\x00\x00\x02me\x00torproject.org\x00"); - test_assert(fetch_from_buf_socks(buf, socks, get_options()->TestSocks, + tt_assert(fetch_from_buf_socks(buf, socks, get_options()->TestSocks, get_options()->SafeSocks) == 1); - test_eq(4, socks->socks_version); - test_eq(0, socks->replylen); /* XXX: shouldn't tor reply? */ - test_streq("torproject.org", socks->address); + tt_int_op(4,==, socks->socks_version); + tt_int_op(0,==, socks->replylen); /* XXX: shouldn't tor reply? */ + tt_str_op("torproject.org",==, socks->address); - test_eq(0, buf_datalen(buf)); + tt_int_op(0,==, buf_datalen(buf)); done: ; @@ -133,33 +133,43 @@ test_socks_5_unsupported_commands(void *ptr) /* SOCKS 5 Send unsupported BIND [02] command */ ADD_DATA(buf, "\x05\x02\x00\x01"); - test_eq(fetch_from_buf_socks(buf, socks, get_options()->TestSocks, - get_options()->SafeSocks), 0); - test_eq(0, buf_datalen(buf)); - test_eq(5, socks->socks_version); - test_eq(2, socks->replylen); - test_eq(5, socks->reply[0]); - test_eq(0, socks->reply[1]); + tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks, + get_options()->SafeSocks),==, 0); + tt_int_op(0,==, buf_datalen(buf)); + tt_int_op(5,==, socks->socks_version); + tt_int_op(2,==, socks->replylen); + tt_int_op(5,==, socks->reply[0]); + tt_int_op(0,==, socks->reply[1]); ADD_DATA(buf, "\x05\x02\x00\x01\x02\x02\x02\x01\x01\x01"); - test_eq(fetch_from_buf_socks(buf, socks, get_options()->TestSocks, - get_options()->SafeSocks), -1); - /* XXX: shouldn't tor reply 'command not supported' [07]? */ + tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks, + get_options()->SafeSocks),==, -1); + + tt_int_op(5,==,socks->socks_version); + tt_int_op(10,==,socks->replylen); + tt_int_op(5,==,socks->reply[0]); + tt_int_op(SOCKS5_COMMAND_NOT_SUPPORTED,==,socks->reply[1]); + tt_int_op(1,==,socks->reply[3]); buf_clear(buf); socks_request_clear(socks); /* SOCKS 5 Send unsupported UDP_ASSOCIATE [03] command */ - ADD_DATA(buf, "\x05\x03\x00\x01\x02"); - test_eq(fetch_from_buf_socks(buf, socks, get_options()->TestSocks, - get_options()->SafeSocks), 0); - test_eq(5, socks->socks_version); - test_eq(2, socks->replylen); - test_eq(5, socks->reply[0]); - test_eq(2, socks->reply[1]); + ADD_DATA(buf, "\x05\x02\x00\x01"); + tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks, + get_options()->SafeSocks),==, 0); + tt_int_op(5,==, socks->socks_version); + tt_int_op(2,==, socks->replylen); + tt_int_op(5,==, socks->reply[0]); + tt_int_op(0,==, socks->reply[1]); ADD_DATA(buf, "\x05\x03\x00\x01\x02\x02\x02\x01\x01\x01"); - test_eq(fetch_from_buf_socks(buf, socks, get_options()->TestSocks, - get_options()->SafeSocks), -1); - /* XXX: shouldn't tor reply 'command not supported' [07]? */ + tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks, + get_options()->SafeSocks),==, -1); + + tt_int_op(5,==,socks->socks_version); + tt_int_op(10,==,socks->replylen); + tt_int_op(5,==,socks->reply[0]); + tt_int_op(SOCKS5_COMMAND_NOT_SUPPORTED,==,socks->reply[1]); + tt_int_op(1,==,socks->reply[3]); done: ; @@ -173,64 +183,64 @@ test_socks_5_supported_commands(void *ptr) /* SOCKS 5 Send CONNECT [01] to IP address 2.2.2.2:4369 */ ADD_DATA(buf, "\x05\x01\x00"); - test_eq(fetch_from_buf_socks(buf, socks, get_options()->TestSocks, - get_options()->SafeSocks), 0); - test_eq(5, socks->socks_version); - test_eq(2, socks->replylen); - test_eq(5, socks->reply[0]); - test_eq(0, socks->reply[1]); + tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks, + get_options()->SafeSocks),==, 0); + tt_int_op(5,==, socks->socks_version); + tt_int_op(2,==, socks->replylen); + tt_int_op(5,==, socks->reply[0]); + tt_int_op(0,==, socks->reply[1]); ADD_DATA(buf, "\x05\x01\x00\x01\x02\x02\x02\x02\x11\x11"); - test_eq(fetch_from_buf_socks(buf, socks, get_options()->TestSocks, - get_options()->SafeSocks), 1); - test_streq("2.2.2.2", socks->address); - test_eq(4369, socks->port); + tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks, + get_options()->SafeSocks),==, 1); + tt_str_op("2.2.2.2",==, socks->address); + tt_int_op(4369,==, socks->port); - test_eq(0, buf_datalen(buf)); + tt_int_op(0,==, buf_datalen(buf)); socks_request_clear(socks); /* SOCKS 5 Send CONNECT [01] to FQDN torproject.org:4369 */ ADD_DATA(buf, "\x05\x01\x00"); ADD_DATA(buf, "\x05\x01\x00\x03\x0Etorproject.org\x11\x11"); - test_eq(fetch_from_buf_socks(buf, socks, get_options()->TestSocks, - get_options()->SafeSocks), 1); + tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks, + get_options()->SafeSocks),==, 1); - test_eq(5, socks->socks_version); - test_eq(2, socks->replylen); - test_eq(5, socks->reply[0]); - test_eq(0, socks->reply[1]); - test_streq("torproject.org", socks->address); - test_eq(4369, socks->port); + tt_int_op(5,==, socks->socks_version); + tt_int_op(2,==, socks->replylen); + tt_int_op(5,==, socks->reply[0]); + tt_int_op(0,==, socks->reply[1]); + tt_str_op("torproject.org",==, socks->address); + tt_int_op(4369,==, socks->port); - test_eq(0, buf_datalen(buf)); + tt_int_op(0,==, buf_datalen(buf)); socks_request_clear(socks); /* SOCKS 5 Send RESOLVE [F0] request for torproject.org:4369 */ ADD_DATA(buf, "\x05\x01\x00"); ADD_DATA(buf, "\x05\xF0\x00\x03\x0Etorproject.org\x01\x02"); - test_assert(fetch_from_buf_socks(buf, socks, get_options()->TestSocks, + tt_assert(fetch_from_buf_socks(buf, socks, get_options()->TestSocks, get_options()->SafeSocks) == 1); - test_eq(5, socks->socks_version); - test_eq(2, socks->replylen); - test_eq(5, socks->reply[0]); - test_eq(0, socks->reply[1]); - test_streq("torproject.org", socks->address); + tt_int_op(5,==, socks->socks_version); + tt_int_op(2,==, socks->replylen); + tt_int_op(5,==, socks->reply[0]); + tt_int_op(0,==, socks->reply[1]); + tt_str_op("torproject.org",==, socks->address); - test_eq(0, buf_datalen(buf)); + tt_int_op(0,==, buf_datalen(buf)); socks_request_clear(socks); /* SOCKS 5 Send RESOLVE_PTR [F1] for IP address 2.2.2.5 */ ADD_DATA(buf, "\x05\x01\x00"); ADD_DATA(buf, "\x05\xF1\x00\x01\x02\x02\x02\x05\x01\x03"); - test_assert(fetch_from_buf_socks(buf, socks, get_options()->TestSocks, + tt_assert(fetch_from_buf_socks(buf, socks, get_options()->TestSocks, get_options()->SafeSocks) == 1); - test_eq(5, socks->socks_version); - test_eq(2, socks->replylen); - test_eq(5, socks->reply[0]); - test_eq(0, socks->reply[1]); - test_streq("2.2.2.5", socks->address); + tt_int_op(5,==, socks->socks_version); + tt_int_op(2,==, socks->replylen); + tt_int_op(5,==, socks->reply[0]); + tt_int_op(0,==, socks->reply[1]); + tt_str_op("2.2.2.5",==, socks->address); - test_eq(0, buf_datalen(buf)); + tt_int_op(0,==, buf_datalen(buf)); done: ; @@ -244,30 +254,30 @@ test_socks_5_no_authenticate(void *ptr) /*SOCKS 5 No Authentication */ ADD_DATA(buf,"\x05\x01\x00"); - test_assert(!fetch_from_buf_socks(buf, socks, + tt_assert(!fetch_from_buf_socks(buf, socks, get_options()->TestSocks, get_options()->SafeSocks)); - test_eq(2, socks->replylen); - test_eq(5, socks->reply[0]); - test_eq(SOCKS_NO_AUTH, socks->reply[1]); + tt_int_op(2,==, socks->replylen); + tt_int_op(5,==, socks->reply[0]); + tt_int_op(SOCKS_NO_AUTH,==, socks->reply[1]); - test_eq(0, buf_datalen(buf)); + tt_int_op(0,==, buf_datalen(buf)); /*SOCKS 5 Send username/password anyway - pretend to be broken */ ADD_DATA(buf,"\x01\x02\x01\x01\x02\x01\x01"); - test_assert(!fetch_from_buf_socks(buf, socks, + tt_assert(!fetch_from_buf_socks(buf, socks, get_options()->TestSocks, get_options()->SafeSocks)); - test_eq(5, socks->socks_version); - test_eq(2, socks->replylen); - test_eq(1, socks->reply[0]); - test_eq(0, socks->reply[1]); + tt_int_op(5,==, socks->socks_version); + tt_int_op(2,==, socks->replylen); + tt_int_op(1,==, socks->reply[0]); + tt_int_op(0,==, socks->reply[1]); - test_eq(2, socks->usernamelen); - test_eq(2, socks->passwordlen); + tt_int_op(2,==, socks->usernamelen); + tt_int_op(2,==, socks->passwordlen); - test_memeq("\x01\x01", socks->username, 2); - test_memeq("\x01\x01", socks->password, 2); + tt_mem_op("\x01\x01",==, socks->username, 2); + tt_mem_op("\x01\x01",==, socks->password, 2); done: ; @@ -282,31 +292,31 @@ test_socks_5_authenticate(void *ptr) /* SOCKS 5 Negotiate username/password authentication */ ADD_DATA(buf, "\x05\x01\x02"); - test_assert(!fetch_from_buf_socks(buf, socks, + tt_assert(!fetch_from_buf_socks(buf, socks, get_options()->TestSocks, get_options()->SafeSocks)); - test_eq(2, socks->replylen); - test_eq(5, socks->reply[0]); - test_eq(SOCKS_USER_PASS, socks->reply[1]); - test_eq(5, socks->socks_version); + tt_int_op(2,==, socks->replylen); + tt_int_op(5,==, socks->reply[0]); + tt_int_op(SOCKS_USER_PASS,==, socks->reply[1]); + tt_int_op(5,==, socks->socks_version); - test_eq(0, buf_datalen(buf)); + tt_int_op(0,==, buf_datalen(buf)); /* SOCKS 5 Send username/password */ ADD_DATA(buf, "\x01\x02me\x08mypasswd"); - test_assert(!fetch_from_buf_socks(buf, socks, + tt_assert(!fetch_from_buf_socks(buf, socks, get_options()->TestSocks, get_options()->SafeSocks)); - test_eq(5, socks->socks_version); - test_eq(2, socks->replylen); - test_eq(1, socks->reply[0]); - test_eq(0, socks->reply[1]); + tt_int_op(5,==, socks->socks_version); + tt_int_op(2,==, socks->replylen); + tt_int_op(1,==, socks->reply[0]); + tt_int_op(0,==, socks->reply[1]); - test_eq(2, socks->usernamelen); - test_eq(8, socks->passwordlen); + tt_int_op(2,==, socks->usernamelen); + tt_int_op(8,==, socks->passwordlen); - test_memeq("me", socks->username, 2); - test_memeq("mypasswd", socks->password, 8); + tt_mem_op("me",==, socks->username, 2); + tt_mem_op("mypasswd",==, socks->password, 8); done: ; @@ -321,34 +331,34 @@ test_socks_5_authenticate_with_data(void *ptr) /* SOCKS 5 Negotiate username/password authentication */ ADD_DATA(buf, "\x05\x01\x02"); - test_assert(!fetch_from_buf_socks(buf, socks, + tt_assert(!fetch_from_buf_socks(buf, socks, get_options()->TestSocks, get_options()->SafeSocks)); - test_eq(2, socks->replylen); - test_eq(5, socks->reply[0]); - test_eq(SOCKS_USER_PASS, socks->reply[1]); - test_eq(5, socks->socks_version); + tt_int_op(2,==, socks->replylen); + tt_int_op(5,==, socks->reply[0]); + tt_int_op(SOCKS_USER_PASS,==, socks->reply[1]); + tt_int_op(5,==, socks->socks_version); - test_eq(0, buf_datalen(buf)); + tt_int_op(0,==, buf_datalen(buf)); /* SOCKS 5 Send username/password */ /* SOCKS 5 Send CONNECT [01] to IP address 2.2.2.2:4369 */ ADD_DATA(buf, "\x01\x02me\x03you\x05\x01\x00\x01\x02\x02\x02\x02\x11\x11"); - test_assert(fetch_from_buf_socks(buf, socks, + tt_assert(fetch_from_buf_socks(buf, socks, get_options()->TestSocks, get_options()->SafeSocks) == 1); - test_eq(5, socks->socks_version); - test_eq(2, socks->replylen); - test_eq(1, socks->reply[0]); - test_eq(0, socks->reply[1]); + tt_int_op(5,==, socks->socks_version); + tt_int_op(2,==, socks->replylen); + tt_int_op(1,==, socks->reply[0]); + tt_int_op(0,==, socks->reply[1]); - test_streq("2.2.2.2", socks->address); - test_eq(4369, socks->port); + tt_str_op("2.2.2.2",==, socks->address); + tt_int_op(4369,==, socks->port); - test_eq(2, socks->usernamelen); - test_eq(3, socks->passwordlen); - test_memeq("me", socks->username, 2); - test_memeq("you", socks->password, 3); + tt_int_op(2,==, socks->usernamelen); + tt_int_op(3,==, socks->passwordlen); + tt_mem_op("me",==, socks->username, 2); + tt_mem_op("you",==, socks->password, 3); done: ; @@ -362,13 +372,84 @@ test_socks_5_auth_before_negotiation(void *ptr) /* SOCKS 5 Send username/password */ ADD_DATA(buf, "\x01\x02me\x02me"); - test_assert(fetch_from_buf_socks(buf, socks, + tt_assert(fetch_from_buf_socks(buf, socks, get_options()->TestSocks, get_options()->SafeSocks) == -1); - test_eq(0, socks->socks_version); - test_eq(0, socks->replylen); - test_eq(0, socks->reply[0]); - test_eq(0, socks->reply[1]); + tt_int_op(0,==, socks->socks_version); + tt_int_op(0,==, socks->replylen); + tt_int_op(0,==, socks->reply[0]); + tt_int_op(0,==, socks->reply[1]); + + done: + ; +} + +/** Perform malformed SOCKS 5 commands */ +static void +test_socks_5_malformed_commands(void *ptr) +{ + SOCKS_TEST_INIT(); + + /* XXX: Stringified address length > MAX_SOCKS_ADDR_LEN will never happen */ + + /* SOCKS 5 Send CONNECT [01] to IP address 2.2.2.2:4369, with SafeSocks set */ + ADD_DATA(buf, "\x05\x01\x00"); + ADD_DATA(buf, "\x05\x01\x00\x01\x02\x02\x02\x02\x11\x11"); + tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks, 1),==, + -1); + + tt_int_op(5,==,socks->socks_version); + tt_int_op(10,==,socks->replylen); + tt_int_op(5,==,socks->reply[0]); + tt_int_op(SOCKS5_NOT_ALLOWED,==,socks->reply[1]); + tt_int_op(1,==,socks->reply[3]); + + buf_clear(buf); + socks_request_clear(socks); + + /* SOCKS 5 Send RESOLVE_PTR [F1] for FQDN torproject.org */ + ADD_DATA(buf, "\x05\x01\x00"); + ADD_DATA(buf, "\x05\xF1\x00\x03\x0Etorproject.org\x11\x11"); + tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks, + get_options()->SafeSocks),==, -1); + + tt_int_op(5,==,socks->socks_version); + tt_int_op(10,==,socks->replylen); + tt_int_op(5,==,socks->reply[0]); + tt_int_op(SOCKS5_ADDRESS_TYPE_NOT_SUPPORTED,==,socks->reply[1]); + tt_int_op(1,==,socks->reply[3]); + + buf_clear(buf); + socks_request_clear(socks); + + /* XXX: len + 1 > MAX_SOCKS_ADDR_LEN (FQDN request) will never happen */ + + /* SOCKS 5 Send CONNECT [01] to FQDN """"".com */ + ADD_DATA(buf, "\x05\x01\x00"); + ADD_DATA(buf, "\x05\x01\x00\x03\x09\"\"\"\"\".com\x11\x11"); + tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks, + get_options()->SafeSocks),==, -1); + + tt_int_op(5,==,socks->socks_version); + tt_int_op(10,==,socks->replylen); + tt_int_op(5,==,socks->reply[0]); + tt_int_op(SOCKS5_GENERAL_ERROR,==,socks->reply[1]); + tt_int_op(1,==,socks->reply[3]); + + buf_clear(buf); + socks_request_clear(socks); + + /* SOCKS 5 Send CONNECT [01] to address type 0x23 */ + ADD_DATA(buf, "\x05\x01\x00"); + ADD_DATA(buf, "\x05\x01\x00\x23\x02\x02\x02\x02\x11\x11"); + tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks, + get_options()->SafeSocks),==, -1); + + tt_int_op(5,==,socks->socks_version); + tt_int_op(10,==,socks->replylen); + tt_int_op(5,==,socks->reply[0]); + tt_int_op(SOCKS5_ADDRESS_TYPE_NOT_SUPPORTED,==,socks->reply[1]); + tt_int_op(1,==,socks->reply[3]); done: ; @@ -387,6 +468,7 @@ struct testcase_t socks_tests[] = { SOCKSENT(5_auth_before_negotiation), SOCKSENT(5_authenticate), SOCKSENT(5_authenticate_with_data), + SOCKSENT(5_malformed_commands), END_OF_TESTCASES }; diff --git a/src/test/test_util.c b/src/test/test_util.c index 1b7c936fd7..e1f77b9636 100644 --- a/src/test/test_util.c +++ b/src/test/test_util.c @@ -22,6 +22,7 @@ #include <tchar.h> #endif #include <math.h> +#include <ctype.h> /* XXXX this is a minimal wrapper to make the unit tests compile with the * changed tor_timegm interface. */ @@ -64,8 +65,8 @@ test_util_read_until_eof_impl(const char *fname, size_t file_len, else tt_int_op(sz, ==, file_len); - test_mem_op(test_str, ==, str, sz); - test_assert(str[sz] == '\0'); + tt_mem_op(test_str, ==, str, sz); + tt_int_op(str[sz], ==, '\0'); done: unlink(fifo_name); @@ -177,7 +178,7 @@ test_util_write_chunks_to_file(void *arg) str = read_file_to_str(fname, RFTS_BIN, &st); tt_assert(str != NULL); tt_u64_op((uint64_t)st.st_size, ==, data_str_len); - test_mem_op(data_str, ==, str, data_str_len); + tt_mem_op(data_str, ==, str, data_str_len); tor_free(str); // assert that the tempfile is removed (should not leave artifacts) @@ -208,14 +209,14 @@ test_util_write_chunks_to_file(void *arg) str = read_file_to_str(fname, RFTS_BIN, &st); tt_assert(str != NULL); tt_u64_op((uint64_t)st.st_size, ==, data_str_len); - test_mem_op(data_str, ==, str, data_str_len); + tt_mem_op(data_str, ==, str, data_str_len); tor_free(str); // assert the tempfile still contains the known string str = read_file_to_str(tempname, RFTS_BIN, &st); tt_assert(str != NULL); tt_u64_op((uint64_t)st.st_size, ==, temp_str_len); - test_mem_op(temp_str, ==, str, temp_str_len); + tt_mem_op(temp_str, ==, str, temp_str_len); done: unlink(fname); @@ -228,11 +229,24 @@ test_util_write_chunks_to_file(void *arg) tor_free(temp_str); } +#define _TFE(a, b, f) tt_int_op((a).f, ==, (b).f) +/** test the minimum set of struct tm fields needed for a unique epoch value + * this is also the set we use to test tor_timegm */ +#define TM_EQUAL(a, b) \ + TT_STMT_BEGIN \ + _TFE(a, b, tm_year); \ + _TFE(a, b, tm_mon ); \ + _TFE(a, b, tm_mday); \ + _TFE(a, b, tm_hour); \ + _TFE(a, b, tm_min ); \ + _TFE(a, b, tm_sec ); \ + TT_STMT_END + static void -test_util_time(void) +test_util_time(void *arg) { struct timeval start, end; - struct tm a_time; + struct tm a_time, b_time; char timestr[128]; time_t t_res; int i; @@ -240,117 +254,343 @@ test_util_time(void) /* Test tv_udiff */ + (void)arg; start.tv_sec = 5; start.tv_usec = 5000; end.tv_sec = 5; end.tv_usec = 5000; - test_eq(0L, tv_udiff(&start, &end)); + tt_int_op(0L,==, tv_udiff(&start, &end)); end.tv_usec = 7000; - test_eq(2000L, tv_udiff(&start, &end)); + tt_int_op(2000L,==, tv_udiff(&start, &end)); end.tv_sec = 6; - test_eq(1002000L, tv_udiff(&start, &end)); + tt_int_op(1002000L,==, tv_udiff(&start, &end)); end.tv_usec = 0; - test_eq(995000L, tv_udiff(&start, &end)); + tt_int_op(995000L,==, tv_udiff(&start, &end)); end.tv_sec = 4; - test_eq(-1005000L, tv_udiff(&start, &end)); + tt_int_op(-1005000L,==, tv_udiff(&start, &end)); - /* Test tor_timegm */ + /* Test tor_timegm & tor_gmtime_r */ /* The test values here are confirmed to be correct on a platform - * with a working timegm. */ + * with a working timegm & gmtime_r. */ + + /* Start with known-zero a_time and b_time. + * This avoids passing uninitialised values to TM_EQUAL in a_time. + * Zeroing may not be needed for b_time, as long as tor_gmtime_r + * never reads the existing values in the structure. + * But we really don't want intermittently failing tests. */ + memset(&a_time, 0, sizeof(struct tm)); + memset(&b_time, 0, sizeof(struct tm)); + a_time.tm_year = 2003-1900; a_time.tm_mon = 7; a_time.tm_mday = 30; a_time.tm_hour = 6; a_time.tm_min = 14; a_time.tm_sec = 55; - test_eq((time_t) 1062224095UL, tor_timegm(&a_time)); + t_res = 1062224095UL; + tt_int_op(t_res, ==, tor_timegm(&a_time)); + tor_gmtime_r(&t_res, &b_time); + TM_EQUAL(a_time, b_time); + a_time.tm_year = 2004-1900; /* Try a leap year, after feb. */ - test_eq((time_t) 1093846495UL, tor_timegm(&a_time)); + t_res = 1093846495UL; + tt_int_op(t_res, ==, tor_timegm(&a_time)); + tor_gmtime_r(&t_res, &b_time); + TM_EQUAL(a_time, b_time); + a_time.tm_mon = 1; /* Try a leap year, in feb. */ a_time.tm_mday = 10; - test_eq((time_t) 1076393695UL, tor_timegm(&a_time)); + t_res = 1076393695UL; + tt_int_op(t_res, ==, tor_timegm(&a_time)); + tor_gmtime_r(&t_res, &b_time); + TM_EQUAL(a_time, b_time); + a_time.tm_mon = 0; - a_time.tm_mday = 10; - test_eq((time_t) 1073715295UL, tor_timegm(&a_time)); + t_res = 1073715295UL; + tt_int_op(t_res, ==, tor_timegm(&a_time)); + tor_gmtime_r(&t_res, &b_time); + TM_EQUAL(a_time, b_time); + + /* Test tor_timegm out of range */ + + /* year */ + + /* Wrong year < 1970 */ + a_time.tm_year = 1969-1900; + tt_int_op((time_t) -1,==, tor_timegm(&a_time)); + + a_time.tm_year = -1-1900; + tt_int_op((time_t) -1,==, tor_timegm(&a_time)); + +#if SIZEOF_INT == 4 || SIZEOF_INT == 8 + a_time.tm_year = -1*(1 << 16); + tt_int_op((time_t) -1,==, tor_timegm(&a_time)); + + /* one of the smallest tm_year values my 64 bit system supports: + * t_res = -9223372036854775LL without clamping */ + a_time.tm_year = -292275055-1900; + tt_int_op((time_t) -1,==, tor_timegm(&a_time)); + + a_time.tm_year = INT32_MIN; + tt_int_op((time_t) -1,==, tor_timegm(&a_time)); +#endif + +#if SIZEOF_INT == 8 + a_time.tm_year = -1*(1 << 48); + tt_int_op((time_t) -1,==, tor_timegm(&a_time)); + + /* while unlikely, the system's gmtime(_r) could return + * a "correct" retrospective gregorian negative year value, + * which I'm pretty sure is: + * -1*(2^63)/60/60/24*2000/730485 + 1970 = -292277022657 + * 730485 is the number of days in two millenia, including leap days */ + a_time.tm_year = -292277022657-1900; + tt_int_op((time_t) -1,==, tor_timegm(&a_time)); + + a_time.tm_year = INT64_MIN; + tt_int_op((time_t) -1,==, tor_timegm(&a_time)); +#endif + + /* Wrong year >= INT32_MAX - 1900 */ +#if SIZEOF_INT == 4 || SIZEOF_INT == 8 + a_time.tm_year = INT32_MAX-1900; + tt_int_op((time_t) -1,==, tor_timegm(&a_time)); + + a_time.tm_year = INT32_MAX; + tt_int_op((time_t) -1,==, tor_timegm(&a_time)); +#endif + +#if SIZEOF_INT == 8 + /* one of the largest tm_year values my 64 bit system supports */ + a_time.tm_year = 292278994-1900; + tt_int_op((time_t) -1,==, tor_timegm(&a_time)); + + /* while unlikely, the system's gmtime(_r) could return + * a "correct" proleptic gregorian year value, + * which I'm pretty sure is: + * (2^63-1)/60/60/24*2000/730485 + 1970 = 292277026596 + * 730485 is the number of days in two millenia, including leap days */ + a_time.tm_year = 292277026596-1900; + tt_int_op((time_t) -1,==, tor_timegm(&a_time)); + + a_time.tm_year = INT64_MAX-1900; + tt_int_op((time_t) -1,==, tor_timegm(&a_time)); + + a_time.tm_year = INT64_MAX; + tt_int_op((time_t) -1,==, tor_timegm(&a_time)); +#endif + + /* month */ + a_time.tm_year = 2007-1900; /* restore valid year */ + a_time.tm_mon = 12; /* Wrong month, it's 0-based */ - a_time.tm_mday = 10; - test_eq((time_t) -1, tor_timegm(&a_time)); + tt_int_op((time_t) -1,==, tor_timegm(&a_time)); + a_time.tm_mon = -1; /* Wrong month */ - a_time.tm_mday = 10; - test_eq((time_t) -1, tor_timegm(&a_time)); + tt_int_op((time_t) -1,==, tor_timegm(&a_time)); + + /* day */ + a_time.tm_mon = 6; /* Try July */ + a_time.tm_mday = 32; /* Wrong day */ + tt_int_op((time_t) -1,==, tor_timegm(&a_time)); + + a_time.tm_mon = 5; /* Try June */ + a_time.tm_mday = 31; /* Wrong day */ + tt_int_op((time_t) -1,==, tor_timegm(&a_time)); + + a_time.tm_year = 2008-1900; /* Try a leap year */ + a_time.tm_mon = 1; /* in feb. */ + a_time.tm_mday = 30; /* Wrong day */ + tt_int_op((time_t) -1,==, tor_timegm(&a_time)); + + a_time.tm_year = 2011-1900; /* Try a non-leap year */ + a_time.tm_mon = 1; /* in feb. */ + a_time.tm_mday = 29; /* Wrong day */ + tt_int_op((time_t) -1,==, tor_timegm(&a_time)); + + a_time.tm_mday = 0; /* Wrong day, it's 1-based (to be different) */ + tt_int_op((time_t) -1,==, tor_timegm(&a_time)); + + /* hour */ + a_time.tm_mday = 3; /* restore valid month day */ + + a_time.tm_hour = 24; /* Wrong hour, it's 0-based */ + tt_int_op((time_t) -1,==, tor_timegm(&a_time)); + + a_time.tm_hour = -1; /* Wrong hour */ + tt_int_op((time_t) -1,==, tor_timegm(&a_time)); + + /* minute */ + a_time.tm_hour = 22; /* restore valid hour */ + + a_time.tm_min = 60; /* Wrong minute, it's 0-based */ + tt_int_op((time_t) -1,==, tor_timegm(&a_time)); + + a_time.tm_min = -1; /* Wrong minute */ + tt_int_op((time_t) -1,==, tor_timegm(&a_time)); + + /* second */ + a_time.tm_min = 37; /* restore valid minute */ + + a_time.tm_sec = 61; /* Wrong second: 0-based with leap seconds */ + tt_int_op((time_t) -1,==, tor_timegm(&a_time)); + + a_time.tm_sec = -1; /* Wrong second */ + tt_int_op((time_t) -1,==, tor_timegm(&a_time)); + + /* Test tor_gmtime_r out of range */ + + /* time_t < 0 yields a year clamped to 1 or 1970, + * depending on whether the implementation of the system gmtime(_r) + * sets struct tm (1) or not (1970) */ + t_res = -1; + tor_gmtime_r(&t_res, &b_time); + tt_assert(b_time.tm_year == (1970-1900) || + b_time.tm_year == (1969-1900)); + + if (sizeof(time_t) == 4 || sizeof(time_t) == 8) { + t_res = -1*(1 << 30); + tor_gmtime_r(&t_res, &b_time); + tt_assert(b_time.tm_year == (1970-1900) || + b_time.tm_year == (1935-1900)); + + t_res = INT32_MIN; + tor_gmtime_r(&t_res, &b_time); + tt_assert(b_time.tm_year == (1970-1900) || + b_time.tm_year == (1901-1900)); + } + + if (sizeof(time_t) == 8) { + /* one of the smallest tm_year values my 64 bit system supports: + * b_time.tm_year == (-292275055LL-1900LL) without clamping */ + t_res = -9223372036854775LL; + tor_gmtime_r(&t_res, &b_time); + tt_assert(b_time.tm_year == (1970-1900) || + b_time.tm_year == (1-1900)); + + /* while unlikely, the system's gmtime(_r) could return + * a "correct" retrospective gregorian negative year value, + * which I'm pretty sure is: + * -1*(2^63)/60/60/24*2000/730485 + 1970 = -292277022657 + * 730485 is the number of days in two millenia, including leap days + * (int64_t)b_time.tm_year == (-292277022657LL-1900LL) without clamping */ + t_res = INT64_MIN; + tor_gmtime_r(&t_res, &b_time); + tt_assert(b_time.tm_year == (1970-1900) || + b_time.tm_year == (1-1900)); + } + + /* time_t >= INT_MAX yields a year clamped to 2037 or 9999, + * depending on whether the implementation of the system gmtime(_r) + * sets struct tm (9999) or not (2037) */ + if (sizeof(time_t) == 4 || sizeof(time_t) == 8) { + t_res = 3*(1 << 29); + tor_gmtime_r(&t_res, &b_time); + tt_assert(b_time.tm_year == (2021-1900)); + + t_res = INT32_MAX; + tor_gmtime_r(&t_res, &b_time); + tt_assert(b_time.tm_year == (2037-1900) || + b_time.tm_year == (2038-1900)); + } + + if (sizeof(time_t) == 8) { + /* one of the largest tm_year values my 64 bit system supports: + * b_time.tm_year == (292278994L-1900L) without clamping */ + t_res = 9223372036854775LL; + tor_gmtime_r(&t_res, &b_time); + tt_assert(b_time.tm_year == (2037-1900) || + b_time.tm_year == (9999-1900)); + + /* while unlikely, the system's gmtime(_r) could return + * a "correct" proleptic gregorian year value, + * which I'm pretty sure is: + * (2^63-1)/60/60/24*2000/730485 + 1970 = 292277026596 + * 730485 is the number of days in two millenia, including leap days + * (int64_t)b_time.tm_year == (292277026596L-1900L) without clamping */ + t_res = INT64_MAX; + tor_gmtime_r(&t_res, &b_time); + tt_assert(b_time.tm_year == (2037-1900) || + b_time.tm_year == (9999-1900)); + } /* Test {format,parse}_rfc1123_time */ format_rfc1123_time(timestr, 0); - test_streq("Thu, 01 Jan 1970 00:00:00 GMT", timestr); + tt_str_op("Thu, 01 Jan 1970 00:00:00 GMT",==, timestr); format_rfc1123_time(timestr, (time_t)1091580502UL); - test_streq("Wed, 04 Aug 2004 00:48:22 GMT", timestr); + tt_str_op("Wed, 04 Aug 2004 00:48:22 GMT",==, timestr); t_res = 0; i = parse_rfc1123_time(timestr, &t_res); - test_eq(0,i); - test_eq(t_res, (time_t)1091580502UL); + tt_int_op(0,==, i); + tt_int_op(t_res,==, (time_t)1091580502UL); /* The timezone doesn't matter */ t_res = 0; - test_eq(0, parse_rfc1123_time("Wed, 04 Aug 2004 00:48:22 ZUL", &t_res)); - test_eq(t_res, (time_t)1091580502UL); - test_eq(-1, parse_rfc1123_time("Wed, zz Aug 2004 99-99x99 GMT", &t_res)); - test_eq(-1, parse_rfc1123_time("Wed, 32 Mar 2011 00:00:00 GMT", &t_res)); - test_eq(-1, parse_rfc1123_time("Wed, 30 Mar 2011 24:00:00 GMT", &t_res)); - test_eq(-1, parse_rfc1123_time("Wed, 30 Mar 2011 23:60:00 GMT", &t_res)); - test_eq(-1, parse_rfc1123_time("Wed, 30 Mar 2011 23:59:62 GMT", &t_res)); - test_eq(-1, parse_rfc1123_time("Wed, 30 Mar 1969 23:59:59 GMT", &t_res)); - test_eq(-1, parse_rfc1123_time("Wed, 30 Ene 2011 23:59:59 GMT", &t_res)); - test_eq(-1, parse_rfc1123_time("Wed, 30 Mar 2011 23:59:59 GM", &t_res)); - -#if 0 - /* This fails, I imagine it's important and should be fixed? */ - test_eq(-1, parse_rfc1123_time("Wed, 29 Feb 2011 16:00:00 GMT", &t_res)); - /* Why is this string valid (ie. the test fails because it doesn't - return -1)? */ - test_eq(-1, parse_rfc1123_time("Wed, 30 Mar 2011 23:59:61 GMT", &t_res)); -#endif + tt_int_op(0,==, parse_rfc1123_time("Wed, 04 Aug 2004 00:48:22 ZUL", &t_res)); + tt_int_op(t_res,==, (time_t)1091580502UL); + tt_int_op(-1,==, + parse_rfc1123_time("Wed, zz Aug 2004 99-99x99 GMT", &t_res)); + tt_int_op(-1,==, + parse_rfc1123_time("Wed, 32 Mar 2011 00:00:00 GMT", &t_res)); + tt_int_op(-1,==, + parse_rfc1123_time("Wed, 30 Mar 2011 24:00:00 GMT", &t_res)); + tt_int_op(-1,==, + parse_rfc1123_time("Wed, 30 Mar 2011 23:60:00 GMT", &t_res)); + tt_int_op(-1,==, + parse_rfc1123_time("Wed, 30 Mar 2011 23:59:62 GMT", &t_res)); + tt_int_op(-1,==, + parse_rfc1123_time("Wed, 30 Mar 1969 23:59:59 GMT", &t_res)); + tt_int_op(-1,==, + parse_rfc1123_time("Wed, 30 Ene 2011 23:59:59 GMT", &t_res)); + tt_int_op(-1,==, + parse_rfc1123_time("Wed, 30 Mar 2011 23:59:59 GM", &t_res)); + + tt_int_op(-1,==, + parse_rfc1123_time("Wed, 29 Feb 2011 16:00:00 GMT", &t_res)); + tt_int_op(-1,==, + parse_rfc1123_time("Wed, 30 Mar 2011 23:59:61 GMT", &t_res)); /* Test parse_iso_time */ t_res = 0; i = parse_iso_time("", &t_res); - test_eq(-1, i); + tt_int_op(-1,==, i); t_res = 0; i = parse_iso_time("2004-08-32 00:48:22", &t_res); - test_eq(-1, i); + tt_int_op(-1,==, i); t_res = 0; i = parse_iso_time("1969-08-03 00:48:22", &t_res); - test_eq(-1, i); + tt_int_op(-1,==, i); t_res = 0; i = parse_iso_time("2004-08-04 00:48:22", &t_res); - test_eq(0,i); - test_eq(t_res, (time_t)1091580502UL); + tt_int_op(0,==, i); + tt_int_op(t_res,==, (time_t)1091580502UL); t_res = 0; i = parse_iso_time("2004-8-4 0:48:22", &t_res); - test_eq(0, i); - test_eq(t_res, (time_t)1091580502UL); - test_eq(-1, parse_iso_time("2004-08-zz 99-99x99 GMT", &t_res)); - test_eq(-1, parse_iso_time("2011-03-32 00:00:00 GMT", &t_res)); - test_eq(-1, parse_iso_time("2011-03-30 24:00:00 GMT", &t_res)); - test_eq(-1, parse_iso_time("2011-03-30 23:60:00 GMT", &t_res)); - test_eq(-1, parse_iso_time("2011-03-30 23:59:62 GMT", &t_res)); - test_eq(-1, parse_iso_time("1969-03-30 23:59:59 GMT", &t_res)); - test_eq(-1, parse_iso_time("2011-00-30 23:59:59 GMT", &t_res)); - test_eq(-1, parse_iso_time("2147483647-08-29 14:00:00", &t_res)); - test_eq(-1, parse_iso_time("2011-03-30 23:59", &t_res)); + tt_int_op(0,==, i); + tt_int_op(t_res,==, (time_t)1091580502UL); + tt_int_op(-1,==, parse_iso_time("2004-08-zz 99-99x99 GMT", &t_res)); + tt_int_op(-1,==, parse_iso_time("2011-03-32 00:00:00 GMT", &t_res)); + tt_int_op(-1,==, parse_iso_time("2011-03-30 24:00:00 GMT", &t_res)); + tt_int_op(-1,==, parse_iso_time("2011-03-30 23:60:00 GMT", &t_res)); + tt_int_op(-1,==, parse_iso_time("2011-03-30 23:59:62 GMT", &t_res)); + tt_int_op(-1,==, parse_iso_time("1969-03-30 23:59:59 GMT", &t_res)); + tt_int_op(-1,==, parse_iso_time("2011-00-30 23:59:59 GMT", &t_res)); + tt_int_op(-1,==, parse_iso_time("2147483647-08-29 14:00:00", &t_res)); + tt_int_op(-1,==, parse_iso_time("2011-03-30 23:59", &t_res)); /* Test tor_gettimeofday */ @@ -370,7 +610,7 @@ test_util_time(void) tv.tv_sec = (time_t)1326296338; tv.tv_usec = 3060; format_iso_time(timestr, (time_t)tv.tv_sec); - test_streq("2012-01-11 15:38:58", timestr); + tt_str_op("2012-01-11 15:38:58",==, timestr); /* The output of format_local_iso_time will vary by timezone, and setting our timezone for testing purposes would be a nontrivial flaky pain. Skip this test for now. @@ -378,11 +618,11 @@ test_util_time(void) test_streq("2012-01-11 10:38:58", timestr); */ format_iso_time_nospace(timestr, (time_t)tv.tv_sec); - test_streq("2012-01-11T15:38:58", timestr); - test_eq(strlen(timestr), ISO_TIME_LEN); + tt_str_op("2012-01-11T15:38:58",==, timestr); + tt_int_op(strlen(timestr),==, ISO_TIME_LEN); format_iso_time_nospace_usec(timestr, &tv); - test_streq("2012-01-11T15:38:58.003060", timestr); - test_eq(strlen(timestr), ISO_TIME_USEC_LEN); + tt_str_op("2012-01-11T15:38:58.003060",==, timestr); + tt_int_op(strlen(timestr),==, ISO_TIME_USEC_LEN); done: ; @@ -403,55 +643,66 @@ test_util_parse_http_time(void *arg) /* Test parse_http_time */ - test_eq(-1, parse_http_time("", &a_time)); - test_eq(-1, parse_http_time("Sunday, 32 Aug 2004 00:48:22 GMT", &a_time)); - test_eq(-1, parse_http_time("Sunday, 3 Aug 1869 00:48:22 GMT", &a_time)); - test_eq(-1, parse_http_time("Sunday, 32-Aug-94 00:48:22 GMT", &a_time)); - test_eq(-1, parse_http_time("Sunday, 3-Ago-04 00:48:22", &a_time)); - test_eq(-1, parse_http_time("Sunday, August the third", &a_time)); - test_eq(-1, parse_http_time("Wednesday,,04 Aug 1994 00:48:22 GMT", &a_time)); - - test_eq(0, parse_http_time("Wednesday, 04 Aug 1994 00:48:22 GMT", &a_time)); - test_eq((time_t)775961302UL, tor_timegm(&a_time)); + tt_int_op(-1,==, + parse_http_time("", &a_time)); + tt_int_op(-1,==, + parse_http_time("Sunday, 32 Aug 2004 00:48:22 GMT", &a_time)); + tt_int_op(-1,==, + parse_http_time("Sunday, 3 Aug 1869 00:48:22 GMT", &a_time)); + tt_int_op(-1,==, + parse_http_time("Sunday, 32-Aug-94 00:48:22 GMT", &a_time)); + tt_int_op(-1,==, + parse_http_time("Sunday, 3-Ago-04 00:48:22", &a_time)); + tt_int_op(-1,==, + parse_http_time("Sunday, August the third", &a_time)); + tt_int_op(-1,==, + parse_http_time("Wednesday,,04 Aug 1994 00:48:22 GMT", &a_time)); + + tt_int_op(0,==, + parse_http_time("Wednesday, 04 Aug 1994 00:48:22 GMT", &a_time)); + tt_int_op((time_t)775961302UL,==, tor_timegm(&a_time)); T("1994-08-04 00:48:22"); - test_eq(0, parse_http_time("Wednesday, 4 Aug 1994 0:48:22 GMT", &a_time)); - test_eq((time_t)775961302UL, tor_timegm(&a_time)); + tt_int_op(0,==, + parse_http_time("Wednesday, 4 Aug 1994 0:48:22 GMT", &a_time)); + tt_int_op((time_t)775961302UL,==, tor_timegm(&a_time)); T("1994-08-04 00:48:22"); - test_eq(0, parse_http_time("Miercoles, 4 Aug 1994 0:48:22 GMT", &a_time)); - test_eq((time_t)775961302UL, tor_timegm(&a_time)); + tt_int_op(0,==, + parse_http_time("Miercoles, 4 Aug 1994 0:48:22 GMT", &a_time)); + tt_int_op((time_t)775961302UL,==, tor_timegm(&a_time)); T("1994-08-04 00:48:22"); - test_eq(0, parse_http_time("Wednesday, 04-Aug-94 00:48:22 GMT", &a_time)); - test_eq((time_t)775961302UL, tor_timegm(&a_time)); + tt_int_op(0,==, + parse_http_time("Wednesday, 04-Aug-94 00:48:22 GMT", &a_time)); + tt_int_op((time_t)775961302UL,==, tor_timegm(&a_time)); T("1994-08-04 00:48:22"); - test_eq(0, parse_http_time("Wednesday, 4-Aug-94 0:48:22 GMT", &a_time)); - test_eq((time_t)775961302UL, tor_timegm(&a_time)); + tt_int_op(0,==, parse_http_time("Wednesday, 4-Aug-94 0:48:22 GMT", &a_time)); + tt_int_op((time_t)775961302UL,==, tor_timegm(&a_time)); T("1994-08-04 00:48:22"); - test_eq(0, parse_http_time("Miercoles, 4-Aug-94 0:48:22 GMT", &a_time)); - test_eq((time_t)775961302UL, tor_timegm(&a_time)); + tt_int_op(0,==, parse_http_time("Miercoles, 4-Aug-94 0:48:22 GMT", &a_time)); + tt_int_op((time_t)775961302UL,==, tor_timegm(&a_time)); T("1994-08-04 00:48:22"); - test_eq(0, parse_http_time("Wed Aug 04 00:48:22 1994", &a_time)); - test_eq((time_t)775961302UL, tor_timegm(&a_time)); + tt_int_op(0,==, parse_http_time("Wed Aug 04 00:48:22 1994", &a_time)); + tt_int_op((time_t)775961302UL,==, tor_timegm(&a_time)); T("1994-08-04 00:48:22"); - test_eq(0, parse_http_time("Wed Aug 4 0:48:22 1994", &a_time)); - test_eq((time_t)775961302UL, tor_timegm(&a_time)); + tt_int_op(0,==, parse_http_time("Wed Aug 4 0:48:22 1994", &a_time)); + tt_int_op((time_t)775961302UL,==, tor_timegm(&a_time)); T("1994-08-04 00:48:22"); - test_eq(0, parse_http_time("Mie Aug 4 0:48:22 1994", &a_time)); - test_eq((time_t)775961302UL, tor_timegm(&a_time)); + tt_int_op(0,==, parse_http_time("Mie Aug 4 0:48:22 1994", &a_time)); + tt_int_op((time_t)775961302UL,==, tor_timegm(&a_time)); T("1994-08-04 00:48:22"); - test_eq(0, parse_http_time("Sun, 1 Jan 2012 00:00:00 GMT", &a_time)); - test_eq((time_t)1325376000UL, tor_timegm(&a_time)); + tt_int_op(0,==, parse_http_time("Sun, 1 Jan 2012 00:00:00 GMT", &a_time)); + tt_int_op((time_t)1325376000UL,==, tor_timegm(&a_time)); T("2012-01-01 00:00:00"); - test_eq(0, parse_http_time("Mon, 31 Dec 2012 00:00:00 GMT", &a_time)); - test_eq((time_t)1356912000UL, tor_timegm(&a_time)); + tt_int_op(0,==, parse_http_time("Mon, 31 Dec 2012 00:00:00 GMT", &a_time)); + tt_int_op((time_t)1356912000UL,==, tor_timegm(&a_time)); T("2012-12-31 00:00:00"); - test_eq(-1, parse_http_time("2004-08-zz 99-99x99 GMT", &a_time)); - test_eq(-1, parse_http_time("2011-03-32 00:00:00 GMT", &a_time)); - test_eq(-1, parse_http_time("2011-03-30 24:00:00 GMT", &a_time)); - test_eq(-1, parse_http_time("2011-03-30 23:60:00 GMT", &a_time)); - test_eq(-1, parse_http_time("2011-03-30 23:59:62 GMT", &a_time)); - test_eq(-1, parse_http_time("1969-03-30 23:59:59 GMT", &a_time)); - test_eq(-1, parse_http_time("2011-00-30 23:59:59 GMT", &a_time)); - test_eq(-1, parse_http_time("2011-03-30 23:59", &a_time)); + tt_int_op(-1,==, parse_http_time("2004-08-zz 99-99x99 GMT", &a_time)); + tt_int_op(-1,==, parse_http_time("2011-03-32 00:00:00 GMT", &a_time)); + tt_int_op(-1,==, parse_http_time("2011-03-30 24:00:00 GMT", &a_time)); + tt_int_op(-1,==, parse_http_time("2011-03-30 23:60:00 GMT", &a_time)); + tt_int_op(-1,==, parse_http_time("2011-03-30 23:59:62 GMT", &a_time)); + tt_int_op(-1,==, parse_http_time("1969-03-30 23:59:59 GMT", &a_time)); + tt_int_op(-1,==, parse_http_time("2011-00-30 23:59:59 GMT", &a_time)); + tt_int_op(-1,==, parse_http_time("2011-03-30 23:59", &a_time)); #undef T done: @@ -459,13 +710,14 @@ test_util_parse_http_time(void *arg) } static void -test_util_config_line(void) +test_util_config_line(void *arg) { char buf[1024]; char *k=NULL, *v=NULL; const char *str; /* Test parse_config_line_from_str */ + (void)arg; strlcpy(buf, "k v\n" " key value with spaces \n" "keykey val\n" "k2\n" "k3 \n" "\n" " \n" "#comment\n" @@ -485,110 +737,110 @@ test_util_config_line(void) str = buf; str = parse_config_line_from_str(str, &k, &v); - test_streq(k, "k"); - test_streq(v, "v"); + tt_str_op(k,==, "k"); + tt_str_op(v,==, "v"); tor_free(k); tor_free(v); - test_assert(!strcmpstart(str, "key value with")); + tt_assert(!strcmpstart(str, "key value with")); str = parse_config_line_from_str(str, &k, &v); - test_streq(k, "key"); - test_streq(v, "value with spaces"); + tt_str_op(k,==, "key"); + tt_str_op(v,==, "value with spaces"); tor_free(k); tor_free(v); - test_assert(!strcmpstart(str, "keykey")); + tt_assert(!strcmpstart(str, "keykey")); str = parse_config_line_from_str(str, &k, &v); - test_streq(k, "keykey"); - test_streq(v, "val"); + tt_str_op(k,==, "keykey"); + tt_str_op(v,==, "val"); tor_free(k); tor_free(v); - test_assert(!strcmpstart(str, "k2\n")); + tt_assert(!strcmpstart(str, "k2\n")); str = parse_config_line_from_str(str, &k, &v); - test_streq(k, "k2"); - test_streq(v, ""); + tt_str_op(k,==, "k2"); + tt_str_op(v,==, ""); tor_free(k); tor_free(v); - test_assert(!strcmpstart(str, "k3 \n")); + tt_assert(!strcmpstart(str, "k3 \n")); str = parse_config_line_from_str(str, &k, &v); - test_streq(k, "k3"); - test_streq(v, ""); + tt_str_op(k,==, "k3"); + tt_str_op(v,==, ""); tor_free(k); tor_free(v); - test_assert(!strcmpstart(str, "#comment")); + tt_assert(!strcmpstart(str, "#comment")); str = parse_config_line_from_str(str, &k, &v); - test_streq(k, "k4"); - test_streq(v, ""); + tt_str_op(k,==, "k4"); + tt_str_op(v,==, ""); tor_free(k); tor_free(v); - test_assert(!strcmpstart(str, "k5#abc")); + tt_assert(!strcmpstart(str, "k5#abc")); str = parse_config_line_from_str(str, &k, &v); - test_streq(k, "k5"); - test_streq(v, ""); + tt_str_op(k,==, "k5"); + tt_str_op(v,==, ""); tor_free(k); tor_free(v); - test_assert(!strcmpstart(str, "k6")); + tt_assert(!strcmpstart(str, "k6")); str = parse_config_line_from_str(str, &k, &v); - test_streq(k, "k6"); - test_streq(v, "val"); + tt_str_op(k,==, "k6"); + tt_str_op(v,==, "val"); tor_free(k); tor_free(v); - test_assert(!strcmpstart(str, "kseven")); + tt_assert(!strcmpstart(str, "kseven")); str = parse_config_line_from_str(str, &k, &v); - test_streq(k, "kseven"); - test_streq(v, "a quoted \'string"); + tt_str_op(k,==, "kseven"); + tt_str_op(v,==, "a quoted \'string"); tor_free(k); tor_free(v); - test_assert(!strcmpstart(str, "k8 ")); + tt_assert(!strcmpstart(str, "k8 ")); str = parse_config_line_from_str(str, &k, &v); - test_streq(k, "k8"); - test_streq(v, "a quoted\n\"str\\ing\t\x01\x01\x01\""); + tt_str_op(k,==, "k8"); + tt_str_op(v,==, "a quoted\n\"str\\ing\t\x01\x01\x01\""); tor_free(k); tor_free(v); str = parse_config_line_from_str(str, &k, &v); - test_streq(k, "k9"); - test_streq(v, "a line that spans two lines."); + tt_str_op(k,==, "k9"); + tt_str_op(v,==, "a line that spans two lines."); tor_free(k); tor_free(v); str = parse_config_line_from_str(str, &k, &v); - test_streq(k, "k10"); - test_streq(v, "more than one continuation"); + tt_str_op(k,==, "k10"); + tt_str_op(v,==, "more than one continuation"); tor_free(k); tor_free(v); str = parse_config_line_from_str(str, &k, &v); - test_streq(k, "k11"); - test_streq(v, "continuation at the start"); + tt_str_op(k,==, "k11"); + tt_str_op(v,==, "continuation at the start"); tor_free(k); tor_free(v); str = parse_config_line_from_str(str, &k, &v); - test_streq(k, "k12"); - test_streq(v, "line with a embedded"); + tt_str_op(k,==, "k12"); + tt_str_op(v,==, "line with a embedded"); tor_free(k); tor_free(v); str = parse_config_line_from_str(str, &k, &v); - test_streq(k, "k13"); - test_streq(v, "continuation at the very start"); + tt_str_op(k,==, "k13"); + tt_str_op(v,==, "continuation at the very start"); tor_free(k); tor_free(v); str = parse_config_line_from_str(str, &k, &v); - test_streq(k, "k14"); - test_streq(v, "a line that has a comment and" ); + tt_str_op(k,==, "k14"); + tt_str_op(v,==, "a line that has a comment and" ); tor_free(k); tor_free(v); str = parse_config_line_from_str(str, &k, &v); - test_streq(k, "k15"); - test_streq(v, "this should be the next new line"); + tt_str_op(k,==, "k15"); + tt_str_op(v,==, "this should be the next new line"); tor_free(k); tor_free(v); str = parse_config_line_from_str(str, &k, &v); - test_streq(k, "k16"); - test_streq(v, "a line that has a comment and" ); + tt_str_op(k,==, "k16"); + tt_str_op(v,==, "a line that has a comment and" ); tor_free(k); tor_free(v); str = parse_config_line_from_str(str, &k, &v); - test_streq(k, "k17"); - test_streq(v, "this should be the next new line"); + tt_str_op(k,==, "k17"); + tt_str_op(v,==, "this should be the next new line"); tor_free(k); tor_free(v); - test_streq(str, ""); + tt_str_op(str,==, ""); done: tor_free(k); @@ -596,7 +848,7 @@ test_util_config_line(void) } static void -test_util_config_line_quotes(void) +test_util_config_line_quotes(void *arg) { char buf1[1024]; char buf2[128]; @@ -606,6 +858,7 @@ test_util_config_line_quotes(void) const char *str; /* Test parse_config_line_from_str */ + (void)arg; strlcpy(buf1, "kTrailingSpace \"quoted value\" \n" "kTrailingGarbage \"quoted value\"trailing garbage\n" , sizeof(buf1)); @@ -618,30 +871,30 @@ test_util_config_line_quotes(void) str = buf1; str = parse_config_line_from_str(str, &k, &v); - test_streq(k, "kTrailingSpace"); - test_streq(v, "quoted value"); + tt_str_op(k,==, "kTrailingSpace"); + tt_str_op(v,==, "quoted value"); tor_free(k); tor_free(v); str = parse_config_line_from_str(str, &k, &v); - test_eq_ptr(str, NULL); + tt_ptr_op(str,==, NULL); tor_free(k); tor_free(v); str = buf2; str = parse_config_line_from_str(str, &k, &v); - test_eq_ptr(str, NULL); + tt_ptr_op(str,==, NULL); tor_free(k); tor_free(v); str = buf3; str = parse_config_line_from_str(str, &k, &v); - test_eq_ptr(str, NULL); + tt_ptr_op(str,==, NULL); tor_free(k); tor_free(v); str = buf4; str = parse_config_line_from_str(str, &k, &v); - test_eq_ptr(str, NULL); + tt_ptr_op(str,==, NULL); tor_free(k); tor_free(v); done: @@ -650,13 +903,14 @@ test_util_config_line_quotes(void) } static void -test_util_config_line_comment_character(void) +test_util_config_line_comment_character(void *arg) { char buf[1024]; char *k=NULL, *v=NULL; const char *str; /* Test parse_config_line_from_str */ + (void)arg; strlcpy(buf, "k1 \"# in quotes\"\n" "k2 some value # some comment\n" "k3 /home/user/myTorNetwork#2\n" /* Testcase for #1323 */ @@ -664,16 +918,16 @@ test_util_config_line_comment_character(void) str = buf; str = parse_config_line_from_str(str, &k, &v); - test_streq(k, "k1"); - test_streq(v, "# in quotes"); + tt_str_op(k,==, "k1"); + tt_str_op(v,==, "# in quotes"); tor_free(k); tor_free(v); str = parse_config_line_from_str(str, &k, &v); - test_streq(k, "k2"); - test_streq(v, "some value"); + tt_str_op(k,==, "k2"); + tt_str_op(v,==, "some value"); tor_free(k); tor_free(v); - test_streq(str, "k3 /home/user/myTorNetwork#2\n"); + tt_str_op(str,==, "k3 /home/user/myTorNetwork#2\n"); #if 0 str = parse_config_line_from_str(str, &k, &v); @@ -690,7 +944,7 @@ test_util_config_line_comment_character(void) } static void -test_util_config_line_escaped_content(void) +test_util_config_line_escaped_content(void *arg) { char buf1[1024]; char buf2[128]; @@ -702,6 +956,7 @@ test_util_config_line_escaped_content(void) const char *str; /* Test parse_config_line_from_str */ + (void)arg; strlcpy(buf1, "HexadecimalLower \"\\x2a\"\n" "HexadecimalUpper \"\\x2A\"\n" "HexadecimalUpperX \"\\X2A\"\n" @@ -733,91 +988,91 @@ test_util_config_line_escaped_content(void) str = buf1; str = parse_config_line_from_str(str, &k, &v); - test_streq(k, "HexadecimalLower"); - test_streq(v, "*"); + tt_str_op(k,==, "HexadecimalLower"); + tt_str_op(v,==, "*"); tor_free(k); tor_free(v); str = parse_config_line_from_str(str, &k, &v); - test_streq(k, "HexadecimalUpper"); - test_streq(v, "*"); + tt_str_op(k,==, "HexadecimalUpper"); + tt_str_op(v,==, "*"); tor_free(k); tor_free(v); str = parse_config_line_from_str(str, &k, &v); - test_streq(k, "HexadecimalUpperX"); - test_streq(v, "*"); + tt_str_op(k,==, "HexadecimalUpperX"); + tt_str_op(v,==, "*"); tor_free(k); tor_free(v); str = parse_config_line_from_str(str, &k, &v); - test_streq(k, "Octal"); - test_streq(v, "*"); + tt_str_op(k,==, "Octal"); + tt_str_op(v,==, "*"); tor_free(k); tor_free(v); str = parse_config_line_from_str(str, &k, &v); - test_streq(k, "Newline"); - test_streq(v, "\n"); + tt_str_op(k,==, "Newline"); + tt_str_op(v,==, "\n"); tor_free(k); tor_free(v); str = parse_config_line_from_str(str, &k, &v); - test_streq(k, "Tab"); - test_streq(v, "\t"); + tt_str_op(k,==, "Tab"); + tt_str_op(v,==, "\t"); tor_free(k); tor_free(v); str = parse_config_line_from_str(str, &k, &v); - test_streq(k, "CarriageReturn"); - test_streq(v, "\r"); + tt_str_op(k,==, "CarriageReturn"); + tt_str_op(v,==, "\r"); tor_free(k); tor_free(v); str = parse_config_line_from_str(str, &k, &v); - test_streq(k, "DoubleQuote"); - test_streq(v, "\""); + tt_str_op(k,==, "DoubleQuote"); + tt_str_op(v,==, "\""); tor_free(k); tor_free(v); str = parse_config_line_from_str(str, &k, &v); - test_streq(k, "SimpleQuote"); - test_streq(v, "'"); + tt_str_op(k,==, "SimpleQuote"); + tt_str_op(v,==, "'"); tor_free(k); tor_free(v); str = parse_config_line_from_str(str, &k, &v); - test_streq(k, "Backslash"); - test_streq(v, "\\"); + tt_str_op(k,==, "Backslash"); + tt_str_op(v,==, "\\"); tor_free(k); tor_free(v); str = parse_config_line_from_str(str, &k, &v); - test_streq(k, "Mix"); - test_streq(v, "This is a \"star\":\t'*'\nAnd second line"); + tt_str_op(k,==, "Mix"); + tt_str_op(v,==, "This is a \"star\":\t'*'\nAnd second line"); tor_free(k); tor_free(v); - test_streq(str, ""); + tt_str_op(str,==, ""); str = buf2; str = parse_config_line_from_str(str, &k, &v); - test_eq_ptr(str, NULL); + tt_ptr_op(str,==, NULL); tor_free(k); tor_free(v); str = buf3; str = parse_config_line_from_str(str, &k, &v); - test_eq_ptr(str, NULL); + tt_ptr_op(str,==, NULL); tor_free(k); tor_free(v); str = buf4; str = parse_config_line_from_str(str, &k, &v); - test_eq_ptr(str, NULL); + tt_ptr_op(str,==, NULL); tor_free(k); tor_free(v); #if 0 str = buf5; str = parse_config_line_from_str(str, &k, &v); - test_eq_ptr(str, NULL); + tt_ptr_op(str, ==, NULL); tor_free(k); tor_free(v); #endif str = buf6; str = parse_config_line_from_str(str, &k, &v); - test_eq_ptr(str, NULL); + tt_ptr_op(str,==, NULL); tor_free(k); tor_free(v); done: @@ -827,46 +1082,47 @@ test_util_config_line_escaped_content(void) #ifndef _WIN32 static void -test_util_expand_filename(void) +test_util_expand_filename(void *arg) { char *str; + (void)arg; setenv("HOME", "/home/itv", 1); /* For "internal test value" */ str = expand_filename(""); - test_streq("", str); + tt_str_op("",==, str); tor_free(str); str = expand_filename("/normal/path"); - test_streq("/normal/path", str); + tt_str_op("/normal/path",==, str); tor_free(str); str = expand_filename("/normal/trailing/path/"); - test_streq("/normal/trailing/path/", str); + tt_str_op("/normal/trailing/path/",==, str); tor_free(str); str = expand_filename("~"); - test_streq("/home/itv/", str); + tt_str_op("/home/itv/",==, str); tor_free(str); str = expand_filename("$HOME/nodice"); - test_streq("$HOME/nodice", str); + tt_str_op("$HOME/nodice",==, str); tor_free(str); str = expand_filename("~/"); - test_streq("/home/itv/", str); + tt_str_op("/home/itv/",==, str); tor_free(str); str = expand_filename("~/foobarqux"); - test_streq("/home/itv/foobarqux", str); + tt_str_op("/home/itv/foobarqux",==, str); tor_free(str); str = expand_filename("~/../../etc/passwd"); - test_streq("/home/itv/../../etc/passwd", str); + tt_str_op("/home/itv/../../etc/passwd",==, str); tor_free(str); str = expand_filename("~/trailing/"); - test_streq("/home/itv/trailing/", str); + tt_str_op("/home/itv/trailing/",==, str); tor_free(str); /* Ideally we'd test ~anotheruser, but that's shady to test (we'd have to somehow inject/fake the get_user_homedir call) */ @@ -875,15 +1131,15 @@ test_util_expand_filename(void) setenv("HOME", "/home/itv/", 1); str = expand_filename("~"); - test_streq("/home/itv/", str); + tt_str_op("/home/itv/",==, str); tor_free(str); str = expand_filename("~/"); - test_streq("/home/itv/", str); + tt_str_op("/home/itv/",==, str); tor_free(str); str = expand_filename("~/foo"); - test_streq("/home/itv/foo", str); + tt_str_op("/home/itv/foo",==, str); tor_free(str); /* Try with empty $HOME */ @@ -891,15 +1147,15 @@ test_util_expand_filename(void) setenv("HOME", "", 1); str = expand_filename("~"); - test_streq("/", str); + tt_str_op("/",==, str); tor_free(str); str = expand_filename("~/"); - test_streq("/", str); + tt_str_op("/",==, str); tor_free(str); str = expand_filename("~/foobar"); - test_streq("/foobar", str); + tt_str_op("/foobar",==, str); tor_free(str); /* Try with $HOME unset */ @@ -907,15 +1163,15 @@ test_util_expand_filename(void) unsetenv("HOME"); str = expand_filename("~"); - test_streq("/", str); + tt_str_op("/",==, str); tor_free(str); str = expand_filename("~/"); - test_streq("/", str); + tt_str_op("/",==, str); tor_free(str); str = expand_filename("~/foobar"); - test_streq("/foobar", str); + tt_str_op("/foobar",==, str); tor_free(str); done: @@ -925,37 +1181,38 @@ test_util_expand_filename(void) /** Test tor_escape_str_for_pt_args(). */ static void -test_util_escape_string_socks(void) +test_util_escape_string_socks(void *arg) { char *escaped_string = NULL; /** Simple backslash escape. */ + (void)arg; escaped_string = tor_escape_str_for_pt_args("This is a backslash: \\",";\\"); - test_assert(escaped_string); - test_streq(escaped_string, "This is a backslash: \\\\"); + tt_assert(escaped_string); + tt_str_op(escaped_string,==, "This is a backslash: \\\\"); tor_free(escaped_string); /** Simple semicolon escape. */ escaped_string = tor_escape_str_for_pt_args("First rule:Do not use ;",";\\"); - test_assert(escaped_string); - test_streq(escaped_string, "First rule:Do not use \\;"); + tt_assert(escaped_string); + tt_str_op(escaped_string,==, "First rule:Do not use \\;"); tor_free(escaped_string); /** Empty string. */ escaped_string = tor_escape_str_for_pt_args("", ";\\"); - test_assert(escaped_string); - test_streq(escaped_string, ""); + tt_assert(escaped_string); + tt_str_op(escaped_string,==, ""); tor_free(escaped_string); /** Escape all characters. */ escaped_string = tor_escape_str_for_pt_args(";\\;\\", ";\\"); - test_assert(escaped_string); - test_streq(escaped_string, "\\;\\\\\\;\\\\"); + tt_assert(escaped_string); + tt_str_op(escaped_string,==, "\\;\\\\\\;\\\\"); tor_free(escaped_string); escaped_string = tor_escape_str_for_pt_args(";", ";\\"); - test_assert(escaped_string); - test_streq(escaped_string, "\\;"); + tt_assert(escaped_string); + tt_str_op(escaped_string,==, "\\;"); tor_free(escaped_string); done: @@ -966,288 +1223,290 @@ static void test_util_string_is_key_value(void *ptr) { (void)ptr; - test_assert(string_is_key_value(LOG_WARN, "key=value")); - test_assert(string_is_key_value(LOG_WARN, "k=v")); - test_assert(string_is_key_value(LOG_WARN, "key=")); - test_assert(string_is_key_value(LOG_WARN, "x=")); - test_assert(string_is_key_value(LOG_WARN, "xx=")); - test_assert(!string_is_key_value(LOG_WARN, "=value")); - test_assert(!string_is_key_value(LOG_WARN, "=x")); - test_assert(!string_is_key_value(LOG_WARN, "=")); + tt_assert(string_is_key_value(LOG_WARN, "key=value")); + tt_assert(string_is_key_value(LOG_WARN, "k=v")); + tt_assert(string_is_key_value(LOG_WARN, "key=")); + tt_assert(string_is_key_value(LOG_WARN, "x=")); + tt_assert(string_is_key_value(LOG_WARN, "xx=")); + tt_assert(!string_is_key_value(LOG_WARN, "=value")); + tt_assert(!string_is_key_value(LOG_WARN, "=x")); + tt_assert(!string_is_key_value(LOG_WARN, "=")); /* ??? */ - /* test_assert(!string_is_key_value(LOG_WARN, "===")); */ + /* tt_assert(!string_is_key_value(LOG_WARN, "===")); */ done: ; } /** Test basic string functionality. */ static void -test_util_strmisc(void) +test_util_strmisc(void *arg) { char buf[1024]; int i; char *cp, *cp_tmp = NULL; /* Test strl operations */ - test_eq(5, strlcpy(buf, "Hello", 0)); - test_eq(5, strlcpy(buf, "Hello", 10)); - test_streq(buf, "Hello"); - test_eq(5, strlcpy(buf, "Hello", 6)); - test_streq(buf, "Hello"); - test_eq(5, strlcpy(buf, "Hello", 5)); - test_streq(buf, "Hell"); + (void)arg; + tt_int_op(5,==, strlcpy(buf, "Hello", 0)); + tt_int_op(5,==, strlcpy(buf, "Hello", 10)); + tt_str_op(buf,==, "Hello"); + tt_int_op(5,==, strlcpy(buf, "Hello", 6)); + tt_str_op(buf,==, "Hello"); + tt_int_op(5,==, strlcpy(buf, "Hello", 5)); + tt_str_op(buf,==, "Hell"); strlcpy(buf, "Hello", sizeof(buf)); - test_eq(10, strlcat(buf, "Hello", 5)); + tt_int_op(10,==, strlcat(buf, "Hello", 5)); /* Test strstrip() */ strlcpy(buf, "Testing 1 2 3", sizeof(buf)); tor_strstrip(buf, ",!"); - test_streq(buf, "Testing 1 2 3"); + tt_str_op(buf,==, "Testing 1 2 3"); strlcpy(buf, "!Testing 1 2 3?", sizeof(buf)); tor_strstrip(buf, "!? "); - test_streq(buf, "Testing123"); + tt_str_op(buf,==, "Testing123"); strlcpy(buf, "!!!Testing 1 2 3??", sizeof(buf)); tor_strstrip(buf, "!? "); - test_streq(buf, "Testing123"); + tt_str_op(buf,==, "Testing123"); /* Test parse_long */ /* Empty/zero input */ - test_eq(0L, tor_parse_long("",10,0,100,&i,NULL)); - test_eq(0, i); - test_eq(0L, tor_parse_long("0",10,0,100,&i,NULL)); - test_eq(1, i); + tt_int_op(0L,==, tor_parse_long("",10,0,100,&i,NULL)); + tt_int_op(0,==, i); + tt_int_op(0L,==, tor_parse_long("0",10,0,100,&i,NULL)); + tt_int_op(1,==, i); /* Normal cases */ - test_eq(10L, tor_parse_long("10",10,0,100,&i,NULL)); - test_eq(1, i); - test_eq(10L, tor_parse_long("10",10,0,10,&i,NULL)); - test_eq(1, i); - test_eq(10L, tor_parse_long("10",10,10,100,&i,NULL)); - test_eq(1, i); - test_eq(-50L, tor_parse_long("-50",10,-100,100,&i,NULL)); - test_eq(1, i); - test_eq(-50L, tor_parse_long("-50",10,-100,0,&i,NULL)); - test_eq(1, i); - test_eq(-50L, tor_parse_long("-50",10,-50,0,&i,NULL)); - test_eq(1, i); + tt_int_op(10L,==, tor_parse_long("10",10,0,100,&i,NULL)); + tt_int_op(1,==, i); + tt_int_op(10L,==, tor_parse_long("10",10,0,10,&i,NULL)); + tt_int_op(1,==, i); + tt_int_op(10L,==, tor_parse_long("10",10,10,100,&i,NULL)); + tt_int_op(1,==, i); + tt_int_op(-50L,==, tor_parse_long("-50",10,-100,100,&i,NULL)); + tt_int_op(1,==, i); + tt_int_op(-50L,==, tor_parse_long("-50",10,-100,0,&i,NULL)); + tt_int_op(1,==, i); + tt_int_op(-50L,==, tor_parse_long("-50",10,-50,0,&i,NULL)); + tt_int_op(1,==, i); /* Extra garbage */ - test_eq(0L, tor_parse_long("10m",10,0,100,&i,NULL)); - test_eq(0, i); - test_eq(0L, tor_parse_long("-50 plus garbage",10,-100,100,&i,NULL)); - test_eq(0, i); - test_eq(10L, tor_parse_long("10m",10,0,100,&i,&cp)); - test_eq(1, i); - test_streq(cp, "m"); - test_eq(-50L, tor_parse_long("-50 plus garbage",10,-100,100,&i,&cp)); - test_eq(1, i); - test_streq(cp, " plus garbage"); + tt_int_op(0L,==, tor_parse_long("10m",10,0,100,&i,NULL)); + tt_int_op(0,==, i); + tt_int_op(0L,==, tor_parse_long("-50 plus garbage",10,-100,100,&i,NULL)); + tt_int_op(0,==, i); + tt_int_op(10L,==, tor_parse_long("10m",10,0,100,&i,&cp)); + tt_int_op(1,==, i); + tt_str_op(cp,==, "m"); + tt_int_op(-50L,==, tor_parse_long("-50 plus garbage",10,-100,100,&i,&cp)); + tt_int_op(1,==, i); + tt_str_op(cp,==, " plus garbage"); /* Out of bounds */ - test_eq(0L, tor_parse_long("10",10,50,100,&i,NULL)); - test_eq(0, i); - test_eq(0L, tor_parse_long("-50",10,0,100,&i,NULL)); - test_eq(0, i); + tt_int_op(0L,==, tor_parse_long("10",10,50,100,&i,NULL)); + tt_int_op(0,==, i); + tt_int_op(0L,==, tor_parse_long("-50",10,0,100,&i,NULL)); + tt_int_op(0,==, i); /* Base different than 10 */ - test_eq(2L, tor_parse_long("10",2,0,100,NULL,NULL)); - test_eq(0L, tor_parse_long("2",2,0,100,NULL,NULL)); - test_eq(0L, tor_parse_long("10",-2,0,100,NULL,NULL)); - test_eq(68284L, tor_parse_long("10abc",16,0,70000,NULL,NULL)); - test_eq(68284L, tor_parse_long("10ABC",16,0,70000,NULL,NULL)); - test_eq(0, tor_parse_long("10ABC",-1,0,70000,&i,NULL)); - test_eq(i, 0); + tt_int_op(2L,==, tor_parse_long("10",2,0,100,NULL,NULL)); + tt_int_op(0L,==, tor_parse_long("2",2,0,100,NULL,NULL)); + tt_int_op(0L,==, tor_parse_long("10",-2,0,100,NULL,NULL)); + tt_int_op(68284L,==, tor_parse_long("10abc",16,0,70000,NULL,NULL)); + tt_int_op(68284L,==, tor_parse_long("10ABC",16,0,70000,NULL,NULL)); + tt_int_op(0,==, tor_parse_long("10ABC",-1,0,70000,&i,NULL)); + tt_int_op(i,==, 0); /* Test parse_ulong */ - test_eq(0UL, tor_parse_ulong("",10,0,100,NULL,NULL)); - test_eq(0UL, tor_parse_ulong("0",10,0,100,NULL,NULL)); - test_eq(10UL, tor_parse_ulong("10",10,0,100,NULL,NULL)); - test_eq(0UL, tor_parse_ulong("10",10,50,100,NULL,NULL)); - test_eq(10UL, tor_parse_ulong("10",10,0,10,NULL,NULL)); - test_eq(10UL, tor_parse_ulong("10",10,10,100,NULL,NULL)); - test_eq(0UL, tor_parse_ulong("8",8,0,100,NULL,NULL)); - test_eq(50UL, tor_parse_ulong("50",10,50,100,NULL,NULL)); - test_eq(0UL, tor_parse_ulong("-50",10,-100,100,NULL,NULL)); - test_eq(0UL, tor_parse_ulong("50",-1,50,100,&i,NULL)); - test_eq(0, i); + tt_int_op(0UL,==, tor_parse_ulong("",10,0,100,NULL,NULL)); + tt_int_op(0UL,==, tor_parse_ulong("0",10,0,100,NULL,NULL)); + tt_int_op(10UL,==, tor_parse_ulong("10",10,0,100,NULL,NULL)); + tt_int_op(0UL,==, tor_parse_ulong("10",10,50,100,NULL,NULL)); + tt_int_op(10UL,==, tor_parse_ulong("10",10,0,10,NULL,NULL)); + tt_int_op(10UL,==, tor_parse_ulong("10",10,10,100,NULL,NULL)); + tt_int_op(0UL,==, tor_parse_ulong("8",8,0,100,NULL,NULL)); + tt_int_op(50UL,==, tor_parse_ulong("50",10,50,100,NULL,NULL)); + tt_int_op(0UL,==, tor_parse_ulong("-50",10,-100,100,NULL,NULL)); + tt_int_op(0UL,==, tor_parse_ulong("50",-1,50,100,&i,NULL)); + tt_int_op(0,==, i); /* Test parse_uint64 */ - test_assert(U64_LITERAL(10) == tor_parse_uint64("10 x",10,0,100, &i, &cp)); - test_eq(1, i); - test_streq(cp, " x"); - test_assert(U64_LITERAL(12345678901) == + tt_assert(U64_LITERAL(10) == tor_parse_uint64("10 x",10,0,100, &i, &cp)); + tt_int_op(1,==, i); + tt_str_op(cp,==, " x"); + tt_assert(U64_LITERAL(12345678901) == tor_parse_uint64("12345678901",10,0,UINT64_MAX, &i, &cp)); - test_eq(1, i); - test_streq(cp, ""); - test_assert(U64_LITERAL(0) == + tt_int_op(1,==, i); + tt_str_op(cp,==, ""); + tt_assert(U64_LITERAL(0) == tor_parse_uint64("12345678901",10,500,INT32_MAX, &i, &cp)); - test_eq(0, i); - test_assert(U64_LITERAL(0) == + tt_int_op(0,==, i); + tt_assert(U64_LITERAL(0) == tor_parse_uint64("123",-1,0,INT32_MAX, &i, &cp)); - test_eq(0, i); + tt_int_op(0,==, i); { /* Test parse_double */ double d = tor_parse_double("10", 0, UINT64_MAX,&i,NULL); - test_eq(1, i); - test_assert(DBL_TO_U64(d) == 10); + tt_int_op(1,==, i); + tt_assert(DBL_TO_U64(d) == 10); d = tor_parse_double("0", 0, UINT64_MAX,&i,NULL); - test_eq(1, i); - test_assert(DBL_TO_U64(d) == 0); + tt_int_op(1,==, i); + tt_assert(DBL_TO_U64(d) == 0); d = tor_parse_double(" ", 0, UINT64_MAX,&i,NULL); - test_eq(0, i); + tt_int_op(0,==, i); d = tor_parse_double(".0a", 0, UINT64_MAX,&i,NULL); - test_eq(0, i); + tt_int_op(0,==, i); d = tor_parse_double(".0a", 0, UINT64_MAX,&i,&cp); - test_eq(1, i); + tt_int_op(1,==, i); d = tor_parse_double("-.0", 0, UINT64_MAX,&i,NULL); - test_eq(1, i); - test_assert(DBL_TO_U64(d) == 0); + tt_int_op(1,==, i); + tt_assert(DBL_TO_U64(d) == 0); d = tor_parse_double("-10", -100.0, 100.0,&i,NULL); - test_eq(1, i); - test_eq(-10.0, d); + tt_int_op(1,==, i); + tt_int_op(-10.0,==, d); } { /* Test tor_parse_* where we overflow/underflow the underlying type. */ /* This string should overflow 64-bit ints. */ #define TOOBIG "100000000000000000000000000" - test_eq(0L, tor_parse_long(TOOBIG, 10, LONG_MIN, LONG_MAX, &i, NULL)); - test_eq(i, 0); - test_eq(0L, tor_parse_long("-"TOOBIG, 10, LONG_MIN, LONG_MAX, &i, NULL)); - test_eq(i, 0); - test_eq(0UL, tor_parse_ulong(TOOBIG, 10, 0, ULONG_MAX, &i, NULL)); - test_eq(i, 0); + tt_int_op(0L,==, tor_parse_long(TOOBIG, 10, LONG_MIN, LONG_MAX, &i, NULL)); + tt_int_op(i,==, 0); + tt_int_op(0L,==, + tor_parse_long("-"TOOBIG, 10, LONG_MIN, LONG_MAX, &i, NULL)); + tt_int_op(i,==, 0); + tt_int_op(0UL,==, tor_parse_ulong(TOOBIG, 10, 0, ULONG_MAX, &i, NULL)); + tt_int_op(i,==, 0); tt_u64_op(U64_LITERAL(0), ==, tor_parse_uint64(TOOBIG, 10, 0, UINT64_MAX, &i, NULL)); - test_eq(i, 0); + tt_int_op(i,==, 0); } /* Test snprintf */ /* Returning -1 when there's not enough room in the output buffer */ - test_eq(-1, tor_snprintf(buf, 0, "Foo")); - test_eq(-1, tor_snprintf(buf, 2, "Foo")); - test_eq(-1, tor_snprintf(buf, 3, "Foo")); - test_neq(-1, tor_snprintf(buf, 4, "Foo")); + tt_int_op(-1,==, tor_snprintf(buf, 0, "Foo")); + tt_int_op(-1,==, tor_snprintf(buf, 2, "Foo")); + tt_int_op(-1,==, tor_snprintf(buf, 3, "Foo")); + tt_int_op(-1,!=, tor_snprintf(buf, 4, "Foo")); /* Always NUL-terminate the output */ tor_snprintf(buf, 5, "abcdef"); - test_eq(0, buf[4]); + tt_int_op(0,==, buf[4]); tor_snprintf(buf, 10, "abcdef"); - test_eq(0, buf[6]); + tt_int_op(0,==, buf[6]); /* uint64 */ tor_snprintf(buf, sizeof(buf), "x!"U64_FORMAT"!x", U64_PRINTF_ARG(U64_LITERAL(12345678901))); - test_streq("x!12345678901!x", buf); + tt_str_op("x!12345678901!x",==, buf); /* Test str{,case}cmpstart */ - test_assert(strcmpstart("abcdef", "abcdef")==0); - test_assert(strcmpstart("abcdef", "abc")==0); - test_assert(strcmpstart("abcdef", "abd")<0); - test_assert(strcmpstart("abcdef", "abb")>0); - test_assert(strcmpstart("ab", "abb")<0); - test_assert(strcmpstart("ab", "")==0); - test_assert(strcmpstart("ab", "ab ")<0); - test_assert(strcasecmpstart("abcdef", "abCdEF")==0); - test_assert(strcasecmpstart("abcDeF", "abc")==0); - test_assert(strcasecmpstart("abcdef", "Abd")<0); - test_assert(strcasecmpstart("Abcdef", "abb")>0); - test_assert(strcasecmpstart("ab", "Abb")<0); - test_assert(strcasecmpstart("ab", "")==0); - test_assert(strcasecmpstart("ab", "ab ")<0); + tt_assert(strcmpstart("abcdef", "abcdef")==0); + tt_assert(strcmpstart("abcdef", "abc")==0); + tt_assert(strcmpstart("abcdef", "abd")<0); + tt_assert(strcmpstart("abcdef", "abb")>0); + tt_assert(strcmpstart("ab", "abb")<0); + tt_assert(strcmpstart("ab", "")==0); + tt_assert(strcmpstart("ab", "ab ")<0); + tt_assert(strcasecmpstart("abcdef", "abCdEF")==0); + tt_assert(strcasecmpstart("abcDeF", "abc")==0); + tt_assert(strcasecmpstart("abcdef", "Abd")<0); + tt_assert(strcasecmpstart("Abcdef", "abb")>0); + tt_assert(strcasecmpstart("ab", "Abb")<0); + tt_assert(strcasecmpstart("ab", "")==0); + tt_assert(strcasecmpstart("ab", "ab ")<0); /* Test str{,case}cmpend */ - test_assert(strcmpend("abcdef", "abcdef")==0); - test_assert(strcmpend("abcdef", "def")==0); - test_assert(strcmpend("abcdef", "deg")<0); - test_assert(strcmpend("abcdef", "dee")>0); - test_assert(strcmpend("ab", "aab")>0); - test_assert(strcasecmpend("AbcDEF", "abcdef")==0); - test_assert(strcasecmpend("abcdef", "dEF")==0); - test_assert(strcasecmpend("abcdef", "Deg")<0); - test_assert(strcasecmpend("abcDef", "dee")>0); - test_assert(strcasecmpend("AB", "abb")<0); + tt_assert(strcmpend("abcdef", "abcdef")==0); + tt_assert(strcmpend("abcdef", "def")==0); + tt_assert(strcmpend("abcdef", "deg")<0); + tt_assert(strcmpend("abcdef", "dee")>0); + tt_assert(strcmpend("ab", "aab")>0); + tt_assert(strcasecmpend("AbcDEF", "abcdef")==0); + tt_assert(strcasecmpend("abcdef", "dEF")==0); + tt_assert(strcasecmpend("abcdef", "Deg")<0); + tt_assert(strcasecmpend("abcDef", "dee")>0); + tt_assert(strcasecmpend("AB", "abb")<0); /* Test digest_is_zero */ memset(buf,0,20); buf[20] = 'x'; - test_assert(tor_digest_is_zero(buf)); + tt_assert(tor_digest_is_zero(buf)); buf[19] = 'x'; - test_assert(!tor_digest_is_zero(buf)); + tt_assert(!tor_digest_is_zero(buf)); /* Test mem_is_zero */ memset(buf,0,128); buf[128] = 'x'; - test_assert(tor_mem_is_zero(buf, 10)); - test_assert(tor_mem_is_zero(buf, 20)); - test_assert(tor_mem_is_zero(buf, 128)); - test_assert(!tor_mem_is_zero(buf, 129)); + tt_assert(tor_mem_is_zero(buf, 10)); + tt_assert(tor_mem_is_zero(buf, 20)); + tt_assert(tor_mem_is_zero(buf, 128)); + tt_assert(!tor_mem_is_zero(buf, 129)); buf[60] = (char)255; - test_assert(!tor_mem_is_zero(buf, 128)); + tt_assert(!tor_mem_is_zero(buf, 128)); buf[0] = (char)1; - test_assert(!tor_mem_is_zero(buf, 10)); + tt_assert(!tor_mem_is_zero(buf, 10)); /* Test 'escaped' */ - test_assert(NULL == escaped(NULL)); - test_streq("\"\"", escaped("")); - test_streq("\"abcd\"", escaped("abcd")); - test_streq("\"\\\\ \\n\\r\\t\\\"\\'\"", escaped("\\ \n\r\t\"'")); - test_streq("\"unnecessary \\'backslashes\\'\"", + tt_assert(NULL == escaped(NULL)); + tt_str_op("\"\"",==, escaped("")); + tt_str_op("\"abcd\"",==, escaped("abcd")); + tt_str_op("\"\\\\ \\n\\r\\t\\\"\\'\"",==, escaped("\\ \n\r\t\"'")); + tt_str_op("\"unnecessary \\'backslashes\\'\"",==, escaped("unnecessary \'backslashes\'")); /* Non-printable characters appear as octal */ - test_streq("\"z\\001abc\\277d\"", escaped("z\001abc\277d")); - test_streq("\"z\\336\\255 ;foo\"", escaped("z\xde\xad\x20;foo")); + tt_str_op("\"z\\001abc\\277d\"",==, escaped("z\001abc\277d")); + tt_str_op("\"z\\336\\255 ;foo\"",==, escaped("z\xde\xad\x20;foo")); /* Test strndup and memdup */ { const char *s = "abcdefghijklmnopqrstuvwxyz"; cp_tmp = tor_strndup(s, 30); - test_streq(cp_tmp, s); /* same string, */ - test_neq_ptr(cp_tmp, s); /* but different pointers. */ + tt_str_op(cp_tmp,==, s); /* same string, */ + tt_ptr_op(cp_tmp,!=,s); /* but different pointers. */ tor_free(cp_tmp); cp_tmp = tor_strndup(s, 5); - test_streq(cp_tmp, "abcde"); + tt_str_op(cp_tmp,==, "abcde"); tor_free(cp_tmp); s = "a\0b\0c\0d\0e\0"; cp_tmp = tor_memdup(s,10); - test_memeq(cp_tmp, s, 10); /* same ram, */ - test_neq_ptr(cp_tmp, s); /* but different pointers. */ + tt_mem_op(cp_tmp,==, s, 10); /* same ram, */ + tt_ptr_op(cp_tmp,!=,s); /* but different pointers. */ tor_free(cp_tmp); } /* Test str-foo functions */ cp_tmp = tor_strdup("abcdef"); - test_assert(tor_strisnonupper(cp_tmp)); + tt_assert(tor_strisnonupper(cp_tmp)); cp_tmp[3] = 'D'; - test_assert(!tor_strisnonupper(cp_tmp)); + tt_assert(!tor_strisnonupper(cp_tmp)); tor_strupper(cp_tmp); - test_streq(cp_tmp, "ABCDEF"); + tt_str_op(cp_tmp,==, "ABCDEF"); tor_strlower(cp_tmp); - test_streq(cp_tmp, "abcdef"); - test_assert(tor_strisnonupper(cp_tmp)); - test_assert(tor_strisprint(cp_tmp)); + tt_str_op(cp_tmp,==, "abcdef"); + tt_assert(tor_strisnonupper(cp_tmp)); + tt_assert(tor_strisprint(cp_tmp)); cp_tmp[3] = 3; - test_assert(!tor_strisprint(cp_tmp)); + tt_assert(!tor_strisprint(cp_tmp)); tor_free(cp_tmp); /* Test memmem and memstr */ { const char *haystack = "abcde"; - test_assert(!tor_memmem(haystack, 5, "ef", 2)); - test_eq_ptr(tor_memmem(haystack, 5, "cd", 2), haystack + 2); - test_eq_ptr(tor_memmem(haystack, 5, "cde", 3), haystack + 2); - test_assert(!tor_memmem(haystack, 4, "cde", 3)); + tt_assert(!tor_memmem(haystack, 5, "ef", 2)); + tt_ptr_op(tor_memmem(haystack, 5, "cd", 2),==, haystack + 2); + tt_ptr_op(tor_memmem(haystack, 5, "cde", 3),==, haystack + 2); + tt_assert(!tor_memmem(haystack, 4, "cde", 3)); haystack = "ababcad"; - test_eq_ptr(tor_memmem(haystack, 7, "abc", 3), haystack + 2); - test_eq_ptr(tor_memmem(haystack, 7, "ad", 2), haystack + 5); - test_eq_ptr(tor_memmem(haystack, 7, "cad", 3), haystack + 4); - test_assert(!tor_memmem(haystack, 7, "dadad", 5)); - test_assert(!tor_memmem(haystack, 7, "abcdefghij", 10)); + tt_ptr_op(tor_memmem(haystack, 7, "abc", 3),==, haystack + 2); + tt_ptr_op(tor_memmem(haystack, 7, "ad", 2),==, haystack + 5); + tt_ptr_op(tor_memmem(haystack, 7, "cad", 3),==, haystack + 4); + tt_assert(!tor_memmem(haystack, 7, "dadad", 5)); + tt_assert(!tor_memmem(haystack, 7, "abcdefghij", 10)); /* memstr */ - test_eq_ptr(tor_memstr(haystack, 7, "abc"), haystack + 2); - test_eq_ptr(tor_memstr(haystack, 7, "cad"), haystack + 4); - test_assert(!tor_memstr(haystack, 6, "cad")); - test_assert(!tor_memstr(haystack, 7, "cadd")); - test_assert(!tor_memstr(haystack, 7, "fe")); - test_assert(!tor_memstr(haystack, 7, "ababcade")); + tt_ptr_op(tor_memstr(haystack, 7, "abc"),==, haystack + 2); + tt_ptr_op(tor_memstr(haystack, 7, "cad"),==, haystack + 4); + tt_assert(!tor_memstr(haystack, 6, "cad")); + tt_assert(!tor_memstr(haystack, 7, "cadd")); + tt_assert(!tor_memstr(haystack, 7, "fe")); + tt_assert(!tor_memstr(haystack, 7, "ababcade")); } /* Test hex_str */ @@ -1256,19 +1515,20 @@ test_util_strmisc(void) size_t i; for (i = 0; i < sizeof(binary_data); ++i) binary_data[i] = i; - test_streq(hex_str(binary_data, 0), ""); - test_streq(hex_str(binary_data, 1), "00"); - test_streq(hex_str(binary_data, 17), "000102030405060708090A0B0C0D0E0F10"); - test_streq(hex_str(binary_data, 32), + tt_str_op(hex_str(binary_data, 0),==, ""); + tt_str_op(hex_str(binary_data, 1),==, "00"); + tt_str_op(hex_str(binary_data, 17),==, + "000102030405060708090A0B0C0D0E0F10"); + tt_str_op(hex_str(binary_data, 32),==, "000102030405060708090A0B0C0D0E0F" "101112131415161718191A1B1C1D1E1F"); - test_streq(hex_str(binary_data, 34), + tt_str_op(hex_str(binary_data, 34),==, "000102030405060708090A0B0C0D0E0F" "101112131415161718191A1B1C1D1E1F"); /* Repeat these tests for shorter strings after longer strings have been tried, to make sure we're correctly terminating strings */ - test_streq(hex_str(binary_data, 1), "00"); - test_streq(hex_str(binary_data, 0), ""); + tt_str_op(hex_str(binary_data, 1),==, "00"); + tt_str_op(hex_str(binary_data, 0),==, ""); } /* Test strcmp_opt */ @@ -1297,20 +1557,21 @@ test_util_strmisc(void) } static void -test_util_pow2(void) +test_util_pow2(void *arg) { /* Test tor_log2(). */ - test_eq(tor_log2(64), 6); - test_eq(tor_log2(65), 6); - test_eq(tor_log2(63), 5); - test_eq(tor_log2(0), 0); /* incorrect mathematically, but as specified */ - test_eq(tor_log2(1), 0); - test_eq(tor_log2(2), 1); - test_eq(tor_log2(3), 1); - test_eq(tor_log2(4), 2); - test_eq(tor_log2(5), 2); - test_eq(tor_log2(U64_LITERAL(40000000000000000)), 55); - test_eq(tor_log2(UINT64_MAX), 63); + (void)arg; + tt_int_op(tor_log2(64),==, 6); + tt_int_op(tor_log2(65),==, 6); + tt_int_op(tor_log2(63),==, 5); + tt_int_op(tor_log2(0),==, 0);/* incorrect mathematically, but as specified */ + tt_int_op(tor_log2(1),==, 0); + tt_int_op(tor_log2(2),==, 1); + tt_int_op(tor_log2(3),==, 1); + tt_int_op(tor_log2(4),==, 2); + tt_int_op(tor_log2(5),==, 2); + tt_int_op(tor_log2(U64_LITERAL(40000000000000000)),==, 55); + tt_int_op(tor_log2(UINT64_MAX),==, 63); /* Test round_to_power_of_2 */ tt_u64_op(round_to_power_of_2(120), ==, 128); @@ -1395,7 +1656,7 @@ thread_test_func_(void* _s) /** Run unit tests for threading logic. */ static void -test_util_threads(void) +test_util_threads(void *arg) { char *s1 = NULL, *s2 = NULL; int done = 0, timedout = 0; @@ -1405,6 +1666,7 @@ test_util_threads(void) tv.tv_sec=0; tv.tv_usec=100*1000; #endif + (void)arg; thread_test_mutex_ = tor_mutex_new(); thread_test_start1_ = tor_mutex_new(); thread_test_start2_ = tor_mutex_new(); @@ -1442,15 +1704,15 @@ test_util_threads(void) if (timedout) { printf("\nTimed out: %d %d", t1_count, t2_count); - test_assert(strmap_get(thread_test_strmap_, "thread 1")); - test_assert(strmap_get(thread_test_strmap_, "thread 2")); - test_assert(!timedout); + tt_assert(strmap_get(thread_test_strmap_, "thread 1")); + tt_assert(strmap_get(thread_test_strmap_, "thread 2")); + tt_assert(!timedout); } /* different thread IDs. */ - test_assert(strcmp(strmap_get(thread_test_strmap_, "thread 1"), + tt_assert(strcmp(strmap_get(thread_test_strmap_, "thread 1"), strmap_get(thread_test_strmap_, "thread 2"))); - test_assert(!strcmp(strmap_get(thread_test_strmap_, "thread 1"), + tt_assert(!strcmp(strmap_get(thread_test_strmap_, "thread 1"), strmap_get(thread_test_strmap_, "last to run")) || !strcmp(strmap_get(thread_test_strmap_, "thread 2"), strmap_get(thread_test_strmap_, "last to run"))); @@ -1470,51 +1732,52 @@ test_util_threads(void) /** Run unit tests for compression functions */ static void -test_util_gzip(void) +test_util_gzip(void *arg) { char *buf1=NULL, *buf2=NULL, *buf3=NULL, *cp1, *cp2; const char *ccp2; size_t len1, len2; tor_zlib_state_t *state = NULL; + (void)arg; buf1 = tor_strdup("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAAAAAAAAAAAAAAAAZ"); - test_assert(detect_compression_method(buf1, strlen(buf1)) == UNKNOWN_METHOD); + tt_assert(detect_compression_method(buf1, strlen(buf1)) == UNKNOWN_METHOD); if (is_gzip_supported()) { - test_assert(!tor_gzip_compress(&buf2, &len1, buf1, strlen(buf1)+1, + tt_assert(!tor_gzip_compress(&buf2, &len1, buf1, strlen(buf1)+1, GZIP_METHOD)); - test_assert(buf2); - test_assert(len1 < strlen(buf1)); - test_assert(detect_compression_method(buf2, len1) == GZIP_METHOD); + tt_assert(buf2); + tt_assert(len1 < strlen(buf1)); + tt_assert(detect_compression_method(buf2, len1) == GZIP_METHOD); - test_assert(!tor_gzip_uncompress(&buf3, &len2, buf2, len1, + tt_assert(!tor_gzip_uncompress(&buf3, &len2, buf2, len1, GZIP_METHOD, 1, LOG_INFO)); - test_assert(buf3); - test_eq(strlen(buf1) + 1, len2); - test_streq(buf1, buf3); + tt_assert(buf3); + tt_int_op(strlen(buf1) + 1,==, len2); + tt_str_op(buf1,==, buf3); tor_free(buf2); tor_free(buf3); } - test_assert(!tor_gzip_compress(&buf2, &len1, buf1, strlen(buf1)+1, + tt_assert(!tor_gzip_compress(&buf2, &len1, buf1, strlen(buf1)+1, ZLIB_METHOD)); - test_assert(buf2); - test_assert(detect_compression_method(buf2, len1) == ZLIB_METHOD); + tt_assert(buf2); + tt_assert(detect_compression_method(buf2, len1) == ZLIB_METHOD); - test_assert(!tor_gzip_uncompress(&buf3, &len2, buf2, len1, + tt_assert(!tor_gzip_uncompress(&buf3, &len2, buf2, len1, ZLIB_METHOD, 1, LOG_INFO)); - test_assert(buf3); - test_eq(strlen(buf1) + 1, len2); - test_streq(buf1, buf3); + tt_assert(buf3); + tt_int_op(strlen(buf1) + 1,==, len2); + tt_str_op(buf1,==, buf3); /* Check whether we can uncompress concatenated, compressed strings. */ tor_free(buf3); buf2 = tor_reallocarray(buf2, len1, 2); memcpy(buf2+len1, buf2, len1); - test_assert(!tor_gzip_uncompress(&buf3, &len2, buf2, len1*2, + tt_assert(!tor_gzip_uncompress(&buf3, &len2, buf2, len1*2, ZLIB_METHOD, 1, LOG_INFO)); - test_eq((strlen(buf1)+1)*2, len2); - test_memeq(buf3, + tt_int_op((strlen(buf1)+1)*2,==, len2); + tt_mem_op(buf3,==, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAAAAAAAAAAAAAAAAZ\0" "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAAAAAAAAAAAAAAAAZ\0", (strlen(buf1)+1)*2); @@ -1526,7 +1789,7 @@ test_util_gzip(void) /* Check whether we can uncompress partial strings. */ buf1 = tor_strdup("String with low redundancy that won't be compressed much."); - test_assert(!tor_gzip_compress(&buf2, &len1, buf1, strlen(buf1)+1, + tt_assert(!tor_gzip_compress(&buf2, &len1, buf1, strlen(buf1)+1, ZLIB_METHOD)); tt_assert(len1>16); /* when we allow an incomplete string, we should succeed.*/ @@ -1552,22 +1815,22 @@ test_util_gzip(void) len1 = 1024; ccp2 = "ABCDEFGHIJABCDEFGHIJ"; len2 = 21; - test_assert(tor_zlib_process(state, &cp1, &len1, &ccp2, &len2, 0) + tt_assert(tor_zlib_process(state, &cp1, &len1, &ccp2, &len2, 0) == TOR_ZLIB_OK); - test_eq(0, len2); /* Make sure we compressed it all. */ - test_assert(cp1 > buf1); + tt_int_op(0,==, len2); /* Make sure we compressed it all. */ + tt_assert(cp1 > buf1); len2 = 0; cp2 = cp1; - test_assert(tor_zlib_process(state, &cp1, &len1, &ccp2, &len2, 1) + tt_assert(tor_zlib_process(state, &cp1, &len1, &ccp2, &len2, 1) == TOR_ZLIB_DONE); - test_eq(0, len2); - test_assert(cp1 > cp2); /* Make sure we really added something. */ + tt_int_op(0,==, len2); + tt_assert(cp1 > cp2); /* Make sure we really added something. */ tt_assert(!tor_gzip_uncompress(&buf3, &len2, buf1, 1024-len1, ZLIB_METHOD, 1, LOG_WARN)); - test_streq(buf3, "ABCDEFGHIJABCDEFGHIJ"); /*Make sure it compressed right.*/ - test_eq(21, len2); + tt_str_op(buf3,==,"ABCDEFGHIJABCDEFGHIJ"); /*Make sure it compressed right.*/ + tt_int_op(21,==, len2); done: if (state) @@ -1579,7 +1842,7 @@ test_util_gzip(void) /** Run unit tests for mmap() wrapper functionality. */ static void -test_util_mmap(void) +test_util_mmap(void *arg) { char *fname1 = tor_strdup(get_fname("mapped_1")); char *fname2 = tor_strdup(get_fname("mapped_2")); @@ -1588,25 +1851,26 @@ test_util_mmap(void) char *buf = tor_malloc(17000); tor_mmap_t *mapping = NULL; + (void)arg; crypto_rand(buf, buflen); mapping = tor_mmap_file(fname1); - test_assert(! mapping); + tt_assert(! mapping); write_str_to_file(fname1, "Short file.", 1); mapping = tor_mmap_file(fname1); - test_assert(mapping); - test_eq(mapping->size, strlen("Short file.")); - test_streq(mapping->data, "Short file."); + tt_assert(mapping); + tt_int_op(mapping->size,==, strlen("Short file.")); + tt_str_op(mapping->data,==, "Short file."); #ifdef _WIN32 tt_int_op(0, ==, tor_munmap_file(mapping)); mapping = NULL; - test_assert(unlink(fname1) == 0); + tt_assert(unlink(fname1) == 0); #else /* make sure we can unlink. */ - test_assert(unlink(fname1) == 0); - test_streq(mapping->data, "Short file."); + tt_assert(unlink(fname1) == 0); + tt_str_op(mapping->data,==, "Short file."); tt_int_op(0, ==, tor_munmap_file(mapping)); mapping = NULL; #endif @@ -1614,29 +1878,29 @@ test_util_mmap(void) /* Now a zero-length file. */ write_str_to_file(fname1, "", 1); mapping = tor_mmap_file(fname1); - test_eq_ptr(mapping, NULL); - test_eq(ERANGE, errno); + tt_ptr_op(mapping,==, NULL); + tt_int_op(ERANGE,==, errno); unlink(fname1); /* Make sure that we fail to map a no-longer-existent file. */ mapping = tor_mmap_file(fname1); - test_assert(! mapping); + tt_assert(! mapping); /* Now try a big file that stretches across a few pages and isn't aligned */ write_bytes_to_file(fname2, buf, buflen, 1); mapping = tor_mmap_file(fname2); - test_assert(mapping); - test_eq(mapping->size, buflen); - test_memeq(mapping->data, buf, buflen); + tt_assert(mapping); + tt_int_op(mapping->size,==, buflen); + tt_mem_op(mapping->data,==, buf, buflen); tt_int_op(0, ==, tor_munmap_file(mapping)); mapping = NULL; /* Now try a big aligned file. */ write_bytes_to_file(fname3, buf, 16384, 1); mapping = tor_mmap_file(fname3); - test_assert(mapping); - test_eq(mapping->size, 16384); - test_memeq(mapping->data, buf, 16384); + tt_assert(mapping); + tt_int_op(mapping->size,==, 16384); + tt_mem_op(mapping->data,==, buf, 16384); tt_int_op(0, ==, tor_munmap_file(mapping)); mapping = NULL; @@ -1655,17 +1919,18 @@ test_util_mmap(void) /** Run unit tests for escaping/unescaping data for use by controllers. */ static void -test_util_control_formats(void) +test_util_control_formats(void *arg) { char *out = NULL; const char *inp = "..This is a test\r\n.of the emergency \n..system.\r\n\rZ.\r\n"; size_t sz; + (void)arg; sz = read_escaped_data(inp, strlen(inp), &out); - test_streq(out, + tt_str_op(out,==, ".This is a test\nof the emergency \n.system.\n\rZ.\n"); - test_eq(sz, strlen(out)); + tt_int_op(sz,==, strlen(out)); done: tor_free(out); @@ -1685,9 +1950,10 @@ test_util_control_formats(void) } while (0) static void -test_util_sscanf(void) +test_util_sscanf(void *arg) { unsigned u1, u2, u3; + unsigned long ulng; char s1[20], s2[10], s3[10], ch; int r; long lng1,lng2; @@ -1695,186 +1961,335 @@ test_util_sscanf(void) double d1,d2,d3,d4; /* Simple tests (malformed patterns, literal matching, ...) */ - test_eq(-1, tor_sscanf("123", "%i", &r)); /* %i is not supported */ - test_eq(-1, tor_sscanf("wrong", "%5c", s1)); /* %c cannot have a number. */ - test_eq(-1, tor_sscanf("hello", "%s", s1)); /* %s needs a number. */ - test_eq(-1, tor_sscanf("prettylongstring", "%999999s", s1)); + (void)arg; + tt_int_op(-1,==, tor_sscanf("123", "%i", &r)); /* %i is not supported */ + tt_int_op(-1,==, + tor_sscanf("wrong", "%5c", s1)); /* %c cannot have a number. */ + tt_int_op(-1,==, tor_sscanf("hello", "%s", s1)); /* %s needs a number. */ + tt_int_op(-1,==, tor_sscanf("prettylongstring", "%999999s", s1)); #if 0 /* GCC thinks these two are illegal. */ test_eq(-1, tor_sscanf("prettylongstring", "%0s", s1)); test_eq(0, tor_sscanf("prettylongstring", "%10s", NULL)); #endif /* No '%'-strings: always "success" */ - test_eq(0, tor_sscanf("hello world", "hello world")); - test_eq(0, tor_sscanf("hello world", "good bye")); + tt_int_op(0,==, tor_sscanf("hello world", "hello world")); + tt_int_op(0,==, tor_sscanf("hello world", "good bye")); /* Excess data */ - test_eq(0, tor_sscanf("hello 3", "%u", &u1)); /* have to match the start */ - test_eq(0, tor_sscanf(" 3 hello", "%u", &u1)); - test_eq(0, tor_sscanf(" 3 hello", "%2u", &u1)); /* not even in this case */ - test_eq(1, tor_sscanf("3 hello", "%u", &u1)); /* but trailing is alright */ + tt_int_op(0,==, + tor_sscanf("hello 3", "%u", &u1)); /* have to match the start */ + tt_int_op(0,==, tor_sscanf(" 3 hello", "%u", &u1)); + tt_int_op(0,==, + tor_sscanf(" 3 hello", "%2u", &u1)); /* not even in this case */ + tt_int_op(1,==, + tor_sscanf("3 hello", "%u", &u1)); /* but trailing is alright */ /* Numbers (ie. %u) */ - test_eq(0, tor_sscanf("hello world 3", "hello worlb %u", &u1)); /* d vs b */ - test_eq(1, tor_sscanf("12345", "%u", &u1)); - test_eq(12345u, u1); - test_eq(1, tor_sscanf("12346 ", "%u", &u1)); - test_eq(12346u, u1); - test_eq(0, tor_sscanf(" 12347", "%u", &u1)); - test_eq(1, tor_sscanf(" 12348", " %u", &u1)); - test_eq(12348u, u1); - test_eq(1, tor_sscanf("0", "%u", &u1)); - test_eq(0u, u1); - test_eq(1, tor_sscanf("0000", "%u", &u2)); - test_eq(0u, u2); - test_eq(0, tor_sscanf("", "%u", &u1)); /* absent number */ - test_eq(0, tor_sscanf("A", "%u", &u1)); /* bogus number */ - test_eq(0, tor_sscanf("-1", "%u", &u1)); /* negative number */ - test_eq(1, tor_sscanf("4294967295", "%u", &u1)); /* UINT32_MAX should work */ - test_eq(4294967295u, u1); - test_eq(0, tor_sscanf("4294967296", "%u", &u1)); /* But not at 32 bits */ - test_eq(1, tor_sscanf("4294967296", "%9u", &u1)); /* but parsing only 9... */ - test_eq(429496729u, u1); + tt_int_op(0,==, + tor_sscanf("hello world 3", "hello worlb %u", &u1)); /* d vs b */ + tt_int_op(1,==, tor_sscanf("12345", "%u", &u1)); + tt_int_op(12345u,==, u1); + tt_int_op(1,==, tor_sscanf("12346 ", "%u", &u1)); + tt_int_op(12346u,==, u1); + tt_int_op(0,==, tor_sscanf(" 12347", "%u", &u1)); + tt_int_op(1,==, tor_sscanf(" 12348", " %u", &u1)); + tt_int_op(12348u,==, u1); + tt_int_op(1,==, tor_sscanf("0", "%u", &u1)); + tt_int_op(0u,==, u1); + tt_int_op(1,==, tor_sscanf("0000", "%u", &u2)); + tt_int_op(0u,==, u2); + tt_int_op(0,==, tor_sscanf("", "%u", &u1)); /* absent number */ + tt_int_op(0,==, tor_sscanf("A", "%u", &u1)); /* bogus number */ + tt_int_op(0,==, tor_sscanf("-1", "%u", &u1)); /* negative number */ /* Numbers with size (eg. %2u) */ - test_eq(0, tor_sscanf("-1", "%2u", &u1)); - test_eq(2, tor_sscanf("123456", "%2u%u", &u1, &u2)); - test_eq(12u, u1); - test_eq(3456u, u2); - test_eq(1, tor_sscanf("123456", "%8u", &u1)); - test_eq(123456u, u1); - test_eq(1, tor_sscanf("123457 ", "%8u", &u1)); - test_eq(123457u, u1); - test_eq(0, tor_sscanf(" 123456", "%8u", &u1)); - test_eq(3, tor_sscanf("!12:3:456", "!%2u:%2u:%3u", &u1, &u2, &u3)); - test_eq(12u, u1); - test_eq(3u, u2); - test_eq(456u, u3); - test_eq(3, tor_sscanf("67:8:099", "%2u:%2u:%3u", &u1, &u2, &u3)); /* 0s */ - test_eq(67u, u1); - test_eq(8u, u2); - test_eq(99u, u3); + tt_int_op(0,==, tor_sscanf("-1", "%2u", &u1)); + tt_int_op(2,==, tor_sscanf("123456", "%2u%u", &u1, &u2)); + tt_int_op(12u,==, u1); + tt_int_op(3456u,==, u2); + tt_int_op(1,==, tor_sscanf("123456", "%8u", &u1)); + tt_int_op(123456u,==, u1); + tt_int_op(1,==, tor_sscanf("123457 ", "%8u", &u1)); + tt_int_op(123457u,==, u1); + tt_int_op(0,==, tor_sscanf(" 123456", "%8u", &u1)); + tt_int_op(3,==, tor_sscanf("!12:3:456", "!%2u:%2u:%3u", &u1, &u2, &u3)); + tt_int_op(12u,==, u1); + tt_int_op(3u,==, u2); + tt_int_op(456u,==, u3); + tt_int_op(3,==, + tor_sscanf("67:8:099", "%2u:%2u:%3u", &u1, &u2, &u3)); /* 0s */ + tt_int_op(67u,==, u1); + tt_int_op(8u,==, u2); + tt_int_op(99u,==, u3); /* %u does not match space.*/ - test_eq(2, tor_sscanf("12:3: 45", "%2u:%2u:%3u", &u1, &u2, &u3)); - test_eq(12u, u1); - test_eq(3u, u2); + tt_int_op(2,==, tor_sscanf("12:3: 45", "%2u:%2u:%3u", &u1, &u2, &u3)); + tt_int_op(12u,==, u1); + tt_int_op(3u,==, u2); /* %u does not match negative numbers. */ - test_eq(2, tor_sscanf("67:8:-9", "%2u:%2u:%3u", &u1, &u2, &u3)); - test_eq(67u, u1); - test_eq(8u, u2); + tt_int_op(2,==, tor_sscanf("67:8:-9", "%2u:%2u:%3u", &u1, &u2, &u3)); + tt_int_op(67u,==, u1); + tt_int_op(8u,==, u2); /* Arbitrary amounts of 0-padding are okay */ - test_eq(3, tor_sscanf("12:03:000000000000000099", "%2u:%2u:%u", + tt_int_op(3,==, tor_sscanf("12:03:000000000000000099", "%2u:%2u:%u", &u1, &u2, &u3)); - test_eq(12u, u1); - test_eq(3u, u2); - test_eq(99u, u3); + tt_int_op(12u,==, u1); + tt_int_op(3u,==, u2); + tt_int_op(99u,==, u3); /* Hex (ie. %x) */ - test_eq(3, tor_sscanf("1234 02aBcdEf ff", "%x %x %x", &u1, &u2, &u3)); - test_eq(0x1234, u1); - test_eq(0x2ABCDEF, u2); - test_eq(0xFF, u3); + tt_int_op(3,==, tor_sscanf("1234 02aBcdEf ff", "%x %x %x", &u1, &u2, &u3)); + tt_int_op(0x1234,==, u1); + tt_int_op(0x2ABCDEF,==, u2); + tt_int_op(0xFF,==, u3); /* Width works on %x */ - test_eq(3, tor_sscanf("f00dcafe444", "%4x%4x%u", &u1, &u2, &u3)); - test_eq(0xf00d, u1); - test_eq(0xcafe, u2); - test_eq(444, u3); + tt_int_op(3,==, tor_sscanf("f00dcafe444", "%4x%4x%u", &u1, &u2, &u3)); + tt_int_op(0xf00d,==, u1); + tt_int_op(0xcafe,==, u2); + tt_int_op(444,==, u3); /* Literal '%' (ie. '%%') */ - test_eq(1, tor_sscanf("99% fresh", "%3u%% fresh", &u1)); - test_eq(99, u1); - test_eq(0, tor_sscanf("99 fresh", "%% %3u %s", &u1, s1)); - test_eq(1, tor_sscanf("99 fresh", "%3u%% %s", &u1, s1)); - test_eq(2, tor_sscanf("99 fresh", "%3u %5s %%", &u1, s1)); - test_eq(99, u1); - test_streq(s1, "fresh"); - test_eq(1, tor_sscanf("% boo", "%% %3s", s1)); - test_streq("boo", s1); + tt_int_op(1,==, tor_sscanf("99% fresh", "%3u%% fresh", &u1)); + tt_int_op(99,==, u1); + tt_int_op(0,==, tor_sscanf("99 fresh", "%% %3u %s", &u1, s1)); + tt_int_op(1,==, tor_sscanf("99 fresh", "%3u%% %s", &u1, s1)); + tt_int_op(2,==, tor_sscanf("99 fresh", "%3u %5s %%", &u1, s1)); + tt_int_op(99,==, u1); + tt_str_op(s1,==, "fresh"); + tt_int_op(1,==, tor_sscanf("% boo", "%% %3s", s1)); + tt_str_op("boo",==, s1); /* Strings (ie. %s) */ - test_eq(2, tor_sscanf("hello", "%3s%7s", s1, s2)); - test_streq(s1, "hel"); - test_streq(s2, "lo"); - test_eq(2, tor_sscanf("WD40", "%2s%u", s3, &u1)); /* %s%u */ - test_streq(s3, "WD"); - test_eq(40, u1); - test_eq(2, tor_sscanf("WD40", "%3s%u", s3, &u1)); /* %s%u */ - test_streq(s3, "WD4"); - test_eq(0, u1); - test_eq(2, tor_sscanf("76trombones", "%6u%9s", &u1, s1)); /* %u%s */ - test_eq(76, u1); - test_streq(s1, "trombones"); - test_eq(1, tor_sscanf("prettylongstring", "%999s", s1)); - test_streq(s1, "prettylongstring"); + tt_int_op(2,==, tor_sscanf("hello", "%3s%7s", s1, s2)); + tt_str_op(s1,==, "hel"); + tt_str_op(s2,==, "lo"); + tt_int_op(2,==, tor_sscanf("WD40", "%2s%u", s3, &u1)); /* %s%u */ + tt_str_op(s3,==, "WD"); + tt_int_op(40,==, u1); + tt_int_op(2,==, tor_sscanf("WD40", "%3s%u", s3, &u1)); /* %s%u */ + tt_str_op(s3,==, "WD4"); + tt_int_op(0,==, u1); + tt_int_op(2,==, tor_sscanf("76trombones", "%6u%9s", &u1, s1)); /* %u%s */ + tt_int_op(76,==, u1); + tt_str_op(s1,==, "trombones"); + tt_int_op(1,==, tor_sscanf("prettylongstring", "%999s", s1)); + tt_str_op(s1,==, "prettylongstring"); /* %s doesn't eat spaces */ - test_eq(2, tor_sscanf("hello world", "%9s %9s", s1, s2)); - test_streq(s1, "hello"); - test_streq(s2, "world"); - test_eq(2, tor_sscanf("bye world?", "%9s %9s", s1, s2)); - test_streq(s1, "bye"); - test_streq(s2, ""); - test_eq(3, tor_sscanf("hi", "%9s%9s%3s", s1, s2, s3)); /* %s can be empty. */ - test_streq(s1, "hi"); - test_streq(s2, ""); - test_streq(s3, ""); - - test_eq(3, tor_sscanf("1.2.3", "%u.%u.%u%c", &u1, &u2, &u3, &ch)); - test_eq(4, tor_sscanf("1.2.3 foobar", "%u.%u.%u%c", &u1, &u2, &u3, &ch)); - test_eq(' ', ch); + tt_int_op(2,==, tor_sscanf("hello world", "%9s %9s", s1, s2)); + tt_str_op(s1,==, "hello"); + tt_str_op(s2,==, "world"); + tt_int_op(2,==, tor_sscanf("bye world?", "%9s %9s", s1, s2)); + tt_str_op(s1,==, "bye"); + tt_str_op(s2,==, ""); + tt_int_op(3,==, + tor_sscanf("hi", "%9s%9s%3s", s1, s2, s3)); /* %s can be empty. */ + tt_str_op(s1,==, "hi"); + tt_str_op(s2,==, ""); + tt_str_op(s3,==, ""); + + tt_int_op(3,==, tor_sscanf("1.2.3", "%u.%u.%u%c", &u1, &u2, &u3, &ch)); + tt_int_op(4,==, + tor_sscanf("1.2.3 foobar", "%u.%u.%u%c", &u1, &u2, &u3, &ch)); + tt_int_op(' ',==, ch); r = tor_sscanf("12345 -67890 -1", "%d %ld %d", &int1, &lng1, &int2); - test_eq(r,3); - test_eq(int1, 12345); - test_eq(lng1, -67890); - test_eq(int2, -1); + tt_int_op(r,==, 3); + tt_int_op(int1,==, 12345); + tt_int_op(lng1,==, -67890); + tt_int_op(int2,==, -1); #if SIZEOF_INT == 4 + /* %u */ + /* UINT32_MAX should work */ + tt_int_op(1,==, tor_sscanf("4294967295", "%u", &u1)); + tt_int_op(4294967295U,==, u1); + + /* But UINT32_MAX + 1 shouldn't work */ + tt_int_op(0,==, tor_sscanf("4294967296", "%u", &u1)); + /* but parsing only 9... */ + tt_int_op(1,==, tor_sscanf("4294967296", "%9u", &u1)); + tt_int_op(429496729U,==, u1); + + /* %x */ + /* UINT32_MAX should work */ + tt_int_op(1,==, tor_sscanf("FFFFFFFF", "%x", &u1)); + tt_int_op(0xFFFFFFFF,==, u1); + + /* But UINT32_MAX + 1 shouldn't work */ + tt_int_op(0,==, tor_sscanf("100000000", "%x", &u1)); + + /* %d */ + /* INT32_MIN and INT32_MAX should work */ r = tor_sscanf("-2147483648. 2147483647.", "%d. %d.", &int1, &int2); - test_eq(r,2); - test_eq(int1, -2147483647-1); - test_eq(int2, 2147483647); + tt_int_op(r,==, 2); + tt_int_op(int1,==, -2147483647 - 1); + tt_int_op(int2,==, 2147483647); + + /* But INT32_MIN - 1 and INT32_MAX + 1 shouldn't work */ + r = tor_sscanf("-2147483649.", "%d.", &int1); + tt_int_op(r,==, 0); - r = tor_sscanf("-2147483679.", "%d.", &int1); - test_eq(r,0); + r = tor_sscanf("2147483648.", "%d.", &int1); + tt_int_op(r,==, 0); - r = tor_sscanf("2147483678.", "%d.", &int1); - test_eq(r,0); + /* and the first failure stops further processing */ + r = tor_sscanf("-2147483648. 2147483648.", + "%d. %d.", &int1, &int2); + tt_int_op(r,==, 1); + + r = tor_sscanf("-2147483649. 2147483647.", + "%d. %d.", &int1, &int2); + tt_int_op(r,==, 0); + + r = tor_sscanf("2147483648. -2147483649.", + "%d. %d.", &int1, &int2); + tt_int_op(r,==, 0); #elif SIZEOF_INT == 8 + /* %u */ + /* UINT64_MAX should work */ + tt_int_op(1,==, tor_sscanf("18446744073709551615", "%u", &u1)); + tt_int_op(18446744073709551615U,==, u1); + + /* But UINT64_MAX + 1 shouldn't work */ + tt_int_op(0,==, tor_sscanf("18446744073709551616", "%u", &u1)); + /* but parsing only 19... */ + tt_int_op(1,==, tor_sscanf("18446744073709551616", "%19u", &u1)); + tt_int_op(1844674407370955161U,==, u1); + + /* %x */ + /* UINT64_MAX should work */ + tt_int_op(1,==, tor_sscanf("FFFFFFFFFFFFFFFF", "%x", &u1)); + tt_int_op(0xFFFFFFFFFFFFFFFF,==, u1); + + /* But UINT64_MAX + 1 shouldn't work */ + tt_int_op(0,==, tor_sscanf("10000000000000000", "%x", &u1)); + + /* %d */ + /* INT64_MIN and INT64_MAX should work */ r = tor_sscanf("-9223372036854775808. 9223372036854775807.", "%d. %d.", &int1, &int2); - test_eq(r,2); - test_eq(int1, -9223372036854775807-1); - test_eq(int2, 9223372036854775807); + tt_int_op(r,==, 2); + tt_int_op(int1,==, -9223372036854775807 - 1); + tt_int_op(int2,==, 9223372036854775807); + /* But INT64_MIN - 1 and INT64_MAX + 1 shouldn't work */ r = tor_sscanf("-9223372036854775809.", "%d.", &int1); - test_eq(r,0); + tt_int_op(r,==, 0); r = tor_sscanf("9223372036854775808.", "%d.", &int1); - test_eq(r,0); + tt_int_op(r,==, 0); + + /* and the first failure stops further processing */ + r = tor_sscanf("-9223372036854775808. 9223372036854775808.", + "%d. %d.", &int1, &int2); + tt_int_op(r,==, 1); + + r = tor_sscanf("-9223372036854775809. 9223372036854775807.", + "%d. %d.", &int1, &int2); + tt_int_op(r,==, 0); + + r = tor_sscanf("9223372036854775808. -9223372036854775809.", + "%d. %d.", &int1, &int2); + tt_int_op(r,==, 0); #endif #if SIZEOF_LONG == 4 + /* %lu */ + /* UINT32_MAX should work */ + tt_int_op(1,==, tor_sscanf("4294967295", "%lu", &ulng)); + tt_int_op(4294967295UL,==, ulng); + + /* But UINT32_MAX + 1 shouldn't work */ + tt_int_op(0,==, tor_sscanf("4294967296", "%lu", &ulng)); + /* but parsing only 9... */ + tt_int_op(1,==, tor_sscanf("4294967296", "%9lu", &ulng)); + tt_int_op(429496729UL,==, ulng); + + /* %lx */ + /* UINT32_MAX should work */ + tt_int_op(1,==, tor_sscanf("FFFFFFFF", "%lx", &ulng)); + tt_int_op(0xFFFFFFFFUL,==, ulng); + + /* But UINT32_MAX + 1 shouldn't work */ + tt_int_op(0,==, tor_sscanf("100000000", "%lx", &ulng)); + + /* %ld */ + /* INT32_MIN and INT32_MAX should work */ r = tor_sscanf("-2147483648. 2147483647.", "%ld. %ld.", &lng1, &lng2); - test_eq(r,2); - test_eq(lng1, -2147483647 - 1); - test_eq(lng2, 2147483647); + tt_int_op(r,==, 2); + tt_int_op(lng1,==, -2147483647L - 1L); + tt_int_op(lng2,==, 2147483647L); + + /* But INT32_MIN - 1 and INT32_MAX + 1 shouldn't work */ + r = tor_sscanf("-2147483649.", "%ld.", &lng1); + tt_int_op(r,==, 0); + + r = tor_sscanf("2147483648.", "%ld.", &lng1); + tt_int_op(r,==, 0); + + /* and the first failure stops further processing */ + r = tor_sscanf("-2147483648. 2147483648.", + "%ld. %ld.", &lng1, &lng2); + tt_int_op(r,==, 1); + + r = tor_sscanf("-2147483649. 2147483647.", + "%ld. %ld.", &lng1, &lng2); + tt_int_op(r,==, 0); + + r = tor_sscanf("2147483648. -2147483649.", + "%ld. %ld.", &lng1, &lng2); + tt_int_op(r,==, 0); #elif SIZEOF_LONG == 8 + /* %lu */ + /* UINT64_MAX should work */ + tt_int_op(1,==, tor_sscanf("18446744073709551615", "%lu", &ulng)); + tt_int_op(18446744073709551615UL,==, ulng); + + /* But UINT64_MAX + 1 shouldn't work */ + tt_int_op(0,==, tor_sscanf("18446744073709551616", "%lu", &ulng)); + /* but parsing only 19... */ + tt_int_op(1,==, tor_sscanf("18446744073709551616", "%19lu", &ulng)); + tt_int_op(1844674407370955161UL,==, ulng); + + /* %lx */ + /* UINT64_MAX should work */ + tt_int_op(1,==, tor_sscanf("FFFFFFFFFFFFFFFF", "%lx", &ulng)); + tt_int_op(0xFFFFFFFFFFFFFFFFUL,==, ulng); + + /* But UINT64_MAX + 1 shouldn't work */ + tt_int_op(0,==, tor_sscanf("10000000000000000", "%lx", &ulng)); + + /* %ld */ + /* INT64_MIN and INT64_MAX should work */ r = tor_sscanf("-9223372036854775808. 9223372036854775807.", "%ld. %ld.", &lng1, &lng2); - test_eq(r,2); - test_eq(lng1, -9223372036854775807L - 1); - test_eq(lng2, 9223372036854775807L); + tt_int_op(r,==, 2); + tt_int_op(lng1,==, -9223372036854775807L - 1L); + tt_int_op(lng2,==, 9223372036854775807L); + + /* But INT64_MIN - 1 and INT64_MAX + 1 shouldn't work */ + r = tor_sscanf("-9223372036854775809.", "%ld.", &lng1); + tt_int_op(r,==, 0); + + r = tor_sscanf("9223372036854775808.", "%ld.", &lng1); + tt_int_op(r,==, 0); + /* and the first failure stops further processing */ r = tor_sscanf("-9223372036854775808. 9223372036854775808.", "%ld. %ld.", &lng1, &lng2); - test_eq(r,1); - r = tor_sscanf("-9223372036854775809. 9223372036854775808.", + tt_int_op(r,==, 1); + + r = tor_sscanf("-9223372036854775809. 9223372036854775807.", + "%ld. %ld.", &lng1, &lng2); + tt_int_op(r,==, 0); + + r = tor_sscanf("9223372036854775808. -9223372036854775809.", "%ld. %ld.", &lng1, &lng2); - test_eq(r,0); + tt_int_op(r,==, 0); #endif r = tor_sscanf("123.456 .000007 -900123123.2000787 00003.2", "%lf %lf %lf %lf", &d1,&d2,&d3,&d4); - test_eq(r,4); + tt_int_op(r,==, 4); test_feq(d1, 123.456); test_feq(d2, .000007); test_feq(d3, -900123123.2000787); @@ -1884,34 +2299,466 @@ test_util_sscanf(void) ; } +#define tt_char_op(a,op,b) tt_assert_op_type(a,op,b,char,"%c") +#define tt_ci_char_op(a,op,b) tt_char_op(tolower(a),op,tolower(b)) + +#ifndef HAVE_STRNLEN +static size_t +strnlen(const char *s, size_t len) +{ + const char *p = memchr(s, 0, len); + if (!p) + return len; + return p - s; +} +#endif + static void -test_util_path_is_relative(void) +test_util_format_time_interval(void *arg) +{ + /* use the same sized buffer and integers as tor uses */ +#define DBUF_SIZE 64 + char dbuf[DBUF_SIZE]; +#define T_ "%ld" + long sec, min, hour, day; + + /* we don't care about the exact spelling of the + * second(s), minute(s), hour(s), day(s) labels */ +#define LABEL_SIZE 21 +#define L_ "%20s" + char label_s[LABEL_SIZE]; + char label_m[LABEL_SIZE]; + char label_h[LABEL_SIZE]; + char label_d[LABEL_SIZE]; + +#define TL_ T_ " " L_ + + int r; + + (void)arg; + + /* In these tests, we're not picky about + * spelling or abbreviations */ + + /* seconds: 0, 1, 9, 10, 59 */ + + /* ignore exact spelling of "second(s)"*/ + format_time_interval(dbuf, sizeof(dbuf), 0); + tt_int_op(strnlen(dbuf, DBUF_SIZE),<=, DBUF_SIZE - 1); + r = tor_sscanf(dbuf, TL_, &sec, label_s); + tt_int_op(r,==, 2); + tt_ci_char_op(label_s[0],==, 's'); + tt_int_op(sec,==, 0); + + format_time_interval(dbuf, sizeof(dbuf), 1); + tt_int_op(strnlen(dbuf, DBUF_SIZE),<=, DBUF_SIZE - 1); + r = tor_sscanf(dbuf, TL_, &sec, label_s); + tt_int_op(r,==, 2); + tt_ci_char_op(label_s[0],==, 's'); + tt_int_op(sec,==, 1); + + format_time_interval(dbuf, sizeof(dbuf), 10); + tt_int_op(strnlen(dbuf, DBUF_SIZE),<=, DBUF_SIZE - 1); + r = tor_sscanf(dbuf, TL_, &sec, label_s); + tt_int_op(r,==, 2); + tt_ci_char_op(label_s[0],==, 's'); + tt_int_op(sec,==, 10); + + format_time_interval(dbuf, sizeof(dbuf), 59); + tt_int_op(strnlen(dbuf, DBUF_SIZE),<=, DBUF_SIZE - 1); + r = tor_sscanf(dbuf, TL_, &sec, label_s); + tt_int_op(r,==, 2); + tt_ci_char_op(label_s[0],==, 's'); + tt_int_op(sec,==, 59); + + /* negative seconds are reported as their absolute value */ + + format_time_interval(dbuf, sizeof(dbuf), -4); + tt_int_op(strnlen(dbuf, DBUF_SIZE),<=, DBUF_SIZE - 1); + r = tor_sscanf(dbuf, TL_, &sec, label_s); + tt_int_op(r,==, 2); + tt_ci_char_op(label_s[0],==, 's'); + tt_int_op(sec,==, 4); + tt_int_op(strnlen(dbuf, DBUF_SIZE),<=, DBUF_SIZE - 1); + + format_time_interval(dbuf, sizeof(dbuf), -32); + tt_int_op(strnlen(dbuf, DBUF_SIZE),<=, DBUF_SIZE - 1); + r = tor_sscanf(dbuf, TL_, &sec, label_s); + tt_int_op(r,==, 2); + tt_ci_char_op(label_s[0],==, 's'); + tt_int_op(sec,==, 32); + tt_int_op(strnlen(dbuf, DBUF_SIZE),<=, DBUF_SIZE - 1); + + /* minutes: 1:00, 1:01, 1:59, 2:00, 2:01, 59:59 */ + + /* ignore trailing "0 second(s)", if present */ + format_time_interval(dbuf, sizeof(dbuf), 60); + tt_int_op(strnlen(dbuf, DBUF_SIZE),<=, DBUF_SIZE - 1); + r = tor_sscanf(dbuf, TL_, &min, label_m); + tt_int_op(r,==, 2); + tt_ci_char_op(label_m[0],==, 'm'); + tt_int_op(min,==, 1); + tt_int_op(strnlen(dbuf, DBUF_SIZE),<=, DBUF_SIZE - 1); + + /* ignore exact spelling of "minute(s)," and "second(s)" */ + format_time_interval(dbuf, sizeof(dbuf), 60 + 1); + tt_int_op(strnlen(dbuf, DBUF_SIZE),<=, DBUF_SIZE - 1); + r = tor_sscanf(dbuf, TL_ " " TL_, + &min, label_m, &sec, label_s); + tt_int_op(r,==, 4); + tt_int_op(min,==, 1); + tt_ci_char_op(label_m[0],==, 'm'); + tt_int_op(sec,==, 1); + tt_ci_char_op(label_s[0],==, 's'); + tt_int_op(strnlen(dbuf, DBUF_SIZE),<=, DBUF_SIZE - 1); + + format_time_interval(dbuf, sizeof(dbuf), 60*2 - 1); + tt_int_op(strnlen(dbuf, DBUF_SIZE),<=, DBUF_SIZE - 1); + r = tor_sscanf(dbuf, TL_ " " TL_, + &min, label_m, &sec, label_s); + tt_int_op(r,==, 4); + tt_int_op(min,==, 1); + tt_ci_char_op(label_m[0],==, 'm'); + tt_int_op(sec,==, 59); + tt_ci_char_op(label_s[0],==, 's'); + + /* ignore trailing "0 second(s)", if present */ + format_time_interval(dbuf, sizeof(dbuf), 60*2); + tt_int_op(strnlen(dbuf, DBUF_SIZE),<=, DBUF_SIZE - 1); + r = tor_sscanf(dbuf, TL_, &min, label_m); + tt_int_op(r,==, 2); + tt_int_op(min,==, 2); + tt_ci_char_op(label_m[0],==, 'm'); + + /* ignore exact spelling of "minute(s)," and "second(s)" */ + format_time_interval(dbuf, sizeof(dbuf), 60*2 + 1); + tt_int_op(strnlen(dbuf, DBUF_SIZE),<=, DBUF_SIZE - 1); + r = tor_sscanf(dbuf, TL_ " " TL_, + &min, label_m, &sec, label_s); + tt_int_op(r,==, 4); + tt_int_op(min,==, 2); + tt_ci_char_op(label_m[0],==, 'm'); + tt_int_op(sec,==, 1); + tt_ci_char_op(label_s[0],==, 's'); + + format_time_interval(dbuf, sizeof(dbuf), 60*60 - 1); + tt_int_op(strnlen(dbuf, DBUF_SIZE),<=, DBUF_SIZE - 1); + r = tor_sscanf(dbuf, TL_ " " TL_, + &min, label_m, &sec, label_s); + tt_int_op(r,==, 4); + tt_int_op(min,==, 59); + tt_ci_char_op(label_m[0],==, 'm'); + tt_int_op(sec,==, 59); + tt_ci_char_op(label_s[0],==, 's'); + + /* negative minutes are reported as their absolute value */ + + /* ignore trailing "0 second(s)", if present */ + format_time_interval(dbuf, sizeof(dbuf), -3*60); + tt_int_op(strnlen(dbuf, DBUF_SIZE),<=, DBUF_SIZE - 1); + r = tor_sscanf(dbuf, TL_, &min, label_m); + tt_int_op(r,==, 2); + tt_int_op(min,==, 3); + tt_ci_char_op(label_m[0],==, 'm'); + + /* ignore exact spelling of "minute(s)," and "second(s)" */ + format_time_interval(dbuf, sizeof(dbuf), -96); + tt_int_op(strnlen(dbuf, DBUF_SIZE),<=, DBUF_SIZE - 1); + r = tor_sscanf(dbuf, TL_ " " TL_, + &min, label_m, &sec, label_s); + tt_int_op(r,==, 4); + tt_int_op(min,==, 1); + tt_ci_char_op(label_m[0],==, 'm'); + tt_int_op(sec,==, 36); + tt_ci_char_op(label_s[0],==, 's'); + + format_time_interval(dbuf, sizeof(dbuf), -2815); + tt_int_op(strnlen(dbuf, DBUF_SIZE),<=, DBUF_SIZE - 1); + r = tor_sscanf(dbuf, TL_ " " TL_, + &min, label_m, &sec, label_s); + tt_int_op(r,==, 4); + tt_int_op(min,==, 46); + tt_ci_char_op(label_m[0],==, 'm'); + tt_int_op(sec,==, 55); + tt_ci_char_op(label_s[0],==, 's'); + + /* hours: 1:00, 1:00:01, 1:01, 23:59, 23:59:59 */ + /* always ignore trailing seconds, if present */ + + /* ignore trailing "0 minute(s)" etc., if present */ + format_time_interval(dbuf, sizeof(dbuf), 60*60); + tt_int_op(strnlen(dbuf, DBUF_SIZE),<=, DBUF_SIZE - 1); + r = tor_sscanf(dbuf, TL_, &hour, label_h); + tt_int_op(r,==, 2); + tt_int_op(hour,==, 1); + tt_ci_char_op(label_h[0],==, 'h'); + + format_time_interval(dbuf, sizeof(dbuf), 60*60 + 1); + tt_int_op(strnlen(dbuf, DBUF_SIZE),<=, DBUF_SIZE - 1); + r = tor_sscanf(dbuf, TL_, &hour, label_h); + tt_int_op(r,==, 2); + tt_int_op(hour,==, 1); + tt_ci_char_op(label_h[0],==, 'h'); + + /* ignore exact spelling of "hour(s)," etc. */ + format_time_interval(dbuf, sizeof(dbuf), 60*60 + 60); + tt_int_op(strnlen(dbuf, DBUF_SIZE),<=, DBUF_SIZE - 1); + r = tor_sscanf(dbuf, TL_ " " TL_, + &hour, label_h, &min, label_m); + tt_int_op(r,==, 4); + tt_int_op(hour,==, 1); + tt_ci_char_op(label_h[0],==, 'h'); + tt_int_op(min,==, 1); + tt_ci_char_op(label_m[0],==, 'm'); + + format_time_interval(dbuf, sizeof(dbuf), 24*60*60 - 60); + tt_int_op(strnlen(dbuf, DBUF_SIZE),<=, DBUF_SIZE - 1); + r = tor_sscanf(dbuf, TL_ " " TL_, + &hour, label_h, &min, label_m); + tt_int_op(r,==, 4); + tt_int_op(hour,==, 23); + tt_ci_char_op(label_h[0],==, 'h'); + tt_int_op(min,==, 59); + tt_ci_char_op(label_m[0],==, 'm'); + + format_time_interval(dbuf, sizeof(dbuf), 24*60*60 - 1); + tt_int_op(strnlen(dbuf, DBUF_SIZE),<=, DBUF_SIZE - 1); + r = tor_sscanf(dbuf, TL_ " " TL_, + &hour, label_h, &min, label_m); + tt_int_op(r,==, 4); + tt_int_op(hour,==, 23); + tt_ci_char_op(label_h[0],==, 'h'); + tt_int_op(min,==, 59); + tt_ci_char_op(label_m[0],==, 'm'); + + /* negative hours are reported as their absolute value */ + + /* ignore exact spelling of "hour(s)," etc., if present */ + format_time_interval(dbuf, sizeof(dbuf), -2*60*60); + tt_int_op(strnlen(dbuf, DBUF_SIZE),<=, DBUF_SIZE - 1); + r = tor_sscanf(dbuf, TL_, &hour, label_h); + tt_int_op(r,==, 2); + tt_int_op(hour,==, 2); + tt_ci_char_op(label_h[0],==, 'h'); + + format_time_interval(dbuf, sizeof(dbuf), -75804); + tt_int_op(strnlen(dbuf, DBUF_SIZE),<=, DBUF_SIZE - 1); + r = tor_sscanf(dbuf, TL_ " " TL_, + &hour, label_h, &min, label_m); + tt_int_op(r,==, 4); + tt_int_op(hour,==, 21); + tt_ci_char_op(label_h[0],==, 'h'); + tt_int_op(min,==, 3); + tt_ci_char_op(label_m[0],==, 'm'); + + /* days: 1:00, 1:00:00:01, 1:00:01, 1:01 */ + /* always ignore trailing seconds, if present */ + + /* ignore trailing "0 hours(s)" etc., if present */ + format_time_interval(dbuf, sizeof(dbuf), 24*60*60); + tt_int_op(strnlen(dbuf, DBUF_SIZE),<=, DBUF_SIZE - 1); + r = tor_sscanf(dbuf, TL_, &day, label_d); + tt_int_op(r,==, 2); + tt_int_op(day,==, 1); + tt_ci_char_op(label_d[0],==, 'd'); + + format_time_interval(dbuf, sizeof(dbuf), 24*60*60 + 1); + tt_int_op(strnlen(dbuf, DBUF_SIZE),<=, DBUF_SIZE - 1); + r = tor_sscanf(dbuf, TL_, &day, label_d); + tt_int_op(r,==, 2); + tt_int_op(day,==, 1); + tt_ci_char_op(label_d[0],==, 'd'); + + /* ignore exact spelling of "days(s)," etc. */ + format_time_interval(dbuf, sizeof(dbuf), 24*60*60 + 60); + tt_int_op(strnlen(dbuf, DBUF_SIZE),<=, DBUF_SIZE - 1); + r = tor_sscanf(dbuf, TL_ " " TL_ " " TL_, + &day, label_d, &hour, label_h, &min, label_m); + if (r == -1) { + /* ignore 0 hours(s), if present */ + r = tor_sscanf(dbuf, TL_ " " TL_, + &day, label_d, &min, label_m); + } + tt_assert(r == 4 || r == 6); + tt_int_op(day,==, 1); + tt_ci_char_op(label_d[0],==, 'd'); + if (r == 6) { + tt_int_op(hour,==, 0); + tt_ci_char_op(label_h[0],==, 'h'); + } + tt_int_op(min,==, 1); + tt_ci_char_op(label_m[0],==, 'm'); + + /* ignore trailing "0 minutes(s)" etc., if present */ + format_time_interval(dbuf, sizeof(dbuf), 24*60*60 + 60*60); + tt_int_op(strnlen(dbuf, DBUF_SIZE),<=, DBUF_SIZE - 1); + r = tor_sscanf(dbuf, TL_ " " TL_, + &day, label_d, &hour, label_h); + tt_int_op(r,==, 4); + tt_int_op(day,==, 1); + tt_ci_char_op(label_d[0],==, 'd'); + tt_int_op(hour,==, 1); + tt_ci_char_op(label_h[0],==, 'h'); + + /* negative days are reported as their absolute value */ + + format_time_interval(dbuf, sizeof(dbuf), -21936184); + tt_int_op(strnlen(dbuf, DBUF_SIZE),<=, DBUF_SIZE - 1); + r = tor_sscanf(dbuf, TL_ " " TL_ " " TL_, + &day, label_d, &hour, label_h, &min, label_m); + tt_int_op(r,==, 6); + tt_int_op(day,==, 253); + tt_ci_char_op(label_d[0],==, 'd'); + tt_int_op(hour,==, 21); + tt_ci_char_op(label_h[0],==, 'h'); + tt_int_op(min,==, 23); + tt_ci_char_op(label_m[0],==, 'm'); + + /* periods > 1 year are reported in days (warn?) */ + + /* ignore exact spelling of "days(s)," etc., if present */ + format_time_interval(dbuf, sizeof(dbuf), 758635154); + tt_int_op(strnlen(dbuf, DBUF_SIZE),<=, DBUF_SIZE - 1); + r = tor_sscanf(dbuf, TL_ " " TL_ " " TL_, + &day, label_d, &hour, label_h, &min, label_m); + tt_int_op(r,==, 6); + tt_int_op(day,==, 8780); + tt_ci_char_op(label_d[0],==, 'd'); + tt_int_op(hour,==, 11); + tt_ci_char_op(label_h[0],==, 'h'); + tt_int_op(min,==, 59); + tt_ci_char_op(label_m[0],==, 'm'); + + /* negative periods > 1 year are reported in days (warn?) */ + + format_time_interval(dbuf, sizeof(dbuf), -1427014922); + tt_int_op(strnlen(dbuf, DBUF_SIZE),<=, DBUF_SIZE - 1); + r = tor_sscanf(dbuf, TL_ " " TL_ " " TL_, + &day, label_d, &hour, label_h, &min, label_m); + tt_int_op(r,==, 6); + tt_int_op(day,==, 16516); + tt_ci_char_op(label_d[0],==, 'd'); + tt_int_op(hour,==, 9); + tt_ci_char_op(label_h[0],==, 'h'); + tt_int_op(min,==, 2); + tt_ci_char_op(label_m[0],==, 'm'); + +#if SIZEOF_LONG == 4 || SIZEOF_LONG == 8 + + /* We can try INT32_MIN/MAX */ + /* Always ignore second(s) */ + + /* INT32_MAX */ + format_time_interval(dbuf, sizeof(dbuf), 2147483647); + tt_int_op(strnlen(dbuf, DBUF_SIZE),<=, DBUF_SIZE - 1); + r = tor_sscanf(dbuf, TL_ " " TL_ " " TL_, + &day, label_d, &hour, label_h, &min, label_m); + tt_int_op(r,==, 6); + tt_int_op(day,==, 24855); + tt_ci_char_op(label_d[0],==, 'd'); + tt_int_op(hour,==, 3); + tt_ci_char_op(label_h[0],==, 'h'); + tt_int_op(min,==, 14); + tt_ci_char_op(label_m[0],==, 'm'); + /* and 7 seconds - ignored */ + + /* INT32_MIN: check that we get the absolute value of interval, + * which doesn't actually fit in int32_t. + * We expect INT32_MAX or INT32_MAX + 1 with 64 bit longs */ + format_time_interval(dbuf, sizeof(dbuf), -2147483647L - 1L); + tt_int_op(strnlen(dbuf, DBUF_SIZE),<=, DBUF_SIZE - 1); + r = tor_sscanf(dbuf, TL_ " " TL_ " " TL_, + &day, label_d, &hour, label_h, &min, label_m); + tt_int_op(r,==, 6); + tt_int_op(day,==, 24855); + tt_ci_char_op(label_d[0],==, 'd'); + tt_int_op(hour,==, 3); + tt_ci_char_op(label_h[0],==, 'h'); + tt_int_op(min,==, 14); + tt_ci_char_op(label_m[0],==, 'm'); + /* and 7 or 8 seconds - ignored */ + +#endif + +#if SIZEOF_LONG == 8 + + /* We can try INT64_MIN/MAX */ + /* Always ignore second(s) */ + + /* INT64_MAX */ + format_time_interval(dbuf, sizeof(dbuf), 9223372036854775807L); + tt_int_op(strnlen(dbuf, DBUF_SIZE),<=, DBUF_SIZE - 1); + r = tor_sscanf(dbuf, TL_ " " TL_ " " TL_, + &day, label_d, &hour, label_h, &min, label_m); + tt_int_op(r,==, 6); + tt_int_op(day,==, 106751991167300L); + tt_ci_char_op(label_d[0],==, 'd'); + tt_int_op(hour,==, 15); + tt_ci_char_op(label_h[0],==, 'h'); + tt_int_op(min,==, 30); + tt_ci_char_op(label_m[0],==, 'm'); + /* and 7 seconds - ignored */ + + /* INT64_MIN: check that we get the absolute value of interval, + * which doesn't actually fit in int64_t. + * We expect INT64_MAX */ + format_time_interval(dbuf, sizeof(dbuf), + -9223372036854775807L - 1L); + tt_int_op(strnlen(dbuf, DBUF_SIZE),<=, DBUF_SIZE - 1); + r = tor_sscanf(dbuf, TL_ " " TL_ " " TL_, + &day, label_d, &hour, label_h, &min, label_m); + tt_int_op(r,==, 6); + tt_int_op(day,==, 106751991167300L); + tt_ci_char_op(label_d[0],==, 'd'); + tt_int_op(hour,==, 15); + tt_ci_char_op(label_h[0],==, 'h'); + tt_int_op(min,==, 30); + tt_ci_char_op(label_m[0],==, 'm'); + /* and 7 or 8 seconds - ignored */ + +#endif + + done: + ; +} + +#undef tt_char_op +#undef tt_ci_char_op +#undef DBUF_SIZE +#undef T_ +#undef LABEL_SIZE +#undef L_ +#undef TL_ + +static void +test_util_path_is_relative(void *arg) { /* OS-independent tests */ - test_eq(1, path_is_relative("")); - test_eq(1, path_is_relative("dir")); - test_eq(1, path_is_relative("dir/")); - test_eq(1, path_is_relative("./dir")); - test_eq(1, path_is_relative("../dir")); + (void)arg; + tt_int_op(1,==, path_is_relative("")); + tt_int_op(1,==, path_is_relative("dir")); + tt_int_op(1,==, path_is_relative("dir/")); + tt_int_op(1,==, path_is_relative("./dir")); + tt_int_op(1,==, path_is_relative("../dir")); - test_eq(0, path_is_relative("/")); - test_eq(0, path_is_relative("/dir")); - test_eq(0, path_is_relative("/dir/")); + tt_int_op(0,==, path_is_relative("/")); + tt_int_op(0,==, path_is_relative("/dir")); + tt_int_op(0,==, path_is_relative("/dir/")); /* Windows */ #ifdef _WIN32 /* I don't have Windows so I can't test this, hence the "#ifdef 0". These are tests that look useful, so please try to get them running and uncomment if it all works as it should */ - test_eq(1, path_is_relative("dir")); - test_eq(1, path_is_relative("dir\\")); - test_eq(1, path_is_relative("dir\\a:")); - test_eq(1, path_is_relative("dir\\a:\\")); - test_eq(1, path_is_relative("http:\\dir")); - - test_eq(0, path_is_relative("\\dir")); - test_eq(0, path_is_relative("a:\\dir")); - test_eq(0, path_is_relative("z:\\dir")); + tt_int_op(1,==, path_is_relative("dir")); + tt_int_op(1,==, path_is_relative("dir\\")); + tt_int_op(1,==, path_is_relative("dir\\a:")); + tt_int_op(1,==, path_is_relative("dir\\a:\\")); + tt_int_op(1,==, path_is_relative("http:\\dir")); + + tt_int_op(0,==, path_is_relative("\\dir")); + tt_int_op(0,==, path_is_relative("a:\\dir")); + tt_int_op(0,==, path_is_relative("z:\\dir")); #endif done: @@ -1922,25 +2769,26 @@ test_util_path_is_relative(void) /** Run unittests for memory pool allocator */ static void -test_util_mempool(void) +test_util_mempool(void *arg) { mp_pool_t *pool = NULL; smartlist_t *allocated = NULL; int i; + (void)arg; pool = mp_pool_new(1, 100); - test_assert(pool); - test_assert(pool->new_chunk_capacity >= 100); - test_assert(pool->item_alloc_size >= sizeof(void*)+1); + tt_assert(pool); + tt_assert(pool->new_chunk_capacity >= 100); + tt_assert(pool->item_alloc_size >= sizeof(void*)+1); mp_pool_destroy(pool); pool = NULL; pool = mp_pool_new(241, 2500); - test_assert(pool); - test_assert(pool->new_chunk_capacity >= 10); - test_assert(pool->item_alloc_size >= sizeof(void*)+241); - test_eq(pool->item_alloc_size & 0x03, 0); - test_assert(pool->new_chunk_capacity < 60); + tt_assert(pool); + tt_assert(pool->new_chunk_capacity >= 10); + tt_assert(pool->item_alloc_size >= sizeof(void*)+241); + tt_int_op(pool->item_alloc_size & 0x03,==, 0); + tt_assert(pool->new_chunk_capacity < 60); allocated = smartlist_new(); for (i = 0; i < 20000; ++i) { @@ -1982,39 +2830,40 @@ test_util_mempool(void) /** Run unittests for memory area allocator */ static void -test_util_memarea(void) +test_util_memarea(void *arg) { memarea_t *area = memarea_new(); char *p1, *p2, *p3, *p1_orig; void *malloced_ptr = NULL; int i; - test_assert(area); + (void)arg; + tt_assert(area); p1_orig = p1 = memarea_alloc(area,64); p2 = memarea_alloc_zero(area,52); p3 = memarea_alloc(area,11); - test_assert(memarea_owns_ptr(area, p1)); - test_assert(memarea_owns_ptr(area, p2)); - test_assert(memarea_owns_ptr(area, p3)); + tt_assert(memarea_owns_ptr(area, p1)); + tt_assert(memarea_owns_ptr(area, p2)); + tt_assert(memarea_owns_ptr(area, p3)); /* Make sure we left enough space. */ - test_assert(p1+64 <= p2); - test_assert(p2+52 <= p3); + tt_assert(p1+64 <= p2); + tt_assert(p2+52 <= p3); /* Make sure we aligned. */ - test_eq(((uintptr_t)p1) % sizeof(void*), 0); - test_eq(((uintptr_t)p2) % sizeof(void*), 0); - test_eq(((uintptr_t)p3) % sizeof(void*), 0); - test_assert(!memarea_owns_ptr(area, p3+8192)); - test_assert(!memarea_owns_ptr(area, p3+30)); - test_assert(tor_mem_is_zero(p2, 52)); + tt_int_op(((uintptr_t)p1) % sizeof(void*),==, 0); + tt_int_op(((uintptr_t)p2) % sizeof(void*),==, 0); + tt_int_op(((uintptr_t)p3) % sizeof(void*),==, 0); + tt_assert(!memarea_owns_ptr(area, p3+8192)); + tt_assert(!memarea_owns_ptr(area, p3+30)); + tt_assert(tor_mem_is_zero(p2, 52)); /* Make sure we don't overalign. */ p1 = memarea_alloc(area, 1); p2 = memarea_alloc(area, 1); - test_eq_ptr(p1+sizeof(void*), p2); + tt_ptr_op(p1+sizeof(void*),==, p2); { malloced_ptr = tor_malloc(64); - test_assert(!memarea_owns_ptr(area, malloced_ptr)); + tt_assert(!memarea_owns_ptr(area, malloced_ptr)); tor_free(malloced_ptr); } @@ -2023,18 +2872,18 @@ test_util_memarea(void) malloced_ptr = tor_malloc(64); crypto_rand((char*)malloced_ptr, 64); p1 = memarea_memdup(area, malloced_ptr, 64); - test_assert(p1 != malloced_ptr); - test_memeq(p1, malloced_ptr, 64); + tt_assert(p1 != malloced_ptr); + tt_mem_op(p1,==, malloced_ptr, 64); tor_free(malloced_ptr); } /* memarea_strdup. */ p1 = memarea_strdup(area,""); p2 = memarea_strdup(area, "abcd"); - test_assert(p1); - test_assert(p2); - test_streq(p1, ""); - test_streq(p2, "abcd"); + tt_assert(p1); + tt_assert(p2); + tt_str_op(p1,==, ""); + tt_str_op(p2,==, "abcd"); /* memarea_strndup. */ { @@ -2043,33 +2892,33 @@ test_util_memarea(void) size_t len = strlen(s); p1 = memarea_strndup(area, s, 1000); p2 = memarea_strndup(area, s, 10); - test_streq(p1, s); - test_assert(p2 >= p1 + len + 1); - test_memeq(s, p2, 10); - test_eq(p2[10], '\0'); + tt_str_op(p1,==, s); + tt_assert(p2 >= p1 + len + 1); + tt_mem_op(s,==, p2, 10); + tt_int_op(p2[10],==, '\0'); p3 = memarea_strndup(area, s, len); - test_streq(p3, s); + tt_str_op(p3,==, s); p3 = memarea_strndup(area, s, len-1); - test_memeq(s, p3, len-1); - test_eq(p3[len-1], '\0'); + tt_mem_op(s,==, p3, len-1); + tt_int_op(p3[len-1],==, '\0'); } memarea_clear(area); p1 = memarea_alloc(area, 1); - test_eq_ptr(p1, p1_orig); + tt_ptr_op(p1,==, p1_orig); memarea_clear(area); /* Check for running over an area's size. */ for (i = 0; i < 512; ++i) { p1 = memarea_alloc(area, crypto_rand_int(5)+1); - test_assert(memarea_owns_ptr(area, p1)); + tt_assert(memarea_owns_ptr(area, p1)); } memarea_assert_ok(area); /* Make sure we can allocate a too-big object. */ p1 = memarea_alloc_zero(area, 9000); p2 = memarea_alloc_zero(area, 16); - test_assert(memarea_owns_ptr(area, p1)); - test_assert(memarea_owns_ptr(area, p2)); + tt_assert(memarea_owns_ptr(area, p1)); + tt_assert(memarea_owns_ptr(area, p2)); done: memarea_drop_all(area); @@ -2079,31 +2928,32 @@ test_util_memarea(void) /** Run unit tests for utility functions to get file names relative to * the data directory. */ static void -test_util_datadir(void) +test_util_datadir(void *arg) { char buf[1024]; char *f = NULL; char *temp_dir = NULL; + (void)arg; temp_dir = get_datadir_fname(NULL); f = get_datadir_fname("state"); tor_snprintf(buf, sizeof(buf), "%s"PATH_SEPARATOR"state", temp_dir); - test_streq(f, buf); + tt_str_op(f,==, buf); tor_free(f); f = get_datadir_fname2("cache", "thingy"); tor_snprintf(buf, sizeof(buf), "%s"PATH_SEPARATOR"cache"PATH_SEPARATOR"thingy", temp_dir); - test_streq(f, buf); + tt_str_op(f,==, buf); tor_free(f); f = get_datadir_fname2_suffix("cache", "thingy", ".foo"); tor_snprintf(buf, sizeof(buf), "%s"PATH_SEPARATOR"cache"PATH_SEPARATOR"thingy.foo", temp_dir); - test_streq(f, buf); + tt_str_op(f,==, buf); tor_free(f); f = get_datadir_fname_suffix("cache", ".foo"); tor_snprintf(buf, sizeof(buf), "%s"PATH_SEPARATOR"cache.foo", temp_dir); - test_streq(f, buf); + tt_str_op(f,==, buf); done: tor_free(f); @@ -2111,13 +2961,14 @@ test_util_datadir(void) } static void -test_util_strtok(void) +test_util_strtok(void *arg) { char buf[128]; char buf2[128]; int i; char *cp1, *cp2; + (void)arg; for (i = 0; i < 3; i++) { const char *pad1="", *pad2=""; switch (i) { @@ -2134,8 +2985,8 @@ test_util_strtok(void) } tor_snprintf(buf, sizeof(buf), "%s", pad1); tor_snprintf(buf2, sizeof(buf2), "%s", pad2); - test_assert(NULL == tor_strtok_r_impl(buf, " ", &cp1)); - test_assert(NULL == tor_strtok_r_impl(buf2, ".!..;!", &cp2)); + tt_assert(NULL == tor_strtok_r_impl(buf, " ", &cp1)); + tt_assert(NULL == tor_strtok_r_impl(buf2, ".!..;!", &cp2)); tor_snprintf(buf, sizeof(buf), "%sGraved on the dark in gestures of descent%s", pad1, pad1); @@ -2143,43 +2994,43 @@ test_util_strtok(void) "%sthey.seemed;;their!.own;most.perfect;monument%s",pad2,pad2); /* -- "Year's End", Richard Wilbur */ - test_streq("Graved", tor_strtok_r_impl(buf, " ", &cp1)); - test_streq("they", tor_strtok_r_impl(buf2, ".!..;!", &cp2)); + tt_str_op("Graved",==, tor_strtok_r_impl(buf, " ", &cp1)); + tt_str_op("they",==, tor_strtok_r_impl(buf2, ".!..;!", &cp2)); #define S1() tor_strtok_r_impl(NULL, " ", &cp1) #define S2() tor_strtok_r_impl(NULL, ".!..;!", &cp2) - test_streq("on", S1()); - test_streq("the", S1()); - test_streq("dark", S1()); - test_streq("seemed", S2()); - test_streq("their", S2()); - test_streq("own", S2()); - test_streq("in", S1()); - test_streq("gestures", S1()); - test_streq("of", S1()); - test_streq("most", S2()); - test_streq("perfect", S2()); - test_streq("descent", S1()); - test_streq("monument", S2()); - test_eq_ptr(NULL, S1()); - test_eq_ptr(NULL, S2()); + tt_str_op("on",==, S1()); + tt_str_op("the",==, S1()); + tt_str_op("dark",==, S1()); + tt_str_op("seemed",==, S2()); + tt_str_op("their",==, S2()); + tt_str_op("own",==, S2()); + tt_str_op("in",==, S1()); + tt_str_op("gestures",==, S1()); + tt_str_op("of",==, S1()); + tt_str_op("most",==, S2()); + tt_str_op("perfect",==, S2()); + tt_str_op("descent",==, S1()); + tt_str_op("monument",==, S2()); + tt_ptr_op(NULL,==, S1()); + tt_ptr_op(NULL,==, S2()); } buf[0] = 0; - test_eq_ptr(NULL, tor_strtok_r_impl(buf, " ", &cp1)); - test_eq_ptr(NULL, tor_strtok_r_impl(buf, "!", &cp1)); + tt_ptr_op(NULL,==, tor_strtok_r_impl(buf, " ", &cp1)); + tt_ptr_op(NULL,==, tor_strtok_r_impl(buf, "!", &cp1)); strlcpy(buf, "Howdy!", sizeof(buf)); - test_streq("Howdy", tor_strtok_r_impl(buf, "!", &cp1)); - test_eq_ptr(NULL, tor_strtok_r_impl(NULL, "!", &cp1)); + tt_str_op("Howdy",==, tor_strtok_r_impl(buf, "!", &cp1)); + tt_ptr_op(NULL,==, tor_strtok_r_impl(NULL, "!", &cp1)); strlcpy(buf, " ", sizeof(buf)); - test_eq_ptr(NULL, tor_strtok_r_impl(buf, " ", &cp1)); + tt_ptr_op(NULL,==, tor_strtok_r_impl(buf, " ", &cp1)); strlcpy(buf, " ", sizeof(buf)); - test_eq_ptr(NULL, tor_strtok_r_impl(buf, " ", &cp1)); + tt_ptr_op(NULL,==, tor_strtok_r_impl(buf, " ", &cp1)); strlcpy(buf, "something ", sizeof(buf)); - test_streq("something", tor_strtok_r_impl(buf, " ", &cp1)); - test_eq_ptr(NULL, tor_strtok_r_impl(NULL, ";", &cp1)); + tt_str_op("something",==, tor_strtok_r_impl(buf, " ", &cp1)); + tt_ptr_op(NULL,==, tor_strtok_r_impl(NULL, ";", &cp1)); done: ; } @@ -2199,23 +3050,24 @@ test_util_find_str_at_start_of_line(void *ptr) (void)ptr; - test_eq_ptr(long_string, find_str_at_start_of_line(long_string, "")); - test_eq_ptr(NULL, find_str_at_start_of_line(short_string, "nonsense")); - test_eq_ptr(NULL, find_str_at_start_of_line(long_string, "nonsense")); - test_eq_ptr(NULL, find_str_at_start_of_line(long_string, "\n")); - test_eq_ptr(NULL, find_str_at_start_of_line(long_string, "how ")); - test_eq_ptr(NULL, find_str_at_start_of_line(long_string, "kitty")); - test_eq_ptr(long_string, find_str_at_start_of_line(long_string, "h")); - test_eq_ptr(long_string, find_str_at_start_of_line(long_string, "how")); - test_eq_ptr(line2, find_str_at_start_of_line(long_string, "he")); - test_eq_ptr(line2, find_str_at_start_of_line(long_string, "hell")); - test_eq_ptr(line2, find_str_at_start_of_line(long_string, "hello k")); - test_eq_ptr(line2, find_str_at_start_of_line(long_string, "hello kitty\n")); - test_eq_ptr(line2, find_str_at_start_of_line(long_string, "hello kitty\nt")); - test_eq_ptr(line3, find_str_at_start_of_line(long_string, "third")); - test_eq_ptr(line3, find_str_at_start_of_line(long_string, "third line")); - test_eq_ptr(NULL, find_str_at_start_of_line(long_string, "third line\n")); - test_eq_ptr(short_line2, find_str_at_start_of_line(short_string, + tt_ptr_op(long_string,==, find_str_at_start_of_line(long_string, "")); + tt_ptr_op(NULL,==, find_str_at_start_of_line(short_string, "nonsense")); + tt_ptr_op(NULL,==, find_str_at_start_of_line(long_string, "nonsense")); + tt_ptr_op(NULL,==, find_str_at_start_of_line(long_string, "\n")); + tt_ptr_op(NULL,==, find_str_at_start_of_line(long_string, "how ")); + tt_ptr_op(NULL,==, find_str_at_start_of_line(long_string, "kitty")); + tt_ptr_op(long_string,==, find_str_at_start_of_line(long_string, "h")); + tt_ptr_op(long_string,==, find_str_at_start_of_line(long_string, "how")); + tt_ptr_op(line2,==, find_str_at_start_of_line(long_string, "he")); + tt_ptr_op(line2,==, find_str_at_start_of_line(long_string, "hell")); + tt_ptr_op(line2,==, find_str_at_start_of_line(long_string, "hello k")); + tt_ptr_op(line2,==, find_str_at_start_of_line(long_string, "hello kitty\n")); + tt_ptr_op(line2,==, + find_str_at_start_of_line(long_string, "hello kitty\nt")); + tt_ptr_op(line3,==, find_str_at_start_of_line(long_string, "third")); + tt_ptr_op(line3,==, find_str_at_start_of_line(long_string, "third line")); + tt_ptr_op(NULL,==, find_str_at_start_of_line(long_string, "third line\n")); + tt_ptr_op(short_line2,==, find_str_at_start_of_line(short_string, "second line\n")); done: ; @@ -2226,25 +3078,25 @@ test_util_string_is_C_identifier(void *ptr) { (void)ptr; - test_eq(1, string_is_C_identifier("string_is_C_identifier")); - test_eq(1, string_is_C_identifier("_string_is_C_identifier")); - test_eq(1, string_is_C_identifier("_")); - test_eq(1, string_is_C_identifier("i")); - test_eq(1, string_is_C_identifier("_____")); - test_eq(1, string_is_C_identifier("__00__")); - test_eq(1, string_is_C_identifier("__init__")); - test_eq(1, string_is_C_identifier("_0")); - test_eq(1, string_is_C_identifier("_0string_is_C_identifier")); - test_eq(1, string_is_C_identifier("_0")); - - test_eq(0, string_is_C_identifier("0_string_is_C_identifier")); - test_eq(0, string_is_C_identifier("0")); - test_eq(0, string_is_C_identifier("")); - test_eq(0, string_is_C_identifier(";")); - test_eq(0, string_is_C_identifier("i;")); - test_eq(0, string_is_C_identifier("_;")); - test_eq(0, string_is_C_identifier("í")); - test_eq(0, string_is_C_identifier("ñ")); + tt_int_op(1,==, string_is_C_identifier("string_is_C_identifier")); + tt_int_op(1,==, string_is_C_identifier("_string_is_C_identifier")); + tt_int_op(1,==, string_is_C_identifier("_")); + tt_int_op(1,==, string_is_C_identifier("i")); + tt_int_op(1,==, string_is_C_identifier("_____")); + tt_int_op(1,==, string_is_C_identifier("__00__")); + tt_int_op(1,==, string_is_C_identifier("__init__")); + tt_int_op(1,==, string_is_C_identifier("_0")); + tt_int_op(1,==, string_is_C_identifier("_0string_is_C_identifier")); + tt_int_op(1,==, string_is_C_identifier("_0")); + + tt_int_op(0,==, string_is_C_identifier("0_string_is_C_identifier")); + tt_int_op(0,==, string_is_C_identifier("0")); + tt_int_op(0,==, string_is_C_identifier("")); + tt_int_op(0,==, string_is_C_identifier(";")); + tt_int_op(0,==, string_is_C_identifier("i;")); + tt_int_op(0,==, string_is_C_identifier("_;")); + tt_int_op(0,==, string_is_C_identifier("í")); + tt_int_op(0,==, string_is_C_identifier("ñ")); done: ; @@ -2261,48 +3113,48 @@ test_util_asprintf(void *ptr) /* simple string */ r = tor_asprintf(&cp, "simple string 100%% safe"); - test_assert(cp); - test_streq("simple string 100% safe", cp); - test_eq(strlen(cp), r); + tt_assert(cp); + tt_str_op("simple string 100% safe",==, cp); + tt_int_op(strlen(cp),==, r); tor_free(cp); /* empty string */ r = tor_asprintf(&cp, "%s", ""); - test_assert(cp); - test_streq("", cp); - test_eq(strlen(cp), r); + tt_assert(cp); + tt_str_op("",==, cp); + tt_int_op(strlen(cp),==, r); tor_free(cp); /* numbers (%i) */ r = tor_asprintf(&cp, "I like numbers-%2i, %i, etc.", -1, 2); - test_assert(cp); - test_streq("I like numbers--1, 2, etc.", cp); - test_eq(strlen(cp), r); + tt_assert(cp); + tt_str_op("I like numbers--1, 2, etc.",==, cp); + tt_int_op(strlen(cp),==, r); /* don't free cp; next test uses it. */ /* numbers (%d) */ r = tor_asprintf(&cp2, "First=%d, Second=%d", 101, 202); - test_assert(cp2); - test_eq(strlen(cp2), r); - test_streq("First=101, Second=202", cp2); - test_assert(cp != cp2); + tt_assert(cp2); + tt_int_op(strlen(cp2),==, r); + tt_str_op("First=101, Second=202",==, cp2); + tt_assert(cp != cp2); tor_free(cp); tor_free(cp2); /* Glass-box test: a string exactly 128 characters long. */ r = tor_asprintf(&cp, "Lorem1: %sLorem2: %s", LOREMIPSUM, LOREMIPSUM); - test_assert(cp); - test_eq(128, r); - test_assert(cp[128] == '\0'); - test_streq("Lorem1: "LOREMIPSUM"Lorem2: "LOREMIPSUM, cp); + tt_assert(cp); + tt_int_op(128,==, r); + tt_int_op(cp[128], ==, '\0'); + tt_str_op("Lorem1: "LOREMIPSUM"Lorem2: "LOREMIPSUM,==, cp); tor_free(cp); /* String longer than 128 characters */ r = tor_asprintf(&cp, "1: %s 2: %s 3: %s", LOREMIPSUM, LOREMIPSUM, LOREMIPSUM); - test_assert(cp); - test_eq(strlen(cp), r); - test_streq("1: "LOREMIPSUM" 2: "LOREMIPSUM" 3: "LOREMIPSUM, cp); + tt_assert(cp); + tt_int_op(strlen(cp),==, r); + tt_str_op("1: "LOREMIPSUM" 2: "LOREMIPSUM" 3: "LOREMIPSUM,==, cp); done: tor_free(cp); @@ -2323,9 +3175,9 @@ test_util_listdir(void *ptr) dir1 = tor_strdup(get_fname("some-directory")); dirname = tor_strdup(get_fname(NULL)); - test_eq(0, write_str_to_file(fname1, "X\n", 0)); - test_eq(0, write_str_to_file(fname2, "Y\n", 0)); - test_eq(0, write_str_to_file(fname3, "Z\n", 0)); + tt_int_op(0,==, write_str_to_file(fname1, "X\n", 0)); + tt_int_op(0,==, write_str_to_file(fname2, "Y\n", 0)); + tt_int_op(0,==, write_str_to_file(fname3, "Z\n", 0)); #ifdef _WIN32 r = mkdir(dir1); #else @@ -2338,15 +3190,15 @@ test_util_listdir(void *ptr) } dir_contents = tor_listdir(dirname); - test_assert(dir_contents); + tt_assert(dir_contents); /* make sure that each filename is listed. */ - test_assert(smartlist_contains_string_case(dir_contents, "hopscotch")); - test_assert(smartlist_contains_string_case(dir_contents, "mumblety-peg")); - test_assert(smartlist_contains_string_case(dir_contents, ".hidden-file")); - test_assert(smartlist_contains_string_case(dir_contents, "some-directory")); + tt_assert(smartlist_contains_string_case(dir_contents, "hopscotch")); + tt_assert(smartlist_contains_string_case(dir_contents, "mumblety-peg")); + tt_assert(smartlist_contains_string_case(dir_contents, ".hidden-file")); + tt_assert(smartlist_contains_string_case(dir_contents, "some-directory")); - test_assert(!smartlist_contains_string(dir_contents, ".")); - test_assert(!smartlist_contains_string(dir_contents, "..")); + tt_assert(!smartlist_contains_string(dir_contents, ".")); + tt_assert(!smartlist_contains_string(dir_contents, "..")); done: tor_free(fname1); @@ -2486,30 +3338,53 @@ test_util_exit_status(void *ptr) (void)ptr; clear_hex_errno(hex_errno); + tt_str_op("",==, hex_errno); + + clear_hex_errno(hex_errno); n = format_helper_exit_status(0, 0, hex_errno); - test_streq("0/0\n", hex_errno); - test_eq(n, strlen(hex_errno)); + tt_str_op("0/0\n",==, hex_errno); + tt_int_op(n,==, strlen(hex_errno)); + +#if SIZEOF_INT == 4 clear_hex_errno(hex_errno); n = format_helper_exit_status(0, 0x7FFFFFFF, hex_errno); - test_streq("0/7FFFFFFF\n", hex_errno); - test_eq(n, strlen(hex_errno)); + tt_str_op("0/7FFFFFFF\n",==, hex_errno); + tt_int_op(n,==, strlen(hex_errno)); clear_hex_errno(hex_errno); n = format_helper_exit_status(0xFF, -0x80000000, hex_errno); - test_streq("FF/-80000000\n", hex_errno); - test_eq(n, strlen(hex_errno)); - test_eq(n, HEX_ERRNO_SIZE); + tt_str_op("FF/-80000000\n",==, hex_errno); + tt_int_op(n,==, strlen(hex_errno)); + tt_int_op(n,==, HEX_ERRNO_SIZE); + +#elif SIZEOF_INT == 8 + + clear_hex_errno(hex_errno); + n = format_helper_exit_status(0, 0x7FFFFFFFFFFFFFFF, hex_errno); + tt_str_op("0/7FFFFFFFFFFFFFFF\n",==, hex_errno); + tt_int_op(n,==, strlen(hex_errno)); + + clear_hex_errno(hex_errno); + n = format_helper_exit_status(0xFF, -0x8000000000000000, hex_errno); + tt_str_op("FF/-8000000000000000\n",==, hex_errno); + tt_int_op(n,==, strlen(hex_errno)); + tt_int_op(n,==, HEX_ERRNO_SIZE); + +#endif clear_hex_errno(hex_errno); n = format_helper_exit_status(0x7F, 0, hex_errno); - test_streq("7F/0\n", hex_errno); - test_eq(n, strlen(hex_errno)); + tt_str_op("7F/0\n",==, hex_errno); + tt_int_op(n,==, strlen(hex_errno)); clear_hex_errno(hex_errno); n = format_helper_exit_status(0x08, -0x242, hex_errno); - test_streq("8/-242\n", hex_errno); - test_eq(n, strlen(hex_errno)); + tt_str_op("8/-242\n",==, hex_errno); + tt_int_op(n,==, strlen(hex_errno)); + + clear_hex_errno(hex_errno); + tt_str_op("",==, hex_errno); done: ; @@ -2637,6 +3512,30 @@ test_util_fgets_eagain(void *ptr) #define EOL "\n" #endif +#ifdef _WIN32 +/* I've assumed Windows doesn't have the gap between fork and exec + * that causes the race condition on unix-like platforms */ +#define MATCH_PROCESS_STATUS(s1,s2) ((s1) == (s2)) + +#else +/* work around a race condition of the timing of SIGCHLD handler updates + * to the process_handle's fields, and checks of those fields + * + * TODO: Once we can signal failure to exec, change PROCESS_STATUS_RUNNING to + * PROCESS_STATUS_ERROR (and similarly with *_OR_NOTRUNNING) */ +#define PROCESS_STATUS_RUNNING_OR_NOTRUNNING (PROCESS_STATUS_RUNNING+1) +#define IS_RUNNING_OR_NOTRUNNING(s) \ + ((s) == PROCESS_STATUS_RUNNING || (s) == PROCESS_STATUS_NOTRUNNING) +/* well, this is ugly */ +#define MATCH_PROCESS_STATUS(s1,s2) \ + ( (s1) == (s2) \ + ||((s1) == PROCESS_STATUS_RUNNING_OR_NOTRUNNING \ + && IS_RUNNING_OR_NOTRUNNING(s2)) \ + ||((s2) == PROCESS_STATUS_RUNNING_OR_NOTRUNNING \ + && IS_RUNNING_OR_NOTRUNNING(s1))) + +#endif // _WIN32 + /** Helper function for testing tor_spawn_background */ static void run_util_spawn_background(const char *argv[], const char *expected_out, @@ -2658,26 +3557,47 @@ run_util_spawn_background(const char *argv[], const char *expected_out, notify_pending_waitpid_callbacks(); - test_eq(expected_status, status); + /* the race condition doesn't affect status, + * because status isn't updated by the SIGCHLD handler, + * but we still need to handle PROCESS_STATUS_RUNNING_OR_NOTRUNNING */ + tt_assert(MATCH_PROCESS_STATUS(expected_status, status)); if (status == PROCESS_STATUS_ERROR) { tt_ptr_op(process_handle, ==, NULL); return; } - test_assert(process_handle != NULL); - test_eq(expected_status, process_handle->status); + tt_assert(process_handle != NULL); + + /* When a spawned process forks, fails, then exits very quickly, + * (this typically occurs when exec fails) + * there is a race condition between the SIGCHLD handler + * updating the process_handle's fields, and this test + * checking the process status in those fields. + * The SIGCHLD update can occur before or after the code below executes. + * This causes intermittent failures in spawn_background_fail(), + * typically when the machine is under load. + * We use PROCESS_STATUS_RUNNING_OR_NOTRUNNING to avoid this issue. */ + + /* the race condition affects the change in + * process_handle->status from RUNNING to NOTRUNNING */ + tt_assert(MATCH_PROCESS_STATUS(expected_status, process_handle->status)); #ifndef _WIN32 notify_pending_waitpid_callbacks(); - tt_ptr_op(process_handle->waitpid_cb, !=, NULL); + /* the race condition affects the change in + * process_handle->waitpid_cb to NULL, + * so we skip the check if expected_status is ambiguous, + * that is, PROCESS_STATUS_RUNNING_OR_NOTRUNNING */ + tt_assert(process_handle->waitpid_cb != NULL + || expected_status == PROCESS_STATUS_RUNNING_OR_NOTRUNNING); #endif #ifdef _WIN32 - test_assert(process_handle->stdout_pipe != INVALID_HANDLE_VALUE); - test_assert(process_handle->stderr_pipe != INVALID_HANDLE_VALUE); + tt_assert(process_handle->stdout_pipe != INVALID_HANDLE_VALUE); + tt_assert(process_handle->stderr_pipe != INVALID_HANDLE_VALUE); #else - test_assert(process_handle->stdout_pipe >= 0); - test_assert(process_handle->stderr_pipe >= 0); + tt_assert(process_handle->stdout_pipe >= 0); + tt_assert(process_handle->stderr_pipe >= 0); #endif /* Check stdout */ @@ -2685,15 +3605,15 @@ run_util_spawn_background(const char *argv[], const char *expected_out, sizeof(stdout_buf) - 1); tt_assert(pos >= 0); stdout_buf[pos] = '\0'; - test_eq(strlen(expected_out), pos); - test_streq(expected_out, stdout_buf); + tt_int_op(strlen(expected_out),==, pos); + tt_str_op(expected_out,==, stdout_buf); notify_pending_waitpid_callbacks(); /* Check it terminated correctly */ retval = tor_get_exit_code(process_handle, 1, &exit_code); - test_eq(PROCESS_EXIT_EXITED, retval); - test_eq(expected_exit, exit_code); + tt_int_op(PROCESS_EXIT_EXITED,==, retval); + tt_int_op(expected_exit,==, exit_code); // TODO: Make test-child exit with something other than 0 #ifndef _WIN32 @@ -2704,10 +3624,10 @@ run_util_spawn_background(const char *argv[], const char *expected_out, /* Check stderr */ pos = tor_read_all_from_process_stderr(process_handle, stderr_buf, sizeof(stderr_buf) - 1); - test_assert(pos >= 0); + tt_assert(pos >= 0); stderr_buf[pos] = '\0'; - test_streq(expected_err, stderr_buf); - test_eq(strlen(expected_err), pos); + tt_str_op(expected_err,==, stderr_buf); + tt_int_op(strlen(expected_err),==, pos); notify_pending_waitpid_callbacks(); @@ -2742,10 +3662,13 @@ test_util_spawn_background_fail(void *ptr) const int expected_status = PROCESS_STATUS_ERROR; #else /* TODO: Once we can signal failure to exec, set this to be - * PROCESS_STATUS_ERROR */ - const int expected_status = PROCESS_STATUS_RUNNING; + * PROCESS_STATUS_RUNNING_OR_ERROR */ + const int expected_status = PROCESS_STATUS_RUNNING_OR_NOTRUNNING; #endif + memset(expected_out, 0xf0, sizeof(expected_out)); + memset(code, 0xf0, sizeof(code)); + (void)ptr; tor_snprintf(code, sizeof(code), "%x/%x", @@ -2793,9 +3716,9 @@ test_util_spawn_background_partial_read_impl(int exit_early) #else status = tor_spawn_background(argv[0], argv, NULL, &process_handle); #endif - test_eq(expected_status, status); - test_assert(process_handle); - test_eq(expected_status, process_handle->status); + tt_int_op(expected_status,==, status); + tt_assert(process_handle); + tt_int_op(expected_status,==, process_handle->status); /* Check stdout */ for (expected_out_ctr = 0; expected_out[expected_out_ctr] != NULL;) { @@ -2804,7 +3727,7 @@ test_util_spawn_background_partial_read_impl(int exit_early) sizeof(stdout_buf) - 1, NULL); #else /* Check that we didn't read the end of file last time */ - test_assert(!eof); + tt_assert(!eof); pos = tor_read_all_handle(process_handle->stdout_handle, stdout_buf, sizeof(stdout_buf) - 1, NULL, &eof); #endif @@ -2814,10 +3737,10 @@ test_util_spawn_background_partial_read_impl(int exit_early) if (0 == pos) continue; - test_assert(pos > 0); + tt_assert(pos > 0); stdout_buf[pos] = '\0'; - test_streq(expected_out[expected_out_ctr], stdout_buf); - test_eq(strlen(expected_out[expected_out_ctr]), pos); + tt_str_op(expected_out[expected_out_ctr],==, stdout_buf); + tt_int_op(strlen(expected_out[expected_out_ctr]),==, pos); expected_out_ctr++; } @@ -2832,33 +3755,33 @@ test_util_spawn_background_partial_read_impl(int exit_early) pos = tor_read_all_handle(process_handle->stdout_pipe, stdout_buf, sizeof(stdout_buf) - 1, process_handle); - test_eq(0, pos); + tt_int_op(0,==, pos); #else if (!eof) { /* We should have got all the data, but maybe not the EOF flag */ pos = tor_read_all_handle(process_handle->stdout_handle, stdout_buf, sizeof(stdout_buf) - 1, process_handle, &eof); - test_eq(0, pos); - test_assert(eof); + tt_int_op(0,==, pos); + tt_assert(eof); } /* Otherwise, we got the EOF on the last read */ #endif /* Check it terminated correctly */ retval = tor_get_exit_code(process_handle, 1, &exit_code); - test_eq(PROCESS_EXIT_EXITED, retval); - test_eq(expected_exit, exit_code); + tt_int_op(PROCESS_EXIT_EXITED,==, retval); + tt_int_op(expected_exit,==, exit_code); // TODO: Make test-child exit with something other than 0 /* Check stderr */ pos = tor_read_all_from_process_stderr(process_handle, stderr_buf, sizeof(stderr_buf) - 1); - test_assert(pos >= 0); + tt_assert(pos >= 0); stderr_buf[pos] = '\0'; - test_streq(expected_err, stderr_buf); - test_eq(strlen(expected_err), pos); + tt_str_op(expected_err,==, stderr_buf); + tt_int_op(strlen(expected_err),==, pos); done: tor_process_handle_destroy(process_handle, 1); @@ -2933,6 +3856,13 @@ test_util_spawn_background_waitpid_notify(void *arg) #undef TEST_CHILD #undef EOL +#undef MATCH_PROCESS_STATUS + +#ifndef _WIN32 +#undef PROCESS_STATUS_RUNNING_OR_NOTRUNNING +#undef IS_RUNNING_OR_NOTRUNNING +#endif + /** * Test for format_hex_number_sigsafe() */ @@ -2963,15 +3893,15 @@ test_util_format_hex_number(void *ptr) for (i = 0; test_data[i].str != NULL; ++i) { len = format_hex_number_sigsafe(test_data[i].x, buf, sizeof(buf)); - test_neq(len, 0); - test_eq(len, strlen(buf)); - test_streq(buf, test_data[i].str); + tt_int_op(len,!=, 0); + tt_int_op(len,==, strlen(buf)); + tt_str_op(buf,==, test_data[i].str); } - test_eq(4, format_hex_number_sigsafe(0xffff, buf, 5)); - test_streq(buf, "FFFF"); - test_eq(0, format_hex_number_sigsafe(0xffff, buf, 4)); - test_eq(0, format_hex_number_sigsafe(0, buf, 1)); + tt_int_op(4,==, format_hex_number_sigsafe(0xffff, buf, 5)); + tt_str_op(buf,==, "FFFF"); + tt_int_op(0,==, format_hex_number_sigsafe(0xffff, buf, 4)); + tt_int_op(0,==, format_hex_number_sigsafe(0, buf, 1)); done: return; @@ -3007,21 +3937,21 @@ test_util_format_dec_number(void *ptr) for (i = 0; test_data[i].str != NULL; ++i) { len = format_dec_number_sigsafe(test_data[i].x, buf, sizeof(buf)); - test_neq(len, 0); - test_eq(len, strlen(buf)); - test_streq(buf, test_data[i].str); + tt_int_op(len,!=, 0); + tt_int_op(len,==, strlen(buf)); + tt_str_op(buf,==, test_data[i].str); len = format_dec_number_sigsafe(test_data[i].x, buf, (int)(strlen(test_data[i].str) + 1)); - test_eq(len, strlen(buf)); - test_streq(buf, test_data[i].str); + tt_int_op(len,==, strlen(buf)); + tt_str_op(buf,==, test_data[i].str); } - test_eq(4, format_dec_number_sigsafe(7331, buf, 5)); - test_streq(buf, "7331"); - test_eq(0, format_dec_number_sigsafe(7331, buf, 4)); - test_eq(1, format_dec_number_sigsafe(0, buf, 2)); - test_eq(0, format_dec_number_sigsafe(0, buf, 1)); + tt_int_op(4,==, format_dec_number_sigsafe(7331, buf, 5)); + tt_str_op(buf,==, "7331"); + tt_int_op(0,==, format_dec_number_sigsafe(7331, buf, 4)); + tt_int_op(1,==, format_dec_number_sigsafe(0, buf, 2)); + tt_int_op(0,==, format_dec_number_sigsafe(0, buf, 1)); done: return; @@ -3070,7 +4000,7 @@ test_util_join_win_cmdline(void *ptr) for (i=0; cmdlines[i]!=NULL; i++) { log_info(LD_GENERAL, "Joining argvs[%d], expecting <%s>", i, cmdlines[i]); joined_argv = tor_join_win_cmdline(argvs[i]); - test_streq(cmdlines[i], joined_argv); + tt_str_op(cmdlines[i],==, joined_argv); tor_free(joined_argv); } @@ -3125,17 +4055,17 @@ test_util_split_lines(void *ptr) i, tests[i].orig_length); SMARTLIST_FOREACH_BEGIN(sl, const char *, line) { /* Check we have not got too many lines */ - test_assert(j < MAX_SPLIT_LINE_COUNT); + tt_int_op(MAX_SPLIT_LINE_COUNT, >, j); /* Check that there actually should be a line here */ - test_assert(tests[i].split_line[j] != NULL); + tt_assert(tests[i].split_line[j] != NULL); log_info(LD_GENERAL, "Line %d of test %d, should be <%s>", j, i, tests[i].split_line[j]); /* Check that the line is as expected */ - test_streq(line, tests[i].split_line[j]); + tt_str_op(line,==, tests[i].split_line[j]); j++; } SMARTLIST_FOREACH_END(line); /* Check that we didn't miss some lines */ - test_eq_ptr(NULL, tests[i].split_line[j]); + tt_ptr_op(NULL,==, tests[i].split_line[j]); tor_free(orig_line); smartlist_free(sl); sl = NULL; @@ -3147,7 +4077,7 @@ test_util_split_lines(void *ptr) } static void -test_util_di_ops(void) +test_util_di_ops(void *arg) { #define LT -1 #define GT 1 @@ -3167,10 +4097,11 @@ test_util_di_ops(void) int i; + (void)arg; for (i = 0; examples[i].a; ++i) { size_t len = strlen(examples[i].a); int eq1, eq2, neq1, neq2, cmp1, cmp2; - test_eq(len, strlen(examples[i].b)); + tt_int_op(len,==, strlen(examples[i].b)); /* We do all of the operations, with operands in both orders. */ eq1 = tor_memeq(examples[i].a, examples[i].b, len); eq2 = tor_memeq(examples[i].b, examples[i].a, len); @@ -3181,18 +4112,37 @@ test_util_di_ops(void) /* Check for correctness of cmp1 */ if (cmp1 < 0 && examples[i].want_sign != LT) - test_fail(); + TT_DIE(("Assertion failed.")); else if (cmp1 > 0 && examples[i].want_sign != GT) - test_fail(); + TT_DIE(("Assertion failed.")); else if (cmp1 == 0 && examples[i].want_sign != EQ) - test_fail(); + TT_DIE(("Assertion failed.")); /* Check for consistency of everything else with cmp1 */ - test_eq(eq1, eq2); - test_eq(neq1, neq2); - test_eq(cmp1, -cmp2); - test_eq(eq1, cmp1 == 0); - test_eq(neq1, !eq1); + tt_int_op(eq1,==, eq2); + tt_int_op(neq1,==, neq2); + tt_int_op(cmp1,==, -cmp2); + tt_int_op(eq1,==, cmp1 == 0); + tt_int_op(neq1,==, !eq1); + } + + { + uint8_t zz = 0; + uint8_t ii = 0; + int z; + + /* exhaustively test tor_memeq and tor_memcmp + * against each possible single-byte numeric difference + * some arithmetic bugs only appear with certain bit patterns */ + for (z = 0; z < 256; z++) { + for (i = 0; i < 256; i++) { + ii = (uint8_t)i; + zz = (uint8_t)z; + tt_int_op(tor_memeq(&zz, &ii, 1),==, zz == ii); + tt_int_op(tor_memcmp(&zz, &ii, 1) > 0 ? GT : EQ,==, zz > ii ? GT : EQ); + tt_int_op(tor_memcmp(&ii, &zz, 1) < 0 ? LT : EQ,==, ii < zz ? LT : EQ); + } + } } tt_int_op(1, ==, safe_mem_is_zero("", 0)); @@ -3216,12 +4166,12 @@ static void test_util_n_bits_set(void *ptr) { (void)ptr; - test_eq(0, n_bits_set_u8(0)); - test_eq(1, n_bits_set_u8(1)); - test_eq(3, n_bits_set_u8(7)); - test_eq(1, n_bits_set_u8(8)); - test_eq(2, n_bits_set_u8(129)); - test_eq(8, n_bits_set_u8(255)); + tt_int_op(0,==, n_bits_set_u8(0)); + tt_int_op(1,==, n_bits_set_u8(1)); + tt_int_op(3,==, n_bits_set_u8(7)); + tt_int_op(1,==, n_bits_set_u8(8)); + tt_int_op(2,==, n_bits_set_u8(129)); + tt_int_op(8,==, n_bits_set_u8(255)); done: ; } @@ -3242,78 +4192,78 @@ test_util_eat_whitespace(void *ptr) strlcpy(str, "fuubaar", sizeof(str)); for (i = 0; i < sizeof(ws); ++i) { str[0] = ws[i]; - test_eq_ptr(str + 1, eat_whitespace(str)); - test_eq_ptr(str + 1, eat_whitespace_eos(str, str + strlen(str))); - test_eq_ptr(str + 1, eat_whitespace_no_nl(str)); - test_eq_ptr(str + 1, eat_whitespace_eos_no_nl(str, str + strlen(str))); + tt_ptr_op(str + 1,==, eat_whitespace(str)); + tt_ptr_op(str + 1,==, eat_whitespace_eos(str, str + strlen(str))); + tt_ptr_op(str + 1,==, eat_whitespace_no_nl(str)); + tt_ptr_op(str + 1,==, eat_whitespace_eos_no_nl(str, str + strlen(str))); } str[0] = '\n'; - test_eq_ptr(str + 1, eat_whitespace(str)); - test_eq_ptr(str + 1, eat_whitespace_eos(str, str + strlen(str))); - test_eq_ptr(str, eat_whitespace_no_nl(str)); - test_eq_ptr(str, eat_whitespace_eos_no_nl(str, str + strlen(str))); + tt_ptr_op(str + 1,==, eat_whitespace(str)); + tt_ptr_op(str + 1,==, eat_whitespace_eos(str, str + strlen(str))); + tt_ptr_op(str,==, eat_whitespace_no_nl(str)); + tt_ptr_op(str,==, eat_whitespace_eos_no_nl(str, str + strlen(str))); /* Empty string */ strlcpy(str, "", sizeof(str)); - test_eq_ptr(str, eat_whitespace(str)); - test_eq_ptr(str, eat_whitespace_eos(str, str)); - test_eq_ptr(str, eat_whitespace_no_nl(str)); - test_eq_ptr(str, eat_whitespace_eos_no_nl(str, str)); + tt_ptr_op(str,==, eat_whitespace(str)); + tt_ptr_op(str,==, eat_whitespace_eos(str, str)); + tt_ptr_op(str,==, eat_whitespace_no_nl(str)); + tt_ptr_op(str,==, eat_whitespace_eos_no_nl(str, str)); /* Only ws */ strlcpy(str, " \t\r\n", sizeof(str)); - test_eq_ptr(str + strlen(str), eat_whitespace(str)); - test_eq_ptr(str + strlen(str), eat_whitespace_eos(str, str + strlen(str))); - test_eq_ptr(str + strlen(str) - 1, + tt_ptr_op(str + strlen(str),==, eat_whitespace(str)); + tt_ptr_op(str + strlen(str),==, eat_whitespace_eos(str, str + strlen(str))); + tt_ptr_op(str + strlen(str) - 1,==, eat_whitespace_no_nl(str)); - test_eq_ptr(str + strlen(str) - 1, + tt_ptr_op(str + strlen(str) - 1,==, eat_whitespace_eos_no_nl(str, str + strlen(str))); strlcpy(str, " \t\r ", sizeof(str)); - test_eq_ptr(str + strlen(str), eat_whitespace(str)); - test_eq_ptr(str + strlen(str), + tt_ptr_op(str + strlen(str),==, eat_whitespace(str)); + tt_ptr_op(str + strlen(str),==, eat_whitespace_eos(str, str + strlen(str))); - test_eq_ptr(str + strlen(str), eat_whitespace_no_nl(str)); - test_eq_ptr(str + strlen(str), + tt_ptr_op(str + strlen(str),==, eat_whitespace_no_nl(str)); + tt_ptr_op(str + strlen(str),==, eat_whitespace_eos_no_nl(str, str + strlen(str))); /* Multiple ws */ strlcpy(str, "fuubaar", sizeof(str)); for (i = 0; i < sizeof(ws); ++i) str[i] = ws[i]; - test_eq_ptr(str + sizeof(ws), eat_whitespace(str)); - test_eq_ptr(str + sizeof(ws), eat_whitespace_eos(str, str + strlen(str))); - test_eq_ptr(str + sizeof(ws), eat_whitespace_no_nl(str)); - test_eq_ptr(str + sizeof(ws), + tt_ptr_op(str + sizeof(ws),==, eat_whitespace(str)); + tt_ptr_op(str + sizeof(ws),==, eat_whitespace_eos(str, str + strlen(str))); + tt_ptr_op(str + sizeof(ws),==, eat_whitespace_no_nl(str)); + tt_ptr_op(str + sizeof(ws),==, eat_whitespace_eos_no_nl(str, str + strlen(str))); /* Eat comment */ strlcpy(str, "# Comment \n No Comment", sizeof(str)); - test_streq("No Comment", eat_whitespace(str)); - test_streq("No Comment", eat_whitespace_eos(str, str + strlen(str))); - test_eq_ptr(str, eat_whitespace_no_nl(str)); - test_eq_ptr(str, eat_whitespace_eos_no_nl(str, str + strlen(str))); + tt_str_op("No Comment",==, eat_whitespace(str)); + tt_str_op("No Comment",==, eat_whitespace_eos(str, str + strlen(str))); + tt_ptr_op(str,==, eat_whitespace_no_nl(str)); + tt_ptr_op(str,==, eat_whitespace_eos_no_nl(str, str + strlen(str))); /* Eat comment & ws mix */ strlcpy(str, " # \t Comment \n\t\nNo Comment", sizeof(str)); - test_streq("No Comment", eat_whitespace(str)); - test_streq("No Comment", eat_whitespace_eos(str, str + strlen(str))); - test_eq_ptr(str + 1, eat_whitespace_no_nl(str)); - test_eq_ptr(str + 1, eat_whitespace_eos_no_nl(str, str + strlen(str))); + tt_str_op("No Comment",==, eat_whitespace(str)); + tt_str_op("No Comment",==, eat_whitespace_eos(str, str + strlen(str))); + tt_ptr_op(str + 1,==, eat_whitespace_no_nl(str)); + tt_ptr_op(str + 1,==, eat_whitespace_eos_no_nl(str, str + strlen(str))); /* Eat entire comment */ strlcpy(str, "#Comment", sizeof(str)); - test_eq_ptr(str + strlen(str), eat_whitespace(str)); - test_eq_ptr(str + strlen(str), eat_whitespace_eos(str, str + strlen(str))); - test_eq_ptr(str, eat_whitespace_no_nl(str)); - test_eq_ptr(str, eat_whitespace_eos_no_nl(str, str + strlen(str))); + tt_ptr_op(str + strlen(str),==, eat_whitespace(str)); + tt_ptr_op(str + strlen(str),==, eat_whitespace_eos(str, str + strlen(str))); + tt_ptr_op(str,==, eat_whitespace_no_nl(str)); + tt_ptr_op(str,==, eat_whitespace_eos_no_nl(str, str + strlen(str))); /* Blank line, then comment */ strlcpy(str, " \t\n # Comment", sizeof(str)); - test_eq_ptr(str + strlen(str), eat_whitespace(str)); - test_eq_ptr(str + strlen(str), eat_whitespace_eos(str, str + strlen(str))); - test_eq_ptr(str + 2, eat_whitespace_no_nl(str)); - test_eq_ptr(str + 2, eat_whitespace_eos_no_nl(str, str + strlen(str))); + tt_ptr_op(str + strlen(str),==, eat_whitespace(str)); + tt_ptr_op(str + strlen(str),==, eat_whitespace_eos(str, str + strlen(str))); + tt_ptr_op(str + 2,==, eat_whitespace_no_nl(str)); + tt_ptr_op(str + 2,==, eat_whitespace_eos_no_nl(str, str + strlen(str))); done: ; @@ -3641,12 +4591,12 @@ test_util_round_to_next_multiple_of(void *arg) { (void)arg; - test_assert(round_uint64_to_next_multiple_of(0,1) == 0); - test_assert(round_uint64_to_next_multiple_of(0,7) == 0); + tt_assert(round_uint64_to_next_multiple_of(0,1) == 0); + tt_assert(round_uint64_to_next_multiple_of(0,7) == 0); - test_assert(round_uint64_to_next_multiple_of(99,1) == 99); - test_assert(round_uint64_to_next_multiple_of(99,7) == 105); - test_assert(round_uint64_to_next_multiple_of(99,9) == 99); + tt_assert(round_uint64_to_next_multiple_of(99,1) == 99); + tt_assert(round_uint64_to_next_multiple_of(99,7) == 105); + tt_assert(round_uint64_to_next_multiple_of(99,9) == 99); done: ; @@ -3673,7 +4623,7 @@ test_util_strclear(void *arg) } #define UTIL_LEGACY(name) \ - { #name, legacy_test_helper, 0, &legacy_setup, test_util_ ## name } + { #name, test_util_ ## name , 0, NULL, NULL } #define UTIL_TEST(name, flags) \ { #name, test_util_ ## name, flags, NULL, NULL } @@ -3858,6 +4808,7 @@ struct testcase_t util_tests[] = { UTIL_LEGACY(mmap), UTIL_LEGACY(threads), UTIL_LEGACY(sscanf), + UTIL_LEGACY(format_time_interval), UTIL_LEGACY(path_is_relative), UTIL_LEGACY(strtok), UTIL_LEGACY(di_ops), |