{"id":292,"date":"2009-04-28T06:35:07","date_gmt":"2009-04-28T11:35:07","guid":{"rendered":"http:\/\/www.visophyte.org\/blog\/?p=292"},"modified":"2009-04-28T06:35:07","modified_gmt":"2009-04-28T11:35:07","slug":"understanding-where-unit-tests-go-wrong-with-object-diffs","status":"publish","type":"post","link":"https:\/\/www.visophyte.org\/blog\/2009\/04\/28\/understanding-where-unit-tests-go-wrong-with-object-diffs\/","title":{"rendered":"understanding where unit tests go wrong with object diffs"},"content":{"rendered":"<p><a href=\"http:\/\/www.visophyte.org\/blog\/wp-content\/uploads\/2009\/04\/chronimoz-diff-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-293\" title=\"chronimoz-diff-1\" src=\"http:\/\/www.visophyte.org\/blog\/wp-content\/uploads\/2009\/04\/chronimoz-diff-1.png\" alt=\"chronimoz-diff-1\" width=\"951\" height=\"546\" srcset=\"https:\/\/www.visophyte.org\/blog\/wp-content\/uploads\/2009\/04\/chronimoz-diff-1.png 951w, https:\/\/www.visophyte.org\/blog\/wp-content\/uploads\/2009\/04\/chronimoz-diff-1-600x344.png 600w, https:\/\/www.visophyte.org\/blog\/wp-content\/uploads\/2009\/04\/chronimoz-diff-1-300x172.png 300w\" sizes=\"auto, (max-width: 951px) 100vw, 951px\" \/><\/a><\/p>\n<p>In our <a href=\"http:\/\/www.visophyte.org\/blog\/2009\/03\/15\/understanding-libmime-using-chroniquery-and-unit-tests\/\">last chroniquery adventure<\/a>, we used <a href=\"http:\/\/weblogs.mozillazine.org\/roc\/\">roc<\/a>&#8216;s <a href=\"http:\/\/code.google.com\/p\/chronicle-recorder\/\">chronicle-recorder<\/a> to trace the execution of an xpcshell unit test and <a href=\"http:\/\/www.visophyte.org\/blog\/tag\/chroniquery\/\">chroniquery<\/a> (<a href=\"http:\/\/www.visophyte.org\/blog\/chroniquery\/\">repo info<\/a>) to use that trace to help us understand what was happening in some particularly confusing C-ish code.\u00a0 Actually, we&#8217;re doing that this time too, but the bag of tricks now contains additional tricks.<\/p>\n<p>The exciting things happening in the screenshot above, in order of increasing awesomeness:<\/p>\n<ul>\n<li>The argument list is exposing out-parameters (via a heuristic though, it doesn&#8217;t know the XPCOM details.)\u00a0 ex: &#8220;*folderInfo: 0x0&#8221; used to be &#8220;folderInfo: some pointer to hold an out-parameter that leaves us none the wiser.&#8221;<\/li>\n<li>Chronifer now sees through &#8216;this&#8217;-adjusting trampolines\/wrappers.\u00a0 Previously, function calls might be hidden because the stack pointer change that chronicle uses to determine function calls jumped to the trampoline whose bytecode was not associated with the actual function being called, and so would potentially be assumed to be boring.\u00a0 The trampoline would modify rdi then perform a trivial jump (it could have just fallen through) into the function proper, which the existing trampoline detector would not notice.\u00a0 (That detector only would notice an instant jump of more than 128 bytes; intended for dynamic linking indirection purposes.)<\/li>\n<li>Pretty printers allow us to translate nsresult error codes to strings, display the strings referenced by nsString\/nsCString instead of the raw structure (mData\/mLength\/mFlags), pierce nsCOMPtr&#8217;s, etc.<\/li>\n<li>Pretty printers allow us to detect exceptional values and show them in red!\u00a0 For example, that NS_ERROR_INVALID_POINTER is red because the nsresult pretty printer&#8217;s is_exceptional method returned True because the error bit was high.<\/li>\n<li>The configuration method that lets us say what directories\/files\/classes\/functions are interesting\/boring has been augmented to let us specify arguments and the sub-fields of arguments to dump.\u00a0 For example, in the above screenshot, we have added &#8220;dump_this=True&#8221; to the section labeled &#8220;[class@nsMsgLocalMailFolder]&#8221;.\u00a0 As a result, any time a method is called on nsMsgLocalMailFolder, we dump the contents of its &#8216;this&#8217;.\u00a0 If we only wanted a few fields from &#8220;this&#8221;, we could have used &#8220;dump_this=mPath,mIsServer,mName,mURI&#8221; instead.\u00a0 You can see the end of a full object dump at the top of the screenshot.<\/li>\n<li>The <strong>object dump output is diffed against the result of previous calls<\/strong>.\u00a0 This is why we have that text in yellow.\u00a0 The first entire GetDBFolderInfoAndDB call you see on the screen is a succesful call (no red!) diffed against a previous successful call.\u00a0 Mainly we see the name-derived things changing and things we expect to be distinct (file path, database).\u00a0 Then we have an error case, with a few things we probably would not have noticed if we were doing this by hand.\u00a0 I was somewhat surprised that mHaveParsedURI, the reference count, and m_numOfflineMsgLines showed up.\u00a0 The others are not entirely shocking, but it&#8217;s useful to have them all there.\u00a0 Without the diff, we would be looking at 65 lines of attribute values, and that is with us already benefitting from the pretty printers.<\/li>\n<\/ul>\n<p>Exciting possibilities opened by enhancements here:<\/p>\n<ul>\n<li>The pretty printers and internal cleanups\/refactoring make it feasible to express complicated data-based constraints simply.\u00a0 For example, with a tractable amount of work I could opt to only see calls on the folder named &#8220;gabba3&#8221; using the constraint &#8220;mURI == &#8216;mailbox:\/\/nobody@Local%20Folders\/gabba0&#8242;&#8221;.\u00a0 This could be made particularly efficient if we make an assumption that the attribute is invariant once observed and then allow us to key off the pointer\/memory region.<\/li>\n<li>Code-sharing of pretty printers between my chroniquery code and my archer gdb plugins.<\/li>\n<li>Now that archer-gdb has python inferior control, potential use of archer-gdb as an alternate back-end to chroniquery.<\/li>\n<li>It would be neat to be able to expose chroniquery&#8217;s functionality via a web interface so that things could be expanded\/drilled down without having to re-run things.\u00a0 This would also help offset the non-trivial startup costs to chronicle-recorder&#8217;s own chronicle-query.\u00a0 (Although arguably the startup time is nothing compared to the inefficiency of all the work chronicle-query does for a call and throws away when the next call pretty much wants that same data.)<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>In our last chroniquery adventure, we used roc&#8216;s chronicle-recorder to trace the execution of an xpcshell unit test and chroniquery (repo info) to use that trace to help us understand what was happening in some particularly confusing C-ish code.\u00a0 Actually, &hellip; <a href=\"https:\/\/www.visophyte.org\/blog\/2009\/04\/28\/understanding-where-unit-tests-go-wrong-with-object-diffs\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"footnotes":""},"categories":[7,8],"tags":[29,28],"class_list":["post-292","post","type-post","status-publish","format-standard","hentry","category-debugging","category-program-execution","tag-chronicle","tag-chroniquery"],"_links":{"self":[{"href":"https:\/\/www.visophyte.org\/blog\/wp-json\/wp\/v2\/posts\/292","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.visophyte.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.visophyte.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.visophyte.org\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.visophyte.org\/blog\/wp-json\/wp\/v2\/comments?post=292"}],"version-history":[{"count":4,"href":"https:\/\/www.visophyte.org\/blog\/wp-json\/wp\/v2\/posts\/292\/revisions"}],"predecessor-version":[{"id":297,"href":"https:\/\/www.visophyte.org\/blog\/wp-json\/wp\/v2\/posts\/292\/revisions\/297"}],"wp:attachment":[{"href":"https:\/\/www.visophyte.org\/blog\/wp-json\/wp\/v2\/media?parent=292"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.visophyte.org\/blog\/wp-json\/wp\/v2\/categories?post=292"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.visophyte.org\/blog\/wp-json\/wp\/v2\/tags?post=292"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}