1. Project Clover database Wed Nov 12 2025 05:07:35 UTC
  2. Package guru.mikelue.foxglove.jdbc

File JdbcTxWorkerTest.java

 

Code metrics

6
46
9
1
203
140
14
0.3
5.11
9
1.56

Classes

Class Line # Actions
JdbcTxWorkerTest 23 46 0% 14 0
1.0100%
 

Contributing tests

This file is covered by 12 tests. .

Source view

1    package guru.mikelue.foxglove.jdbc;
2   
3    import java.sql.*;
4    import java.util.LinkedHashMap;
5    import java.util.List;
6   
7    import org.junit.jupiter.api.AfterEach;
8    import org.junit.jupiter.api.BeforeEach;
9    import org.junit.jupiter.params.ParameterizedTest;
10    import org.junit.jupiter.params.provider.CsvSource;
11   
12    import guru.mikelue.foxglove.ColumnMeta;
13    import guru.mikelue.misc.testlib.AbstractTestBase;
14   
15    import mockit.Expectations;
16    import mockit.Mocked;
17    import mockit.Verifications;
18   
19    import static guru.mikelue.foxglove.ColumnMetaTestUtils.newColumnMeta;
20    import static java.sql.Statement.RETURN_GENERATED_KEYS;
21    import static org.assertj.core.api.Assertions.assertThat;
22   
 
23    public class JdbcTxWorkerTest extends AbstractTestBase {
24    @Mocked
25    private Connection mockConn;
26   
27    @Mocked
28    private DatabaseMetaData mockDbMeta;
29   
30    @Mocked
31    private PreparedStatement mockStmt;
32   
33    @Mocked
34    private RowParamsGenerator mockRowGenerator;
35   
 
36  12 toggle public JdbcTxWorkerTest() {}
37   
 
38  12 toggle @BeforeEach
39    void setup() {}
40   
 
41  12 toggle @AfterEach
42    void tearDown() {}
43   
44    /**
45    * Tests the transaction controlled by batch size.
46    */
 
47  6 toggle @ParameterizedTest
48    @CsvSource({
49    "3,10,1", // No remaining batch
50    "3,10,2", // No remaining batch
51    "10,5,1", // No remaining batch
52    "10,5,2", // No remaining batch
53    "20,7,1", // Has remaining batch
54    "20,7,3", // Has remaining batch
55    })
56    void byBatchSize(
57    int numberOfRows, int batchSize,
58    int tableCount
59    ) throws SQLException {
60  6 final int remainBatch = (numberOfRows % batchSize == 0) ? 0 : 1;
61   
62  6 var txGear = new TransactionGear(
63    mockConn, batchSize, false
64    );
65   
66  6 mockAndExerciseInsertion(
67    numberOfRows, batchSize, tableCount,
68    txGear
69    );
70   
71    /*
72    * Asserts:
73    *
74    * 1. Auto-commit is disabled at the beginning
75    * 2. Auto-commit is enabled at the end
76    */
 
77  6 toggle new Verifications() {{
78  6 mockConn.setAutoCommit(false);
79  6 times = 1;
80   
81  6 mockStmt.executeBatch();
82  6 times = (numberOfRows / batchSize + remainBatch) * tableCount;
83   
84  6 mockConn.commit();
85  6 times = (numberOfRows * tableCount) / batchSize + remainBatch;
86   
87  6 mockConn.setAutoCommit(true);
88  6 times = 1;
89    }};
90    // :~)
91    }
92   
93    /**
94    * Tests the transaction is controlled by outside.
95    */
 
96  6 toggle @ParameterizedTest
97    @CsvSource({
98    "3,10,1", // No remaining batch
99    "3,10,2", // No remaining batch
100    "10,5,1", // No remaining batch
101    "10,5,2", // No remaining batch
102    "20,7,1", // Has remaining batch
103    "20,7,3", // Has remaining batch
104    })
105    void byOutside(
106    int numberOfRows, int batchSize,
107    int tableCount
108    ) throws SQLException {
109  6 final int remainBatch = (numberOfRows % batchSize == 0) ? 0 : 1;
110   
111  6 var txGear = new TransactionGear(
112    mockConn, batchSize, true
113    );
114   
115  6 mockAndExerciseInsertion(
116    numberOfRows, batchSize, tableCount,
117    txGear
118    );
119   
120    /*
121    * Asserts:
122    *
123    * 1. Auto-commit is disabled at the beginning
124    * 2. Auto-commit is enabled at the end
125    */
 
126  6 toggle new Verifications() {{
127  6 mockConn.setAutoCommit(anyBoolean);
128  6 times = 0;
129   
130  6 mockStmt.executeBatch();
131  6 times = (numberOfRows / batchSize + remainBatch) * tableCount;
132   
133  6 mockConn.commit();
134  6 times = 0;
135    }};
136    // :~)
137    }
138   
 
139  12 toggle private void mockAndExerciseInsertion(
140    int numberOfRows, int batchSize,
141    int tableCount,
142    TransactionGear txGear
143    ) throws SQLException {
144  12 var sampleTable = JdbcTableFacet.builder("any_table")
145    .numberOfRows(numberOfRows)
146    .build();
147  12 var sampleColumns = List.of(
148    newColumnMeta("col1", JDBCType.VARCHAR),
149    newColumnMeta("col2", JDBCType.INTEGER)
150    );
151   
152  12 var sampleResultOfGeneratedRow = new LinkedHashMap<ColumnMeta, Object>();
153  12 sampleResultOfGeneratedRow.put(sampleColumns.get(0), "sample-string");
154  12 sampleResultOfGeneratedRow.put(sampleColumns.get(1), 12345);
155   
156    /*
157    * Mocks fake values of rows
158    */
 
159  12 toggle new Expectations() {{
160  12 mockDbMeta.getIdentifierQuoteString();
161  12 result = "";
162   
163  12 mockConn.getAutoCommit();
164  12 result = true;
165   
166  12 mockConn.prepareStatement(anyString, RETURN_GENERATED_KEYS);
167  12 result = mockStmt;
168   
169  12 mockConn.getMetaData().getDriverName();
170  12 result = "HSQL Database Engine Driver";
171   
172  12 mockRowGenerator.generateRowParams();
173  12 result = sampleResultOfGeneratedRow;
174  12 times = numberOfRows * tableCount;
175    }};
176    // :~)
177   
178    /*
179    * Performs insert operations
180    */
181  12 try (var testedWorker = new JdbcTxWorker(txGear)) {
182  12 int numberOfGeneratedRows = 0;
183   
184  12 var insertSql = MetaUtils.buildInsertSql(
185    mockDbMeta,
186    sampleTable.tableName(), sampleColumns
187    );
188  32 for (int i = 0; i < tableCount; i++) {
189  20 numberOfGeneratedRows += testedWorker.performInsert(
190    new JdbcTxWorker.InsertionContext(
191    insertSql, numberOfRows, new String[0],
192    mockRowGenerator::generateRowParams
193    ),
194    v -> {}
195    );
196    }
197   
198  12 assertThat(numberOfGeneratedRows)
199    .isEqualTo(numberOfRows * tableCount);
200    }
201    // :~)
202    }
203    }