From cc86f8d609969b40793a227b9af4b41a18657dfb Mon Sep 17 00:00:00 2001 From: Jakob Odersky Date: Thu, 22 Mar 2018 15:47:42 -0700 Subject: Add blob storage abstractions --- .../scala/xyz/driver/core/BlobStorageTest.scala | 88 ++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 src/test/scala/xyz/driver/core/BlobStorageTest.scala (limited to 'src/test/scala/xyz/driver/core/BlobStorageTest.scala') diff --git a/src/test/scala/xyz/driver/core/BlobStorageTest.scala b/src/test/scala/xyz/driver/core/BlobStorageTest.scala new file mode 100644 index 0000000..65f9cbc --- /dev/null +++ b/src/test/scala/xyz/driver/core/BlobStorageTest.scala @@ -0,0 +1,88 @@ +package xyz.driver.core + +import java.nio.file.Files + +import akka.actor.ActorSystem +import akka.stream.ActorMaterializer +import akka.stream.scaladsl._ +import akka.util.ByteString +import org.scalatest._ +import org.scalatest.concurrent.ScalaFutures +import xyz.driver.core.storage.{BlobStorage, FileSystemBlobStorage} + +import scala.concurrent.Future +import scala.concurrent.duration._ + +class BlobStorageTest extends FlatSpec with ScalaFutures { + + implicit val patientce = PatienceConfig(timeout = 100.seconds) + + implicit val system = ActorSystem("blobstorage-test") + implicit val mat = ActorMaterializer() + import system.dispatcher + + def storageBehaviour(storage: BlobStorage) = { + val key = "foo" + val data = "hello world".getBytes + it should "upload data" in { + assert(storage.exists(key).futureValue === false) + assert(storage.uploadContent(key, data).futureValue === key) + assert(storage.exists(key).futureValue === true) + } + it should "download data" in { + val content = storage.content(key).futureValue + assert(content.isDefined) + assert(content.get === data) + } + it should "not download non-existing data" in { + assert(storage.content("bar").futureValue.isEmpty) + } + it should "overwrite an existing key" in { + val newData = "new string".getBytes("utf-8") + assert(storage.uploadContent(key, newData).futureValue === key) + assert(storage.content(key).futureValue.get === newData) + } + it should "upload a file" in { + val tmp = Files.createTempFile("testfile", "txt") + Files.write(tmp, data) + assert(storage.uploadFile(key, tmp).futureValue === key) + Files.delete(tmp) + } + it should "upload content" in { + val text = "foobar" + val src = Source + .single(text) + .map(l => ByteString(l)) + src.runWith(storage.upload(key).futureValue).futureValue + assert(storage.content(key).futureValue.map(_.toSeq) === Some("foobar".getBytes.toSeq)) + } + it should "delete content" in { + assert(storage.exists(key).futureValue) + storage.delete(key).futureValue + assert(!storage.exists(key).futureValue) + } + it should "download content" in { + storage.uploadContent(key, data) futureValue + val srcOpt = storage.download(key).futureValue + assert(srcOpt.isDefined) + val src = srcOpt.get + val content: Future[Array[Byte]] = src.runWith(Sink.fold(Array[Byte]())(_ ++ _)) + assert(content.futureValue === data) + } + it should "list keys" in { + assert(storage.list("").futureValue === Set(key)) + storage.uploadContent("a/a.txt", data).futureValue + storage.uploadContent("a/b", data).futureValue + storage.uploadContent("c/d", data).futureValue + storage.uploadContent("d", data).futureValue + assert(storage.list("").futureValue === Set(key, "a", "c", "d")) + assert(storage.list("a").futureValue === Set("a/a.txt", "a/b")) + assert(storage.list("a").futureValue === Set("a/a.txt", "a/b")) + assert(storage.list("c").futureValue === Set("c/d")) + } + } + + "File system storage" should behave like storageBehaviour( + new FileSystemBlobStorage(Files.createTempDirectory("test"))) + +} -- cgit v1.2.3