Edgewall Software
Modify

#13160 closed defect (fixed)

Unit tests failing when psycopg2 2.8.x due to raising `UniqueViolation` instead of `IntegrityError`

Reported by: Jun Omae Owned by: Ryan J Ollos
Priority: normal Milestone: 1.0.19
Component: general Version:
Severity: normal Keywords:
Cc: Branch:
Release Notes:

Fixed unit test failures with psycopg2 2.8.x due to raising UniqueViolation rather than IntegrityError.

API Changes:
Internal Changes:

Description

https://travis-ci.org/edgewall/trac/jobs/521140057

======================================================================
FAIL: test_component_add_error_already_exists (trac.admin.tests.console.TracadminTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/travis/build/edgewall/trac/trac/admin/tests/console.py", line 541, in test_component_add_error_already_exists
    self.assertExpectedResult(output)
  File "/home/travis/build/edgewall/trac/trac/admin/tests/console.py", line 172, in assertExpectedResult
    self.assertEqual(expected_result, output)
  File "/home/travis/build/edgewall/trac/trac/admin/tests/console.py", line 194, in assertEqual
    output, diff()))
AssertionError: u'IntegrityError: [...]\n' != u'UniqueViolation: duplicate key value violates unique constraint "component_pkey"\nDETAIL:  Key (name)=(component1) already exists.\n\n'
--- expected
+++ actual
@@ -1,2 +1,4 @@
-IntegrityError: [...]
+UniqueViolation: duplicate key value violates unique constraint "component_pkey"
+DETAIL:  Key (name)=(component1) already exists.
 
+
...

----------------------------------------------------------------------
Ran 1958 tests in 132.317s

FAILED (failures=10)
make: *** [unit-test] Error 1

Attachments (0)

Change History (12)

comment:1 by Jun Omae, 18 months ago

The UniqueViolation exception is inherited from IntegrityError and not exported.

>>> import psycopg2
>>> psycopg2.__version__
'2.8.2 (dt dec pq3 ext lo64)'
>>> from psycopg2 import UniqueViolation
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: cannot import name UniqueViolation
>>> from psycopg2._psycopg import sqlstate_errors
>>> sqlstate_errors['23505']
<class 'psycopg2.errors.UniqueViolation'>
>>> sqlstate_errors['23505'].__bases__
(<class 'psycopg2.IntegrityError'>,)
>>> issubclass(sqlstate_errors['23505'], psycopg2.IntegrityError)
True

comment:2 by Jun Omae, 18 months ago

Ad hoc patch is pinning psycopg2<2.8.

  • .travis.yml

    diff --git a/.travis.yml b/.travis.yml
    index 8fc1192e8..860026e63 100644
    a b install:  
    103103      2.6) requires="$requires Babel<2.6.0 lxml<4.3.0" ;;
    104104      *)   requires="$requires Babel lxml" ;;
    105105    esac
    106     if [ "$tracdb" = postgres ]; then requires="$requires psycopg2"; fi
     106    if [ "$tracdb" = postgres ]; then requires="$requires psycopg2<2.8"; fi
    107107    if [ "$tracdb" = mysql ]; then requires="$requires MySQL-python"; fi
    108108    pip install $requires
    109109    python -c 'import sys, pkg_resources as p; p.require(sys.argv[1:])' $requires
  • contrib/appveyor.ps1

    diff --git a/contrib/appveyor.ps1 b/contrib/appveyor.ps1
    index af5a3b867..a6bac3ff2 100644
    a b function Trac-Install {  
    254254        # "postgres://tracuser:password@localhost/trac?schema=tractest"
    255255        #
    256256
    257         & pip install psycopg2
     257        & pip install psycopg2<2.8
    258258
    259259        Add-AppveyorMessage -Message "1.1. psycopg2 package installed" `
    260260          -Category Information

comment:3 by Ryan J Ollos, 18 months ago

The workaround looks good to get our build passing again.

Once that is committed I'll do some testing on a branch with Ubuntu Xenial, which is being rolled out.

comment:4 by Jun Omae, 18 months ago

I noticed the unit tests on trunk pass with psycopg2 2.8.2 at https://travis-ci.org/edgewall/trac/jobs/521143761#L708. The tests which try to insert non-unique ticket property have been removed in r15380….

in reply to:  4 comment:5 by Jun Omae, 18 months ago

Replying to Jun Omae:

I noticed the unit tests on trunk pass with psycopg2 2.8.2 at https://travis-ci.org/edgewall/trac/jobs/521143761#L708. The tests which try to insert non-unique ticket property have been removed in r15380….

ResourceExistsError is raised on trunk in the case and the tests exist in trac/ticket/tests/console-tests.txt.

comment:6 by Ryan J Ollos, 16 months ago

I committed the comment:2 workaround in r16906, r16907, record-only merge in r16908.

comment:7 by Ryan J Ollos, 15 months ago

Milestone: 1.0.181.0.19

comment:8 by Ryan J Ollos, 14 months ago

Owner: set to Ryan J Ollos
Release Notes: modified (diff)
Status: newassigned

comment:9 by Ryan J Ollos, 14 months ago

We could backport [15774-15775] from #11419 and raise ResourceExistsError. I'd prefer to not spend time on that, and it will result in an API change on 1.0-stable and 1.2-stable.

UniqueViolation inherits from IntegrityError, so any plugins trapping IntegrityError should continue to work fine provided we don't make an API change.

>>> import psycopg2
>>> psycopg2.__version__
'2.8.3 (dt dec pq3 ext lo64)'
>>> psycopg2.errors.UniqueViolation.__bases__
(<class 'psycopg2.IntegrityError'>,)

Alternatively we could just put a workaround in place so that the tests pass.

  • trac/admin/tests/console.py

    diff --git a/trac/admin/tests/console.py b/trac/admin/tests/console.py
    index 1e35c7ba2..a2c9f668d 100644
    a b class TracadminTestCase(unittest.TestCase):  
    184184            return ''.join(difflib.unified_diff(expected_lines, output_lines,
    185185                                                'expected', 'actual'))
    186186
     187        output = re.sub('^(UniqueViolation:)', 'IntegrityError:', output)
    187188        if '[...]' in expected_results:
    188189            m = re.match('.*'.join(map(re.escape,
    189190                                       expected_results.split('[...]'))) +

Thoughts?

comment:10 by Ryan J Ollos, 14 months ago

Release Notes: modified (diff)

in reply to:  9 comment:11 by Jun Omae, 14 months ago

Alternatively we could just put a workaround in place so that the tests pass.

+1. I think that is the second best solution, but enough to work around it.

comment:12 by Ryan J Ollos, 14 months ago

Resolution: fixed
Status: assignedclosed

Thanks for reviewing. Committed to 1.0-stable in r17076, merged in r17077. Record-only merge on trunk in r17078.

Modify Ticket

Change Properties
Set your email in Preferences
Action
as closed The owner will remain Ryan J Ollos.
The resolution will be deleted. Next status will be 'reopened'.
to The owner will be changed from Ryan J Ollos to the specified user.

Add Comment


E-mail address and name can be saved in the Preferences .
 
Note: See TracTickets for help on using tickets.