Skip to content

Commit

Permalink
test: EXPOSED-191 Flaky Oracle test on TC build (#2098)
Browse files Browse the repository at this point in the history
* test: EXPOSED-191 Flaky Oracle test on TC build
  • Loading branch information
obabichevjb authored Jun 4, 2024
1 parent 1703407 commit 38c3aa8
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package org.jetbrains.exposed.sql.statements

import org.jetbrains.exposed.sql.*
import org.jetbrains.exposed.sql.statements.api.PreparedStatementApi
import org.jetbrains.exposed.sql.transactions.TransactionManager
import org.jetbrains.exposed.sql.vendors.*
import org.jetbrains.exposed.sql.vendors.inProperCase
import java.sql.ResultSet
Expand Down Expand Up @@ -51,7 +52,7 @@ open class InsertStatement<Key : Any>(
*/
fun <T> getOrNull(column: Column<T>): T? = resultedValues?.firstOrNull()?.getOrNull(column)

@Suppress("NestedBlockDepth", "ComplexMethod")
@Suppress("NestedBlockDepth", "ComplexMethod", "TooGenericExceptionCaught")
private fun processResults(rs: ResultSet?, inserted: Int): List<ResultRow> {
val autoGeneratedKeys = arrayListOf<MutableMap<Column<*>, Any?>>()

Expand All @@ -68,9 +69,33 @@ open class InsertStatement<Key : Any>(
val firstAutoIncColumn = autoIncColumns.firstOrNull { it.autoIncColumnType != null } ?: autoIncColumns.firstOrNull()
if (firstAutoIncColumn != null || returnedColumns.isNotEmpty()) {
while (rs?.next() == true) {
val returnedValues = returnedColumns.associateTo(mutableMapOf()) { it.first to rs.getObject(it.second) }
if (returnedValues.isEmpty() && firstAutoIncColumn != null) returnedValues[firstAutoIncColumn] = rs.getObject(1)
autoGeneratedKeys.add(returnedValues)
try {
val returnedValues = returnedColumns.associateTo(mutableMapOf()) { it.first to rs.getObject(it.second) }
if (returnedValues.isEmpty() && firstAutoIncColumn != null) {
returnedValues[firstAutoIncColumn] = rs.getObject(1)
}
autoGeneratedKeys.add(returnedValues)
} catch (cause: ArrayIndexOutOfBoundsException) {
// EXPOSED-191 Flaky Oracle test on TC build
// this try/catch should help to get information about the flaky test.
// try/catch can be safely removed after the fixing the issue.
// TooGenericExceptionCaught suppress also can be removed

val preparedSql = this.prepareSQL(TransactionManager.current(), prepared = true)

val returnedColumnsString = returnedColumns
.mapIndexed { index, pair -> "column: ${pair.first.name}, index: ${pair.second} (columns-list-index: $index)" }
.joinToString(prefix = "[", postfix = "]", separator = ", ")

exposedLogger.error(
"ArrayIndexOutOfBoundsException on processResults. " +
"Table: ${table.tableName}, firstAutoIncColumn: ${firstAutoIncColumn?.name}, " +
"inserted: $inserted, returnedColumnsString: $returnedColumnsString. " +
"Failed SQL: $preparedSql",
cause
)
throw cause
}
}

if (inserted > 1 && firstAutoIncColumn != null && autoGeneratedKeys.isNotEmpty() && !currentDialect.supportsMultipleGeneratedKeys) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ class EntityCache(private val transaction: Transaction) {
}
}

@Suppress("TooGenericExceptionCaught")
internal fun flushInserts(table: IdTable<*>) {
var toFlush: List<Entity<*>> = inserts.remove(table)?.toList().orEmpty()
while (toFlush.isNotEmpty()) {
Expand All @@ -236,12 +237,26 @@ class EntityCache(private val transaction: Transaction) {
}
}
toFlush = partition.first
val ids = executeAsPartOfEntityLifecycle {
table.batchInsert(toFlush) { entry ->
for ((c, v) in entry.writeValues) {
this[c] = v
val ids = try {
executeAsPartOfEntityLifecycle {
table.batchInsert(toFlush) { entry ->
for ((c, v) in entry.writeValues) {
this[c] = v
}
}
}
} catch (cause: ArrayIndexOutOfBoundsException) {
// EXPOSED-191 Flaky Oracle test on TC build
// this try/catch should help to get information about the flaky test.
// try/catch can be safely removed after the fixing the issue
// TooGenericExceptionCaught suppress also can be removed
val toFlushString = toFlush.joinToString("; ") {
entry ->
entry.writeValues.map { writeValue -> "${writeValue.key.name}=${writeValue.value}" }.joinToString { ", " }
}

exposedLogger.error("ArrayIndexOutOfBoundsException on attempt to make flush inserts. Table: ${table.tableName}, entries: ($toFlushString)", cause)
throw cause
}

for ((entry, genValues) in toFlush.zip(ids)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,7 @@ class EntityTests : DatabaseTestsBase() {
@Test
fun callLimitOnRelationDoesntMutateTheCachedValue() {
withTables(Posts, Boards, Categories) {
addLogger(StdOutSqlLogger)
val category1 = Category.new {
title = "cat1"
}
Expand Down

0 comments on commit 38c3aa8

Please sign in to comment.