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

hongze pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-gluten.git


The following commit(s) were added to refs/heads/main by this push:
     new 95f271d7f6 [CORE] Add a test case where dependencies of a component 
are not registered (#11006)
95f271d7f6 is described below

commit 95f271d7f683deb9d61fb019806d6d221d0fc6c9
Author: Hongze Zhang <[email protected]>
AuthorDate: Mon Nov 3 16:39:17 2025 +0000

    [CORE] Add a test case where dependencies of a component are not registered 
(#11006)
---
 .../org/apache/gluten/component/Component.scala    | 20 ++---
 .../apache/gluten/component/ComponentSuite.scala   | 96 ++++++++++++----------
 2 files changed, 62 insertions(+), 54 deletions(-)

diff --git 
a/gluten-core/src/main/scala/org/apache/gluten/component/Component.scala 
b/gluten-core/src/main/scala/org/apache/gluten/component/Component.scala
index c5093692d4..d90a4af58f 100644
--- a/gluten-core/src/main/scala/org/apache/gluten/component/Component.scala
+++ b/gluten-core/src/main/scala/org/apache/gluten/component/Component.scala
@@ -42,6 +42,14 @@ trait Component {
   private val uid = nextUid.getAndIncrement()
   private val isRegistered = new AtomicBoolean(false)
 
+  final def ensureRegistered(): Unit = {
+    if (!isRegistered.compareAndSet(false, true)) {
+      return
+    }
+    graph.add(this)
+    dependencies().foreach(req => graph.declareDependency(this, req))
+  }
+
   /**
    * Determines whether a component should be registered based on runtime 
conditions. For instance,
    * if a component depends on a Spark extension's JAR, this method should be 
overridden to check
@@ -51,14 +59,6 @@ trait Component {
     true
   }
 
-  def ensureRegistered(): Unit = {
-    if (!isRegistered.compareAndSet(false, true)) {
-      return
-    }
-    graph.add(this)
-    dependencies().foreach(req => graph.declareDependency(this, req))
-  }
-
   /** Base information. */
   def name(): String
   def buildInfo(): BuildInfo
@@ -108,8 +108,8 @@ object Component {
    *   2. [component-C, component-B, component-A]
    *   3. [component-B, component-C, component-A]
    *
-   * By all means component B will be placed before component A because of the 
declared
-   * dependency from component A to component B.
+   * By all means component B will be placed before component A because 
component B is a declared
+   * dependency of component A.
    *
    * @throws UnsupportedOperationException When cycles in dependency graph are 
found.
    */
diff --git 
a/gluten-core/src/test/scala/org/apache/gluten/component/ComponentSuite.scala 
b/gluten-core/src/test/scala/org/apache/gluten/component/ComponentSuite.scala
index 9e124aaaab..ca705b8f16 100644
--- 
a/gluten-core/src/test/scala/org/apache/gluten/component/ComponentSuite.scala
+++ 
b/gluten-core/src/test/scala/org/apache/gluten/component/ComponentSuite.scala
@@ -22,22 +22,29 @@ import org.apache.gluten.extension.injector.Injector
 import org.scalatest.BeforeAndAfterAll
 import org.scalatest.funsuite.AnyFunSuite
 
+import scala.collection.mutable
+
 class ComponentSuite extends AnyFunSuite with BeforeAndAfterAll {
   import ComponentSuite._
 
-  private val d = new DummyComponentD()
-  d.ensureRegistered()
-  private val b = new DummyBackendB()
-  b.ensureRegistered()
-  private val a = new DummyBackendA()
-  a.ensureRegistered()
-  private val c = new DummyComponentC()
-  c.ensureRegistered()
-  private val e = new DummyComponentE()
-  e.ensureRegistered()
-
   test("Load order - sanity") {
-    val possibleOrders =
+    val a = new DummyBackend("A") {}
+    val b = new DummyBackend("B") {}
+    val c = new DummyComponent("C") {}
+    val d = new DummyComponent("D") {}
+    val e = new DummyComponent("E") {}
+
+    c.dependsOn(a)
+    d.dependsOn(a, b)
+    e.dependsOn(a, d)
+
+    a.ensureRegistered()
+    b.ensureRegistered()
+    c.ensureRegistered()
+    d.ensureRegistered()
+    e.ensureRegistered()
+
+    val possibleOrders: Set[Seq[Component]] =
       Set(
         Seq(a, b, c, d, e),
         Seq(a, b, d, c, e),
@@ -45,57 +52,58 @@ class ComponentSuite extends AnyFunSuite with 
BeforeAndAfterAll {
         Seq(b, a, d, c, e)
       )
 
-    assert(possibleOrders.contains(Component.sorted()))
+    assert(possibleOrders.contains(Component.sorted().filter(Seq(a, b, c, d, 
e).contains(_))))
   }
 
   test("Register again") {
+    class DummyBackendA extends DummyBackend("A")
+    new DummyBackendA().ensureRegistered()
     assertThrows[IllegalArgumentException] {
       new DummyBackendA().ensureRegistered()
     }
   }
-}
 
-object ComponentSuite {
-  private class DummyBackendA extends Backend {
-    override def name(): String = "dummy-backend-a"
-    override def buildInfo(): Component.BuildInfo =
-      Component.BuildInfo("DUMMY_BACKEND_A", "N/A", "N/A", "N/A")
-    override def injectRules(injector: Injector): Unit = {}
-  }
+  test("Dependencies not registered") {
+    val a = new DummyBackend("A") {}
+    val c = new DummyComponent("C") {}
 
-  private class DummyBackendB extends Backend {
-    override def name(): String = "dummy-backend-b"
-    override def buildInfo(): Component.BuildInfo =
-      Component.BuildInfo("DUMMY_BACKEND_B", "N/A", "N/A", "N/A")
-    override def injectRules(injector: Injector): Unit = {}
+    c.dependsOn(a)
+    c.ensureRegistered()
+    assertThrows[IllegalArgumentException] {
+      Component.sorted()
+    }
+
+    a.ensureRegistered()
+    assert(Component.sorted().filter(Seq(a, c).contains(_)) === Seq(a, c))
   }
+}
 
-  private class DummyComponentC extends Component {
-    override def dependencies(): Seq[Class[_ <: Component]] = 
classOf[DummyBackendA] :: Nil
+object ComponentSuite {
+  private trait DependencyBuilder extends Component {
+    private val dependencyBuffer = mutable.Set[Class[_ <: Component]]()
 
-    override def name(): String = "dummy-component-c"
-    override def buildInfo(): Component.BuildInfo =
-      Component.BuildInfo("DUMMY_COMPONENT_C", "N/A", "N/A", "N/A")
-    override def injectRules(injector: Injector): Unit = {}
-  }
+    override def dependencies(): Seq[Class[_ <: Component]] = 
dependencyBuffer.toSeq
 
-  private class DummyComponentD extends Component {
-    override def dependencies(): Seq[Class[_ <: Component]] =
-      Seq(classOf[DummyBackendA], classOf[DummyBackendB])
+    def dependsOn(component: Component*): Unit = {
+      dependencyBuffer ++= component.map(_.getClass)
+    }
+  }
 
-    override def name(): String = "dummy-component-d"
+  abstract private class DummyComponent(override val name: String)
+    extends Component
+    with DependencyBuilder {
     override def buildInfo(): Component.BuildInfo =
-      Component.BuildInfo("DUMMY_COMPONENT_D", "N/A", "N/A", "N/A")
+      Component.BuildInfo(name, "N/A", "N/A", "N/A")
+
+    /** Query planner rules. */
     override def injectRules(injector: Injector): Unit = {}
   }
 
-  private class DummyComponentE extends Component {
-    override def dependencies(): Seq[Class[_ <: Component]] =
-      Seq(classOf[DummyBackendA], classOf[DummyComponentD])
-
-    override def name(): String = "dummy-component-e"
+  abstract private class DummyBackend(override val name: String) extends 
Backend {
     override def buildInfo(): Component.BuildInfo =
-      Component.BuildInfo("DUMMY_COMPONENT_E", "N/A", "N/A", "N/A")
+      Component.BuildInfo(name, "N/A", "N/A", "N/A")
+
+    /** Query planner rules. */
     override def injectRules(injector: Injector): Unit = {}
   }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to