Add pgTAP test for normalized MARC records
authorDan Scott <>
Fri, 25 Oct 2013 17:54:35 +0000 (13:54 -0400)
committerDan Wells <>
Tue, 14 Jan 2014 20:02:14 +0000 (15:02 -0500)
Specifically, we're concerned about ensuring that any changes related to
the fix for Encode (requiring the removal of the effectively useless but
now erroring decode_utf8()) do not inadvertently change the content of
the MARC records on ingest. Because we wouldn't want to have to reingest
everything to normalize search, etc.

Signed-off-by: Dan Scott <>
Signed-off-by: Dan Wells <>
Open-ILS/src/sql/Pg/t/regress/ [new file with mode: 0644]

index e40a652..de5d916 100644 (file)
@@ -1 +1,7 @@
 For the tests we put here, let's not assume the stock test data is loaded.
+You can run all of the unit and regression tests using the ''pg_prove''
+command, which accepts standard ''psql'' command line options for
+authentication. For example:
+pg_prove -U evergreen t t/regress
diff --git a/Open-ILS/src/sql/Pg/t/regress/ b/Open-ILS/src/sql/Pg/t/regress/
new file mode 100644 (file)
index 0000000..08f29c7
--- /dev/null
@@ -0,0 +1,13 @@
+SELECT plan(2);
+CREATE OR REPLACE FUNCTION check_bib_hash(bibid BIGINT) RETURNS TEXT AS 'SELECT md5(marc) FROM biblio.record_entry WHERE id = $1' LANGUAGE SQL;
+INSERT INTO biblio.record_entry(id, last_xact_id, marc) VALUES
+(999999998, 'pgtap', '<record xmlns:xsi="" xmlns="" xsi:schemaLocation=""><leader>00895cam a2200289Ia 4500</leader><controlfield tag="001">691</controlfield><controlfield tag="003">CONS</controlfield><controlfield tag="005">20130416180823.0</controlfield><controlfield tag="008">120125s2012    nyu           000 1 eng  </controlfield><datafield tag="019" ind1=" " ind2=" "><subfield code="a">727703191</subfield></datafield><datafield tag="020" ind1=" " ind2=" "><subfield code="a">9780756407117 (hc.)</subfield></datafield><datafield tag="020" ind1=" " ind2=" "><subfield code="a">0756407117 (hc.)</subfield></datafield><datafield tag="035" ind1=" " ind2=" "><subfield code="a">(SC LENDS)1986488</subfield></datafield><datafield tag="092" ind1=" " ind2=" "><subfield code="a">FIC - SAL</subfield></datafield><datafield tag="100" ind1="1" ind2=" "><subfield code="a">Ahmed, Saladin.</subfield></datafield><datafield tag="245" ind1="1" ind2="0"><subfield code="a">Throne of the Crescent Moon /</subfield><subfield code="c">Saladin Ahmed.</subfield></datafield><datafield tag="260" ind1=" " ind2=" "><subfield code="a">New York :</subfield><subfield code="b">DAW Books,</subfield><subfield code="c">c2012.</subfield></datafield><datafield tag="300" ind1=" " ind2=" "><subfield code="a">274 p. ;</subfield><subfield code="c">23 cm.</subfield></datafield><datafield tag="490" ind1="1" ind2=" "><subfield code="a">The Crescent Moon Kingdoms ;</subfield><subfield code="v">bk. 1</subfield></datafield><datafield tag="520" ind1=" " ind2=" "><subfield code="a">From Saladin Ahmed, finalist for the Nebula and Campbell Awards, comes one of the year''s most anticipated fantasy debuts, THRONE OF THE CRESCENT MOON, a fantasy adventure with all the magic of The Arabian Nights.The Crescent Moon Kingdoms, land of djenn and ghuls, holy warriors and heretics, Khalifs and killers, is at the boiling point of a power struggle between the iron-fisted Khalif and the mysterious master thief known as the Falcon Prince.  In the midst of this brewing rebellion a series of brutal supernatural murders strikes at the heart of the Kingdoms. It is up to a handful of heroes to learn the truth behind these killings:Doctor Adoulla Makhslood, "The last real ghul hunter in the great city of Dhamsawaat," just wants a quiet cup of tea.  Three score and more years old, he has grown weary of hunting monsters and saving lives, and is more than ready to retire from his dangerous and demanding vocation. But when an old flame''s family is murdered, Adoulla is drawn back to the hunter''s path.Raseed bas Raseed, Adoulla''s young assistant, a hidebound holy warrior whose prowess is matched only by his piety, is eager to deliver God''s justice. But even as Raseed''s sword is tested by ghuls and manjackals, his soul is tested when he and Adoulla cross paths with the tribeswoman Zamia.Zamia Badawi, Protector of the Band, has been gifted with the near-mythical power of the Lion-Shape, but shunned by her people for daring to take up a man''s title. She lives only to avenge her father''s death. Until she learns that Adoulla and his allies also hunt her father''s killer. Until she meets Raseed.When they learn that the murders and the Falcon Prince''s brewing revolution are connected, the companions must race against time--and struggle against their own misgivings--to save the life of a vicious despot.  In so doing they discover a plot for the Throne of the Crescent Moon that threatens to turn Dhamsawaat, and the world itself, into a blood-soaked ruin. -</subfield></datafield><datafield tag="520" ind1=" " ind2=" "><subfield code="a">Have you ever read a book and wanted it to be better than it was? No, not just in a &#x201C;I&#x2019;m spending my precious time on this&#x201D; way but for external reasons as well? I&#x2019;ve spent six months reading The Throne of the Crescent Moon. It is true I don&#x2019;t get a lot of time to read but I also found this book easy to put down and interrupt with &#x2026; well, most things. Now, I must admit my bias. I have a deep affection for mythic Arabian settings so this book appealed to me. I was also glad to have a book that wasn&#x2019;t marketed as part of a trilogy or longer series. Additionally, this book was on several best of the year lists for 2012 so my hopes were high. Icarus found out what happens when things fly too high.The failings of Throne of the Crescent Moon are damning and easily enumerated. One, the characters are flat - they do not grow or change or surprise you. The dervish''s growth is a farce - you know what will happen to him in vague strokes within the first few pages of the book and by the time the bedouin girl is introduced you can guess the exact ending (and you will be right). Two, the plot is thin; the twists have nothing to surprise you much less go &#x201C;wow I would have never thought of that.&#x201D; And it&#x2019;s third sin is that it isn''t a world, The Throne of the Crescent Moon is really a great Dungeons and Dragons campaign setting and if the author hasn&#x2019;t played plenty of D&amp;D in his life I would be shocked. I won&#x2019;t list the details here but players of D&amp;D will recognize the subtle conventions he obeys and the structures he fits things into. That is not a sin in and of itself - The Gentleman Bastard books show how you can take a gaming campaign and tell compelling stories in it. But, when you supply that kind of structure you are telling stories as you do in a game and the writer takes the place of the Dungeon Master. It&#x2019;s a dangerous gamble because not only does the writer get to stack the deck but there aren&#x2019;t really any players to make choices. To make the story that comes out of it compelling the writer has to be gifted enough to create that illusion. And that is where this failed.  The characters are likeable to but too flat with no surprises and as a reader you never feel so invested that you cheer for them or feel as if their failures harm you. The structure is that of a classic adventure and that&#x2019;s not a great thing for a novel. The threat is massive but fits into too small a story&#x2019;s space. The book is too small. The book I was thrilled to see as a stand alone novel was resolved in half the space it should have been. It felt like we jumped from the prelude with the foot soldiers straight to killing the big bad without any twists in the plot. The challenges along the way are ... not significant. I bought into the grandeur of the kingdom and that made the adventure too small. The resolution feels like a deus ex machina. Perhaps the frustration is that the writer does know his craft. His sense of language is good and engaging. There are elements of the world&#x2019;s construction that are forced and others that draw you in. The characters are too flat (is that the third time I&#x2019;ve mentioned that?) but likeable and while not unique are not cliches either. There was enough good here that I want to read more in this world and I want to read more from this writer. There was enough good that I want to see him grow and be there to read his work as it improves. Did this debut novel blow me away? No, but it was a throw away enjoyable read in the end if disappointing because there at times hints of it&#x2019;s greater potential. Heck, it was better than Steinbeck&#x2019;s first book, Cup of Gold!  Finally, there is something compelling about a writer with the cojones to just throw out there &#x201C;here is my pseudo Muslim world of good versus evil and the good guys are good because they are the faithful of God.&#x201D; Maybe that&#x2019;s what I find hard to define but I like so far about the author&#x2019;s attitude: he has audacity and a voice and sometimes those are the hardest things for an author to have.  -</subfield></datafield><datafield tag="650" ind1=" " ind2="0"><subfield code="a">Fantasy fiction.</subfield></datafield><datafield tag="650" ind1=" " ind2="0"><subfield code="a">Adventure stories.</subfield></datafield><datafield tag="650" ind1=" " ind2="0"><subfield code="a">Arabian Nights fiction.</subfield></datafield><datafield tag="655" ind1=" " ind2="0"><subfield code="a">Fantasy fiction.</subfield></datafield><datafield tag="655" ind1=" " ind2="0"><subfield code="a">Adventure stories.</subfield></datafield><datafield tag="800" ind1="1" ind2=" "><subfield code="a">Ahmed, Saladin.</subfield><subfield code="t">Crescent Moon Kingdoms ;</subfield><subfield code="v">bk. 1.=852 4\</subfield><subfield code="a">gaaagpl</subfield><subfield code="b">YCL-RH</subfield><subfield code="b">YCL-RH</subfield><subfield code="c">Adult Fiction</subfield><subfield code="j">FIC </subfield></datafield><datafield tag="901" ind1=" " ind2=" "><subfield code="a">691</subfield><subfield code="b"/><subfield code="c">691</subfield><subfield code="t">biblio</subfield></datafield></record>'),
+(999999999, 'pgtap', '<record xmlns:xsi="" xsi:schemaLocation=""><leader>01750 am a2200481Ia 4500</leader><controlfield tag="001">2784593</controlfield><controlfield tag="003">CONIFER</controlfield><controlfield tag="005">20121031173514.0</controlfield><controlfield tag="008">121026s2012    ja ac         001 0beng d</controlfield><datafield tag="020" ind1=" " ind2=" "><subfield code="a">9784924971332</subfield></datafield><datafield tag="020" ind1=" " ind2=" "><subfield code="a">4924971332</subfield></datafield><datafield tag="041" ind1="1" ind2=" "><subfield code="a">eng</subfield><subfield code="h">jpn</subfield></datafield><datafield tag="050" ind1="0" ind2="0"><subfield code="a">DS890.M442</subfield><subfield code="b">K3513 2012 </subfield></datafield><datafield tag="100" ind1="1" ind2=" "><subfield code="6">880-01</subfield><subfield code="a">Kaimai, Jun,</subfield><subfield code="d">1957-</subfield></datafield><datafield tag="245" ind1="1" ind2="0"><subfield code="a">Matsumoto Shigeharu :</subfield><subfield code="b">bearing witness /</subfield><subfield code="c">Kaimai Jun ; English adaptation by Waku Miller.</subfield></datafield><datafield tag="246" ind1="1" ind2="0"><subfield code="a">Bearing witness</subfield></datafield><datafield tag="250" ind1=" " ind2=" "><subfield code="a">1st English ed.</subfield></datafield><datafield tag="260" ind1=" " ind2=" "><subfield code="a">Tokyo :</subfield><subfield code="b">International House of Japan,</subfield><subfield code="c">2012.</subfield></datafield><datafield tag="300" ind1=" " ind2=" "><subfield code="a">xviii, 219 p., [1] leaf of plates :</subfield><subfield code="b">ill., portraits ;</subfield><subfield code="c">24 cm.</subfield></datafield><datafield tag="490" ind1="1" ind2=" "><subfield code="a">LTCB international library selection ; no. 31</subfield></datafield><datafield tag="500" ind1=" " ind2=" "><subfield code="a">Translation of: Matsumoto Shigeharu den : saigo no riberarisuto.</subfield></datafield><datafield tag="500" ind1=" " ind2=" "><subfield code="a">Includes index.</subfield></datafield><datafield tag="600" ind1="1" ind2="0"><subfield code="6">880-03</subfield><subfield code="a">Matsumoto, Shigeharu,</subfield><subfield code="d">1899-1989.</subfield></datafield><datafield tag="610" ind1="2" ind2="0"><subfield code="6">880-04</subfield><subfield code="a">D&#x14D;mei Ts&#x16B;shinsha.</subfield></datafield><datafield tag="650" ind1=" " ind2="0"><subfield code="a">Liberals</subfield><subfield code="z">Japan</subfield><subfield code="v">Biography.</subfield></datafield><datafield tag="650" ind1=" " ind2="0"><subfield code="a">Journalists</subfield><subfield code="z">Japan</subfield><subfield code="v">Biography.</subfield></datafield><datafield tag="700" ind1="1" ind2=" "><subfield code="a">Miller, Waku.</subfield></datafield><datafield tag="830" ind1=" " ind2="0"><subfield code="a">LTCB international library selection ;</subfield><subfield code="v">no. 31.</subfield></datafield><datafield tag="880" ind1="1" ind2=" "><subfield code="6">100-01</subfield><subfield code="a">&#x958B;&#x7C73;&#x6F64;,</subfield><subfield code="d">1957-</subfield></datafield><datafield tag="880" ind1="1" ind2="0"><subfield code="6">240-02</subfield><subfield code="a">&#x677E;&#x672C;&#x91CD;&#x6CBB;&#x4F1D;.</subfield><subfield code="l">English</subfield></datafield><datafield tag="880" ind1="1" ind2="4"><subfield code="6">600-03</subfield><subfield code="a">&#x677E;&#x672C;&#x91CD;&#x6CBB;,</subfield><subfield code="d">1899-1989.</subfield></datafield><datafield tag="880" ind1="2" ind2="4"><subfield code="6">610-04</subfield><subfield code="a">&#x540C;&#x76DF;&#x901A;&#x4FE1;&#x793E;.</subfield></datafield><datafield tag="901" ind1=" " ind2=" "><subfield code="a">5894462</subfield><subfield code="b">OCoLC</subfield><subfield code="c">2784593</subfield><subfield code="t">biblio</subfield></datafield></record>')
+SELECT is(check_bib_hash('999999998'), '08aecaf68253284de07d97df7755c83e', 'Check MD5 hash of MARC record 999999998 with diacritics');
+SELECT is(check_bib_hash('999999999'), '43ec26bc42346e06f82508b242c5cd19', 'Check MD5 hash of MARC record 999999999 with diacritics');