This is an automated email from the ASF dual-hosted git repository.

ntimofeev pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cayenne.git

commit 8af684a960a304049b0f6383e00ead7a47a5bfa2
Author: Dmitriy Tarasenko <dmitriy.tarasie...@gmail.com>
AuthorDate: Sat May 29 21:48:47 2021 +0300

    feat: tests for descriptor and listeners new properties
---
 .../apache/cayenne/tx/TransactionDescriptor.java   |  13 +-
 .../cayenne/tx/DefaultTransactionManagerIT.java    |   8 +-
 .../cayenne/tx/TransactionCustomConnectionIT.java  | 226 +++++++++++++++++++++
 .../apache/cayenne/tx/TransactionIsolationIT.java  |   2 +-
 .../tx/TransactionPropagationRollbackIT.java       |   6 +-
 5 files changed, 243 insertions(+), 12 deletions(-)

diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/tx/TransactionDescriptor.java 
b/cayenne-server/src/main/java/org/apache/cayenne/tx/TransactionDescriptor.java
index ecb273a..3ced787 100644
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/tx/TransactionDescriptor.java
+++ 
b/cayenne-server/src/main/java/org/apache/cayenne/tx/TransactionDescriptor.java
@@ -52,7 +52,7 @@ public class TransactionDescriptor {
      *                    <code>TransactionDescriptor.ISOLATION_DEFAULT</code>
      * @param propagation transaction propagation behaviour
      * @see TransactionPropagation
-     * @deprecated since 4.2.M4. Use builder instead
+     * @deprecated since 4.2. Use builder instead
      */
     @Deprecated
     public TransactionDescriptor(int isolation, TransactionPropagation 
propagation) {
@@ -78,7 +78,7 @@ public class TransactionDescriptor {
     /**
      * @param propagation transaction propagation behaviour
      * @see TransactionPropagation
-     * @deprecated since 4.2.M4. Use builder instead
+     * @deprecated since 4.2. Use builder instead
      */
     @Deprecated
     public TransactionDescriptor(TransactionPropagation propagation) {
@@ -106,14 +106,19 @@ public class TransactionDescriptor {
         return customConnectionSupplier;
     }
 
+    public static Builder builder(){
+        return new Builder();
+    }
+
     /**
      * Builder class for TransactionDescriptor.
-     *
-     * @since 4.2.M4
+     * @since 4.2
      */
     public static class Builder {
         private final TransactionDescriptor transactionDescriptor = new 
TransactionDescriptor();
 
+        private Builder(){}
+
         /**
          * @param isolation one of the following <code>Connection</code> 
constants:
          *                  
<code>Connection.TRANSACTION_READ_UNCOMMITTED</code>,
diff --git 
a/cayenne-server/src/test/java/org/apache/cayenne/tx/DefaultTransactionManagerIT.java
 
b/cayenne-server/src/test/java/org/apache/cayenne/tx/DefaultTransactionManagerIT.java
index ef9de67..276b258 100644
--- 
a/cayenne-server/src/test/java/org/apache/cayenne/tx/DefaultTransactionManagerIT.java
+++ 
b/cayenne-server/src/test/java/org/apache/cayenne/tx/DefaultTransactionManagerIT.java
@@ -86,7 +86,7 @@ public class DefaultTransactionManagerIT {
                         assertSame(tx, BaseTransaction.getThreadTransaction());
                         return expectedResult;
                     },
-                    new TransactionDescriptor.Builder()
+                    TransactionDescriptor.builder()
                             .propagation(TransactionPropagation.NESTED)
                             .build()
             );
@@ -111,7 +111,7 @@ public class DefaultTransactionManagerIT {
                         assertSame(tx, BaseTransaction.getThreadTransaction());
                         return expectedResult;
                     },
-                    new TransactionDescriptor.Builder()
+                    TransactionDescriptor.builder()
                             .propagation(TransactionPropagation.MANDATORY)
                             .build()
             );
@@ -137,7 +137,7 @@ public class DefaultTransactionManagerIT {
                         assertSame(tx, BaseTransaction.getThreadTransaction());
                         return expectedResult;
                     },
-                    new TransactionDescriptor.Builder()
+                    TransactionDescriptor.builder()
                             .propagation(TransactionPropagation.MANDATORY)
                             .build()
             );
@@ -169,7 +169,7 @@ public class DefaultTransactionManagerIT {
                         assertSame(tx2, 
BaseTransaction.getThreadTransaction());
                         return expectedResult;
                     },
-                    new TransactionDescriptor.Builder()
+                    TransactionDescriptor.builder()
                             .propagation(TransactionPropagation.REQUIRES_NEW)
                             .build()
             );
diff --git 
a/cayenne-server/src/test/java/org/apache/cayenne/tx/TransactionCustomConnectionIT.java
 
b/cayenne-server/src/test/java/org/apache/cayenne/tx/TransactionCustomConnectionIT.java
new file mode 100644
index 0000000..90f2397
--- /dev/null
+++ 
b/cayenne-server/src/test/java/org/apache/cayenne/tx/TransactionCustomConnectionIT.java
@@ -0,0 +1,226 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    https://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+
+package org.apache.cayenne.tx;
+
+import org.apache.cayenne.access.DataContext;
+import org.apache.cayenne.configuration.server.ServerRuntime;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.log.JdbcEventLogger;
+import org.apache.cayenne.query.ObjectSelect;
+import org.apache.cayenne.testdo.testmap.Artist;
+import org.apache.cayenne.unit.di.server.CayenneProjects;
+import org.apache.cayenne.unit.di.server.ServerCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.junit.Assert.*;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.*;
+
+/**
+ * Check if connection can be decorated with listeners and that default 
connection of TransactionDescriptor
+ * has major priority
+ *
+ * @see BaseTransaction,TransactionDescriptor
+ * @since 4.2
+ */
+@UseServerRuntime(CayenneProjects.TESTMAP_PROJECT)
+public class TransactionCustomConnectionIT extends ServerCase {
+
+    private final Logger logger = 
LoggerFactory.getLogger(TransactionIsolationIT.class);
+
+    @Inject
+    DataContext context;
+
+    @Inject
+    ServerRuntime runtime;
+
+    @Inject
+    private JdbcEventLogger jdbcEventLogger;
+
+    TransactionManager manager;
+    private static boolean firstReadonlyCondition;
+
+    @Before
+    public void initTransactionManager() {
+        // no binding in test container, get it from runtime
+        manager = runtime.getInjector().getInstance(TransactionManager.class);
+    }
+
+    /**
+     * Test depends on decoration of readonly property of the connection, but 
not every driver supports readonly setting.
+     * So this test calculated for drivers with current support, but if it is 
not supported, this test mustn't fail
+     * because it checks if readonly wasn't changed by setter and changes 
firstReadonlyCondition flag value
+     * if it is true to avoid fails. In that case test is useless, but it's 
behavior in other cases can submit
+     * right behavior of methods
+     */
+    @Test
+    public void testConnectionDecorationWithListeners() {
+        Transaction t = new CayenneTransaction(jdbcEventLogger);
+        //add listeners which will check if connection object will be changed 
after every decorate call
+        List<TransactionListener> listeners = 
addAndGetListenersWithCustomReadonlyTo(t);
+        BaseTransaction.bindThreadTransaction(t);
+        try {
+            ObjectSelect.query(Artist.class).select(context);
+
+            //check if the last listener set readonly property to false
+            t.getConnections().forEach((key, connection) -> {
+                try {
+                    assertEquals(connection.isReadOnly(), 
firstReadonlyCondition);
+                } catch (SQLException throwables) {
+                    throwables.printStackTrace();
+                }
+            });
+
+            //check if every decoration from listener was called
+            for (TransactionListener transactionListener : listeners) {
+                verify(transactionListener).decorateConnection(any(), any());
+            }
+        } finally {
+            BaseTransaction.bindThreadTransaction(null);
+            t.commit();
+        }
+    }
+
+    private List<TransactionListener> 
addAndGetListenersWithCustomReadonlyTo(Transaction t) {
+        Class<?>[] classes = new 
Class[]{ListenerWithFirstReadonlyDecorator.class, 
ListenerWithSecondReadonlyDecorator.class};
+        List<TransactionListener> listeners = new ArrayList<>();
+        for (Class<?> aClass : classes) {
+            TransactionListener listener = (TransactionListener) mock(aClass);
+            listeners.add(listener);
+            when(listener.decorateConnection(any(), 
any())).thenCallRealMethod();
+            t.addListener(listener);
+        }
+        return listeners;
+    }
+
+    //listener, which will check if readonly property of connection is false 
and set it to true
+    class ListenerWithFirstReadonlyDecorator implements TransactionListener {
+
+        @Override
+        public void willCommit(Transaction tx) {
+
+        }
+
+        @Override
+        public void willRollback(Transaction tx) {
+
+        }
+
+        @Override
+        public void willAddConnection(Transaction tx, String connectionName, 
Connection connection) {
+
+        }
+
+        @Override
+        public Connection decorateConnection(Transaction tx, Connection 
connection) {
+            try {
+                firstReadonlyCondition = connection.isReadOnly();
+                connection.setReadOnly(!firstReadonlyCondition);
+
+                if (connection.isReadOnly() == firstReadonlyCondition) {
+                    firstReadonlyCondition = !connection.isReadOnly();
+                }
+            } catch (SQLException throwables) {
+                throwables.printStackTrace();
+            }
+            return connection;
+        }
+    }
+
+    //listener, which will check if readonly property of connection is true 
and set it to false
+    class ListenerWithSecondReadonlyDecorator implements TransactionListener {
+
+        @Override
+        public void willCommit(Transaction tx) {
+
+        }
+
+        @Override
+        public void willRollback(Transaction tx) {
+
+        }
+
+        @Override
+        public void willAddConnection(Transaction tx, String connectionName, 
Connection connection) {
+
+        }
+
+        @Override
+        public Connection decorateConnection(Transaction tx, Connection 
connection) {
+            try {
+                assertEquals(!firstReadonlyCondition, connection.isReadOnly());
+                connection.setReadOnly(!connection.isReadOnly());
+                if (connection.isReadOnly() == !firstReadonlyCondition) {
+                    firstReadonlyCondition = !firstReadonlyCondition;
+                }
+            } catch (SQLException throwables) {
+                throwables.printStackTrace();
+            }
+            return connection;
+        }
+    }
+
+    @Test
+    public void testDefaultConnectionInDescriptor() {
+        Transaction t = new CayenneTransaction(jdbcEventLogger);
+        BaseTransaction.bindThreadTransaction(t);
+        try {
+            ObjectSelect.query(Artist.class).select(context);
+            Connection connection = 
t.getConnections().values().stream().findFirst().get();
+
+            try {
+                connection.setAutoCommit(true);
+            } catch (SQLException throwables) {
+                throwables.printStackTrace();
+            }
+
+            TransactionDescriptor mockDescriptor = 
mock(TransactionDescriptor.class);
+            when(mockDescriptor.getCustomConnectionSupplier()).thenReturn(() 
-> connection);
+            
when(mockDescriptor.getPropagation()).thenReturn(TransactionPropagation.REQUIRES_NEW);
+            
when(mockDescriptor.getIsolation()).thenReturn(Connection.TRANSACTION_SERIALIZABLE);
+
+            performInTransaction(mockDescriptor);
+            verify(mockDescriptor, times(2)).getCustomConnectionSupplier();
+        } finally {
+            BaseTransaction.bindThreadTransaction(null);
+            t.commit();
+        }
+
+    }
+
+    private void performInTransaction(TransactionDescriptor descriptor) {
+        Artist artist = context.newObject(Artist.class);
+        artist.setArtistName("test");
+        manager.performInTransaction(() -> {
+            artist.setArtistName("test3");
+            context.commitChanges();
+            return null;
+        }, descriptor);
+    }
+}
diff --git 
a/cayenne-server/src/test/java/org/apache/cayenne/tx/TransactionIsolationIT.java
 
b/cayenne-server/src/test/java/org/apache/cayenne/tx/TransactionIsolationIT.java
index c2d00af..3bdefee 100644
--- 
a/cayenne-server/src/test/java/org/apache/cayenne/tx/TransactionIsolationIT.java
+++ 
b/cayenne-server/src/test/java/org/apache/cayenne/tx/TransactionIsolationIT.java
@@ -74,7 +74,7 @@ public class TransactionIsolationIT extends ServerCase {
             return;
         }
 
-        TransactionDescriptor descriptor = new TransactionDescriptor.Builder()
+        TransactionDescriptor descriptor = TransactionDescriptor.builder()
                 .propagation(TransactionPropagation.REQUIRES_NEW)
                 .isolation(Connection.TRANSACTION_SERIALIZABLE)
                 .build();
diff --git 
a/cayenne-server/src/test/java/org/apache/cayenne/tx/TransactionPropagationRollbackIT.java
 
b/cayenne-server/src/test/java/org/apache/cayenne/tx/TransactionPropagationRollbackIT.java
index cd6c937..8306d2e 100644
--- 
a/cayenne-server/src/test/java/org/apache/cayenne/tx/TransactionPropagationRollbackIT.java
+++ 
b/cayenne-server/src/test/java/org/apache/cayenne/tx/TransactionPropagationRollbackIT.java
@@ -69,7 +69,7 @@ public class TransactionPropagationRollbackIT extends 
ServerCase {
      */
     @Test
     public void testPropagationRequiresNew() {
-        TransactionDescriptor descriptor = new TransactionDescriptor.Builder()
+        TransactionDescriptor descriptor = TransactionDescriptor.builder()
                 .propagation(TransactionPropagation.REQUIRES_NEW)
                 .isolation(Connection.TRANSACTION_SERIALIZABLE)
                 .build();
@@ -89,7 +89,7 @@ public class TransactionPropagationRollbackIT extends 
ServerCase {
     @Test
     public void testPropagationNested() {
 
-        TransactionDescriptor descriptor = new TransactionDescriptor.Builder()
+        TransactionDescriptor descriptor = TransactionDescriptor.builder()
                 .isolation(Connection.TRANSACTION_SERIALIZABLE)
                 .propagation(TransactionPropagation.NESTED)
                 .build();
@@ -109,7 +109,7 @@ public class TransactionPropagationRollbackIT extends 
ServerCase {
     @Test
     public void testPropagationMandatory() {
 
-        TransactionDescriptor descriptor = new TransactionDescriptor.Builder()
+        TransactionDescriptor descriptor = TransactionDescriptor.builder()
                 .isolation(Connection.TRANSACTION_SERIALIZABLE)
                 .propagation(TransactionPropagation.MANDATORY)
                 .build();

Reply via email to