database_unittest.cc 118 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632
  1. // Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  8. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  9. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  12. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. // PERFORMANCE OF THIS SOFTWARE.
  14. #include <boost/foreach.hpp>
  15. #include <gtest/gtest.h>
  16. #include <dns/name.h>
  17. #include <dns/rrttl.h>
  18. #include <dns/rrset.h>
  19. #include <exceptions/exceptions.h>
  20. #include <datasrc/database.h>
  21. #include <datasrc/zone.h>
  22. #include <datasrc/data_source.h>
  23. #include <datasrc/iterator.h>
  24. #include <datasrc/sqlite3_accessor.h>
  25. #include <testutils/dnsmessage_test.h>
  26. #include <map>
  27. using namespace isc::datasrc;
  28. using namespace std;
  29. using namespace boost;
  30. using namespace isc::dns;
  31. namespace {
  32. // Imaginary zone IDs used in the mock accessor below.
  33. const int READONLY_ZONE_ID = 42;
  34. const int WRITABLE_ZONE_ID = 4200;
  35. // Commonly used test data
  36. const char* const TEST_RECORDS[][5] = {
  37. // some plain data
  38. {"www.example.org.", "A", "3600", "", "192.0.2.1"},
  39. {"www.example.org.", "AAAA", "3600", "", "2001:db8::1"},
  40. {"www.example.org.", "AAAA", "3600", "", "2001:db8::2"},
  41. {"www.example.org.", "NSEC", "3600", "", "www2.example.org. A AAAA NSEC RRSIG"},
  42. {"www.example.org.", "RRSIG", "3600", "", "NSEC 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE"},
  43. {"www2.example.org.", "A", "3600", "", "192.0.2.1"},
  44. {"www2.example.org.", "AAAA", "3600", "", "2001:db8::1"},
  45. {"www2.example.org.", "A", "3600", "", "192.0.2.2"},
  46. {"cname.example.org.", "CNAME", "3600", "", "www.example.org."},
  47. // some DNSSEC-'signed' data
  48. {"signed1.example.org.", "A", "3600", "", "192.0.2.1"},
  49. {"signed1.example.org.", "RRSIG", "3600", "", "A 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE"},
  50. {"signed1.example.org.", "RRSIG", "3600", "", "A 5 3 3600 20000101000000 20000201000000 12346 example.org. FAKEFAKEFAKE"},
  51. {"signed1.example.org.", "AAAA", "3600", "", "2001:db8::1"},
  52. {"signed1.example.org.", "AAAA", "3600", "", "2001:db8::2"},
  53. {"signed1.example.org.", "RRSIG", "3600", "", "AAAA 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE"},
  54. {"signedcname1.example.org.", "CNAME", "3600", "", "www.example.org."},
  55. {"signedcname1.example.org.", "RRSIG", "3600", "", "CNAME 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE"},
  56. // special case might fail; sig is for cname, which isn't there (should be ignored)
  57. // (ignoring of 'normal' other type is done above by www.)
  58. {"acnamesig1.example.org.", "A", "3600", "", "192.0.2.1"},
  59. {"acnamesig1.example.org.", "RRSIG", "3600", "", "A 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE"},
  60. {"acnamesig1.example.org.", "RRSIG", "3600", "", "CNAME 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE"},
  61. // let's pretend we have a database that is not careful
  62. // about the order in which it returns data
  63. {"signed2.example.org.", "RRSIG", "3600", "", "A 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE"},
  64. {"signed2.example.org.", "AAAA", "3600", "", "2001:db8::2"},
  65. {"signed2.example.org.", "RRSIG", "3600", "", "A 5 3 3600 20000101000000 20000201000000 12346 example.org. FAKEFAKEFAKE"},
  66. {"signed2.example.org.", "A", "3600", "", "192.0.2.1"},
  67. {"signed2.example.org.", "RRSIG", "3600", "", "AAAA 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE"},
  68. {"signed2.example.org.", "AAAA", "3600", "", "2001:db8::1"},
  69. {"signedcname2.example.org.", "RRSIG", "3600", "", "CNAME 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE"},
  70. {"signedcname2.example.org.", "CNAME", "3600", "", "www.example.org."},
  71. {"acnamesig2.example.org.", "RRSIG", "3600", "", "CNAME 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE"},
  72. {"acnamesig2.example.org.", "A", "3600", "", "192.0.2.1"},
  73. {"acnamesig2.example.org.", "RRSIG", "3600", "", "A 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE"},
  74. {"acnamesig3.example.org.", "RRSIG", "3600", "", "CNAME 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE"},
  75. {"acnamesig3.example.org.", "RRSIG", "3600", "", "A 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE"},
  76. {"acnamesig3.example.org.", "A", "3600", "", "192.0.2.1"},
  77. {"ttldiff1.example.org.", "A", "3600", "", "192.0.2.1"},
  78. {"ttldiff1.example.org.", "A", "360", "", "192.0.2.2"},
  79. {"ttldiff2.example.org.", "A", "360", "", "192.0.2.1"},
  80. {"ttldiff2.example.org.", "A", "3600", "", "192.0.2.2"},
  81. // also add some intentionally bad data
  82. {"badcname1.example.org.", "A", "3600", "", "192.0.2.1"},
  83. {"badcname1.example.org.", "CNAME", "3600", "", "www.example.org."},
  84. {"badcname2.example.org.", "CNAME", "3600", "", "www.example.org."},
  85. {"badcname2.example.org.", "A", "3600", "", "192.0.2.1"},
  86. {"badcname3.example.org.", "CNAME", "3600", "", "www.example.org."},
  87. {"badcname3.example.org.", "CNAME", "3600", "", "www.example2.org."},
  88. {"badrdata.example.org.", "A", "3600", "", "bad"},
  89. {"badtype.example.org.", "BAD_TYPE", "3600", "", "192.0.2.1"},
  90. {"badttl.example.org.", "A", "badttl", "", "192.0.2.1"},
  91. {"badsig.example.org.", "A", "badttl", "", "192.0.2.1"},
  92. {"badsig.example.org.", "RRSIG", "3600", "", "A 5 3 3600 somebaddata 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE"},
  93. {"badsigtype.example.org.", "A", "3600", "", "192.0.2.1"},
  94. {"badsigtype.example.org.", "RRSIG", "3600", "TXT", "A 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE"},
  95. // Data for testing delegation (with NS and DNAME)
  96. {"delegation.example.org.", "NS", "3600", "", "ns.example.com."},
  97. {"delegation.example.org.", "NS", "3600", "",
  98. "ns.delegation.example.org."},
  99. {"delegation.example.org.", "DS", "3600", "", "1 RSAMD5 2 abcd"},
  100. {"delegation.example.org.", "RRSIG", "3600", "", "NS 5 3 3600 "
  101. "20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE"},
  102. {"ns.delegation.example.org.", "A", "3600", "", "192.0.2.1"},
  103. {"deep.below.delegation.example.org.", "A", "3600", "", "192.0.2.1"},
  104. {"dname.example.org.", "A", "3600", "", "192.0.2.1"},
  105. {"dname.example.org.", "DNAME", "3600", "", "dname.example.com."},
  106. {"dname.example.org.", "RRSIG", "3600", "",
  107. "DNAME 5 3 3600 20000101000000 20000201000000 12345 "
  108. "example.org. FAKEFAKEFAKE"},
  109. {"below.dname.example.org.", "A", "3600", "", "192.0.2.1"},
  110. // Broken NS
  111. {"brokenns1.example.org.", "A", "3600", "", "192.0.2.1"},
  112. {"brokenns1.example.org.", "NS", "3600", "", "ns.example.com."},
  113. {"brokenns2.example.org.", "NS", "3600", "", "ns.example.com."},
  114. {"brokenns2.example.org.", "A", "3600", "", "192.0.2.1"},
  115. // Now double DNAME, to test failure mode
  116. {"baddname.example.org.", "DNAME", "3600", "", "dname1.example.com."},
  117. {"baddname.example.org.", "DNAME", "3600", "", "dname2.example.com."},
  118. // Put some data into apex (including NS) so we can check our NS
  119. // doesn't break anything
  120. {"example.org.", "SOA", "3600", "", "ns1.example.org. admin.example.org. "
  121. "1234 3600 1800 2419200 7200" },
  122. {"example.org.", "NS", "3600", "", "ns.example.com."},
  123. {"example.org.", "A", "3600", "", "192.0.2.1"},
  124. {"example.org.", "NSEC", "3600", "", "acnamesig1.example.org. NS A NSEC RRSIG"},
  125. {"example.org.", "RRSIG", "3600", "", "SOA 5 3 3600 20000101000000 "
  126. "20000201000000 12345 example.org. FAKEFAKEFAKE"},
  127. {"example.org.", "RRSIG", "3600", "", "NSEC 5 3 3600 20000101000000 "
  128. "20000201000000 12345 example.org. FAKEFAKEFAKE"},
  129. {"example.org.", "RRSIG", "3600", "", "NS 5 3 3600 20000101000000 "
  130. "20000201000000 12345 example.org. FAKEFAKEFAKE"},
  131. // This is because of empty domain test
  132. {"a.b.example.org.", "A", "3600", "", "192.0.2.1"},
  133. // Something for wildcards
  134. {"*.wild.example.org.", "A", "3600", "", "192.0.2.5"},
  135. {"*.wild.example.org.", "RRSIG", "3600", "A", "A 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE"},
  136. {"*.wild.example.org.", "NSEC", "3600", "", "cancel.here.wild.example.org. A NSEC RRSIG"},
  137. {"*.wild.example.org.", "RRSIG", "3600", "", "NSEC 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE"},
  138. {"cancel.here.wild.example.org.", "AAAA", "3600", "", "2001:db8::5"},
  139. {"delegatedwild.example.org.", "NS", "3600", "", "ns.example.com."},
  140. {"*.delegatedwild.example.org.", "A", "3600", "", "192.0.2.5"},
  141. {"wild.*.foo.example.org.", "A", "3600", "", "192.0.2.5"},
  142. {"wild.*.foo.*.bar.example.org.", "A", "3600", "", "192.0.2.5"},
  143. {"wild.*.foo.*.bar.example.org.", "NSEC", "3600", "",
  144. "brokenns1.example.org. A NSEC"},
  145. {"bao.example.org.", "NSEC", "3600", "", "wild.*.foo.*.bar.example.org. NSEC"},
  146. {"*.cnamewild.example.org.", "CNAME", "3600", "", "www.example.org."},
  147. {"*.dnamewild.example.org.", "DNAME", "3600", "", "dname.example.com."},
  148. {"*.nswild.example.org.", "NS", "3600", "", "ns.example.com."},
  149. // For NSEC empty non-terminal
  150. {"l.example.org.", "NSEC", "3600", "", "empty.nonterminal.example.org. NSEC"},
  151. {"empty.nonterminal.example.org.", "A", "3600", "", "192.0.2.1"},
  152. // Invalid rdata
  153. {"invalidrdata.example.org.", "A", "3600", "", "Bunch of nonsense"},
  154. {"invalidrdata2.example.org.", "A", "3600", "", "192.0.2.1"},
  155. {"invalidrdata2.example.org.", "RRSIG", "3600", "", "Nonsense"},
  156. {NULL, NULL, NULL, NULL, NULL},
  157. };
  158. /*
  159. * An accessor with minimum implementation, keeping the original
  160. * "NotImplemented" methods.
  161. */
  162. class NopAccessor : public DatabaseAccessor {
  163. public:
  164. NopAccessor() : database_name_("mock_database")
  165. { }
  166. virtual std::pair<bool, int> getZone(const std::string& name) const {
  167. if (name == "example.org.") {
  168. return (std::pair<bool, int>(true, READONLY_ZONE_ID));
  169. } else if (name == "null.example.org.") {
  170. return (std::pair<bool, int>(true, 13));
  171. } else if (name == "empty.example.org.") {
  172. return (std::pair<bool, int>(true, 0));
  173. } else if (name == "bad.example.org.") {
  174. return (std::pair<bool, int>(true, -1));
  175. } else {
  176. return (std::pair<bool, int>(false, 0));
  177. }
  178. }
  179. virtual shared_ptr<DatabaseAccessor> clone() {
  180. // This accessor is stateless, so we can simply return a new instance.
  181. return (shared_ptr<DatabaseAccessor>(new NopAccessor));
  182. }
  183. virtual std::pair<bool, int> startUpdateZone(const std::string&, bool) {
  184. // return dummy value. unused anyway.
  185. return (pair<bool, int>(true, 0));
  186. }
  187. virtual void startTransaction() {}
  188. virtual void commit() {}
  189. virtual void rollback() {}
  190. virtual void addRecordToZone(const string (&)[ADD_COLUMN_COUNT]) {}
  191. virtual void deleteRecordInZone(const string (&)[DEL_PARAM_COUNT]) {}
  192. virtual void addRecordDiff(int, uint32_t, DiffOperation,
  193. const std::string (&)[DIFF_PARAM_COUNT]) {}
  194. virtual const std::string& getDBName() const {
  195. return (database_name_);
  196. }
  197. virtual IteratorContextPtr getRecords(const std::string&, int, bool)
  198. const
  199. {
  200. isc_throw(isc::NotImplemented,
  201. "This database datasource can't be iterated");
  202. }
  203. virtual IteratorContextPtr getAllRecords(int) const {
  204. isc_throw(isc::NotImplemented,
  205. "This database datasource can't be iterated");
  206. }
  207. virtual IteratorContextPtr getDiffs(int, uint32_t, uint32_t) const {
  208. isc_throw(isc::NotImplemented,
  209. "This database datasource can't be iterated");
  210. }
  211. virtual std::string findPreviousName(int, const std::string&) const {
  212. isc_throw(isc::NotImplemented,
  213. "This data source doesn't support DNSSEC");
  214. }
  215. private:
  216. const std::string database_name_;
  217. };
  218. /*
  219. * A virtual database accessor that pretends it contains single zone --
  220. * example.org.
  221. *
  222. * It has the same getZone method as NopConnection, but it provides
  223. * implementation of the optional functionality.
  224. */
  225. class MockAccessor : public NopAccessor {
  226. // Type of mock database "row"s. This is a map whose keys are the
  227. // own names. We internally sort them by the name comparison order.
  228. struct NameCompare : public binary_function<string, string, bool> {
  229. bool operator()(const string& n1, const string& n2) const {
  230. return (Name(n1).compare(Name(n2)).getOrder() < 0);
  231. }
  232. };
  233. typedef std::map<std::string,
  234. std::vector< std::vector<std::string> >,
  235. NameCompare > Domains;
  236. public:
  237. MockAccessor() : rollbacked_(false), did_transaction_(false) {
  238. readonly_records_ = &readonly_records_master_;
  239. update_records_ = &update_records_master_;
  240. empty_records_ = &empty_records_master_;
  241. fillData();
  242. }
  243. virtual shared_ptr<DatabaseAccessor> clone() {
  244. shared_ptr<MockAccessor> cloned_accessor(new MockAccessor());
  245. cloned_accessor->readonly_records_ = &readonly_records_master_;
  246. cloned_accessor->update_records_ = &update_records_master_;
  247. cloned_accessor->empty_records_ = &empty_records_master_;
  248. latest_clone_ = cloned_accessor;
  249. return (cloned_accessor);
  250. }
  251. virtual void startTransaction() {
  252. // Currently we only use this transaction for simple read-only
  253. // operations. So we just make a local copy of the data (we don't
  254. // care about what happens after commit() or rollback()).
  255. // Obviously as a consequence, if a test case tries to make multiple
  256. // transactions on a single mock accessor it will fail.
  257. // Check any attempt of multiple transactions
  258. if (did_transaction_) {
  259. isc_throw(isc::Unexpected, "MockAccessor::startTransaction() "
  260. "called multiple times - likely a bug in the test");
  261. }
  262. readonly_records_copy_ = *readonly_records_;
  263. readonly_records_ = &readonly_records_copy_;
  264. did_transaction_ = true;
  265. }
  266. private:
  267. class MockNameIteratorContext : public IteratorContext {
  268. public:
  269. MockNameIteratorContext(const MockAccessor& mock_accessor, int zone_id,
  270. const std::string& name, bool subdomains) :
  271. searched_name_(name), cur_record_(0)
  272. {
  273. // 'hardcoded' names to trigger exceptions
  274. // On these names some exceptions are thrown, to test the robustness
  275. // of the find() method.
  276. if (searched_name_ == "dsexception.in.search.") {
  277. isc_throw(DataSourceError, "datasource exception on search");
  278. } else if (searched_name_ == "iscexception.in.search.") {
  279. isc_throw(isc::Exception, "isc exception on search");
  280. } else if (searched_name_ == "basicexception.in.search.") {
  281. throw std::exception();
  282. }
  283. cur_record_ = 0;
  284. const Domains& cur_records = mock_accessor.getMockRecords(zone_id);
  285. if (cur_records.count(name) > 0) {
  286. // we're not aiming for efficiency in this test, simply
  287. // copy the relevant vector from records
  288. cur_name = cur_records.find(name)->second;
  289. } else if (subdomains) {
  290. cur_name.clear();
  291. // Just walk everything and check if it is a subdomain.
  292. // If it is, just copy all data from there.
  293. for (Domains::const_iterator i(cur_records.begin());
  294. i != cur_records.end(); ++i) {
  295. const Name local(i->first);
  296. if (local.compare(Name(name)).getRelation() ==
  297. isc::dns::NameComparisonResult::SUBDOMAIN) {
  298. cur_name.insert(cur_name.end(), i->second.begin(),
  299. i->second.end());
  300. }
  301. }
  302. } else {
  303. cur_name.clear();
  304. }
  305. }
  306. virtual bool getNext(std::string (&columns)[COLUMN_COUNT]) {
  307. if (searched_name_ == "dsexception.in.getnext.") {
  308. isc_throw(DataSourceError, "datasource exception on getnextrecord");
  309. } else if (searched_name_ == "iscexception.in.getnext.") {
  310. isc_throw(isc::Exception, "isc exception on getnextrecord");
  311. } else if (searched_name_ == "basicexception.in.getnext.") {
  312. throw std::exception();
  313. }
  314. if (cur_record_ < cur_name.size()) {
  315. for (size_t i = 0; i < COLUMN_COUNT; ++i) {
  316. columns[i] = cur_name[cur_record_][i];
  317. }
  318. cur_record_++;
  319. return (true);
  320. } else {
  321. return (false);
  322. }
  323. }
  324. private:
  325. const std::string searched_name_;
  326. int cur_record_;
  327. std::vector< std::vector<std::string> > cur_name;
  328. };
  329. class MockIteratorContext : public IteratorContext {
  330. private:
  331. int step;
  332. const Domains& domains_;
  333. public:
  334. MockIteratorContext(const Domains& domains) :
  335. step(0), domains_(domains)
  336. { }
  337. virtual bool getNext(string (&data)[COLUMN_COUNT]) {
  338. // A special case: if the given set of domains is already empty,
  339. // we always return false.
  340. if (domains_.empty()) {
  341. return (false);
  342. }
  343. // Return faked data for tests
  344. switch (step ++) {
  345. case 0:
  346. data[DatabaseAccessor::NAME_COLUMN] = "example.org";
  347. data[DatabaseAccessor::TYPE_COLUMN] = "A";
  348. data[DatabaseAccessor::TTL_COLUMN] = "3600";
  349. data[DatabaseAccessor::RDATA_COLUMN] = "192.0.2.1";
  350. return (true);
  351. case 1:
  352. data[DatabaseAccessor::NAME_COLUMN] = "example.org";
  353. data[DatabaseAccessor::TYPE_COLUMN] = "SOA";
  354. data[DatabaseAccessor::TTL_COLUMN] = "3600";
  355. data[DatabaseAccessor::RDATA_COLUMN] = "ns1.example.org. admin.example.org. "
  356. "1234 3600 1800 2419200 7200";
  357. return (true);
  358. case 2:
  359. data[DatabaseAccessor::NAME_COLUMN] = "x.example.org";
  360. data[DatabaseAccessor::TYPE_COLUMN] = "A";
  361. data[DatabaseAccessor::TTL_COLUMN] = "300";
  362. data[DatabaseAccessor::RDATA_COLUMN] = "192.0.2.1";
  363. return (true);
  364. case 3:
  365. data[DatabaseAccessor::NAME_COLUMN] = "x.example.org";
  366. data[DatabaseAccessor::TYPE_COLUMN] = "A";
  367. data[DatabaseAccessor::TTL_COLUMN] = "300";
  368. data[DatabaseAccessor::RDATA_COLUMN] = "192.0.2.2";
  369. return (true);
  370. case 4:
  371. data[DatabaseAccessor::NAME_COLUMN] = "x.example.org";
  372. data[DatabaseAccessor::TYPE_COLUMN] = "AAAA";
  373. data[DatabaseAccessor::TTL_COLUMN] = "300";
  374. data[DatabaseAccessor::RDATA_COLUMN] = "2001:db8::1";
  375. return (true);
  376. case 5:
  377. data[DatabaseAccessor::NAME_COLUMN] = "x.example.org";
  378. data[DatabaseAccessor::TYPE_COLUMN] = "AAAA";
  379. data[DatabaseAccessor::TTL_COLUMN] = "300";
  380. data[DatabaseAccessor::RDATA_COLUMN] = "2001:db8::2";
  381. return (true);
  382. default:
  383. ADD_FAILURE() <<
  384. "Request past the end of iterator context";
  385. case 6:
  386. return (false);
  387. }
  388. }
  389. };
  390. class EmptyIteratorContext : public IteratorContext {
  391. public:
  392. virtual bool getNext(string(&)[COLUMN_COUNT]) {
  393. return (false);
  394. }
  395. };
  396. class BadIteratorContext : public IteratorContext {
  397. private:
  398. int step;
  399. public:
  400. BadIteratorContext() :
  401. step(0)
  402. { }
  403. virtual bool getNext(string (&data)[COLUMN_COUNT]) {
  404. switch (step ++) {
  405. case 0:
  406. data[DatabaseAccessor::NAME_COLUMN] = "x.example.org";
  407. data[DatabaseAccessor::TYPE_COLUMN] = "A";
  408. data[DatabaseAccessor::TTL_COLUMN] = "300";
  409. data[DatabaseAccessor::RDATA_COLUMN] = "192.0.2.1";
  410. return (true);
  411. case 1:
  412. data[DatabaseAccessor::NAME_COLUMN] = "x.example.org";
  413. data[DatabaseAccessor::TYPE_COLUMN] = "A";
  414. data[DatabaseAccessor::TTL_COLUMN] = "301";
  415. data[DatabaseAccessor::RDATA_COLUMN] = "192.0.2.2";
  416. return (true);
  417. default:
  418. ADD_FAILURE() <<
  419. "Request past the end of iterator context";
  420. case 2:
  421. return (false);
  422. }
  423. }
  424. };
  425. public:
  426. virtual IteratorContextPtr getAllRecords(int id) const {
  427. if (id == READONLY_ZONE_ID) {
  428. return (IteratorContextPtr(new MockIteratorContext(
  429. *readonly_records_)));
  430. } else if (id == 13) {
  431. return (IteratorContextPtr());
  432. } else if (id == 0) {
  433. return (IteratorContextPtr(new EmptyIteratorContext()));
  434. } else if (id == -1) {
  435. return (IteratorContextPtr(new BadIteratorContext()));
  436. } else {
  437. isc_throw(isc::Unexpected, "Unknown zone ID");
  438. }
  439. }
  440. virtual IteratorContextPtr getRecords(const std::string& name, int id,
  441. bool subdomains) const
  442. {
  443. if (id == READONLY_ZONE_ID || id == WRITABLE_ZONE_ID) {
  444. return (IteratorContextPtr(
  445. new MockNameIteratorContext(*this, id, name,
  446. subdomains)));
  447. } else {
  448. // This iterator is bogus, but for the cases tested below that's
  449. // sufficient.
  450. return (IteratorContextPtr(
  451. new MockNameIteratorContext(*this, READONLY_ZONE_ID,
  452. name, subdomains)));
  453. }
  454. }
  455. virtual pair<bool, int> startUpdateZone(const std::string& zone_name,
  456. bool replace)
  457. {
  458. const pair<bool, int> zone_info = getZone(zone_name);
  459. if (!zone_info.first) {
  460. return (pair<bool, int>(false, 0));
  461. }
  462. // Prepare the record set for update. If replacing the existing one,
  463. // we use an empty set; otherwise we use a writable copy of the
  464. // original.
  465. if (replace) {
  466. update_records_->clear();
  467. } else {
  468. *update_records_ = *readonly_records_;
  469. }
  470. return (pair<bool, int>(true, WRITABLE_ZONE_ID));
  471. }
  472. virtual void commit() {
  473. *readonly_records_ = *update_records_;
  474. }
  475. virtual void rollback() {
  476. // Special hook: if something with a name of "throw.example.org"
  477. // has been added, trigger an imaginary unexpected event with an
  478. // exception.
  479. if (update_records_->count("throw.example.org.") > 0) {
  480. isc_throw(DataSourceError, "unexpected failure in rollback");
  481. }
  482. rollbacked_ = true;
  483. }
  484. virtual void addRecordToZone(const string (&columns)[ADD_COLUMN_COUNT]) {
  485. // Copy the current value to cur_name. If it doesn't exist,
  486. // operator[] will create a new one.
  487. cur_name_ = (*update_records_)[columns[DatabaseAccessor::ADD_NAME]];
  488. vector<string> record_columns;
  489. record_columns.push_back(columns[DatabaseAccessor::ADD_TYPE]);
  490. record_columns.push_back(columns[DatabaseAccessor::ADD_TTL]);
  491. record_columns.push_back(columns[DatabaseAccessor::ADD_SIGTYPE]);
  492. record_columns.push_back(columns[DatabaseAccessor::ADD_RDATA]);
  493. record_columns.push_back(columns[DatabaseAccessor::ADD_NAME]);
  494. // copy back the added entry
  495. cur_name_.push_back(record_columns);
  496. (*update_records_)[columns[DatabaseAccessor::ADD_NAME]] = cur_name_;
  497. // remember this one so that test cases can check it.
  498. copy(columns, columns + DatabaseAccessor::ADD_COLUMN_COUNT,
  499. columns_lastadded_);
  500. }
  501. // Helper predicate class used in deleteRecordInZone().
  502. struct deleteMatch {
  503. deleteMatch(const string& type, const string& rdata) :
  504. type_(type), rdata_(rdata)
  505. {}
  506. bool operator()(const vector<string>& row) const {
  507. return (row[0] == type_ && row[3] == rdata_);
  508. }
  509. const string& type_;
  510. const string& rdata_;
  511. };
  512. virtual void deleteRecordInZone(const string (&params)[DEL_PARAM_COUNT]) {
  513. vector<vector<string> >& records =
  514. (*update_records_)[params[DatabaseAccessor::DEL_NAME]];
  515. records.erase(remove_if(records.begin(), records.end(),
  516. deleteMatch(
  517. params[DatabaseAccessor::DEL_TYPE],
  518. params[DatabaseAccessor::DEL_RDATA])),
  519. records.end());
  520. if (records.empty()) {
  521. (*update_records_).erase(params[DatabaseAccessor::DEL_NAME]);
  522. }
  523. }
  524. //
  525. // Helper methods to keep track of some update related activities
  526. //
  527. bool isRollbacked() const {
  528. return (rollbacked_);
  529. }
  530. const string* getLastAdded() const {
  531. return (columns_lastadded_);
  532. }
  533. // This allows the test code to get the accessor used in an update context
  534. shared_ptr<const MockAccessor> getLatestClone() const {
  535. return (latest_clone_);
  536. }
  537. virtual std::string findPreviousName(int id, const std::string& rname)
  538. const
  539. {
  540. if (id == -1) {
  541. isc_throw(isc::NotImplemented, "Test not implemented behaviour");
  542. } else if (id == READONLY_ZONE_ID) {
  543. // For some specific names we intentionally return broken or
  544. // unexpected result.
  545. if (rname == "org.example.badnsec2.") {
  546. return ("badnsec1.example.org.");
  547. } else if (rname == "org.example.brokenname.") {
  548. return ("brokenname...example.org.");
  549. } else if (rname == "org.example.notimplnsec." ||
  550. rname == "org.example.wild.here.") {
  551. isc_throw(isc::NotImplemented, "Not implemented in this test");
  552. }
  553. // For the general case, we search for the first name N in the
  554. // domains that meets N >= reverse(rname) using lower_bound.
  555. // The "previous name" is the name of the previous entry of N.
  556. // Note that Domains are internally sorted by the Name comparison
  557. // order. Due to the API requirement we are given a reversed
  558. // name (rname), so we need to reverse it again to convert it
  559. // to the original name.
  560. Domains::const_iterator it(readonly_records_->lower_bound(
  561. Name(rname).reverse().toText()));
  562. if (it == readonly_records_->begin()) {
  563. isc_throw(isc::Unexpected, "Unexpected name");
  564. }
  565. if (it == readonly_records_->end()) {
  566. return ((*readonly_records_->rbegin()).first);
  567. }
  568. return ((*(--it)).first);
  569. } else {
  570. isc_throw(isc::Unexpected, "Unknown zone ID");
  571. }
  572. }
  573. private:
  574. // The following member variables are storage and/or update work space
  575. // of the test zone. The "master"s are the real objects that contain
  576. // the data, and they are shared among all accessors cloned from
  577. // an initially created one. The "copy" data will be used for read-only
  578. // transaction. The pointer members allow the sharing.
  579. // "readonly" is for normal lookups. "update" is the workspace for
  580. // updates. When update starts it will be initialized either as an
  581. // empty set (when replacing the entire zone) or as a copy of the
  582. // "readonly" one. "empty" is a sentinel to produce negative results.
  583. Domains readonly_records_master_;
  584. Domains readonly_records_copy_;
  585. Domains* readonly_records_;
  586. Domains update_records_master_;
  587. Domains* update_records_;
  588. const Domains empty_records_master_;
  589. const Domains* empty_records_;
  590. // used as temporary storage after searchForRecord() and during
  591. // getNextRecord() calls, as well as during the building of the
  592. // fake data
  593. std::vector< std::vector<std::string> > cur_name_;
  594. // The columns that were most recently added via addRecordToZone()
  595. string columns_lastadded_[ADD_COLUMN_COUNT];
  596. // Whether rollback operation has been performed for the database.
  597. // Not useful except for purely testing purpose.
  598. bool rollbacked_;
  599. // Remember the mock accessor that was last cloned
  600. boost::shared_ptr<MockAccessor> latest_clone_;
  601. // Internal flag for duplicate check
  602. bool did_transaction_;
  603. const Domains& getMockRecords(int zone_id) const {
  604. if (zone_id == READONLY_ZONE_ID) {
  605. return (*readonly_records_);
  606. } else if (zone_id == WRITABLE_ZONE_ID) {
  607. return (*update_records_);
  608. }
  609. return (*empty_records_);
  610. }
  611. // Adds one record to the current name in the database
  612. // The actual data will not be added to 'records' until
  613. // addCurName() is called
  614. void addRecord(const std::string& type,
  615. const std::string& ttl,
  616. const std::string& sigtype,
  617. const std::string& rdata) {
  618. std::vector<std::string> columns;
  619. columns.push_back(type);
  620. columns.push_back(ttl);
  621. columns.push_back(sigtype);
  622. columns.push_back(rdata);
  623. cur_name_.push_back(columns);
  624. }
  625. // Adds all records we just built with calls to addRecords
  626. // to the actual fake database. This will clear cur_name_,
  627. // so we can immediately start adding new records.
  628. void addCurName(const std::string& name) {
  629. ASSERT_EQ(0, readonly_records_->count(name));
  630. // Append the name to all of them
  631. for (std::vector<std::vector<std::string> >::iterator
  632. i(cur_name_.begin()); i != cur_name_.end(); ++ i) {
  633. i->push_back(name);
  634. }
  635. (*readonly_records_)[name] = cur_name_;
  636. cur_name_.clear();
  637. }
  638. // Fills the database with zone data.
  639. // This method constructs a number of resource records (with addRecord),
  640. // which will all be added for one domain name to the fake database
  641. // (with addCurName). So for instance the first set of calls create
  642. // data for the name 'www.example.org', which will consist of one A RRset
  643. // of one record, and one AAAA RRset of two records.
  644. // The order in which they are added is the order in which getNextRecord()
  645. // will return them (so we can test whether find() etc. support data that
  646. // might not come in 'normal' order)
  647. // It shall immediately fail if you try to add the same name twice.
  648. void fillData() {
  649. const char* prev_name = NULL;
  650. for (int i = 0; TEST_RECORDS[i][0] != NULL; ++i) {
  651. if (prev_name != NULL &&
  652. strcmp(prev_name, TEST_RECORDS[i][0]) != 0) {
  653. addCurName(prev_name);
  654. }
  655. prev_name = TEST_RECORDS[i][0];
  656. addRecord(TEST_RECORDS[i][1], TEST_RECORDS[i][2],
  657. TEST_RECORDS[i][3], TEST_RECORDS[i][4]);
  658. }
  659. addCurName(prev_name);
  660. }
  661. };
  662. // This tests the default getRecords behaviour, throwing NotImplemented
  663. TEST(DatabaseConnectionTest, getRecords) {
  664. EXPECT_THROW(NopAccessor().getRecords(".", 1, false),
  665. isc::NotImplemented);
  666. }
  667. // This tests the default getAllRecords behaviour, throwing NotImplemented
  668. TEST(DatabaseConnectionTest, getAllRecords) {
  669. // The parameters don't matter
  670. EXPECT_THROW(NopAccessor().getAllRecords(1),
  671. isc::NotImplemented);
  672. }
  673. // This test fixture is templated so that we can share (most of) the test
  674. // cases with different types of data sources. Note that in test cases
  675. // we need to use 'this' to refer to member variables of the test class.
  676. template <typename ACCESSOR_TYPE>
  677. class DatabaseClientTest : public ::testing::Test {
  678. public:
  679. DatabaseClientTest() : zname_("example.org"), qname_("www.example.org"),
  680. qclass_(RRClass::IN()), qtype_(RRType::A()),
  681. rrttl_(3600)
  682. {
  683. createClient();
  684. // set up the commonly used finder.
  685. DataSourceClient::FindResult zone(client_->findZone(zname_));
  686. assert(zone.code == result::SUCCESS);
  687. finder_ = dynamic_pointer_cast<DatabaseClient::Finder>(
  688. zone.zone_finder);
  689. // Test IN/A RDATA to be added in update tests. Intentionally using
  690. // different data than the initial data configured in the MockAccessor.
  691. rrset_.reset(new RRset(qname_, qclass_, qtype_, rrttl_));
  692. rrset_->addRdata(rdata::createRdata(rrset_->getType(),
  693. rrset_->getClass(), "192.0.2.2"));
  694. // And its RRSIG. Also different from the configured one.
  695. rrsigset_.reset(new RRset(qname_, qclass_, RRType::RRSIG(),
  696. rrttl_));
  697. rrsigset_->addRdata(rdata::createRdata(rrsigset_->getType(),
  698. rrsigset_->getClass(),
  699. "A 5 3 0 20000101000000 "
  700. "20000201000000 0 example.org. "
  701. "FAKEFAKEFAKE"));
  702. }
  703. /*
  704. * We initialize the client from a function, so we can call it multiple
  705. * times per test.
  706. */
  707. void createClient() {
  708. current_accessor_ = new ACCESSOR_TYPE();
  709. is_mock_ = (dynamic_cast<MockAccessor*>(current_accessor_) != NULL);
  710. client_.reset(new DatabaseClient(qclass_,
  711. shared_ptr<ACCESSOR_TYPE>(
  712. current_accessor_)));
  713. }
  714. /**
  715. * Check the zone finder is a valid one and references the zone ID and
  716. * database available here.
  717. */
  718. void checkZoneFinder(const DataSourceClient::FindResult& zone) {
  719. ASSERT_NE(ZoneFinderPtr(), zone.zone_finder) << "No zone finder";
  720. shared_ptr<DatabaseClient::Finder> finder(
  721. dynamic_pointer_cast<DatabaseClient::Finder>(zone.zone_finder));
  722. ASSERT_NE(shared_ptr<DatabaseClient::Finder>(), finder) <<
  723. "Wrong type of finder";
  724. if (is_mock_) {
  725. EXPECT_EQ(READONLY_ZONE_ID, finder->zone_id());
  726. }
  727. EXPECT_EQ(current_accessor_, &finder->getAccessor());
  728. }
  729. shared_ptr<DatabaseClient::Finder> getFinder() {
  730. DataSourceClient::FindResult zone(client_->findZone(zname_));
  731. EXPECT_EQ(result::SUCCESS, zone.code);
  732. shared_ptr<DatabaseClient::Finder> finder(
  733. dynamic_pointer_cast<DatabaseClient::Finder>(zone.zone_finder));
  734. if (is_mock_) {
  735. EXPECT_EQ(READONLY_ZONE_ID, finder->zone_id());
  736. }
  737. return (finder);
  738. }
  739. // Helper methods for update tests
  740. bool isRollbacked(bool expected = false) const {
  741. if (is_mock_) {
  742. const MockAccessor& mock_accessor =
  743. dynamic_cast<const MockAccessor&>(*update_accessor_);
  744. return (mock_accessor.isRollbacked());
  745. } else {
  746. return (expected);
  747. }
  748. }
  749. void checkLastAdded(const char* const expected[]) const {
  750. if (is_mock_) {
  751. const MockAccessor* mock_accessor =
  752. dynamic_cast<const MockAccessor*>(current_accessor_);
  753. for (int i = 0; i < DatabaseAccessor::ADD_COLUMN_COUNT; ++i) {
  754. EXPECT_EQ(expected[i],
  755. mock_accessor->getLatestClone()->getLastAdded()[i]);
  756. }
  757. }
  758. }
  759. void setUpdateAccessor() {
  760. if (is_mock_) {
  761. const MockAccessor* mock_accessor =
  762. dynamic_cast<const MockAccessor*>(current_accessor_);
  763. update_accessor_ = mock_accessor->getLatestClone();
  764. }
  765. }
  766. // Some tests only work for MockAccessor. We remember whether our accessor
  767. // is of that type.
  768. bool is_mock_;
  769. // Will be deleted by client_, just keep the current value for comparison.
  770. ACCESSOR_TYPE* current_accessor_;
  771. shared_ptr<DatabaseClient> client_;
  772. const std::string database_name_;
  773. // The zone finder of the test zone commonly used in various tests.
  774. shared_ptr<DatabaseClient::Finder> finder_;
  775. // Some shortcut variables for commonly used test parameters
  776. const Name zname_; // the zone name stored in the test data source
  777. const Name qname_; // commonly used name to be found
  778. const RRClass qclass_; // commonly used RR class used with qname
  779. const RRType qtype_; // commonly used RR type used with qname
  780. const RRTTL rrttl_; // commonly used RR TTL
  781. RRsetPtr rrset_; // for adding/deleting an RRset
  782. RRsetPtr rrsigset_; // for adding/deleting an RRset
  783. // update related objects to be tested
  784. ZoneUpdaterPtr updater_;
  785. shared_ptr<const DatabaseAccessor> update_accessor_;
  786. // placeholders
  787. const std::vector<std::string> empty_rdatas_; // for NXRRSET/NXDOMAIN
  788. std::vector<std::string> expected_rdatas_;
  789. std::vector<std::string> expected_sig_rdatas_;
  790. };
  791. class TestSQLite3Accessor : public SQLite3Accessor {
  792. public:
  793. TestSQLite3Accessor() : SQLite3Accessor(
  794. TEST_DATA_BUILDDIR "/rwtest.sqlite3.copied", "IN")
  795. {
  796. startUpdateZone("example.org.", true);
  797. string columns[ADD_COLUMN_COUNT];
  798. for (int i = 0; TEST_RECORDS[i][0] != NULL; ++i) {
  799. columns[ADD_NAME] = TEST_RECORDS[i][0];
  800. columns[ADD_REV_NAME] = Name(columns[ADD_NAME]).reverse().toText();
  801. columns[ADD_TYPE] = TEST_RECORDS[i][1];
  802. columns[ADD_TTL] = TEST_RECORDS[i][2];
  803. columns[ADD_SIGTYPE] = TEST_RECORDS[i][3];
  804. columns[ADD_RDATA] = TEST_RECORDS[i][4];
  805. addRecordToZone(columns);
  806. }
  807. commit();
  808. }
  809. };
  810. // The following two lines instantiate test cases with concrete accessor
  811. // classes to be tested.
  812. // XXX: clang++ installed on our FreeBSD buildbot cannot complete compiling
  813. // this file, seemingly due to the size of the code. We'll consider more
  814. // complete workaround, but for a short term workaround we'll reduce the
  815. // number of tested accessor classes (thus reducing the amount of code
  816. // to be compiled) for this particular environment.
  817. #if defined(__clang__) && defined(__FreeBSD__)
  818. typedef ::testing::Types<MockAccessor> TestAccessorTypes;
  819. #else
  820. typedef ::testing::Types<MockAccessor, TestSQLite3Accessor> TestAccessorTypes;
  821. #endif
  822. TYPED_TEST_CASE(DatabaseClientTest, TestAccessorTypes);
  823. // In some cases the entire test fixture is for the mock accessor only.
  824. // We use the usual TEST_F for them with the corresponding specialized class
  825. // to make the code simpler.
  826. typedef DatabaseClientTest<MockAccessor> MockDatabaseClientTest;
  827. TYPED_TEST(DatabaseClientTest, zoneNotFound) {
  828. DataSourceClient::FindResult zone(
  829. this->client_->findZone(Name("example.com")));
  830. EXPECT_EQ(result::NOTFOUND, zone.code);
  831. }
  832. TYPED_TEST(DatabaseClientTest, exactZone) {
  833. DataSourceClient::FindResult zone(
  834. this->client_->findZone(Name("example.org")));
  835. EXPECT_EQ(result::SUCCESS, zone.code);
  836. this->checkZoneFinder(zone);
  837. }
  838. TYPED_TEST(DatabaseClientTest, superZone) {
  839. DataSourceClient::FindResult zone(this->client_->findZone(Name(
  840. "sub.example.org")));
  841. EXPECT_EQ(result::PARTIALMATCH, zone.code);
  842. this->checkZoneFinder(zone);
  843. }
  844. // This test doesn't depend on derived accessor class, so we use TEST().
  845. TEST(GenericDatabaseClientTest, noAccessorException) {
  846. // We need a dummy variable here; some compiler would regard it a mere
  847. // declaration instead of an instantiation and make the test fail.
  848. EXPECT_THROW(DatabaseClient dummy(RRClass::IN(),
  849. shared_ptr<DatabaseAccessor>()),
  850. isc::InvalidParameter);
  851. }
  852. // If the zone doesn't exist, exception is thrown
  853. TYPED_TEST(DatabaseClientTest, noZoneIterator) {
  854. EXPECT_THROW(this->client_->getIterator(Name("example.com")),
  855. DataSourceError);
  856. }
  857. // If the zone doesn't exist and iteration is not implemented, it still throws
  858. // the exception it doesn't exist
  859. TEST(GenericDatabaseClientTest, noZoneNotImplementedIterator) {
  860. EXPECT_THROW(DatabaseClient(RRClass::IN(),
  861. boost::shared_ptr<DatabaseAccessor>(
  862. new NopAccessor())).getIterator(
  863. Name("example.com")),
  864. DataSourceError);
  865. }
  866. TEST(GenericDatabaseClientTest, notImplementedIterator) {
  867. EXPECT_THROW(DatabaseClient(RRClass::IN(), shared_ptr<DatabaseAccessor>(
  868. new NopAccessor())).getIterator(Name("example.org")),
  869. isc::NotImplemented);
  870. }
  871. // Pretend a bug in the connection and pass NULL as the context
  872. // Should not crash, but gracefully throw. Works for the mock accessor only.
  873. TEST_F(MockDatabaseClientTest, nullIteratorContext) {
  874. EXPECT_THROW(this->client_->getIterator(Name("null.example.org")),
  875. isc::Unexpected);
  876. }
  877. // It doesn't crash or anything if the zone is completely empty.
  878. // Works for the mock accessor only.
  879. TEST_F(MockDatabaseClientTest, emptyIterator) {
  880. ZoneIteratorPtr it(this->client_->getIterator(Name("empty.example.org")));
  881. EXPECT_EQ(ConstRRsetPtr(), it->getNextRRset());
  882. // This is past the end, it should throw
  883. EXPECT_THROW(it->getNextRRset(), isc::Unexpected);
  884. }
  885. // checks if the given rrset matches the
  886. // given name, class, type and rdatas
  887. void
  888. checkRRset(isc::dns::ConstRRsetPtr rrset,
  889. const isc::dns::Name& name,
  890. const isc::dns::RRClass& rrclass,
  891. const isc::dns::RRType& rrtype,
  892. const isc::dns::RRTTL& rrttl,
  893. const std::vector<std::string>& rdatas) {
  894. isc::dns::RRsetPtr expected_rrset(
  895. new isc::dns::RRset(name, rrclass, rrtype, rrttl));
  896. for (unsigned int i = 0; i < rdatas.size(); ++i) {
  897. expected_rrset->addRdata(
  898. isc::dns::rdata::createRdata(rrtype, rrclass,
  899. rdatas[i]));
  900. }
  901. isc::testutils::rrsetCheck(expected_rrset, rrset);
  902. }
  903. // Iterate through a zone
  904. TYPED_TEST(DatabaseClientTest, iterator) {
  905. ZoneIteratorPtr it(this->client_->getIterator(Name("example.org")));
  906. ConstRRsetPtr rrset(it->getNextRRset());
  907. ASSERT_NE(ConstRRsetPtr(), rrset);
  908. // The first name should be the zone origin.
  909. EXPECT_EQ(this->zname_, rrset->getName());
  910. // The rest of the checks work only for the mock accessor.
  911. if (!this->is_mock_) {
  912. return;
  913. }
  914. this->expected_rdatas_.clear();
  915. this->expected_rdatas_.push_back("192.0.2.1");
  916. checkRRset(rrset, Name("example.org"), this->qclass_, RRType::A(),
  917. this->rrttl_, this->expected_rdatas_);
  918. rrset = it->getNextRRset();
  919. this->expected_rdatas_.clear();
  920. this->expected_rdatas_.push_back("ns1.example.org. admin.example.org. "
  921. "1234 3600 1800 2419200 7200");
  922. checkRRset(rrset, Name("example.org"), this->qclass_, RRType::SOA(),
  923. this->rrttl_, this->expected_rdatas_);
  924. rrset = it->getNextRRset();
  925. this->expected_rdatas_.clear();
  926. this->expected_rdatas_.push_back("192.0.2.1");
  927. this->expected_rdatas_.push_back("192.0.2.2");
  928. checkRRset(rrset, Name("x.example.org"), this->qclass_, RRType::A(),
  929. RRTTL(300), this->expected_rdatas_);
  930. rrset = it->getNextRRset();
  931. this->expected_rdatas_.clear();
  932. this->expected_rdatas_.push_back("2001:db8::1");
  933. this->expected_rdatas_.push_back("2001:db8::2");
  934. checkRRset(rrset, Name("x.example.org"), this->qclass_, RRType::AAAA(),
  935. RRTTL(300), this->expected_rdatas_);
  936. }
  937. // This has inconsistent TTL in the set (the rest, like nonsense in
  938. // the data is handled in rdata itself). Works for the mock accessor only.
  939. TEST_F(MockDatabaseClientTest, badIterator) {
  940. // It should not throw, but get the lowest one of them
  941. ZoneIteratorPtr it(this->client_->getIterator(Name("bad.example.org")));
  942. EXPECT_EQ(it->getNextRRset()->getTTL(), isc::dns::RRTTL(300));
  943. }
  944. TYPED_TEST(DatabaseClientTest, getSOAFromIterator) {
  945. vector<string> soa_data;
  946. soa_data.push_back("ns1.example.org. admin.example.org. "
  947. "1234 3600 1800 2419200 7200");
  948. ZoneIteratorPtr it(this->client_->getIterator(this->zname_));
  949. ASSERT_TRUE(it);
  950. checkRRset(it->getSOA(), this->zname_, this->qclass_, RRType::SOA(),
  951. this->rrttl_, soa_data);
  952. // Iterate over the zone until we find an SOA. Although there's a broken
  953. // RDATA that would trigger an exception in getNextRRset(), we should
  954. // reach the SOA as the sequence should be sorted and the SOA is at
  955. // the origin name (which has no bogus data).
  956. ConstRRsetPtr rrset;
  957. while ((rrset = it->getNextRRset()) != ConstRRsetPtr() &&
  958. rrset->getType() != RRType::SOA()) {
  959. ;
  960. }
  961. ASSERT_TRUE(rrset);
  962. // It should be identical to the result of getSOA().
  963. isc::testutils::rrsetCheck(it->getSOA(), rrset);
  964. }
  965. TYPED_TEST(DatabaseClientTest, noSOAFromIterator) {
  966. // First, empty the zone.
  967. this->updater_ = this->client_->getUpdater(this->zname_, true);
  968. this->updater_->commit();
  969. // Then getSOA() should return NULL.
  970. ZoneIteratorPtr it(this->client_->getIterator(this->zname_));
  971. ASSERT_TRUE(it);
  972. EXPECT_FALSE(it->getSOA());
  973. }
  974. TYPED_TEST(DatabaseClientTest, iterateThenUpdate) {
  975. ZoneIteratorPtr it(this->client_->getIterator(this->zname_));
  976. ASSERT_TRUE(it);
  977. // Try to empty the zone after getting the iterator. Depending on the
  978. // underlying data source, it may result in an exception due to the
  979. // transaction for the iterator. In either case the integrity of the
  980. // iterator result should be reserved.
  981. try {
  982. this->updater_ = this->client_->getUpdater(this->zname_, true);
  983. this->updater_->commit();
  984. // Confirm at least it doesn't contain any SOA
  985. EXPECT_EQ(ZoneFinder::NXDOMAIN,
  986. this->getFinder()->find(this->zname_, RRType::SOA()).code);
  987. } catch (const DataSourceError&) {}
  988. ConstRRsetPtr rrset;
  989. while ((rrset = it->getNextRRset()) != ConstRRsetPtr() &&
  990. rrset->getType() != RRType::SOA()) {
  991. ;
  992. }
  993. ASSERT_TRUE(rrset);
  994. // It should be identical to the result of getSOA().
  995. isc::testutils::rrsetCheck(it->getSOA(), rrset);
  996. }
  997. TYPED_TEST(DatabaseClientTest, updateThenIterateThenUpdate) {
  998. // First clear the zone.
  999. this->updater_ = this->client_->getUpdater(this->zname_, true);
  1000. this->updater_->commit();
  1001. // Then iterate over it. It should immediately reach the end, at which
  1002. // point the transaction should be committed.
  1003. ZoneIteratorPtr it(this->client_->getIterator(this->zname_));
  1004. ASSERT_TRUE(it);
  1005. EXPECT_FALSE(it->getNextRRset());
  1006. // So another update attempt should succeed, too.
  1007. this->updater_ = this->client_->getUpdater(this->zname_, true);
  1008. this->updater_->commit();
  1009. }
  1010. TYPED_TEST(DatabaseClientTest, updateAfterDeleteIterator) {
  1011. // Similar to the previous case, but we delete the iterator in the
  1012. // middle of zone. The transaction should be canceled (actually no
  1013. // different from commit though) at that point.
  1014. ZoneIteratorPtr it(this->client_->getIterator(this->zname_));
  1015. ASSERT_TRUE(it);
  1016. EXPECT_TRUE(it->getNextRRset());
  1017. it.reset();
  1018. // So another update attempt should succeed.
  1019. this->updater_ = this->client_->getUpdater(this->zname_, true);
  1020. this->updater_->commit();
  1021. }
  1022. void
  1023. doFindTest(ZoneFinder& finder,
  1024. const isc::dns::Name& name,
  1025. const isc::dns::RRType& type,
  1026. const isc::dns::RRType& expected_type,
  1027. const isc::dns::RRTTL expected_ttl,
  1028. ZoneFinder::Result expected_result,
  1029. const std::vector<std::string>& expected_rdatas,
  1030. const std::vector<std::string>& expected_sig_rdatas,
  1031. const isc::dns::Name& expected_name = isc::dns::Name::ROOT_NAME(),
  1032. const ZoneFinder::FindOptions options = ZoneFinder::FIND_DEFAULT)
  1033. {
  1034. SCOPED_TRACE("doFindTest " + name.toText() + " " + type.toText());
  1035. const ZoneFinder::FindResult result = finder.find(name, type, NULL,
  1036. options);
  1037. ASSERT_EQ(expected_result, result.code) << name << " " << type;
  1038. if (!expected_rdatas.empty() && result.rrset) {
  1039. checkRRset(result.rrset, expected_name != Name(".") ? expected_name :
  1040. name, finder.getClass(), expected_type, expected_ttl,
  1041. expected_rdatas);
  1042. if (!expected_sig_rdatas.empty() && result.rrset->getRRsig()) {
  1043. checkRRset(result.rrset->getRRsig(), expected_name != Name(".") ?
  1044. expected_name : name, finder.getClass(),
  1045. isc::dns::RRType::RRSIG(), expected_ttl,
  1046. expected_sig_rdatas);
  1047. } else if (expected_sig_rdatas.empty()) {
  1048. EXPECT_EQ(isc::dns::RRsetPtr(), result.rrset->getRRsig());
  1049. } else {
  1050. ADD_FAILURE() << "Missing RRSIG";
  1051. }
  1052. } else if (expected_rdatas.empty()) {
  1053. EXPECT_EQ(isc::dns::RRsetPtr(), result.rrset);
  1054. } else {
  1055. ADD_FAILURE() << "Missing result";
  1056. }
  1057. }
  1058. TYPED_TEST(DatabaseClientTest, find) {
  1059. shared_ptr<DatabaseClient::Finder> finder(this->getFinder());
  1060. this->expected_rdatas_.clear();
  1061. this->expected_sig_rdatas_.clear();
  1062. this->expected_rdatas_.push_back("192.0.2.1");
  1063. doFindTest(*finder, isc::dns::Name("www.example.org."),
  1064. this->qtype_, this->qtype_, this->rrttl_, ZoneFinder::SUCCESS,
  1065. this->expected_rdatas_, this->expected_sig_rdatas_);
  1066. this->expected_rdatas_.clear();
  1067. this->expected_sig_rdatas_.clear();
  1068. this->expected_rdatas_.push_back("192.0.2.1");
  1069. this->expected_rdatas_.push_back("192.0.2.2");
  1070. doFindTest(*finder, isc::dns::Name("www2.example.org."),
  1071. this->qtype_, this->qtype_, this->rrttl_, ZoneFinder::SUCCESS,
  1072. this->expected_rdatas_, this->expected_sig_rdatas_);
  1073. this->expected_rdatas_.clear();
  1074. this->expected_sig_rdatas_.clear();
  1075. this->expected_rdatas_.push_back("2001:db8::1");
  1076. this->expected_rdatas_.push_back("2001:db8::2");
  1077. doFindTest(*finder, isc::dns::Name("www.example.org."),
  1078. isc::dns::RRType::AAAA(), isc::dns::RRType::AAAA(),
  1079. this->rrttl_,
  1080. ZoneFinder::SUCCESS,
  1081. this->expected_rdatas_, this->expected_sig_rdatas_);
  1082. this->expected_rdatas_.clear();
  1083. this->expected_sig_rdatas_.clear();
  1084. doFindTest(*finder, isc::dns::Name("www.example.org."),
  1085. isc::dns::RRType::TXT(), isc::dns::RRType::TXT(),
  1086. this->rrttl_,
  1087. ZoneFinder::NXRRSET,
  1088. this->expected_rdatas_, this->expected_sig_rdatas_);
  1089. this->expected_rdatas_.clear();
  1090. this->expected_sig_rdatas_.clear();
  1091. this->expected_rdatas_.push_back("www.example.org.");
  1092. doFindTest(*finder, isc::dns::Name("cname.example.org."),
  1093. this->qtype_, isc::dns::RRType::CNAME(), this->rrttl_,
  1094. ZoneFinder::CNAME, this->expected_rdatas_,
  1095. this->expected_sig_rdatas_);
  1096. this->expected_rdatas_.clear();
  1097. this->expected_sig_rdatas_.clear();
  1098. this->expected_rdatas_.push_back("www.example.org.");
  1099. doFindTest(*finder, isc::dns::Name("cname.example.org."),
  1100. isc::dns::RRType::CNAME(), isc::dns::RRType::CNAME(),
  1101. this->rrttl_, ZoneFinder::SUCCESS, this->expected_rdatas_,
  1102. this->expected_sig_rdatas_);
  1103. this->expected_rdatas_.clear();
  1104. this->expected_sig_rdatas_.clear();
  1105. doFindTest(*finder, isc::dns::Name("doesnotexist.example.org."),
  1106. this->qtype_, this->qtype_, this->rrttl_, ZoneFinder::NXDOMAIN,
  1107. this->expected_rdatas_, this->expected_sig_rdatas_);
  1108. this->expected_rdatas_.clear();
  1109. this->expected_sig_rdatas_.clear();
  1110. this->expected_rdatas_.push_back("192.0.2.1");
  1111. this->expected_sig_rdatas_.push_back("A 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
  1112. this->expected_sig_rdatas_.push_back("A 5 3 3600 20000101000000 20000201000000 12346 example.org. FAKEFAKEFAKE");
  1113. doFindTest(*finder, isc::dns::Name("signed1.example.org."),
  1114. this->qtype_, this->qtype_, this->rrttl_, ZoneFinder::SUCCESS,
  1115. this->expected_rdatas_, this->expected_sig_rdatas_);
  1116. this->expected_rdatas_.clear();
  1117. this->expected_sig_rdatas_.clear();
  1118. this->expected_rdatas_.push_back("2001:db8::1");
  1119. this->expected_rdatas_.push_back("2001:db8::2");
  1120. this->expected_sig_rdatas_.push_back("AAAA 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
  1121. doFindTest(*finder, isc::dns::Name("signed1.example.org."),
  1122. isc::dns::RRType::AAAA(), isc::dns::RRType::AAAA(),
  1123. this->rrttl_, ZoneFinder::SUCCESS, this->expected_rdatas_,
  1124. this->expected_sig_rdatas_);
  1125. this->expected_rdatas_.clear();
  1126. this->expected_sig_rdatas_.clear();
  1127. doFindTest(*finder, isc::dns::Name("signed1.example.org."),
  1128. isc::dns::RRType::TXT(), isc::dns::RRType::TXT(), this->rrttl_,
  1129. ZoneFinder::NXRRSET, this->expected_rdatas_,
  1130. this->expected_sig_rdatas_);
  1131. this->expected_rdatas_.clear();
  1132. this->expected_sig_rdatas_.clear();
  1133. this->expected_rdatas_.push_back("www.example.org.");
  1134. this->expected_sig_rdatas_.push_back("CNAME 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
  1135. doFindTest(*finder, isc::dns::Name("signedcname1.example.org."),
  1136. this->qtype_, isc::dns::RRType::CNAME(), this->rrttl_,
  1137. ZoneFinder::CNAME, this->expected_rdatas_,
  1138. this->expected_sig_rdatas_);
  1139. this->expected_rdatas_.clear();
  1140. this->expected_sig_rdatas_.clear();
  1141. this->expected_rdatas_.push_back("192.0.2.1");
  1142. this->expected_sig_rdatas_.push_back("A 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
  1143. this->expected_sig_rdatas_.push_back("A 5 3 3600 20000101000000 20000201000000 12346 example.org. FAKEFAKEFAKE");
  1144. doFindTest(*finder, isc::dns::Name("signed2.example.org."),
  1145. this->qtype_, this->qtype_, this->rrttl_, ZoneFinder::SUCCESS,
  1146. this->expected_rdatas_, this->expected_sig_rdatas_);
  1147. this->expected_rdatas_.clear();
  1148. this->expected_sig_rdatas_.clear();
  1149. this->expected_rdatas_.push_back("2001:db8::2");
  1150. this->expected_rdatas_.push_back("2001:db8::1");
  1151. this->expected_sig_rdatas_.push_back("AAAA 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
  1152. doFindTest(*finder, isc::dns::Name("signed2.example.org."),
  1153. isc::dns::RRType::AAAA(), isc::dns::RRType::AAAA(),
  1154. this->rrttl_, ZoneFinder::SUCCESS, this->expected_rdatas_,
  1155. this->expected_sig_rdatas_);
  1156. this->expected_rdatas_.clear();
  1157. this->expected_sig_rdatas_.clear();
  1158. doFindTest(*finder, isc::dns::Name("signed2.example.org."),
  1159. isc::dns::RRType::TXT(), isc::dns::RRType::TXT(), this->rrttl_,
  1160. ZoneFinder::NXRRSET, this->expected_rdatas_,
  1161. this->expected_sig_rdatas_);
  1162. this->expected_rdatas_.clear();
  1163. this->expected_sig_rdatas_.clear();
  1164. this->expected_rdatas_.push_back("www.example.org.");
  1165. this->expected_sig_rdatas_.push_back("CNAME 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
  1166. doFindTest(*finder, isc::dns::Name("signedcname2.example.org."),
  1167. this->qtype_, isc::dns::RRType::CNAME(), this->rrttl_,
  1168. ZoneFinder::CNAME, this->expected_rdatas_,
  1169. this->expected_sig_rdatas_);
  1170. this->expected_rdatas_.clear();
  1171. this->expected_sig_rdatas_.clear();
  1172. this->expected_rdatas_.push_back("192.0.2.1");
  1173. this->expected_sig_rdatas_.push_back("A 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
  1174. doFindTest(*finder, isc::dns::Name("acnamesig1.example.org."),
  1175. this->qtype_, this->qtype_, this->rrttl_, ZoneFinder::SUCCESS,
  1176. this->expected_rdatas_, this->expected_sig_rdatas_);
  1177. this->expected_rdatas_.clear();
  1178. this->expected_sig_rdatas_.clear();
  1179. this->expected_rdatas_.push_back("192.0.2.1");
  1180. this->expected_sig_rdatas_.push_back("A 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
  1181. doFindTest(*finder, isc::dns::Name("acnamesig2.example.org."),
  1182. this->qtype_, this->qtype_, this->rrttl_, ZoneFinder::SUCCESS,
  1183. this->expected_rdatas_, this->expected_sig_rdatas_);
  1184. this->expected_rdatas_.clear();
  1185. this->expected_sig_rdatas_.clear();
  1186. this->expected_rdatas_.push_back("192.0.2.1");
  1187. this->expected_sig_rdatas_.push_back("A 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
  1188. doFindTest(*finder, isc::dns::Name("acnamesig3.example.org."),
  1189. this->qtype_, this->qtype_, this->rrttl_, ZoneFinder::SUCCESS,
  1190. this->expected_rdatas_, this->expected_sig_rdatas_);
  1191. this->expected_rdatas_.clear();
  1192. this->expected_sig_rdatas_.clear();
  1193. this->expected_rdatas_.push_back("192.0.2.1");
  1194. this->expected_rdatas_.push_back("192.0.2.2");
  1195. doFindTest(*finder, isc::dns::Name("ttldiff1.example.org."),
  1196. this->qtype_, this->qtype_, isc::dns::RRTTL(360),
  1197. ZoneFinder::SUCCESS, this->expected_rdatas_,
  1198. this->expected_sig_rdatas_);
  1199. this->expected_rdatas_.clear();
  1200. this->expected_sig_rdatas_.clear();
  1201. this->expected_rdatas_.push_back("192.0.2.1");
  1202. this->expected_rdatas_.push_back("192.0.2.2");
  1203. doFindTest(*finder, isc::dns::Name("ttldiff2.example.org."),
  1204. this->qtype_, this->qtype_, isc::dns::RRTTL(360),
  1205. ZoneFinder::SUCCESS, this->expected_rdatas_,
  1206. this->expected_sig_rdatas_);
  1207. EXPECT_THROW(finder->find(isc::dns::Name("badcname1.example.org."),
  1208. this->qtype_,
  1209. NULL, ZoneFinder::FIND_DEFAULT),
  1210. DataSourceError);
  1211. EXPECT_THROW(finder->find(isc::dns::Name("badcname2.example.org."),
  1212. this->qtype_,
  1213. NULL, ZoneFinder::FIND_DEFAULT),
  1214. DataSourceError);
  1215. EXPECT_THROW(finder->find(isc::dns::Name("badcname3.example.org."),
  1216. this->qtype_,
  1217. NULL, ZoneFinder::FIND_DEFAULT),
  1218. DataSourceError);
  1219. EXPECT_THROW(finder->find(isc::dns::Name("badrdata.example.org."),
  1220. this->qtype_,
  1221. NULL, ZoneFinder::FIND_DEFAULT),
  1222. DataSourceError);
  1223. EXPECT_THROW(finder->find(isc::dns::Name("badtype.example.org."),
  1224. this->qtype_,
  1225. NULL, ZoneFinder::FIND_DEFAULT),
  1226. DataSourceError);
  1227. EXPECT_THROW(finder->find(isc::dns::Name("badttl.example.org."),
  1228. this->qtype_,
  1229. NULL, ZoneFinder::FIND_DEFAULT),
  1230. DataSourceError);
  1231. EXPECT_THROW(finder->find(isc::dns::Name("badsig.example.org."),
  1232. this->qtype_,
  1233. NULL, ZoneFinder::FIND_DEFAULT),
  1234. DataSourceError);
  1235. // Trigger the hardcoded exceptions and see if find() has cleaned up
  1236. if (this->is_mock_) {
  1237. EXPECT_THROW(finder->find(isc::dns::Name("dsexception.in.search."),
  1238. this->qtype_,
  1239. NULL, ZoneFinder::FIND_DEFAULT),
  1240. DataSourceError);
  1241. EXPECT_THROW(finder->find(isc::dns::Name("iscexception.in.search."),
  1242. this->qtype_,
  1243. NULL, ZoneFinder::FIND_DEFAULT),
  1244. isc::Exception);
  1245. EXPECT_THROW(finder->find(isc::dns::Name("basicexception.in.search."),
  1246. this->qtype_,
  1247. NULL, ZoneFinder::FIND_DEFAULT),
  1248. std::exception);
  1249. EXPECT_THROW(finder->find(isc::dns::Name("dsexception.in.getnext."),
  1250. this->qtype_,
  1251. NULL, ZoneFinder::FIND_DEFAULT),
  1252. DataSourceError);
  1253. EXPECT_THROW(finder->find(isc::dns::Name("iscexception.in.getnext."),
  1254. this->qtype_,
  1255. NULL, ZoneFinder::FIND_DEFAULT),
  1256. isc::Exception);
  1257. EXPECT_THROW(finder->find(isc::dns::Name("basicexception.in.getnext."),
  1258. this->qtype_,
  1259. NULL, ZoneFinder::FIND_DEFAULT),
  1260. std::exception);
  1261. }
  1262. // This RRSIG has the wrong sigtype field, which should be
  1263. // an error if we decide to keep using that field
  1264. // Right now the field is ignored, so it does not error
  1265. this->expected_rdatas_.clear();
  1266. this->expected_sig_rdatas_.clear();
  1267. this->expected_rdatas_.push_back("192.0.2.1");
  1268. this->expected_sig_rdatas_.push_back("A 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
  1269. doFindTest(*finder, isc::dns::Name("badsigtype.example.org."),
  1270. this->qtype_, this->qtype_, this->rrttl_, ZoneFinder::SUCCESS,
  1271. this->expected_rdatas_, this->expected_sig_rdatas_);
  1272. }
  1273. TYPED_TEST(DatabaseClientTest, findDelegation) {
  1274. shared_ptr<DatabaseClient::Finder> finder(this->getFinder());
  1275. // The apex should not be considered delegation point and we can access
  1276. // data
  1277. this->expected_rdatas_.clear();
  1278. this->expected_sig_rdatas_.clear();
  1279. this->expected_rdatas_.push_back("192.0.2.1");
  1280. doFindTest(*finder, isc::dns::Name("example.org."),
  1281. this->qtype_, this->qtype_,
  1282. this->rrttl_, ZoneFinder::SUCCESS, this->expected_rdatas_,
  1283. this->expected_sig_rdatas_);
  1284. this->expected_rdatas_.clear();
  1285. this->expected_rdatas_.push_back("ns.example.com.");
  1286. this->expected_sig_rdatas_.push_back("NS 5 3 3600 20000101000000 20000201000000 "
  1287. "12345 example.org. FAKEFAKEFAKE");
  1288. doFindTest(*finder, isc::dns::Name("example.org."),
  1289. isc::dns::RRType::NS(), isc::dns::RRType::NS(),
  1290. this->rrttl_, ZoneFinder::SUCCESS, this->expected_rdatas_,
  1291. this->expected_sig_rdatas_);
  1292. // Check when we ask for something below delegation point, we get the NS
  1293. // (Both when the RRset there exists and doesn't)
  1294. this->expected_rdatas_.clear();
  1295. this->expected_sig_rdatas_.clear();
  1296. this->expected_rdatas_.push_back("ns.example.com.");
  1297. this->expected_rdatas_.push_back("ns.delegation.example.org.");
  1298. this->expected_sig_rdatas_.push_back("NS 5 3 3600 20000101000000 20000201000000 "
  1299. "12345 example.org. FAKEFAKEFAKE");
  1300. doFindTest(*finder, isc::dns::Name("ns.delegation.example.org."),
  1301. this->qtype_, isc::dns::RRType::NS(),
  1302. this->rrttl_, ZoneFinder::DELEGATION, this->expected_rdatas_,
  1303. this->expected_sig_rdatas_,
  1304. isc::dns::Name("delegation.example.org."));
  1305. doFindTest(*finder, isc::dns::Name("ns.delegation.example.org."),
  1306. isc::dns::RRType::AAAA(), isc::dns::RRType::NS(),
  1307. this->rrttl_, ZoneFinder::DELEGATION, this->expected_rdatas_,
  1308. this->expected_sig_rdatas_,
  1309. isc::dns::Name("delegation.example.org."));
  1310. doFindTest(*finder, isc::dns::Name("deep.below.delegation.example.org."),
  1311. isc::dns::RRType::AAAA(), isc::dns::RRType::NS(),
  1312. this->rrttl_, ZoneFinder::DELEGATION, this->expected_rdatas_,
  1313. this->expected_sig_rdatas_,
  1314. isc::dns::Name("delegation.example.org."));
  1315. // Even when we check directly at the delegation point, we should get
  1316. // the NS
  1317. doFindTest(*finder, isc::dns::Name("delegation.example.org."),
  1318. isc::dns::RRType::AAAA(), isc::dns::RRType::NS(),
  1319. this->rrttl_, ZoneFinder::DELEGATION, this->expected_rdatas_,
  1320. this->expected_sig_rdatas_);
  1321. // And when we ask direcly for the NS, we should still get delegation
  1322. doFindTest(*finder, isc::dns::Name("delegation.example.org."),
  1323. isc::dns::RRType::NS(), isc::dns::RRType::NS(),
  1324. this->rrttl_, ZoneFinder::DELEGATION, this->expected_rdatas_,
  1325. this->expected_sig_rdatas_);
  1326. // Now test delegation. If it is below the delegation point, we should get
  1327. // the DNAME (the one with data under DNAME is invalid zone, but we test
  1328. // the behaviour anyway just to make sure)
  1329. this->expected_rdatas_.clear();
  1330. this->expected_rdatas_.push_back("dname.example.com.");
  1331. this->expected_sig_rdatas_.clear();
  1332. this->expected_sig_rdatas_.push_back("DNAME 5 3 3600 20000101000000 "
  1333. "20000201000000 12345 example.org. "
  1334. "FAKEFAKEFAKE");
  1335. doFindTest(*finder, isc::dns::Name("below.dname.example.org."),
  1336. this->qtype_, isc::dns::RRType::DNAME(),
  1337. this->rrttl_, ZoneFinder::DNAME, this->expected_rdatas_,
  1338. this->expected_sig_rdatas_, isc::dns::Name("dname.example.org."));
  1339. doFindTest(*finder, isc::dns::Name("below.dname.example.org."),
  1340. isc::dns::RRType::AAAA(), isc::dns::RRType::DNAME(),
  1341. this->rrttl_, ZoneFinder::DNAME, this->expected_rdatas_,
  1342. this->expected_sig_rdatas_, isc::dns::Name("dname.example.org."));
  1343. doFindTest(*finder, isc::dns::Name("really.deep.below.dname.example.org."),
  1344. isc::dns::RRType::AAAA(), isc::dns::RRType::DNAME(),
  1345. this->rrttl_, ZoneFinder::DNAME, this->expected_rdatas_,
  1346. this->expected_sig_rdatas_, isc::dns::Name("dname.example.org."));
  1347. // Asking direcly for DNAME should give SUCCESS
  1348. doFindTest(*finder, isc::dns::Name("dname.example.org."),
  1349. isc::dns::RRType::DNAME(), isc::dns::RRType::DNAME(),
  1350. this->rrttl_, ZoneFinder::SUCCESS, this->expected_rdatas_,
  1351. this->expected_sig_rdatas_);
  1352. // But we don't delegate at DNAME point
  1353. this->expected_rdatas_.clear();
  1354. this->expected_rdatas_.push_back("192.0.2.1");
  1355. this->expected_sig_rdatas_.clear();
  1356. doFindTest(*finder, isc::dns::Name("dname.example.org."),
  1357. this->qtype_, this->qtype_,
  1358. this->rrttl_, ZoneFinder::SUCCESS, this->expected_rdatas_,
  1359. this->expected_sig_rdatas_);
  1360. this->expected_rdatas_.clear();
  1361. doFindTest(*finder, isc::dns::Name("dname.example.org."),
  1362. isc::dns::RRType::AAAA(), isc::dns::RRType::AAAA(),
  1363. this->rrttl_, ZoneFinder::NXRRSET, this->expected_rdatas_,
  1364. this->expected_sig_rdatas_);
  1365. // This is broken dname, it contains two targets
  1366. EXPECT_THROW(finder->find(isc::dns::Name("below.baddname.example.org."),
  1367. this->qtype_, NULL,
  1368. ZoneFinder::FIND_DEFAULT),
  1369. DataSourceError);
  1370. // Broken NS - it lives together with something else
  1371. EXPECT_THROW(finder->find(isc::dns::Name("brokenns1.example.org."),
  1372. this->qtype_, NULL,
  1373. ZoneFinder::FIND_DEFAULT),
  1374. DataSourceError);
  1375. EXPECT_THROW(finder->find(isc::dns::Name("brokenns2.example.org."),
  1376. this->qtype_, NULL,
  1377. ZoneFinder::FIND_DEFAULT),
  1378. DataSourceError);
  1379. }
  1380. TYPED_TEST(DatabaseClientTest, emptyDomain) {
  1381. shared_ptr<DatabaseClient::Finder> finder(this->getFinder());
  1382. // This domain doesn't exist, but a subdomain of it does.
  1383. // Therefore we should pretend the domain is there, but contains no RRsets
  1384. doFindTest(*finder, isc::dns::Name("b.example.org."), this->qtype_,
  1385. this->qtype_, this->rrttl_, ZoneFinder::NXRRSET,
  1386. this->expected_rdatas_, this->expected_sig_rdatas_);
  1387. }
  1388. // Glue-OK mode. Just go through NS delegations down (but not through
  1389. // DNAME) and pretend it is not there.
  1390. TYPED_TEST(DatabaseClientTest, glueOK) {
  1391. shared_ptr<DatabaseClient::Finder> finder(this->getFinder());
  1392. this->expected_rdatas_.clear();
  1393. this->expected_sig_rdatas_.clear();
  1394. doFindTest(*finder, isc::dns::Name("ns.delegation.example.org."),
  1395. isc::dns::RRType::AAAA(), isc::dns::RRType::AAAA(),
  1396. this->rrttl_, ZoneFinder::NXRRSET,
  1397. this->expected_rdatas_, this->expected_sig_rdatas_,
  1398. isc::dns::Name("ns.delegation.example.org."),
  1399. ZoneFinder::FIND_GLUE_OK);
  1400. doFindTest(*finder, isc::dns::Name("nothere.delegation.example.org."),
  1401. isc::dns::RRType::AAAA(), isc::dns::RRType::AAAA(),
  1402. this->rrttl_, ZoneFinder::NXDOMAIN,
  1403. this->expected_rdatas_, this->expected_sig_rdatas_,
  1404. isc::dns::Name("nothere.delegation.example.org."),
  1405. ZoneFinder::FIND_GLUE_OK);
  1406. this->expected_rdatas_.push_back("192.0.2.1");
  1407. doFindTest(*finder, isc::dns::Name("ns.delegation.example.org."),
  1408. this->qtype_, this->qtype_,
  1409. this->rrttl_, ZoneFinder::SUCCESS,
  1410. this->expected_rdatas_, this->expected_sig_rdatas_,
  1411. isc::dns::Name("ns.delegation.example.org."),
  1412. ZoneFinder::FIND_GLUE_OK);
  1413. this->expected_rdatas_.clear();
  1414. this->expected_rdatas_.push_back("ns.example.com.");
  1415. this->expected_rdatas_.push_back("ns.delegation.example.org.");
  1416. this->expected_sig_rdatas_.clear();
  1417. this->expected_sig_rdatas_.push_back("NS 5 3 3600 20000101000000 "
  1418. "20000201000000 12345 example.org. "
  1419. "FAKEFAKEFAKE");
  1420. // When we request the NS, it should be SUCCESS, not DELEGATION
  1421. // (different in GLUE_OK)
  1422. doFindTest(*finder, isc::dns::Name("delegation.example.org."),
  1423. isc::dns::RRType::NS(), isc::dns::RRType::NS(),
  1424. this->rrttl_, ZoneFinder::SUCCESS,
  1425. this->expected_rdatas_, this->expected_sig_rdatas_,
  1426. isc::dns::Name("delegation.example.org."),
  1427. ZoneFinder::FIND_GLUE_OK);
  1428. this->expected_rdatas_.clear();
  1429. this->expected_rdatas_.push_back("dname.example.com.");
  1430. this->expected_sig_rdatas_.clear();
  1431. this->expected_sig_rdatas_.push_back("DNAME 5 3 3600 20000101000000 "
  1432. "20000201000000 12345 example.org. "
  1433. "FAKEFAKEFAKE");
  1434. doFindTest(*finder, isc::dns::Name("below.dname.example.org."),
  1435. this->qtype_, isc::dns::RRType::DNAME(),
  1436. this->rrttl_, ZoneFinder::DNAME, this->expected_rdatas_,
  1437. this->expected_sig_rdatas_,
  1438. isc::dns::Name("dname.example.org."), ZoneFinder::FIND_GLUE_OK);
  1439. doFindTest(*finder, isc::dns::Name("below.dname.example.org."),
  1440. isc::dns::RRType::AAAA(), isc::dns::RRType::DNAME(),
  1441. this->rrttl_, ZoneFinder::DNAME, this->expected_rdatas_,
  1442. this->expected_sig_rdatas_,
  1443. isc::dns::Name("dname.example.org."), ZoneFinder::FIND_GLUE_OK);
  1444. }
  1445. TYPED_TEST(DatabaseClientTest, wildcard) {
  1446. shared_ptr<DatabaseClient::Finder> finder(this->getFinder());
  1447. // First, simple wildcard match
  1448. // Check also that the RRSIG is added from the wildcard (not modified)
  1449. this->expected_rdatas_.push_back("192.0.2.5");
  1450. this->expected_sig_rdatas_.push_back("A 5 3 3600 20000101000000 "
  1451. "20000201000000 12345 example.org. "
  1452. "FAKEFAKEFAKE");
  1453. doFindTest(*finder, isc::dns::Name("a.wild.example.org"),
  1454. this->qtype_, this->qtype_, this->rrttl_,
  1455. ZoneFinder::WILDCARD, this->expected_rdatas_,
  1456. this->expected_sig_rdatas_);
  1457. doFindTest(*finder, isc::dns::Name("b.a.wild.example.org"),
  1458. this->qtype_, this->qtype_, this->rrttl_, ZoneFinder::WILDCARD,
  1459. this->expected_rdatas_, this->expected_sig_rdatas_);
  1460. this->expected_rdatas_.clear();
  1461. this->expected_sig_rdatas_.clear();
  1462. doFindTest(*finder, isc::dns::Name("a.wild.example.org"),
  1463. isc::dns::RRType::AAAA(), isc::dns::RRType::AAAA(),
  1464. this->rrttl_, ZoneFinder::WILDCARD_NXRRSET,
  1465. this->expected_rdatas_, this->expected_sig_rdatas_);
  1466. doFindTest(*finder, isc::dns::Name("b.a.wild.example.org"),
  1467. isc::dns::RRType::AAAA(), isc::dns::RRType::AAAA(),
  1468. this->rrttl_, ZoneFinder::WILDCARD_NXRRSET,
  1469. this->expected_rdatas_, this->expected_sig_rdatas_);
  1470. // Direct request for this wildcard
  1471. this->expected_rdatas_.push_back("192.0.2.5");
  1472. this->expected_sig_rdatas_.push_back("A 5 3 3600 20000101000000 "
  1473. "20000201000000 12345 example.org. "
  1474. "FAKEFAKEFAKE");
  1475. doFindTest(*finder, isc::dns::Name("*.wild.example.org"),
  1476. this->qtype_, this->qtype_, this->rrttl_, ZoneFinder::SUCCESS,
  1477. this->expected_rdatas_, this->expected_sig_rdatas_);
  1478. this->expected_rdatas_.clear();
  1479. this->expected_sig_rdatas_.clear();
  1480. doFindTest(*finder, isc::dns::Name("*.wild.example.org"),
  1481. isc::dns::RRType::AAAA(), isc::dns::RRType::AAAA(),
  1482. this->rrttl_, ZoneFinder::NXRRSET, this->expected_rdatas_,
  1483. this->expected_sig_rdatas_);
  1484. // This is nonsense, but check it doesn't match by some stupid accident
  1485. doFindTest(*finder, isc::dns::Name("a.*.wild.example.org"),
  1486. this->qtype_, this->qtype_, this->rrttl_, ZoneFinder::NXDOMAIN,
  1487. this->expected_rdatas_, this->expected_sig_rdatas_);
  1488. // These should be canceled, since it is below a domain which exitsts
  1489. doFindTest(*finder, isc::dns::Name("nothing.here.wild.example.org"),
  1490. this->qtype_, this->qtype_, this->rrttl_, ZoneFinder::NXDOMAIN,
  1491. this->expected_rdatas_, this->expected_sig_rdatas_);
  1492. doFindTest(*finder, isc::dns::Name("cancel.here.wild.example.org"),
  1493. this->qtype_, this->qtype_, this->rrttl_, ZoneFinder::NXRRSET,
  1494. this->expected_rdatas_, this->expected_sig_rdatas_);
  1495. doFindTest(*finder,
  1496. isc::dns::Name("below.cancel.here.wild.example.org"),
  1497. this->qtype_, this->qtype_, this->rrttl_, ZoneFinder::NXDOMAIN,
  1498. this->expected_rdatas_, this->expected_sig_rdatas_);
  1499. // And this should be just plain empty non-terminal domain, check
  1500. // the wildcard doesn't hurt it
  1501. doFindTest(*finder, isc::dns::Name("here.wild.example.org"),
  1502. this->qtype_, this->qtype_, this->rrttl_, ZoneFinder::NXRRSET,
  1503. this->expected_rdatas_, this->expected_sig_rdatas_);
  1504. // Also make sure that the wildcard doesn't hurt the original data
  1505. // below the wildcard
  1506. this->expected_rdatas_.push_back("2001:db8::5");
  1507. doFindTest(*finder, isc::dns::Name("cancel.here.wild.example.org"),
  1508. isc::dns::RRType::AAAA(), isc::dns::RRType::AAAA(),
  1509. this->rrttl_, ZoneFinder::SUCCESS,
  1510. this->expected_rdatas_, this->expected_sig_rdatas_);
  1511. this->expected_rdatas_.clear();
  1512. // How wildcard go together with delegation
  1513. this->expected_rdatas_.push_back("ns.example.com.");
  1514. doFindTest(*finder, isc::dns::Name("below.delegatedwild.example.org"),
  1515. this->qtype_, isc::dns::RRType::NS(), this->rrttl_,
  1516. ZoneFinder::DELEGATION, this->expected_rdatas_,
  1517. this->expected_sig_rdatas_,
  1518. isc::dns::Name("delegatedwild.example.org"));
  1519. // FIXME: This doesn't look logically OK, GLUE_OK should make it transparent,
  1520. // so the match should either work or be canceled, but return NXDOMAIN
  1521. doFindTest(*finder, isc::dns::Name("below.delegatedwild.example.org"),
  1522. this->qtype_, isc::dns::RRType::NS(), this->rrttl_,
  1523. ZoneFinder::DELEGATION, this->expected_rdatas_,
  1524. this->expected_sig_rdatas_,
  1525. isc::dns::Name("delegatedwild.example.org"),
  1526. ZoneFinder::FIND_GLUE_OK);
  1527. this->expected_rdatas_.clear();
  1528. this->expected_rdatas_.push_back("192.0.2.5");
  1529. // These are direct matches
  1530. const char* positive_names[] = {
  1531. "wild.*.foo.example.org.",
  1532. "wild.*.foo.*.bar.example.org.",
  1533. NULL
  1534. };
  1535. for (const char** name(positive_names); *name != NULL; ++ name) {
  1536. doFindTest(*finder, isc::dns::Name(*name), this->qtype_,
  1537. this->qtype_, this->rrttl_, ZoneFinder::SUCCESS,
  1538. this->expected_rdatas_,
  1539. this->expected_sig_rdatas_);
  1540. }
  1541. // These are wildcard matches against empty nonterminal asterisk
  1542. this->expected_rdatas_.clear();
  1543. const char* negative_names[] = {
  1544. "a.foo.example.org.",
  1545. "*.foo.example.org.",
  1546. "foo.example.org.",
  1547. "wild.bar.foo.example.org.",
  1548. "baz.foo.*.bar.example.org",
  1549. "baz.foo.baz.bar.example.org",
  1550. "*.foo.baz.bar.example.org",
  1551. "*.foo.*.bar.example.org",
  1552. "foo.*.bar.example.org",
  1553. "*.bar.example.org",
  1554. "bar.example.org",
  1555. NULL
  1556. };
  1557. // Unless FIND_DNSSEC is specified, this is no different from other
  1558. // NXRRSET case.
  1559. for (const char** name(negative_names); *name != NULL; ++ name) {
  1560. doFindTest(*finder, isc::dns::Name(*name), this->qtype_,
  1561. this->qtype_, this->rrttl_, ZoneFinder::NXRRSET,
  1562. this->expected_rdatas_, this->expected_sig_rdatas_);
  1563. }
  1564. // With FIND_DNSSEC, it should result in WILDCARD_NXRRSET.
  1565. const char* negative_dnssec_names[] = {
  1566. "a.bar.example.org.",
  1567. "foo.baz.bar.example.org.",
  1568. "a.foo.bar.example.org.",
  1569. NULL
  1570. };
  1571. this->expected_rdatas_.clear();
  1572. this->expected_rdatas_.push_back("wild.*.foo.*.bar.example.org. NSEC");
  1573. this->expected_sig_rdatas_.clear();
  1574. for (const char** name(negative_dnssec_names); *name != NULL; ++ name) {
  1575. doFindTest(*finder, isc::dns::Name(*name), this->qtype_,
  1576. RRType::NSEC(), this->rrttl_, ZoneFinder::WILDCARD_NXRRSET,
  1577. this->expected_rdatas_, this->expected_sig_rdatas_,
  1578. Name("bao.example.org."), ZoneFinder::FIND_DNSSEC);
  1579. }
  1580. // CNAME on a wildcard. Maybe not so common, but not disallowed.
  1581. this->expected_rdatas_.clear();
  1582. this->expected_rdatas_.push_back("www.example.org.");
  1583. this->expected_sig_rdatas_.clear();
  1584. doFindTest(*finder, isc::dns::Name("a.cnamewild.example.org."),
  1585. isc::dns::RRType::TXT(), isc::dns::RRType::CNAME(),
  1586. this->rrttl_, ZoneFinder::WILDCARD_CNAME,
  1587. this->expected_rdatas_, this->expected_sig_rdatas_);
  1588. // DNAME on a wildcard. In our implementation we ignore DNAMEs on a
  1589. // wildcard, but at a higher level we say the behavior is "unspecified".
  1590. // rfc2672bis strongly discourages the mixture of DNAME and wildcard
  1591. // (with SHOULD NOT).
  1592. this->expected_rdatas_.clear();
  1593. this->expected_sig_rdatas_.clear();
  1594. doFindTest(*finder, Name("a.dnamewild.example.org."),
  1595. this->qtype_, this->qtype_, this->rrttl_,
  1596. ZoneFinder::WILDCARD_NXRRSET, this->expected_rdatas_,
  1597. this->expected_sig_rdatas_);
  1598. // Some strange things in the wild node
  1599. this->expected_rdatas_.clear();
  1600. this->expected_rdatas_.push_back("ns.example.com.");
  1601. doFindTest(*finder, isc::dns::Name("a.nswild.example.org."),
  1602. isc::dns::RRType::TXT(), isc::dns::RRType::NS(),
  1603. this->rrttl_, ZoneFinder::DELEGATION,
  1604. this->expected_rdatas_, this->expected_sig_rdatas_);
  1605. }
  1606. TYPED_TEST(DatabaseClientTest, noWildcard) {
  1607. // Tests with the NO_WILDCARD flag.
  1608. shared_ptr<DatabaseClient::Finder> finder(this->getFinder());
  1609. // This would match *.wild.example.org, but with NO_WILDCARD should
  1610. // result in NXDOMAIN.
  1611. this->expected_rdatas_.push_back("cancel.here.wild.example.org. A "
  1612. "NSEC RRSIG");
  1613. this->expected_sig_rdatas_.push_back("NSEC 5 3 3600 20000101000000 "
  1614. "20000201000000 12345 example.org. "
  1615. "FAKEFAKEFAKE");
  1616. doFindTest(*finder, isc::dns::Name("a.wild.example.org"),
  1617. RRType::NSEC(), RRType::NSEC(), this->rrttl_,
  1618. ZoneFinder::NXDOMAIN, this->expected_rdatas_,
  1619. this->expected_sig_rdatas_, Name("*.wild.example.org."),
  1620. ZoneFinder::FIND_DNSSEC | ZoneFinder::NO_WILDCARD);
  1621. // Should be the same without FIND_DNSSEC (but in this case no RRsets
  1622. // will be returned)
  1623. doFindTest(*finder, isc::dns::Name("a.wild.example.org"),
  1624. RRType::NSEC(), RRType::NSEC(), this->rrttl_,
  1625. ZoneFinder::NXDOMAIN, this->empty_rdatas_,
  1626. this->empty_rdatas_, Name::ROOT_NAME(), // name is dummy
  1627. ZoneFinder::NO_WILDCARD);
  1628. // Same for wildcard empty non terminal.
  1629. this->expected_rdatas_.clear();
  1630. this->expected_rdatas_.push_back("brokenns1.example.org. A NSEC");
  1631. doFindTest(*finder, isc::dns::Name("a.bar.example.org"),
  1632. RRType::NSEC(), RRType::NSEC(), this->rrttl_,
  1633. ZoneFinder::NXDOMAIN, this->expected_rdatas_,
  1634. this->empty_rdatas_, Name("wild.*.foo.*.bar.example.org"),
  1635. ZoneFinder::FIND_DNSSEC | ZoneFinder::NO_WILDCARD);
  1636. // Search for a wildcard name with NO_WILDCARD. There should be no
  1637. // difference. This is, for example, necessary to provide non existence
  1638. // of matching wildcard for isnx.nonterminal.example.org.
  1639. this->expected_rdatas_.clear();
  1640. this->expected_rdatas_.push_back("empty.nonterminal.example.org. NSEC");
  1641. doFindTest(*finder, isc::dns::Name("*.nonterminal.example.org"),
  1642. RRType::NSEC(), RRType::NSEC(), this->rrttl_,
  1643. ZoneFinder::NXDOMAIN, this->expected_rdatas_,
  1644. this->empty_rdatas_, Name("l.example.org"),
  1645. ZoneFinder::FIND_DNSSEC | ZoneFinder::NO_WILDCARD);
  1646. // On the other hand, if there's exact match for the wildcard name
  1647. // it should be found regardless of NO_WILDCARD.
  1648. this->expected_rdatas_.clear();
  1649. this->expected_rdatas_.push_back("192.0.2.5");
  1650. this->expected_sig_rdatas_.clear();
  1651. this->expected_sig_rdatas_.push_back("A 5 3 3600 20000101000000 "
  1652. "20000201000000 12345 example.org. "
  1653. "FAKEFAKEFAKE");
  1654. doFindTest(*finder, isc::dns::Name("*.wild.example.org"),
  1655. this->qtype_, this->qtype_, this->rrttl_,
  1656. ZoneFinder::SUCCESS, this->expected_rdatas_,
  1657. this->expected_sig_rdatas_, Name("*.wild.example.org"),
  1658. ZoneFinder::NO_WILDCARD);
  1659. }
  1660. TYPED_TEST(DatabaseClientTest, NXRRSET_NSEC) {
  1661. // The domain exists, but doesn't have this RRType
  1662. // So we should get its NSEC
  1663. shared_ptr<DatabaseClient::Finder> finder(this->getFinder());
  1664. this->expected_rdatas_.push_back("www2.example.org. A AAAA NSEC RRSIG");
  1665. this->expected_sig_rdatas_.push_back("NSEC 5 3 3600 20000101000000 "
  1666. "20000201000000 12345 example.org. "
  1667. "FAKEFAKEFAKE");
  1668. doFindTest(*finder, isc::dns::Name("www.example.org."),
  1669. isc::dns::RRType::TXT(), isc::dns::RRType::NSEC(),
  1670. this->rrttl_, ZoneFinder::NXRRSET,
  1671. this->expected_rdatas_, this->expected_sig_rdatas_,
  1672. Name::ROOT_NAME(), ZoneFinder::FIND_DNSSEC);
  1673. }
  1674. TYPED_TEST(DatabaseClientTest, wildcardNXRRSET_NSEC) {
  1675. // The domain exists, but doesn't have this RRType
  1676. // So we should get its NSEC
  1677. //
  1678. // The user will have to query us again to get the correct
  1679. // answer (eg. prove there's not an exact match)
  1680. shared_ptr<DatabaseClient::Finder> finder(this->getFinder());
  1681. this->expected_rdatas_.push_back("cancel.here.wild.example.org. A NSEC "
  1682. "RRSIG");
  1683. this->expected_sig_rdatas_.push_back("NSEC 5 3 3600 20000101000000 "
  1684. "20000201000000 12345 example.org. "
  1685. "FAKEFAKEFAKE");
  1686. // Note that the NSEC name should NOT be synthesized.
  1687. doFindTest(*finder, isc::dns::Name("a.wild.example.org."),
  1688. isc::dns::RRType::TXT(), isc::dns::RRType::NSEC(),
  1689. this->rrttl_, ZoneFinder::WILDCARD_NXRRSET,
  1690. this->expected_rdatas_, this->expected_sig_rdatas_,
  1691. Name("*.wild.example.org"), ZoneFinder::FIND_DNSSEC);
  1692. }
  1693. TYPED_TEST(DatabaseClientTest, NXDOMAIN_NSEC) {
  1694. // The domain doesn't exist, so we must get the right NSEC
  1695. shared_ptr<DatabaseClient::Finder> finder(this->getFinder());
  1696. this->expected_rdatas_.push_back("www2.example.org. A AAAA NSEC RRSIG");
  1697. this->expected_sig_rdatas_.push_back("NSEC 5 3 3600 20000101000000 "
  1698. "20000201000000 12345 example.org. "
  1699. "FAKEFAKEFAKE");
  1700. doFindTest(*finder, isc::dns::Name("www1.example.org."),
  1701. isc::dns::RRType::TXT(), isc::dns::RRType::NSEC(),
  1702. this->rrttl_, ZoneFinder::NXDOMAIN,
  1703. this->expected_rdatas_, this->expected_sig_rdatas_,
  1704. Name("www.example.org."), ZoneFinder::FIND_DNSSEC);
  1705. this->expected_rdatas_.clear();
  1706. this->expected_rdatas_.push_back("acnamesig1.example.org. NS A NSEC RRSIG");
  1707. // This tests it works correctly in apex (there was a bug, where a check
  1708. // for NS-alone was there and it would throw).
  1709. doFindTest(*finder, isc::dns::Name("aa.example.org."),
  1710. isc::dns::RRType::TXT(), isc::dns::RRType::NSEC(),
  1711. this->rrttl_, ZoneFinder::NXDOMAIN,
  1712. this->expected_rdatas_, this->expected_sig_rdatas_,
  1713. Name("example.org."), ZoneFinder::FIND_DNSSEC);
  1714. // Check that if the DB doesn't support it, the exception from there
  1715. // is not propagated and it only does not include the NSEC
  1716. if (!this->is_mock_) {
  1717. return; // We don't make the real DB to throw
  1718. }
  1719. EXPECT_NO_THROW(doFindTest(*finder,
  1720. isc::dns::Name("notimplnsec.example.org."),
  1721. isc::dns::RRType::TXT(),
  1722. isc::dns::RRType::NSEC(), this->rrttl_,
  1723. ZoneFinder::NXDOMAIN, this->empty_rdatas_,
  1724. this->empty_rdatas_, Name::ROOT_NAME(),
  1725. ZoneFinder::FIND_DNSSEC));
  1726. }
  1727. TYPED_TEST(DatabaseClientTest, emptyNonterminalNSEC) {
  1728. // Same as NXDOMAIN_NSEC, but with empty non-terminal
  1729. shared_ptr<DatabaseClient::Finder> finder(this->getFinder());
  1730. this->expected_rdatas_.push_back("empty.nonterminal.example.org. NSEC");
  1731. doFindTest(*finder, isc::dns::Name("nonterminal.example.org."),
  1732. isc::dns::RRType::TXT(), isc::dns::RRType::NSEC(), this->rrttl_,
  1733. ZoneFinder::NXRRSET,
  1734. this->expected_rdatas_, this->expected_sig_rdatas_,
  1735. Name("l.example.org."), ZoneFinder::FIND_DNSSEC);
  1736. // Check that if the DB doesn't support it, the exception from there
  1737. // is not propagated and it only does not include the NSEC
  1738. if (!this->is_mock_) {
  1739. return; // We don't make the real DB to throw
  1740. }
  1741. EXPECT_NO_THROW(doFindTest(*finder,
  1742. isc::dns::Name("here.wild.example.org."),
  1743. isc::dns::RRType::TXT(),
  1744. isc::dns::RRType::NSEC(),
  1745. this->rrttl_, ZoneFinder::NXRRSET,
  1746. this->empty_rdatas_, this->empty_rdatas_,
  1747. Name::ROOT_NAME(), ZoneFinder::FIND_DNSSEC));
  1748. }
  1749. TYPED_TEST(DatabaseClientTest, getOrigin) {
  1750. DataSourceClient::FindResult
  1751. zone(this->client_->findZone(Name("example.org")));
  1752. ASSERT_EQ(result::SUCCESS, zone.code);
  1753. shared_ptr<DatabaseClient::Finder> finder(
  1754. dynamic_pointer_cast<DatabaseClient::Finder>(zone.zone_finder));
  1755. if (this->is_mock_) {
  1756. EXPECT_EQ(READONLY_ZONE_ID, finder->zone_id());
  1757. }
  1758. EXPECT_EQ(this->zname_, finder->getOrigin());
  1759. }
  1760. TYPED_TEST(DatabaseClientTest, updaterFinder) {
  1761. this->updater_ = this->client_->getUpdater(this->zname_, false);
  1762. ASSERT_TRUE(this->updater_);
  1763. // If this update isn't replacing the zone, the finder should work
  1764. // just like the normal find() case.
  1765. if (this->is_mock_) {
  1766. DatabaseClient::Finder& finder = dynamic_cast<DatabaseClient::Finder&>(
  1767. this->updater_->getFinder());
  1768. EXPECT_EQ(WRITABLE_ZONE_ID, finder.zone_id());
  1769. }
  1770. this->expected_rdatas_.clear();
  1771. this->expected_rdatas_.push_back("192.0.2.1");
  1772. doFindTest(this->updater_->getFinder(), this->qname_,
  1773. this->qtype_, this->qtype_, this->rrttl_, ZoneFinder::SUCCESS,
  1774. this->expected_rdatas_, this->empty_rdatas_);
  1775. // When replacing the zone, the updater's finder shouldn't see anything
  1776. // in the zone until something is added.
  1777. this->updater_.reset();
  1778. this->updater_ = this->client_->getUpdater(this->zname_, true);
  1779. ASSERT_TRUE(this->updater_);
  1780. if (this->is_mock_) {
  1781. DatabaseClient::Finder& finder = dynamic_cast<DatabaseClient::Finder&>(
  1782. this->updater_->getFinder());
  1783. EXPECT_EQ(WRITABLE_ZONE_ID, finder.zone_id());
  1784. }
  1785. doFindTest(this->updater_->getFinder(), this->qname_, this->qtype_,
  1786. this->qtype_, this->rrttl_, ZoneFinder::NXDOMAIN,
  1787. this->empty_rdatas_, this->empty_rdatas_);
  1788. }
  1789. TYPED_TEST(DatabaseClientTest, flushZone) {
  1790. // A simple update case: flush the entire zone
  1791. shared_ptr<DatabaseClient::Finder> finder(this->getFinder());
  1792. // Before update, the name exists.
  1793. EXPECT_EQ(ZoneFinder::SUCCESS, finder->find(this->qname_,
  1794. this->qtype_).code);
  1795. // start update in the replace mode. the normal finder should still
  1796. // be able to see the record, but the updater's finder shouldn't.
  1797. this->updater_ = this->client_->getUpdater(this->zname_, true);
  1798. this->setUpdateAccessor();
  1799. EXPECT_EQ(ZoneFinder::SUCCESS,
  1800. finder->find(this->qname_, this->qtype_).code);
  1801. EXPECT_EQ(ZoneFinder::NXDOMAIN,
  1802. this->updater_->getFinder().find(this->qname_,
  1803. this->qtype_).code);
  1804. // commit the update. now the normal finder shouldn't see it.
  1805. this->updater_->commit();
  1806. EXPECT_EQ(ZoneFinder::NXDOMAIN, finder->find(this->qname_,
  1807. this->qtype_).code);
  1808. // Check rollback wasn't accidentally performed.
  1809. EXPECT_FALSE(this->isRollbacked());
  1810. }
  1811. TYPED_TEST(DatabaseClientTest, updateCancel) {
  1812. // similar to the previous test, but destruct the updater before commit.
  1813. ZoneFinderPtr finder = this->client_->findZone(this->zname_).zone_finder;
  1814. EXPECT_EQ(ZoneFinder::SUCCESS, finder->find(this->qname_,
  1815. this->qtype_).code);
  1816. this->updater_ = this->client_->getUpdater(this->zname_, true);
  1817. this->setUpdateAccessor();
  1818. EXPECT_EQ(ZoneFinder::NXDOMAIN,
  1819. this->updater_->getFinder().find(this->qname_,
  1820. this->qtype_).code);
  1821. // DB should not have been rolled back yet.
  1822. EXPECT_FALSE(this->isRollbacked());
  1823. this->updater_.reset(); // destruct without commit
  1824. // reset() should have triggered rollback (although it doesn't affect
  1825. // anything to the mock accessor implementation except for the result of
  1826. // isRollbacked())
  1827. EXPECT_TRUE(this->isRollbacked(true));
  1828. EXPECT_EQ(ZoneFinder::SUCCESS, finder->find(this->qname_,
  1829. this->qtype_).code);
  1830. }
  1831. TYPED_TEST(DatabaseClientTest, exceptionFromRollback) {
  1832. this->updater_ = this->client_->getUpdater(this->zname_, true);
  1833. this->rrset_.reset(new RRset(Name("throw.example.org"), this->qclass_,
  1834. this->qtype_, this->rrttl_));
  1835. this->rrset_->addRdata(rdata::createRdata(this->rrset_->getType(),
  1836. this->rrset_->getClass(),
  1837. "192.0.2.1"));
  1838. this->updater_->addRRset(*this->rrset_);
  1839. // destruct without commit. The added name will result in an exception
  1840. // in the MockAccessor's rollback method. It shouldn't be propagated.
  1841. EXPECT_NO_THROW(this->updater_.reset());
  1842. }
  1843. TYPED_TEST(DatabaseClientTest, duplicateCommit) {
  1844. // duplicate commit. should result in exception.
  1845. this->updater_ = this->client_->getUpdater(this->zname_, true);
  1846. this->updater_->commit();
  1847. EXPECT_THROW(this->updater_->commit(), DataSourceError);
  1848. }
  1849. TYPED_TEST(DatabaseClientTest, addRRsetToNewZone) {
  1850. // Add a single RRset to a fresh empty zone
  1851. this->updater_ = this->client_->getUpdater(this->zname_, true);
  1852. this->updater_->addRRset(*this->rrset_);
  1853. this->expected_rdatas_.clear();
  1854. this->expected_rdatas_.push_back("192.0.2.2");
  1855. {
  1856. SCOPED_TRACE("add RRset");
  1857. doFindTest(this->updater_->getFinder(), this->qname_, this->qtype_,
  1858. this->qtype_, this->rrttl_, ZoneFinder::SUCCESS,
  1859. this->expected_rdatas_, this->empty_rdatas_);
  1860. }
  1861. // Similar to the previous case, but with RRSIG
  1862. this->updater_.reset();
  1863. this->updater_ = this->client_->getUpdater(this->zname_, true);
  1864. this->updater_->addRRset(*this->rrset_);
  1865. this->updater_->addRRset(*this->rrsigset_);
  1866. // confirm the expected columns were passed to the accessor (if checkable).
  1867. const char* const rrsig_added[] = {
  1868. "www.example.org.", "org.example.www.", "3600", "RRSIG", "A",
  1869. "A 5 3 0 20000101000000 20000201000000 0 example.org. FAKEFAKEFAKE"
  1870. };
  1871. this->checkLastAdded(rrsig_added);
  1872. this->expected_sig_rdatas_.clear();
  1873. this->expected_sig_rdatas_.push_back(
  1874. rrsig_added[DatabaseAccessor::ADD_RDATA]);
  1875. {
  1876. SCOPED_TRACE("add RRset with RRSIG");
  1877. doFindTest(this->updater_->getFinder(), this->qname_, this->qtype_,
  1878. this->qtype_, this->rrttl_, ZoneFinder::SUCCESS,
  1879. this->expected_rdatas_, this->expected_sig_rdatas_);
  1880. }
  1881. // Add the non RRSIG RRset again, to see the attempt of adding RRSIG
  1882. // causes any unexpected effect, in particular, whether the SIGTYPE
  1883. // field might remain.
  1884. this->updater_->addRRset(*this->rrset_);
  1885. const char* const rrset_added[] = {
  1886. "www.example.org.", "org.example.www.", "3600", "A", "", "192.0.2.2"
  1887. };
  1888. this->checkLastAdded(rrset_added);
  1889. }
  1890. TYPED_TEST(DatabaseClientTest, addRRsetToCurrentZone) {
  1891. // Similar to the previous test, but not replacing the existing data.
  1892. shared_ptr<DatabaseClient::Finder> finder(this->getFinder());
  1893. this->updater_ = this->client_->getUpdater(this->zname_, false);
  1894. this->updater_->addRRset(*this->rrset_);
  1895. // We should see both old and new data.
  1896. this->expected_rdatas_.clear();
  1897. this->expected_rdatas_.push_back("192.0.2.1");
  1898. this->expected_rdatas_.push_back("192.0.2.2");
  1899. {
  1900. SCOPED_TRACE("add RRset");
  1901. doFindTest(this->updater_->getFinder(), this->qname_, this->qtype_,
  1902. this->qtype_, this->rrttl_, ZoneFinder::SUCCESS,
  1903. this->expected_rdatas_, this->empty_rdatas_);
  1904. }
  1905. this->updater_->commit();
  1906. {
  1907. SCOPED_TRACE("add RRset after commit");
  1908. doFindTest(*finder, this->qname_, this->qtype_, this->qtype_,
  1909. this->rrttl_, ZoneFinder::SUCCESS, this->expected_rdatas_,
  1910. this->empty_rdatas_);
  1911. }
  1912. }
  1913. TYPED_TEST(DatabaseClientTest, addMultipleRRs) {
  1914. // Similar to the previous case, but the added RRset contains multiple
  1915. // RRs.
  1916. this->updater_ = this->client_->getUpdater(this->zname_, false);
  1917. this->rrset_->addRdata(rdata::createRdata(this->rrset_->getType(),
  1918. this->rrset_->getClass(),
  1919. "192.0.2.3"));
  1920. this->updater_->addRRset(*this->rrset_);
  1921. this->expected_rdatas_.clear();
  1922. this->expected_rdatas_.push_back("192.0.2.1");
  1923. this->expected_rdatas_.push_back("192.0.2.2");
  1924. this->expected_rdatas_.push_back("192.0.2.3");
  1925. {
  1926. SCOPED_TRACE("add multiple RRs");
  1927. doFindTest(this->updater_->getFinder(), this->qname_, this->qtype_,
  1928. this->qtype_, this->rrttl_, ZoneFinder::SUCCESS,
  1929. this->expected_rdatas_, this->empty_rdatas_);
  1930. }
  1931. }
  1932. TYPED_TEST(DatabaseClientTest, addRRsetOfLargerTTL) {
  1933. // Similar to the previous one, but the TTL of the added RRset is larger
  1934. // than that of the existing record. The finder should use the smaller
  1935. // one.
  1936. this->updater_ = this->client_->getUpdater(this->zname_, false);
  1937. this->rrset_->setTTL(RRTTL(7200));
  1938. this->updater_->addRRset(*this->rrset_);
  1939. this->expected_rdatas_.clear();
  1940. this->expected_rdatas_.push_back("192.0.2.1");
  1941. this->expected_rdatas_.push_back("192.0.2.2");
  1942. {
  1943. SCOPED_TRACE("add RRset of larger TTL");
  1944. doFindTest(this->updater_->getFinder(), this->qname_, this->qtype_,
  1945. this->qtype_, this->rrttl_, ZoneFinder::SUCCESS,
  1946. this->expected_rdatas_, this->empty_rdatas_);
  1947. }
  1948. }
  1949. TYPED_TEST(DatabaseClientTest, addRRsetOfSmallerTTL) {
  1950. // Similar to the previous one, but the added RRset has a smaller TTL.
  1951. // The added TTL should be used by the finder.
  1952. this->updater_ = this->client_->getUpdater(this->zname_, false);
  1953. this->rrset_->setTTL(RRTTL(1800));
  1954. this->updater_->addRRset(*this->rrset_);
  1955. this->expected_rdatas_.clear();
  1956. this->expected_rdatas_.push_back("192.0.2.1");
  1957. this->expected_rdatas_.push_back("192.0.2.2");
  1958. {
  1959. SCOPED_TRACE("add RRset of smaller TTL");
  1960. doFindTest(this->updater_->getFinder(), this->qname_, this->qtype_,
  1961. this->qtype_, RRTTL(1800), ZoneFinder::SUCCESS,
  1962. this->expected_rdatas_, this->empty_rdatas_);
  1963. }
  1964. }
  1965. TYPED_TEST(DatabaseClientTest, addSameRR) {
  1966. // Add the same RR as that is already in the data source.
  1967. // Currently the add interface doesn't try to suppress the duplicate,
  1968. // neither does the finder. We may want to revisit it in future versions.
  1969. this->updater_ = this->client_->getUpdater(this->zname_, false);
  1970. this->rrset_.reset(new RRset(this->qname_, this->qclass_, this->qtype_,
  1971. this->rrttl_));
  1972. this->rrset_->addRdata(rdata::createRdata(this->rrset_->getType(),
  1973. this->rrset_->getClass(),
  1974. "192.0.2.1"));
  1975. this->updater_->addRRset(*this->rrset_);
  1976. this->expected_rdatas_.clear();
  1977. this->expected_rdatas_.push_back("192.0.2.1");
  1978. this->expected_rdatas_.push_back("192.0.2.1");
  1979. {
  1980. SCOPED_TRACE("add same RR");
  1981. doFindTest(this->updater_->getFinder(), this->qname_, this->qtype_,
  1982. this->qtype_, this->rrttl_, ZoneFinder::SUCCESS,
  1983. this->expected_rdatas_, this->empty_rdatas_);
  1984. }
  1985. }
  1986. TYPED_TEST(DatabaseClientTest, addDeviantRR) {
  1987. this->updater_ = this->client_->getUpdater(this->zname_, false);
  1988. // RR class mismatch. This should be detected and rejected.
  1989. this->rrset_.reset(new RRset(this->qname_, RRClass::CH(), RRType::TXT(),
  1990. this->rrttl_));
  1991. this->rrset_->addRdata(rdata::createRdata(this->rrset_->getType(),
  1992. this->rrset_->getClass(),
  1993. "test text"));
  1994. EXPECT_THROW(this->updater_->addRRset(*this->rrset_), DataSourceError);
  1995. // Out-of-zone owner name. At a higher level this should be rejected,
  1996. // but it doesn't happen in this interface.
  1997. this->rrset_.reset(new RRset(Name("example.com"), this->qclass_,
  1998. this->qtype_, this->rrttl_));
  1999. this->rrset_->addRdata(rdata::createRdata(this->rrset_->getType(),
  2000. this->rrset_->getClass(),
  2001. "192.0.2.100"));
  2002. this->updater_->addRRset(*this->rrset_);
  2003. this->expected_rdatas_.clear();
  2004. this->expected_rdatas_.push_back("192.0.2.100");
  2005. {
  2006. // Note: with the find() implementation being more strict about
  2007. // zone cuts, this test may fail. Then the test should be updated.
  2008. SCOPED_TRACE("add out-of-zone RR");
  2009. doFindTest(this->updater_->getFinder(), Name("example.com"),
  2010. this->qtype_, this->qtype_, this->rrttl_,
  2011. ZoneFinder::SUCCESS, this->expected_rdatas_,
  2012. this->empty_rdatas_);
  2013. }
  2014. }
  2015. TYPED_TEST(DatabaseClientTest, addEmptyRRset) {
  2016. this->updater_ = this->client_->getUpdater(this->zname_, false);
  2017. this->rrset_.reset(new RRset(this->qname_, this->qclass_, this->qtype_,
  2018. this->rrttl_));
  2019. EXPECT_THROW(this->updater_->addRRset(*this->rrset_), DataSourceError);
  2020. }
  2021. TYPED_TEST(DatabaseClientTest, addAfterCommit) {
  2022. this->updater_ = this->client_->getUpdater(this->zname_, false);
  2023. this->updater_->commit();
  2024. EXPECT_THROW(this->updater_->addRRset(*this->rrset_), DataSourceError);
  2025. }
  2026. TYPED_TEST(DatabaseClientTest, addRRsetWithRRSIG) {
  2027. this->updater_ = this->client_->getUpdater(this->zname_, false);
  2028. this->rrset_->addRRsig(*this->rrsigset_);
  2029. EXPECT_THROW(this->updater_->addRRset(*this->rrset_), DataSourceError);
  2030. }
  2031. TYPED_TEST(DatabaseClientTest, deleteRRset) {
  2032. shared_ptr<DatabaseClient::Finder> finder(this->getFinder());
  2033. this->rrset_.reset(new RRset(this->qname_, this->qclass_, this->qtype_,
  2034. this->rrttl_));
  2035. this->rrset_->addRdata(rdata::createRdata(this->rrset_->getType(),
  2036. this->rrset_->getClass(),
  2037. "192.0.2.1"));
  2038. // Delete one RR from an RRset
  2039. this->updater_ = this->client_->getUpdater(this->zname_, false);
  2040. this->updater_->deleteRRset(*this->rrset_);
  2041. // Delete the only RR of a name
  2042. this->rrset_.reset(new RRset(Name("cname.example.org"), this->qclass_,
  2043. RRType::CNAME(), this->rrttl_));
  2044. this->rrset_->addRdata(rdata::createRdata(this->rrset_->getType(),
  2045. this->rrset_->getClass(),
  2046. "www.example.org"));
  2047. this->updater_->deleteRRset(*this->rrset_);
  2048. // The this->updater_ finder should immediately see the deleted results.
  2049. {
  2050. SCOPED_TRACE("delete RRset");
  2051. doFindTest(this->updater_->getFinder(), this->qname_, this->qtype_,
  2052. this->qtype_, this->rrttl_, ZoneFinder::NXRRSET,
  2053. this->empty_rdatas_, this->empty_rdatas_);
  2054. doFindTest(this->updater_->getFinder(), Name("cname.example.org"),
  2055. this->qtype_, this->qtype_, this->rrttl_,
  2056. ZoneFinder::NXDOMAIN, this->empty_rdatas_,
  2057. this->empty_rdatas_);
  2058. }
  2059. // before committing the change, the original finder should see the
  2060. // original record.
  2061. {
  2062. SCOPED_TRACE("delete RRset before commit");
  2063. this->expected_rdatas_.push_back("192.0.2.1");
  2064. doFindTest(*finder, this->qname_, this->qtype_, this->qtype_,
  2065. this->rrttl_, ZoneFinder::SUCCESS, this->expected_rdatas_,
  2066. this->empty_rdatas_);
  2067. this->expected_rdatas_.clear();
  2068. this->expected_rdatas_.push_back("www.example.org.");
  2069. doFindTest(*finder, Name("cname.example.org"), this->qtype_,
  2070. RRType::CNAME(), this->rrttl_, ZoneFinder::CNAME,
  2071. this->expected_rdatas_, this->empty_rdatas_);
  2072. }
  2073. // once committed, the record should be removed from the original finder's
  2074. // view, too.
  2075. this->updater_->commit();
  2076. {
  2077. SCOPED_TRACE("delete RRset after commit");
  2078. doFindTest(*finder, this->qname_, this->qtype_, this->qtype_,
  2079. this->rrttl_, ZoneFinder::NXRRSET, this->empty_rdatas_,
  2080. this->empty_rdatas_);
  2081. doFindTest(*finder, Name("cname.example.org"), this->qtype_,
  2082. this->qtype_, this->rrttl_, ZoneFinder::NXDOMAIN,
  2083. this->empty_rdatas_, this->empty_rdatas_);
  2084. }
  2085. }
  2086. TYPED_TEST(DatabaseClientTest, deleteRRsetToNXDOMAIN) {
  2087. // similar to the previous case, but it removes the only record of the
  2088. // given name. a subsequent find() should result in NXDOMAIN.
  2089. this->rrset_.reset(new RRset(Name("cname.example.org"), this->qclass_,
  2090. RRType::CNAME(), this->rrttl_));
  2091. this->rrset_->addRdata(rdata::createRdata(this->rrset_->getType(),
  2092. this->rrset_->getClass(),
  2093. "www.example.org"));
  2094. this->updater_ = this->client_->getUpdater(this->zname_, false);
  2095. this->updater_->deleteRRset(*this->rrset_);
  2096. {
  2097. SCOPED_TRACE("delete RRset to NXDOMAIN");
  2098. doFindTest(this->updater_->getFinder(), Name("cname.example.org"),
  2099. this->qtype_, this->qtype_, this->rrttl_,
  2100. ZoneFinder::NXDOMAIN, this->empty_rdatas_,
  2101. this->empty_rdatas_);
  2102. }
  2103. }
  2104. TYPED_TEST(DatabaseClientTest, deleteMultipleRRs) {
  2105. this->rrset_.reset(new RRset(this->qname_, this->qclass_, RRType::AAAA(),
  2106. this->rrttl_));
  2107. this->rrset_->addRdata(rdata::createRdata(this->rrset_->getType(),
  2108. this->rrset_->getClass(),
  2109. "2001:db8::1"));
  2110. this->rrset_->addRdata(rdata::createRdata(this->rrset_->getType(),
  2111. this->rrset_->getClass(),
  2112. "2001:db8::2"));
  2113. this->updater_ = this->client_->getUpdater(this->zname_, false);
  2114. this->updater_->deleteRRset(*this->rrset_);
  2115. {
  2116. SCOPED_TRACE("delete multiple RRs");
  2117. doFindTest(this->updater_->getFinder(), this->qname_, RRType::AAAA(),
  2118. this->qtype_, this->rrttl_, ZoneFinder::NXRRSET,
  2119. this->empty_rdatas_, this->empty_rdatas_);
  2120. }
  2121. }
  2122. TYPED_TEST(DatabaseClientTest, partialDelete) {
  2123. this->rrset_.reset(new RRset(this->qname_, this->qclass_, RRType::AAAA(),
  2124. this->rrttl_));
  2125. this->rrset_->addRdata(rdata::createRdata(this->rrset_->getType(),
  2126. this->rrset_->getClass(),
  2127. "2001:db8::1"));
  2128. // This does not exist in the test data source:
  2129. this->rrset_->addRdata(rdata::createRdata(this->rrset_->getType(),
  2130. this->rrset_->getClass(),
  2131. "2001:db8::3"));
  2132. // deleteRRset should succeed "silently", and subsequent find() should
  2133. // find the remaining RR.
  2134. this->updater_ = this->client_->getUpdater(this->zname_, false);
  2135. this->updater_->deleteRRset(*this->rrset_);
  2136. {
  2137. SCOPED_TRACE("partial delete");
  2138. this->expected_rdatas_.push_back("2001:db8::2");
  2139. doFindTest(this->updater_->getFinder(), this->qname_, RRType::AAAA(),
  2140. RRType::AAAA(), this->rrttl_, ZoneFinder::SUCCESS,
  2141. this->expected_rdatas_, this->empty_rdatas_);
  2142. }
  2143. }
  2144. TYPED_TEST(DatabaseClientTest, deleteNoMatch) {
  2145. // similar to the previous test, but there's not even a match in the
  2146. // specified RRset. Essentially there's no difference in the result.
  2147. this->updater_ = this->client_->getUpdater(this->zname_, false);
  2148. this->updater_->deleteRRset(*this->rrset_);
  2149. {
  2150. SCOPED_TRACE("delete no match");
  2151. this->expected_rdatas_.push_back("192.0.2.1");
  2152. doFindTest(this->updater_->getFinder(), this->qname_, this->qtype_,
  2153. this->qtype_, this->rrttl_, ZoneFinder::SUCCESS,
  2154. this->expected_rdatas_, this->empty_rdatas_);
  2155. }
  2156. }
  2157. TYPED_TEST(DatabaseClientTest, deleteWithDifferentTTL) {
  2158. // Our delete interface simply ignores TTL (may change in a future version)
  2159. this->rrset_.reset(new RRset(this->qname_, this->qclass_, this->qtype_,
  2160. RRTTL(1800)));
  2161. this->rrset_->addRdata(rdata::createRdata(this->rrset_->getType(),
  2162. this->rrset_->getClass(),
  2163. "192.0.2.1"));
  2164. this->updater_ = this->client_->getUpdater(this->zname_, false);
  2165. this->updater_->deleteRRset(*this->rrset_);
  2166. {
  2167. SCOPED_TRACE("delete RRset with a different TTL");
  2168. doFindTest(this->updater_->getFinder(), this->qname_, this->qtype_,
  2169. this->qtype_, this->rrttl_, ZoneFinder::NXRRSET,
  2170. this->empty_rdatas_, this->empty_rdatas_);
  2171. }
  2172. }
  2173. TYPED_TEST(DatabaseClientTest, deleteDeviantRR) {
  2174. this->updater_ = this->client_->getUpdater(this->zname_, false);
  2175. // RR class mismatch. This should be detected and rejected.
  2176. this->rrset_.reset(new RRset(this->qname_, RRClass::CH(), RRType::TXT(),
  2177. this->rrttl_));
  2178. this->rrset_->addRdata(rdata::createRdata(this->rrset_->getType(),
  2179. this->rrset_->getClass(),
  2180. "test text"));
  2181. EXPECT_THROW(this->updater_->deleteRRset(*this->rrset_), DataSourceError);
  2182. // Out-of-zone owner name. At a higher level this should be rejected,
  2183. // but it doesn't happen in this interface.
  2184. this->rrset_.reset(new RRset(Name("example.com"), this->qclass_,
  2185. this->qtype_, this->rrttl_));
  2186. this->rrset_->addRdata(rdata::createRdata(this->rrset_->getType(),
  2187. this->rrset_->getClass(),
  2188. "192.0.2.100"));
  2189. EXPECT_NO_THROW(this->updater_->deleteRRset(*this->rrset_));
  2190. }
  2191. TYPED_TEST(DatabaseClientTest, deleteAfterCommit) {
  2192. this->updater_ = this->client_->getUpdater(this->zname_, false);
  2193. this->updater_->commit();
  2194. EXPECT_THROW(this->updater_->deleteRRset(*this->rrset_), DataSourceError);
  2195. }
  2196. TYPED_TEST(DatabaseClientTest, deleteEmptyRRset) {
  2197. this->updater_ = this->client_->getUpdater(this->zname_, false);
  2198. this->rrset_.reset(new RRset(this->qname_, this->qclass_, this->qtype_,
  2199. this->rrttl_));
  2200. EXPECT_THROW(this->updater_->deleteRRset(*this->rrset_), DataSourceError);
  2201. }
  2202. TYPED_TEST(DatabaseClientTest, deleteRRsetWithRRSIG) {
  2203. this->updater_ = this->client_->getUpdater(this->zname_, false);
  2204. this->rrset_->addRRsig(*this->rrsigset_);
  2205. EXPECT_THROW(this->updater_->deleteRRset(*this->rrset_), DataSourceError);
  2206. }
  2207. TYPED_TEST(DatabaseClientTest, compoundUpdate) {
  2208. // This test case performs an arbitrary chosen add/delete operations
  2209. // in a single update transaction. Essentially there is nothing new to
  2210. // test here, but there may be some bugs that was overlooked and can
  2211. // only happen in the compound update scenario, so we test it.
  2212. this->updater_ = this->client_->getUpdater(this->zname_, false);
  2213. // add a new RR to an existing RRset
  2214. this->updater_->addRRset(*this->rrset_);
  2215. this->expected_rdatas_.clear();
  2216. this->expected_rdatas_.push_back("192.0.2.1");
  2217. this->expected_rdatas_.push_back("192.0.2.2");
  2218. doFindTest(this->updater_->getFinder(), this->qname_, this->qtype_,
  2219. this->qtype_, this->rrttl_, ZoneFinder::SUCCESS,
  2220. this->expected_rdatas_, this->empty_rdatas_);
  2221. // delete an existing RR
  2222. this->rrset_.reset(new RRset(Name("www.example.org"), this->qclass_,
  2223. this->qtype_, this->rrttl_));
  2224. this->rrset_->addRdata(rdata::createRdata(this->rrset_->getType(),
  2225. this->rrset_->getClass(),
  2226. "192.0.2.1"));
  2227. this->updater_->deleteRRset(*this->rrset_);
  2228. this->expected_rdatas_.clear();
  2229. this->expected_rdatas_.push_back("192.0.2.2");
  2230. doFindTest(this->updater_->getFinder(), this->qname_, this->qtype_,
  2231. this->qtype_, this->rrttl_, ZoneFinder::SUCCESS,
  2232. this->expected_rdatas_, this->empty_rdatas_);
  2233. // re-add it
  2234. this->updater_->addRRset(*this->rrset_);
  2235. this->expected_rdatas_.push_back("192.0.2.1");
  2236. doFindTest(this->updater_->getFinder(), this->qname_, this->qtype_,
  2237. this->qtype_, this->rrttl_, ZoneFinder::SUCCESS,
  2238. this->expected_rdatas_, this->empty_rdatas_);
  2239. // add a new RR with a new name
  2240. const Name newname("newname.example.org");
  2241. const RRType newtype(RRType::AAAA());
  2242. doFindTest(this->updater_->getFinder(), newname, newtype, newtype,
  2243. this->rrttl_, ZoneFinder::NXDOMAIN, this->empty_rdatas_,
  2244. this->empty_rdatas_);
  2245. this->rrset_.reset(new RRset(newname, this->qclass_, newtype,
  2246. this->rrttl_));
  2247. this->rrset_->addRdata(rdata::createRdata(this->rrset_->getType(),
  2248. this->rrset_->getClass(),
  2249. "2001:db8::10"));
  2250. this->rrset_->addRdata(rdata::createRdata(this->rrset_->getType(),
  2251. this->rrset_->getClass(),
  2252. "2001:db8::11"));
  2253. this->updater_->addRRset(*this->rrset_);
  2254. this->expected_rdatas_.clear();
  2255. this->expected_rdatas_.push_back("2001:db8::10");
  2256. this->expected_rdatas_.push_back("2001:db8::11");
  2257. doFindTest(this->updater_->getFinder(), newname, newtype, newtype,
  2258. this->rrttl_, ZoneFinder::SUCCESS, this->expected_rdatas_,
  2259. this->empty_rdatas_);
  2260. // delete one RR from the previous set
  2261. this->rrset_.reset(new RRset(newname, this->qclass_, newtype,
  2262. this->rrttl_));
  2263. this->rrset_->addRdata(rdata::createRdata(this->rrset_->getType(),
  2264. this->rrset_->getClass(),
  2265. "2001:db8::11"));
  2266. this->updater_->deleteRRset(*this->rrset_);
  2267. this->expected_rdatas_.clear();
  2268. this->expected_rdatas_.push_back("2001:db8::10");
  2269. doFindTest(this->updater_->getFinder(), newname, newtype, newtype,
  2270. this->rrttl_, ZoneFinder::SUCCESS, this->expected_rdatas_,
  2271. this->empty_rdatas_);
  2272. // Commit the changes, confirm the entire changes applied.
  2273. this->updater_->commit();
  2274. shared_ptr<DatabaseClient::Finder> finder(this->getFinder());
  2275. this->expected_rdatas_.clear();
  2276. this->expected_rdatas_.push_back("192.0.2.2");
  2277. this->expected_rdatas_.push_back("192.0.2.1");
  2278. doFindTest(*finder, this->qname_, this->qtype_, this->qtype_, this->rrttl_,
  2279. ZoneFinder::SUCCESS, this->expected_rdatas_,
  2280. this->empty_rdatas_);
  2281. this->expected_rdatas_.clear();
  2282. this->expected_rdatas_.push_back("2001:db8::10");
  2283. doFindTest(*finder, newname, newtype, newtype, this->rrttl_,
  2284. ZoneFinder::SUCCESS, this->expected_rdatas_,
  2285. this->empty_rdatas_);
  2286. }
  2287. TYPED_TEST(DatabaseClientTest, previous) {
  2288. shared_ptr<DatabaseClient::Finder> finder(this->getFinder());
  2289. EXPECT_EQ(Name("www.example.org."),
  2290. finder->findPreviousName(Name("www2.example.org.")));
  2291. // Check a name that doesn't exist there
  2292. EXPECT_EQ(Name("www.example.org."),
  2293. finder->findPreviousName(Name("www1.example.org.")));
  2294. if (this->is_mock_) { // We can't really force the DB to throw
  2295. // Check it doesn't crash or anything if the underlying DB throws
  2296. DataSourceClient::FindResult
  2297. zone(this->client_->findZone(Name("bad.example.org")));
  2298. finder =
  2299. dynamic_pointer_cast<DatabaseClient::Finder>(zone.zone_finder);
  2300. EXPECT_THROW(finder->findPreviousName(Name("bad.example.org")),
  2301. isc::NotImplemented);
  2302. } else {
  2303. // No need to test this on mock one, because we test only that
  2304. // the exception gets through
  2305. // A name before the origin
  2306. EXPECT_THROW(finder->findPreviousName(Name("example.com")),
  2307. isc::NotImplemented);
  2308. }
  2309. }
  2310. TYPED_TEST(DatabaseClientTest, invalidRdata) {
  2311. shared_ptr<DatabaseClient::Finder> finder(this->getFinder());
  2312. EXPECT_THROW(finder->find(Name("invalidrdata.example.org."), RRType::A()),
  2313. DataSourceError);
  2314. EXPECT_THROW(finder->find(Name("invalidrdata2.example.org."), RRType::A()),
  2315. DataSourceError);
  2316. }
  2317. TEST_F(MockDatabaseClientTest, missingNSEC) {
  2318. shared_ptr<DatabaseClient::Finder> finder(this->getFinder());
  2319. /*
  2320. * FIXME: For now, we can't really distinguish this bogus input
  2321. * from not-signed zone so we can't throw. But once we can,
  2322. * enable the original test.
  2323. */
  2324. #if 0
  2325. EXPECT_THROW(finder->find(Name("badnsec2.example.org."), RRType::A(), NULL,
  2326. ZoneFinder::FIND_DNSSEC),
  2327. DataSourceError);
  2328. #endif
  2329. doFindTest(*finder, Name("badnsec2.example.org."), RRType::A(),
  2330. RRType::A(), this->rrttl_, ZoneFinder::NXDOMAIN,
  2331. this->expected_rdatas_, this->expected_sig_rdatas_);
  2332. }
  2333. TEST_F(MockDatabaseClientTest, badName) {
  2334. shared_ptr<DatabaseClient::Finder> finder(this->getFinder());
  2335. EXPECT_THROW(finder->findPreviousName(Name("brokenname.example.org.")),
  2336. DataSourceError);
  2337. }
  2338. }