Skip to content

Commit

Permalink
chore: improve test coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
mhamilton723 committed Aug 24, 2022
1 parent e700fd1 commit 44c6d9a
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,11 @@ trait HasImageInput extends HasImageUrl
override protected def inputFunc(schema: StructType): Row => Option[HttpRequestBase] = {
val rowToUrl = prepareUrl
val rowToEntity = prepareEntity;
if (get(imageUrl).orElse(get(imageBytes)).isEmpty){
throw new IllegalArgumentException("Please set one of the" +
" imageUrl, imageUrlCol, imageBytes, imageBytesCol parameters.")
}

{ row: Row =>
if (shouldSkip(row)) {
None
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ import com.microsoft.azure.synapse.ml.Secrets
import com.microsoft.azure.synapse.ml.cognitive._
import com.microsoft.azure.synapse.ml.core.spark.FluentAPI._
import com.microsoft.azure.synapse.ml.core.test.base.{Flaky, TestBase}
import com.microsoft.azure.synapse.ml.core.test.fuzzing.{TestObject, TransformerFuzzing}
import com.microsoft.azure.synapse.ml.core.test.fuzzing.{GetterSetterFuzzing, TestObject, TransformerFuzzing}
import org.apache.spark.ml.NamespaceInjections.pipelineModel
import org.apache.spark.ml.util.MLReadable
import org.apache.spark.sql.functions.typedLit
import org.apache.spark.sql.functions.{col, typedLit}
import org.apache.spark.sql.{DataFrame, Dataset, Row}
import org.scalactic.Equality

Expand Down Expand Up @@ -87,7 +87,8 @@ class OCRSuite extends TransformerFuzzing[OCR] with CognitiveKey with Flaky with
override def reader: MLReadable[_] = OCR
}

class AnalyzeImageSuite extends TransformerFuzzing[AnalyzeImage] with CognitiveKey with Flaky {
class AnalyzeImageSuite extends TransformerFuzzing[AnalyzeImage]
with CognitiveKey with Flaky with GetterSetterFuzzing[AnalyzeImage] {

import spark.implicits._

Expand All @@ -97,6 +98,12 @@ class AnalyzeImageSuite extends TransformerFuzzing[AnalyzeImage] with CognitiveK
("https://mmlspark.blob.core.windows.net/datasets/OCR/test3.png", "en")
).toDF("url", "language")

lazy val nullDf: DataFrame = Seq(
("https://mmlspark.blob.core.windows.net/datasets/OCR/test1.jpg", "en"),
("https://mmlspark.blob.core.windows.net/datasets/OCR/test2.png", null), //scalastyle:ignore null
(null, "en")
).toDF("url", "language")

def baseAI: AnalyzeImage = new AnalyzeImage()
.setSubscriptionKey(cognitiveKey)
.setLocation("eastus")
Expand All @@ -118,6 +125,13 @@ class AnalyzeImageSuite extends TransformerFuzzing[AnalyzeImage] with CognitiveK
def bytesAI: AnalyzeImage = baseAI
.setImageBytesCol("imageBytes")

test("Null handling"){
assertThrows[IllegalArgumentException]{
baseAI.transform(nullDf)
}
assert(ai.transform(nullDf).where(col("features").isNull).count() == 1)
}

test("full parametrization") {
val row = (Seq("Categories"), "en", Seq("Celebrities"),
"https://mmlspark.blob.core.windows.net/datasets/OCR/test1.jpg")
Expand Down Expand Up @@ -188,6 +202,8 @@ class AnalyzeImageSuite extends TransformerFuzzing[AnalyzeImage] with CognitiveK
}
}

override def getterSetterTestObject(): TestObject[AnalyzeImage] = testObjects().head

}

class RecognizeTextSuite extends TransformerFuzzing[RecognizeText]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,14 @@ import com.microsoft.azure.synapse.ml.Secrets
import com.microsoft.azure.synapse.ml.cognitive._
import com.microsoft.azure.synapse.ml.core.test.fuzzing.{TestObject, TransformerFuzzing}
import com.microsoft.azure.synapse.ml.stages.{FixedMiniBatchTransformer, FlattenBatch}
import org.apache.spark.SparkException
import org.apache.spark.ml.util.MLReadable
import org.apache.spark.sql.functions.col
import org.apache.spark.sql.{DataFrame, Row}

import java.util.concurrent.TimeoutException


trait TextEndpoint {
lazy val textKey: String = sys.env.getOrElse("TEXT_API_KEY", Secrets.CognitiveApiKey)
lazy val textApiLocation: String = sys.env.getOrElse("TEXT_API_LOCATION", "eastus")
Expand Down Expand Up @@ -327,6 +332,24 @@ class TextAnalyzeSuite extends TransformerFuzzing[TextAnalyze] with TextEndpoint
assert(results(24).get.sentimentAnalysis.get.document.get.sentiment == "positive")
}

test("Exceeded Retries Info") {
val badModel = model
.setPollingDelay(0)
.setInitialPollingDelay(0)
.setMaxPollingRetries(1)

val results = badModel
.setSuppressMaxRetriesException(true)
.transform(df.coalesce(1))
assert(results.where(!col("error").isNull).count() > 0)

assertThrows[SparkException] {
badModel.setSuppressMaxRetriesException(false)
.transform(df.coalesce(1))
.collect()
}
}

override def testObjects(): Seq[TestObject[TextAnalyze]] =
Seq(new TestObject[TextAnalyze](model, df))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,8 @@ trait DotnetTestFuzzing[S <: PipelineStage] extends TestBase with DataFrameEqual
saveDotnetTestData(conf)
val testDataDirString = dotnetTestDataDir(conf).toString
val generatedTests = dotnetTestObjects().zipWithIndex.map { case (to, i) =>
makeDotnetTests(to, i, testDataDirString) }
makeDotnetTests(to, i, testDataDirString)
}
val stage = dotnetTestObjects().head.stage
val importPath = stage.getClass.getName.split(".".toCharArray).dropRight(1)
val importPathString = importPath.mkString(".")
Expand Down Expand Up @@ -518,8 +519,8 @@ trait SerializationFuzzing[S <: PipelineStage with MLWritable] extends TestBase
val retrySerializationFuzzing = false

test("Serialization Fuzzing") {
if (retrySerializationFuzzing){
tryWithRetries() {() =>
if (retrySerializationFuzzing) {
tryWithRetries() { () =>
testSerialization()
}
} else {
Expand All @@ -529,8 +530,55 @@ trait SerializationFuzzing[S <: PipelineStage with MLWritable] extends TestBase

}


trait GetterSetterFuzzing[S <: PipelineStage] extends TestBase with DataFrameEquality {
def getterSetterTestObject(): TestObject[S]

def testGettersAndSetters(): Unit = {
val pipelineStage = getterSetterTestObject().stage.copy(new ParamMap())
val methods = pipelineStage.getClass.getMethods
pipelineStage.params.foreach { p =>
val getters = methods.filter(_.getName == s"get${p.name.capitalize}").toSeq
val setters = methods.filter(_.getName == s"set${p.name.capitalize}").toSeq
val defaultValue = pipelineStage.get(p).orElse(pipelineStage.getDefault(p))
p match {
case sp: ServiceParam[_] =>
val colGetters = methods.filter(_.getName == s"get${sp.name.capitalize}Col").toSeq
val colSetters = methods.filter(_.getName == s"set${sp.name.capitalize}Col").toSeq
(colGetters, colSetters) match {
case (Seq(getter), Seq(setter)) =>
setter.invoke(pipelineStage, "foo")
assert(getter.invoke(pipelineStage) === "foo")
case _ =>
println(s"Could not test Service parameter column API for: ${sp.name}")
}
(getters, setters, defaultValue) match {
case (Seq(getter), Seq(setter), Some(Left(v))) =>
setter.invoke(pipelineStage, v.asInstanceOf[Object])
assert(getter.invoke(pipelineStage) === v)
case _ =>
println(s"Could not test Service parameter value API ${p.name}")
}
case p: Param[_] =>
(getters, setters, defaultValue) match {
case (Seq(getter), Seq(setter), Some(v)) =>
setter.invoke(pipelineStage, v.asInstanceOf[Object])
assert(getter.invoke(pipelineStage) === v)
case _ =>
println(s"Could not test parameter ${p.name}")
}
}
}
}

test("Getters and Setters work as anticipated") {
testGettersAndSetters()
}

}

trait Fuzzing[S <: PipelineStage with MLWritable] extends SerializationFuzzing[S]
with ExperimentFuzzing[S] with PyTestFuzzing[S] with DotnetTestFuzzing[S] {
with ExperimentFuzzing[S] with PyTestFuzzing[S] with DotnetTestFuzzing[S] with GetterSetterFuzzing[S] {

def testObjects(): Seq[TestObject[S]]

Expand All @@ -542,6 +590,8 @@ trait Fuzzing[S <: PipelineStage with MLWritable] extends SerializationFuzzing[S

def experimentTestObjects(): Seq[TestObject[S]] = testObjects()

def getterSetterTestObject(): TestObject[S] = testObjects().head

}

trait TransformerFuzzing[S <: Transformer with MLWritable] extends Fuzzing[S] {
Expand Down
6 changes: 3 additions & 3 deletions pipeline.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ jobs:
scriptType: bash
inlineScript: |
source activate synapseml
sbt getDatasets installPipPackage
sbt coverage getDatasets installPipPackage
sbt publishM2
sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y
sudo apt-get update
Expand Down Expand Up @@ -398,9 +398,9 @@ jobs:
inlineScript: |
echo "SPARK_HOME=$SPARK_HOME"
echo "DOTNET_WORKER_DIR=$DOTNET_WORKER_DIR"
sbt publishDotnetTestBase
sbt coverage publishDotnetTestBase
sbt publishLocal
sbt "project $(PACKAGE)" publishDotnet
sbt "project $(PACKAGE)" coverage publishDotnet
export SBT_OPTS="-XX:+UseG1GC"
echo "##vso[task.setvariable variable=SBT_OPTS]$SBT_OPTS"
(timeout 5m sbt setup) || (echo "retrying" && timeout 5m sbt setup) || (echo "retrying" && timeout 5m sbt setup)
Expand Down

0 comments on commit 44c6d9a

Please sign in to comment.