From dc46866ff1881bba0b950cb2f2d6ebcda8c23d20 Mon Sep 17 00:00:00 2001 From: Ajay Borra Date: Sat, 11 Aug 2018 20:54:04 +0530 Subject: [PATCH] Added test io.Avro object/class + minor refactor (#48) --- test-data/PassengerDataAll.avro | Bin 0 -> 68316 bytes .../com/salesforce/op/test/TestCommon.scala | 18 ++++++ .../op/utils/io/avro/AvroInOut.scala | 2 +- .../op/utils/io/avro/AvroInOutTest.scala | 56 ++++++++++++++++-- .../op/utils/io/csv/CSVInOutTest.scala | 9 +-- 5 files changed, 71 insertions(+), 14 deletions(-) create mode 100644 test-data/PassengerDataAll.avro diff --git a/test-data/PassengerDataAll.avro b/test-data/PassengerDataAll.avro new file mode 100644 index 0000000000000000000000000000000000000000..5a2e3fb9c9acfee3138434d1ae3fd88930b65588 GIT binary patch literal 68316 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

p|+Vf^)EhLESTs=e^3 zNV0I>bG1Koxelf!z!*^+oTHJ1L8^HpCz3EESehyRBQ^R{zkLeBGy;<2#bqJ<+F+xo zesjnzOg9?GfbZ?k-O#qGW0Me_>{t**+?4v+;9mWQ;aX^FAb{{Z=xA)L(CaV#*ei6Q zk9l&H@3^f&2RqQuYuH3uVvcQqn9=_v&wuMqr_RChFbA&CW{19Xy(*hF*nAxucG7pv o2I throw new IllegalArgumentException(s"Bad path $firstPath: ${ex.getMessage}") } val found = paths.filter(p => fs.exists(new Path(p))) - if (found.isEmpty) throw new IllegalArgumentException("No valid directory found in the list of paths <<$path>>") + if (found.isEmpty) throw new IllegalArgumentException(s"No valid directory found in the list of paths <<$path>>") found.mkString(",") } diff --git a/utils/src/test/scala/com/salesforce/op/utils/io/avro/AvroInOutTest.scala b/utils/src/test/scala/com/salesforce/op/utils/io/avro/AvroInOutTest.scala index 5a212faf68..4ee5ee7024 100644 --- a/utils/src/test/scala/com/salesforce/op/utils/io/avro/AvroInOutTest.scala +++ b/utils/src/test/scala/com/salesforce/op/utils/io/avro/AvroInOutTest.scala @@ -30,23 +30,69 @@ package com.salesforce.op.utils.io.avro -import java.io.{File, FileWriter} +import java.io.{File, FileNotFoundException, FileWriter} import com.salesforce.op.test.TestSparkContext import com.salesforce.op.utils.io.avro.AvroInOut._ +import org.apache.avro.generic.GenericRecord +import org.apache.hadoop.fs.{FileSystem, Path} +import org.apache.spark.rdd.RDD import org.junit.runner.RunWith import org.scalatest.FlatSpec import org.scalatest.junit.JUnitRunner @RunWith(classOf[JUnitRunner]) class AvroInOutTest extends FlatSpec with TestSparkContext { + val avroSchemaPath = s"$testDataDir/PassengerDataAll.avsc" + val avroFilePath = s"$testDataDir/PassengerDataAll.avro" + val avroFileRecordCount = 891 + val hdfs: FileSystem = FileSystem.get(spark.sparkContext.hadoopConfiguration) + lazy val avroTemp: String = tempDir + "/avro-inout-test" - "AvroInOut" should "readPathSeq" in { - // TODO + Spec(AvroInOut.getClass) should "creates RDD from an avro file" in { + val res = readPathSeq(avroFilePath, withCount = true, deepCopy = true, persist = false) + res shouldBe a[RDD[_]] + res.count shouldBe avroFileRecordCount } - "AvroWriter" should "read" in { - // TODO + it should "creates RDD from a sequence of avro files" in { + val res = readPathSeq(s"$avroFilePath,$avroFilePath") + res.count shouldBe avroFileRecordCount*2 + } + + it should "create RDD from a mixed sequence of valid and invalid avro files" in { + val res = readPathSeq(s"badfile/path1,$avroFilePath,badfile/path2,$avroFilePath,badfile/path3") + res.count shouldBe avroFileRecordCount*2 + } + + it should "throw an error if passed in avro files are invalid" in { + val error = intercept[IllegalArgumentException](readPathSeq("badfile/path1,badfile/path2")) + error.getMessage shouldBe "No valid directory found in the list of paths <>" + } + + it should "creates Some(RDD) from an avro file" in { + val res = read(avroFilePath) + res.size shouldBe 1 + res.get shouldBe an[RDD[_]] + res.get.count shouldBe avroFileRecordCount + } + + it should "create None from an invalid avro file" in { + val res = read("badfile/path") + res shouldBe None + } + + Spec[AvroWriter[_]] should "writeAvro to filesystem" in { + val avroData = readPathSeq(avroFilePath).asInstanceOf[RDD[GenericRecord]] + val avroSchema = loadFile(avroSchemaPath) + + val error = intercept[FileNotFoundException](hdfs.listStatus(new Path(avroTemp))) + error.getMessage shouldBe s"File $avroTemp does not exist" + + AvroWriter(avroData).writeAvro(avroTemp, avroSchema) + val hdfsFiles = hdfs.listStatus(new Path(avroTemp)) filter (x => x.getPath.getName.contains("part")) + val res = readPathSeq((for { x <- hdfsFiles } yield avroTemp + "/" + x.getPath.getName).mkString(",")) + res.count shouldBe avroFileRecordCount } it should "checkPathsExist" in { diff --git a/utils/src/test/scala/com/salesforce/op/utils/io/csv/CSVInOutTest.scala b/utils/src/test/scala/com/salesforce/op/utils/io/csv/CSVInOutTest.scala index 326e3697cc..1df0fa3803 100644 --- a/utils/src/test/scala/com/salesforce/op/utils/io/csv/CSVInOutTest.scala +++ b/utils/src/test/scala/com/salesforce/op/utils/io/csv/CSVInOutTest.scala @@ -30,8 +30,6 @@ package com.salesforce.op.utils.io.csv -import java.io.File - import com.salesforce.op.test.TestSparkContext import org.apache.spark.rdd.RDD import org.apache.spark.sql.{AnalysisException, DataFrame} @@ -39,15 +37,10 @@ import org.junit.runner.RunWith import org.scalatest.FlatSpec import org.scalatest.junit.JUnitRunner -import scala.language.postfixOps - @RunWith(classOf[JUnitRunner]) class CSVInOutTest extends FlatSpec with TestSparkContext { - private val testDataDirPath: String = { - Some(new File("test-data")) filter (_.isDirectory) getOrElse new File("../test-data") getPath - } private val csvReader = new CSVInOut(CSVOptions(header = true)) - private val csvFile = s"$testDataDirPath/PassengerDataAllWithHeader.csv" + private val csvFile = s"$testDataDir/PassengerDataAllWithHeader.csv" Spec[CSVInOut] should "throw error for bad file paths with DataFrame" in { val error = intercept[AnalysisException](csvReader.readDataFrame("/bad/file/path/read/dataframe"))