Esempio n. 1
0
    def test_conflict_del_4(self):
        """Check conflict detection. We modify and delete the same object in
        different transactions, simulating separate processes."""
        foo = Foo('foo-first')
        self.dm.root['foo'] = foo

        transaction.commit()

        conn1 = testing.getConnection(testing.DBNAME)
        dm1 = datamanager.PJDataManager(conn1)
        conn2 = testing.getConnection(testing.DBNAME)
        dm2 = datamanager.PJDataManager(conn2)

        self.assertEqual(dm2.root['foo'].name, 'foo-first')
        del dm2.root['foo']

        self.assertEqual(dm1.root['foo'].name, 'foo-first')
        dm1.root['foo'].name = 'foo-second'

        #Finish in order 1 - 2
        # well, try to... dm1.tpc_finish will block until dm2 is done

        dm1.tpc_begin(None)
        dm2.tpc_begin(None)

        @testing.run_in_thread
        def background_commit():
            dm1.tpc_finish(None)
        with self.assertRaises(interfaces.ConflictError):
            dm2.tpc_finish(None)

        transaction.abort()

        conn2.close()
        conn1.close()
Esempio n. 2
0
    def test_conflict_del_1(self):
        """Check conflict detection. We modify and delete the same object in
        different transactions, simulating separate processes."""

        txn = transaction.manager.get()
        foo = Foo('foo-first')
        self.dm.root['foo'] = foo

        transaction.commit()

        conn1 = testing.getConnection(testing.DBNAME)
        conn2 = testing.getConnection(testing.DBNAME)

        dm2 = datamanager.PJDataManager(conn2)
        self.assertEqual(dm2.root['foo'].name, 'foo-first')
        del dm2.root['foo']

        dm1 = datamanager.PJDataManager(conn1)
        self.assertEqual(dm1.root['foo'].name, 'foo-first')
        dm1.root['foo'].name = 'foo-second'

        #Finish in order 2 - 1

        with self.assertRaises(interfaces.ConflictError):
            transaction.commit()

        transaction.abort()

        conn2.close()
        conn1.close()
Esempio n. 3
0
    def test_conflict_del_1(self):
        """Check conflict detection. We modify and delete the same object in
        different transactions, simulating separate processes."""

        foo = Foo('foo-first')
        self.dm.root['foo'] = foo

        transaction.commit()

        conn1 = testing.getConnection(testing.DBNAME)
        dm1 = datamanager.PJDataManager(conn1)

        self.assertEqual(dm1.root['foo'].name, 'foo-first')

        dm1.root['foo'].name = 'foo-second'

        conn2 = testing.getConnection(testing.DBNAME)
        dm2 = datamanager.PJDataManager(conn2)

        self.assertEqual(dm2.root['foo'].name, 'foo-first')
        del dm2.root['foo']

        #Finish in order 2 - 1
        dm2.tpc_begin(None)
        dm2.commit(None)
        dm2.tpc_vote(None)
        dm2.tpc_finish(None)
        dm1.tpc_begin(None)
        with self.assertRaises(interfaces.ConflictError):
            dm1.commit()

        transaction.abort()

        conn2.close()
        conn1.close()
Esempio n. 4
0
    def test_conflict_tracebacks(self):
        """Verify conflict tracebacks are captured properly
        and reset on the next transaction."""

        ctb = datamanager.CONFLICT_TRACEBACK_INFO.traceback
        self.assertIsNone(ctb)

        foo = Foo('foo-first')
        self.dm.root['foo'] = foo

        transaction.commit()

        conn2 = testing.getConnection(testing.DBNAME)
        dm2 = datamanager.PJDataManager(conn2)
        del dm2.root['foo']

        conn1 = testing.getConnection(testing.DBNAME)
        dm1 = datamanager.PJDataManager(conn1)
        dm1.root['foo'].name = 'foo-second'

        ctb = datamanager.CONFLICT_TRACEBACK_INFO.traceback
        self.assertIsNone(ctb)

        # Finish in order 2 - 1
        with self.assertRaises(interfaces.ConflictError):
            transaction.commit()

        # verify by length that we have the full traceback
        ctb = datamanager.CONFLICT_TRACEBACK_INFO.traceback
        self.assertIsNotNone(ctb)
        # Make all work
        self.assertTrue(len(ctb) > 20)
        self.assertIn('Beacon:', ctb[-1])
        transaction.abort()

        # start another transaction and verify the traceback
        # is reset
        datamanager.PJDataManager(conn2)

        ctb = datamanager.CONFLICT_TRACEBACK_INFO.traceback
        self.assertIsNone(ctb)

        conn2.close()
        conn1.close()
Esempio n. 5
0
    def test_conflict_tracebacks(self):
        """Verify conflict tracebacks are captured properly
        and reset on the next transaction."""

        ctb = datamanager.CONFLICT_TRACEBACK_INFO.traceback
        self.assertIsNone(ctb)

        foo = Foo('foo-first')
        self.dm.root['foo'] = foo

        transaction.commit()

        conn2 = testing.getConnection(testing.DBNAME)
        dm2 = datamanager.PJDataManager(conn2)
        del dm2.root['foo']

        conn1 = testing.getConnection(testing.DBNAME)
        dm1 = datamanager.PJDataManager(conn1)
        dm1.root['foo'].name = 'foo-second'

        ctb = datamanager.CONFLICT_TRACEBACK_INFO.traceback
        self.assertIsNone(ctb)

        # Finish in order 2 - 1
        with self.assertRaises(interfaces.ConflictError):
            transaction.commit()

        # verify by length that we have the full traceback
        ctb = datamanager.CONFLICT_TRACEBACK_INFO.traceback
        self.assertIsNotNone(ctb)
        # Make all work
        self.assertTrue(len(ctb) > 20)
        self.assertIn('Beacon:', ctb[-1])
        transaction.abort()

        # start another transaction and verify the traceback
        # is reset
        datamanager.PJDataManager(conn2)

        ctb = datamanager.CONFLICT_TRACEBACK_INFO.traceback
        self.assertIsNone(ctb)

        conn2.close()
        conn1.close()
Esempio n. 6
0
    def test_conflict_del_2(self):
        """Check conflict detection. We modify and delete the same object in
        different transactions, simulating separate processes."""

        foo = Foo('foo-first')
        self.dm.root['foo'] = foo

        transaction.commit()

        conn1 = testing.getConnection(testing.DBNAME)
        dm1 = datamanager.PJDataManager(conn1)

        self.assertEqual(dm1.root['foo'].name, 'foo-first')

        dm1.root['foo'].name = 'foo-second'

        conn2 = testing.getConnection(testing.DBNAME)
        dm2 = datamanager.PJDataManager(conn2)

        self.assertEqual(dm2.root['foo'].name, 'foo-first')
        del dm2.root['foo']

        #Finish in order 1 - 2
        # well, try to... dm1.tpc_finish will block until dm2 is done

        @testing.run_in_thread
        def background_commit():
            with self.assertRaises(interfaces.ConflictError):
                dm1.commit(None)

        dm2.commit(None)

        transaction.abort()

        conn2.close()
        conn1.close()
Esempio n. 7
0
    def test_conflict_commit_1(self):
        """Test conflict on commit

        The typical detail string for such failures is:

        DETAIL:  Reason code: Canceled on identification as a pivot, during
        commit attempt.
        """

        # We will not reproduce the full scenario with pjpersist, however we
        # will pretend the right exception is thrown by commit.
        #
        # First, get the error, that psycopg throws in such case
        # The example is taken from https://wiki.postgresql.org/wiki/SSI
        conn1 = self.conn
        conn2 = testing.getConnection(testing.DBNAME)

        with conn1.cursor() as cur:
            cur.execute("DROP TABLE IF EXISTS mytab")
            cur.execute(
                "CREATE TABLE mytab (class int NOT NULL, value int NOT NULL )")
            cur.execute(
                "INSERT INTO mytab VALUES (1, 10), (1, 20), (2, 100), (2, 200)"
            )
        conn1.commit()

        with conn1.cursor() as cur1, conn2.cursor() as cur2:
            cur1.execute("SELECT SUM(value) FROM mytab WHERE class = 1")
            cur1.execute("INSERT INTO mytab VALUES (2, 30)")

            cur2.execute("SELECT SUM(value) FROM mytab WHERE class = 2")
            cur2.execute("INSERT INTO mytab VALUES (1, 300)")

        conn2.commit()
        conn2.close()

        # Now datamanager, holding conn1 is in doomed state. it is expected to
        # fail on commit attempt.
        txn = transaction.get()
        txn.join(self.dm)

        with self.assertRaises(interfaces.ConflictError):
            transaction.commit()
Esempio n. 8
0
    def test_conflict_commit_1(self):
        """Test conflict on commit

        The typical detail string for such failures is:

        DETAIL:  Reason code: Canceled on identification as a pivot, during commit
        attempt.
        """

        # We will not reproduce the full scenario with pjpersist, however we will
        # pretend the right exception is thrown by commit.
        #
        # First, get the error, that psycopg throws in such case
        # The example is taken from https://wiki.postgresql.org/wiki/SSI
        import psycopg2

        conn1 = self.conn
        conn2 = testing.getConnection(testing.DBNAME)

        with conn1.cursor() as cur:
            cur.execute("DROP TABLE IF EXISTS mytab")
            cur.execute("CREATE TABLE mytab (class int NOT NULL, value int NOT NULL )")
            cur.execute("INSERT INTO mytab VALUES (1, 10), (1, 20), (2, 100), (2, 200)")
        conn1.commit()

        with conn1.cursor() as cur1, conn2.cursor() as cur2:
            cur1.execute("SELECT SUM(value) FROM mytab WHERE class = 1")
            cur1.execute("INSERT INTO mytab VALUES (2, 30)")

            cur2.execute("SELECT SUM(value) FROM mytab WHERE class = 2")
            cur2.execute("INSERT INTO mytab VALUES (1, 300)")

        conn2.commit()
        conn2.close()

        # Now datamanager, holding conn1 is in doomed state. it is expected to
        # fail on commit attempt.
        txn = transaction.get()
        txn.join(self.dm)

        with self.assertRaises(interfaces.ConflictError):
            transaction.commit()
Esempio n. 9
0
    def setUp(self):
        super(DirtyTestCase, self).setUp()

        # get rid of the previous transaction
        transaction.abort()

        tpc_patch = mock.patch(
            "pjpersist.datamanager.PJ_TWO_PHASE_COMMIT_ENABLED", True)
        no_prep_patch = mock.patch(
            "pjpersist.datamanager."
            "CALL_TPC_PREPARE_ON_NO_WRITE_TRANSACTION", False)
        log_patch = mock.patch(
            "pjpersist.datamanager.LOG_READ_WRITE_TRANSACTION", True)
        self.patches = [tpc_patch, no_prep_patch, log_patch]
        for p in self.patches:
            p.start()

        # First PJDataManager instantiation creates tables, what makes the dm
        # dirty, which we want to avoid here.
        self.conn = testing.getConnection(testing.DBNAME)
        self.dm = datamanager.PJDataManager(self.conn)
Esempio n. 10
0
    def setUp(self):
        super(DirtyTestCase, self).setUp()

        # get rid of the previous transaction
        transaction.abort()

        tpc_patch = mock.patch(
            "pjpersist.datamanager.PJ_TWO_PHASE_COMMIT_ENABLED", True)
        no_prep_patch = mock.patch(
            "pjpersist.datamanager."
            "CALL_TPC_PREPARE_ON_NO_WRITE_TRANSACTION", False)
        log_patch = mock.patch(
            "pjpersist.datamanager.LOG_READ_WRITE_TRANSACTION", True)
        self.patches = [tpc_patch, no_prep_patch, log_patch]
        for p in self.patches:
            p.start()

        # First PJDataManager instantiation creates tables, what makes the dm
        # dirty, which we want to avoid here.
        self.conn = testing.getConnection(testing.DBNAME)
        self.dm = datamanager.PJDataManager(self.conn)