Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SPARK-46592][DOCKER][TEST] OracleIntegrationSuite is flaky because of ORA-04021 #44594

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* 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
*
* http://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.spark.sql.jdbc

import java.io.{File, PrintWriter}

import com.github.dockerjava.api.model._

import org.apache.spark.internal.Logging
import org.apache.spark.util.Utils

class OracleDatabaseOnDocker extends DatabaseOnDocker with Logging {
lazy override val imageName =
sys.env.getOrElse("ORACLE_DOCKER_IMAGE_NAME", "gvenzl/oracle-free:23.3")
val oracle_password = "Th1s1sThe0racle#Pass"
override val env = Map(
"ORACLE_PWD" -> oracle_password, // oracle images uses this
"ORACLE_PASSWORD" -> oracle_password // gvenzl/oracle-free uses this
)
override val usesIpc = false
override val jdbcPort: Int = 1521

override def getJdbcUrl(ip: String, port: Int): String = {
s"jdbc:oracle:thin:system/$oracle_password@//$ip:$port/freepdb1"
}

override def beforeContainerStart(
hostConfigBuilder: HostConfig,
containerConfigBuilder: ContainerConfig): Unit = {
try {
val dir = Utils.createTempDir()
val writer = new PrintWriter(new File(dir, "install.sql"))
// SPARK-46592: gvenzl/oracle-free occasionally fails to start with the following error:
// 'ORA-04021: timeout occurred while waiting to lock object', when initializing the
// SYSTEM user. This is due to the fact that the default DDL_LOCK_TIMEOUT is 0, which
// means that the lock will no wait. We set the timeout to 30 seconds to try again.
// TODO: This workaround should be removed once the issue is fixed in the image.
// https://github.com/gvenzl/oci-oracle-free/issues/35
writer.write("ALTER SESSION SET DDL_LOCK_TIMEOUT = 30;")
writer.write(s"""ALTER USER SYSTEM IDENTIFIED BY "$oracle_password";""")
writer.close()
val newBind = new Bind(
dir.getAbsolutePath,
new Volume("/docker-entrypoint-initdb.d"),
AccessMode.ro)
hostConfigBuilder.withBinds(hostConfigBuilder.getBinds :+ newBind: _*)
} catch {
case e: Exception =>
logWarning("Failed to create install.sql file", e)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,19 +65,7 @@ import org.apache.spark.tags.DockerTest
class OracleIntegrationSuite extends DockerJDBCIntegrationSuite with SharedSparkSession {
import testImplicits._

override val db = new DatabaseOnDocker {
lazy override val imageName =
sys.env.getOrElse("ORACLE_DOCKER_IMAGE_NAME", "gvenzl/oracle-free:23.3")
val oracle_password = "Th1s1sThe0racle#Pass"
override val env = Map(
"ORACLE_PWD" -> oracle_password, // oracle images uses this
"ORACLE_PASSWORD" -> oracle_password // gvenzl/oracle-free uses this
)
override val usesIpc = false
override val jdbcPort: Int = 1521
override def getJdbcUrl(ip: String, port: Int): String =
s"jdbc:oracle:thin:system/$oracle_password@//$ip:$port/freepdb1"
}
override val db = new OracleDatabaseOnDocker

override val connectionTimeout = timeout(7.minutes)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import org.apache.spark.{SparkConf, SparkRuntimeException}
import org.apache.spark.sql.AnalysisException
import org.apache.spark.sql.catalyst.util.CharVarcharUtils.CHAR_VARCHAR_TYPE_STRING_METADATA_KEY
import org.apache.spark.sql.execution.datasources.v2.jdbc.JDBCTableCatalog
import org.apache.spark.sql.jdbc.DatabaseOnDocker
import org.apache.spark.sql.jdbc.OracleDatabaseOnDocker
import org.apache.spark.sql.types._
import org.apache.spark.tags.DockerTest

Expand Down Expand Up @@ -75,19 +75,7 @@ class OracleIntegrationSuite extends DockerJDBCIntegrationV2Suite with V2JDBCTes

override val catalogName: String = "oracle"
override val namespaceOpt: Option[String] = Some("SYSTEM")
override val db = new DatabaseOnDocker {
lazy override val imageName =
sys.env.getOrElse("ORACLE_DOCKER_IMAGE_NAME", "gvenzl/oracle-free:23.3")
val oracle_password = "Th1s1sThe0racle#Pass"
override val env = Map(
"ORACLE_PWD" -> oracle_password, // oracle images uses this
"ORACLE_PASSWORD" -> oracle_password // gvenzl/oracle-free uses this
)
override val usesIpc = false
override val jdbcPort: Int = 1521
override def getJdbcUrl(ip: String, port: Int): String =
s"jdbc:oracle:thin:system/$oracle_password@//$ip:$port/freepdb1"
}
override val db = new OracleDatabaseOnDocker

override val defaultMetadata: Metadata = new MetadataBuilder()
.putLong("scale", 0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import java.sql.Connection

import scala.jdk.CollectionConverters._

import org.apache.spark.sql.jdbc.{DatabaseOnDocker, DockerJDBCIntegrationSuite}
import org.apache.spark.sql.jdbc.{DockerJDBCIntegrationSuite, OracleDatabaseOnDocker}
import org.apache.spark.sql.util.CaseInsensitiveStringMap
import org.apache.spark.tags.DockerTest

Expand Down Expand Up @@ -57,19 +57,7 @@ class OracleNamespaceSuite extends DockerJDBCIntegrationSuite with V2JDBCNamespa

override def excluded: Seq[String] = Seq("listNamespaces: basic behavior", "Drop namespace")

override val db = new DatabaseOnDocker {
lazy override val imageName =
sys.env.getOrElse("ORACLE_DOCKER_IMAGE_NAME", "gvenzl/oracle-free:23.3")
val oracle_password = "Th1s1sThe0racle#Pass"
override val env = Map(
"ORACLE_PWD" -> oracle_password, // oracle images uses this
"ORACLE_PASSWORD" -> oracle_password // gvenzl/oracle-free uses this
)
override val usesIpc = false
override val jdbcPort: Int = 1521
override def getJdbcUrl(ip: String, port: Int): String =
s"jdbc:oracle:thin:system/$oracle_password@//$ip:$port/freepdb1"
}
override val db = new OracleDatabaseOnDocker

val map = new CaseInsensitiveStringMap(
Map("url" -> db.getJdbcUrl(dockerIp, externalPort),
Expand Down