aboutsummaryrefslogtreecommitdiff
path: root/src/test/scala/xyz/driver/core/BlobStorageTest.scala
blob: 811cc60e821d82e015ee16468938598e3aeeeb9b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
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._
import scala.language.postfixOps

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"))
    }
    it should "get valid URL" in {
      assert(storage.exists(key).futureValue === true)
      val fooUrl = storage.url(key).futureValue
      assert(fooUrl.isDefined)
    }
  }

  "File system storage" should behave like storageBehaviour(
    new FileSystemBlobStorage(Files.createTempDirectory("test")))

}