You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@texera.apache.org by gi...@apache.org on 2026/06/26 08:44:44 UTC

(texera) branch gh-readonly-queue/main/pr-5951-7a38b6cf4c476e6f7ae0b0555fd711b50f4e85ec created (now c12f908c13)

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

github-merge-queue[bot] pushed a change to branch gh-readonly-queue/main/pr-5951-7a38b6cf4c476e6f7ae0b0555fd711b50f4e85ec
in repository https://gitbox.apache.org/repos/asf/texera.git


      at c12f908c13 test(workflow-operator): add unit test coverage for Sklearn MLP and probability-calibration descriptors (#5951)

This branch includes the following new commits:

     new c12f908c13 test(workflow-operator): add unit test coverage for Sklearn MLP and probability-calibration descriptors (#5951)

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



(texera) 01/01: test(workflow-operator): add unit test coverage for Sklearn MLP and probability-calibration descriptors (#5951)

Posted by gi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

github-merge-queue[bot] pushed a commit to branch gh-readonly-queue/main/pr-5951-7a38b6cf4c476e6f7ae0b0555fd711b50f4e85ec
in repository https://gitbox.apache.org/repos/asf/texera.git

commit c12f908c13fc16c373bf3c2827687c0d89b2dfed
Author: Xinyuan Lin <xi...@uci.edu>
AuthorDate: Fri Jun 26 01:41:01 2026 -0700

    test(workflow-operator): add unit test coverage for Sklearn MLP and probability-calibration descriptors (#5951)
    
    ### What changes were proposed in this PR?
    
    Pin behavior of two previously-untested Sklearn classifier descriptors
    (multi-layer perceptron and probability calibration) in
    `common/workflow-operator`. No production-code changes. This completes
    unit coverage of the concrete `SklearnClassifierOpDesc` classifier
    family.
    
    | Spec | Source class | Tests |
    | --- | --- | --- |
    | `SklearnMultiLayerPerceptronOpDescSpec` |
    `SklearnMultiLayerPerceptronOpDesc` | 5 |
    | `SklearnProbabilityCalibrationOpDescSpec` |
    `SklearnProbabilityCalibrationOpDesc` | 5 |
    
    **Behavior pinned**
    
    | Surface | Contract |
    | --- | --- |
    | `operatorInfo` | exact model name + `Sklearn <name> Operator`
    description; Sklearn group; training/testing input ports + one blocking
    output |
    | field defaults | `countVectorizer`/`tfidfTransformer` `false`;
    `target`/`text` `null` |
    | `getOutputSchemas` | `model_name` (STRING) + `model` (BINARY) keyed by
    the declared output port |
    | `generatePythonCode` | imports the matching sklearn estimator
    (`MLPClassifier`/`CalibratedClassifierCV`) and builds the
    `make_pipeline` model |
    | Round-trip | config fields preserved through the polymorphic
    `LogicalOp` base, with the correct `operatorType` discriminator |
    
    ### Any related issues, documentation, discussions?
    
    Part of the ongoing `workflow-operator` unit-test coverage effort
    (follow-up to the Sklearn classifier coverage in #5925, #5939, #5940,
    #5941, #5945, #5946).
    
    ### How was this PR tested?
    
    - `sbt "WorkflowOperator/testOnly *SklearnMultiLayerPerceptronOpDescSpec
    *SklearnProbabilityCalibrationOpDescSpec"` — 10 tests, all green
    - `sbt "WorkflowOperator/Test/scalafmtCheck"` and `sbt
    "WorkflowOperator/scalafixAll --check"` — clean
    - CI to confirm
    
    ### Was this PR authored or co-authored using generative AI tooling?
    
    Generated-by: Claude Code (Opus 4.8 [1M context])
---
 .../SklearnMultiLayerPerceptronOpDescSpec.scala    | 79 ++++++++++++++++++++++
 .../SklearnProbabilityCalibrationOpDescSpec.scala  | 79 ++++++++++++++++++++++
 2 files changed, 158 insertions(+)

diff --git a/common/workflow-operator/src/test/scala/org/apache/texera/amber/operator/sklearn/SklearnMultiLayerPerceptronOpDescSpec.scala b/common/workflow-operator/src/test/scala/org/apache/texera/amber/operator/sklearn/SklearnMultiLayerPerceptronOpDescSpec.scala
new file mode 100644
index 0000000000..592f577956
--- /dev/null
+++ b/common/workflow-operator/src/test/scala/org/apache/texera/amber/operator/sklearn/SklearnMultiLayerPerceptronOpDescSpec.scala
@@ -0,0 +1,79 @@
+/*
+ * 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.texera.amber.operator.sklearn
+
+import org.apache.texera.amber.core.tuple.AttributeType
+import org.apache.texera.amber.operator.LogicalOp
+import org.apache.texera.amber.operator.metadata.OperatorGroupConstants
+import org.apache.texera.amber.util.JSONUtils.objectMapper
+import org.scalatest.flatspec.AnyFlatSpec
+import org.scalatest.matchers.should.Matchers
+
+class SklearnMultiLayerPerceptronOpDescSpec extends AnyFlatSpec with Matchers {
+
+  "SklearnMultiLayerPerceptronOpDesc.operatorInfo" should
+    "advertise the model name, Sklearn group, and the training/testing port shape" in {
+    val info = (new SklearnMultiLayerPerceptronOpDesc).operatorInfo
+    info.userFriendlyName shouldBe "Multi-layer Perceptron"
+    info.operatorDescription shouldBe "Sklearn Multi-layer Perceptron Operator"
+    info.operatorGroupName shouldBe OperatorGroupConstants.SKLEARN_GROUP
+    info.inputPorts.map(_.displayName) shouldBe List("training", "testing")
+    info.outputPorts should have length 1
+    info.outputPorts.head.blocking shouldBe true
+  }
+
+  "SklearnMultiLayerPerceptronOpDesc" should "default its config fields" in {
+    val d = new SklearnMultiLayerPerceptronOpDesc
+    d.countVectorizer shouldBe false
+    d.tfidfTransformer shouldBe false
+    d.target shouldBe null
+    d.text shouldBe null
+  }
+
+  "SklearnMultiLayerPerceptronOpDesc.getOutputSchemas" should
+    "emit the model_name/model schema keyed by the declared output port" in {
+    val d = new SklearnMultiLayerPerceptronOpDesc
+    val schema = d.getOutputSchemas(Map.empty)(d.operatorInfo.outputPorts.head.id)
+    schema.getAttribute("model_name").getType shouldBe AttributeType.STRING
+    schema.getAttribute("model").getType shouldBe AttributeType.BINARY
+  }
+
+  "SklearnMultiLayerPerceptronOpDesc.generatePythonCode" should "import the configured sklearn estimator" in {
+    val d = new SklearnMultiLayerPerceptronOpDesc
+    d.target = "y"
+    val code = d.generatePythonCode()
+    code should include("from sklearn.neural_network import MLPClassifier")
+    code should include("make_pipeline")
+    code should include("Multi-layer Perceptron")
+  }
+
+  "SklearnMultiLayerPerceptronOpDesc" should "round-trip its config fields through the polymorphic base" in {
+    val d = new SklearnMultiLayerPerceptronOpDesc
+    d.target = "label"
+    d.countVectorizer = true
+    val json = objectMapper.writeValueAsString(d)
+    json should include("\"operatorType\":\"SklearnMultiLayerPerceptron\"")
+    val restored = objectMapper.readValue(json, classOf[LogicalOp])
+    restored shouldBe a[SklearnMultiLayerPerceptronOpDesc]
+    val r = restored.asInstanceOf[SklearnMultiLayerPerceptronOpDesc]
+    r.target shouldBe "label"
+    r.countVectorizer shouldBe true
+  }
+}
diff --git a/common/workflow-operator/src/test/scala/org/apache/texera/amber/operator/sklearn/SklearnProbabilityCalibrationOpDescSpec.scala b/common/workflow-operator/src/test/scala/org/apache/texera/amber/operator/sklearn/SklearnProbabilityCalibrationOpDescSpec.scala
new file mode 100644
index 0000000000..2eab3102cb
--- /dev/null
+++ b/common/workflow-operator/src/test/scala/org/apache/texera/amber/operator/sklearn/SklearnProbabilityCalibrationOpDescSpec.scala
@@ -0,0 +1,79 @@
+/*
+ * 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.texera.amber.operator.sklearn
+
+import org.apache.texera.amber.core.tuple.AttributeType
+import org.apache.texera.amber.operator.LogicalOp
+import org.apache.texera.amber.operator.metadata.OperatorGroupConstants
+import org.apache.texera.amber.util.JSONUtils.objectMapper
+import org.scalatest.flatspec.AnyFlatSpec
+import org.scalatest.matchers.should.Matchers
+
+class SklearnProbabilityCalibrationOpDescSpec extends AnyFlatSpec with Matchers {
+
+  "SklearnProbabilityCalibrationOpDesc.operatorInfo" should
+    "advertise the model name, Sklearn group, and the training/testing port shape" in {
+    val info = (new SklearnProbabilityCalibrationOpDesc).operatorInfo
+    info.userFriendlyName shouldBe "Probability Calibration"
+    info.operatorDescription shouldBe "Sklearn Probability Calibration Operator"
+    info.operatorGroupName shouldBe OperatorGroupConstants.SKLEARN_GROUP
+    info.inputPorts.map(_.displayName) shouldBe List("training", "testing")
+    info.outputPorts should have length 1
+    info.outputPorts.head.blocking shouldBe true
+  }
+
+  "SklearnProbabilityCalibrationOpDesc" should "default its config fields" in {
+    val d = new SklearnProbabilityCalibrationOpDesc
+    d.countVectorizer shouldBe false
+    d.tfidfTransformer shouldBe false
+    d.target shouldBe null
+    d.text shouldBe null
+  }
+
+  "SklearnProbabilityCalibrationOpDesc.getOutputSchemas" should
+    "emit the model_name/model schema keyed by the declared output port" in {
+    val d = new SklearnProbabilityCalibrationOpDesc
+    val schema = d.getOutputSchemas(Map.empty)(d.operatorInfo.outputPorts.head.id)
+    schema.getAttribute("model_name").getType shouldBe AttributeType.STRING
+    schema.getAttribute("model").getType shouldBe AttributeType.BINARY
+  }
+
+  "SklearnProbabilityCalibrationOpDesc.generatePythonCode" should "import the configured sklearn estimator" in {
+    val d = new SklearnProbabilityCalibrationOpDesc
+    d.target = "y"
+    val code = d.generatePythonCode()
+    code should include("from sklearn.calibration import CalibratedClassifierCV")
+    code should include("make_pipeline")
+    code should include("Probability Calibration")
+  }
+
+  "SklearnProbabilityCalibrationOpDesc" should "round-trip its config fields through the polymorphic base" in {
+    val d = new SklearnProbabilityCalibrationOpDesc
+    d.target = "label"
+    d.countVectorizer = true
+    val json = objectMapper.writeValueAsString(d)
+    json should include("\"operatorType\":\"SklearnProbabilityCalibration\"")
+    val restored = objectMapper.readValue(json, classOf[LogicalOp])
+    restored shouldBe a[SklearnProbabilityCalibrationOpDesc]
+    val r = restored.asInstanceOf[SklearnProbabilityCalibrationOpDesc]
+    r.target shouldBe "label"
+    r.countVectorizer shouldBe true
+  }
+}