Skip to content

Commit 2800db2

Browse files
committed
Add test for COPY unique constraint violation error
See #184 for original issue.
1 parent 5e0c68a commit 2800db2

3 files changed

Lines changed: 41 additions & 0 deletions

File tree

postgresql-simple.cabal

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,10 @@ test-suite test
115115
, bytestring
116116
, containers
117117
, cryptohash
118+
, filepath
118119
, tasty
119120
, tasty-hunit
121+
, tasty-golden
120122
, HUnit
121123
, postgresql-simple
122124
, text

test/Main.hs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import qualified Database.PostgreSQL.Simple.Transaction as ST
1212
import Control.Applicative
1313
import Control.Exception as E
1414
import Control.Monad
15+
import Data.Char
1516
import Data.List (sort)
1617
import Data.IORef
1718
import Data.Typeable
@@ -20,13 +21,16 @@ import GHC.Generics (Generic)
2021
import Data.Aeson
2122
import Data.ByteString (ByteString)
2223
import qualified Data.ByteString as B
24+
import qualified Data.ByteString.Lazy.Char8 as BL
2325
import Data.Map (Map)
2426
import qualified Data.Map as Map
2527
import Data.Text(Text)
2628
import qualified Data.Text.Encoding as T
2729
import qualified Data.Vector as V
30+
import System.FilePath
2831

2932
import Test.Tasty
33+
import Test.Tasty.Golden
3034
import Notify
3135
import Serializable
3236
import Time
@@ -47,6 +51,7 @@ tests env = testGroup "tests"
4751
, testCase "Unicode" . testUnicode
4852
, testCase "Values" . testValues
4953
, testCase "Copy" . testCopy
54+
, testCopyFailures
5055
, testCase "Double" . testDouble
5156
, testCase "1-ary generic" . testGeneric1
5257
, testCase "2-ary generic" . testGeneric2
@@ -317,6 +322,35 @@ testCopy TestEnv{..} = do
317322
CopyOutDone _ -> return rows
318323
CopyOutRow row -> loop (row:rows)
319324

325+
testCopyFailures :: TestEnv -> TestTree
326+
testCopyFailures env = testGroup "Copy failures"
327+
$ map ($ env)
328+
[ testCopyUniqueConstraintError ]
329+
330+
goldenTest :: TestName -> IO BL.ByteString -> TestTree
331+
goldenTest testName =
332+
goldenVsString testName (resultsDir </> fileName<.>"expected")
333+
where
334+
resultsDir = "test" </> "results"
335+
fileName = map normalize testName
336+
normalize c | not (isAlpha c) = '-'
337+
| otherwise = c
338+
339+
-- | Test that we provide a sensible error message on failure
340+
testCopyUniqueConstraintError :: TestEnv -> TestTree
341+
testCopyUniqueConstraintError TestEnv{..} =
342+
goldenTest "unique constraint violation"
343+
$ handle (\(SomeException exc) -> return $ BL.pack $ show exc) $ do
344+
execute_ conn "CREATE TEMPORARY TABLE copy_unique_constraint_error_test (x int PRIMARY KEY, y text)"
345+
copy_ conn "COPY copy_unique_constraint_error_test FROM STDIN (FORMAT CSV)"
346+
mapM_ (putCopyData conn) copyRows
347+
_n <- putCopyEnd conn
348+
return BL.empty
349+
where
350+
copyRows = ["1,foo\n"
351+
,"2,bar\n"
352+
,"1,baz\n"]
353+
320354
testDouble :: TestEnv -> Assertion
321355
testDouble TestEnv{..} = do
322356
[Only (x :: Double)] <- query_ conn "SELECT 'NaN'::float8"
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
user error (Database.PostgreSQL.Simple.Copy.putCopyEnd: failed to parse command status
2+
Connection error: ERROR: duplicate key value violates unique constraint "copy_unique_constraint_error_test_pkey"
3+
DETAIL: Key (x)=(1) already exists.
4+
CONTEXT: COPY copy_unique_constraint_error_test, line 3
5+
)

0 commit comments

Comments
 (0)