From 7d688954f7d8a940a0c404a7bb55fe973db424d3 Mon Sep 17 00:00:00 2001 From: Paul Campbell Date: Thu, 9 May 2019 17:34:17 +0100 Subject: [PATCH] [uploadselectionfilter] implement with tests --- .../s3thorp/UploadSelectionFilter.scala | 24 ++++++++---- .../s3thorp/UploadSelectionFilterSuite.scala | 39 +++++++++++++++++++ .../kemitix/s3thorp/test-file-for-hash.txt | 1 + 3 files changed, 57 insertions(+), 7 deletions(-) create mode 100644 src/test/scala/net/kemitix/s3thorp/UploadSelectionFilterSuite.scala create mode 100644 src/test/scala/net/kemitix/s3thorp/test-file-for-hash.txt diff --git a/src/main/scala/net/kemitix/s3thorp/UploadSelectionFilter.scala b/src/main/scala/net/kemitix/s3thorp/UploadSelectionFilter.scala index b22dc46..a2e8609 100644 --- a/src/main/scala/net/kemitix/s3thorp/UploadSelectionFilter.scala +++ b/src/main/scala/net/kemitix/s3thorp/UploadSelectionFilter.scala @@ -1,21 +1,31 @@ package net.kemitix.s3thorp -import java.io.File - import fs2.Stream import cats.effect.IO -import net.kemitix.s3thorp.Main.putStrLn +import net.kemitix.s3thorp.Sync.{Hash, LocalFile} +import java.security.{MessageDigest, DigestInputStream} +import java.io.{File, FileInputStream} trait UploadSelectionFilter { + private def md5File(localFile: LocalFile): Hash = { + val buffer = new Array[Byte](8192) + val md5 = MessageDigest.getInstance("MD5") + + val dis = new DigestInputStream(new FileInputStream(localFile), md5) + try { while (dis.read(buffer) != -1) { } } finally { dis.close() } + + md5.digest.map("%02x".format(_)).mkString + } + def uploadRequiredFilter: Either[File, S3MetaData] => Stream[IO, File] = { case Left(file) => Stream(file) case Right(s3Metadata) => Stream.eval(for { - _ <- putStrLn(s"upload required: ${s3Metadata.localFile}") - //md5File(localFile) - //filter(localHash => options.force || localHash != metadataHash) - } yield s3Metadata.localFile) + localHash <- IO(md5File(s3Metadata.localFile)) + } yield (s3Metadata.localFile, localHash)). + filter { case (_, localHash) => localHash != s3Metadata.remoteHash }. + map {case (localFile,_) => localFile} } } diff --git a/src/test/scala/net/kemitix/s3thorp/UploadSelectionFilterSuite.scala b/src/test/scala/net/kemitix/s3thorp/UploadSelectionFilterSuite.scala new file mode 100644 index 0000000..184cb35 --- /dev/null +++ b/src/test/scala/net/kemitix/s3thorp/UploadSelectionFilterSuite.scala @@ -0,0 +1,39 @@ +package net.kemitix.s3thorp + +import java.io.File +import java.time.Instant + +import org.scalatest.FunSpec + +class UploadSelectionFilterSuite extends FunSpec { + + new UploadSelectionFilter { + describe("uploadRequiredFilter") { + val localFile = new File("src/test/scala/net/kemitix/s3thorp/test-file-for-hash.txt") + val localHash = "0cbfe978783bd7950d5da4ff85e4af37" + def invokeSubject(input: Either[File, S3MetaData]) = { + uploadRequiredFilter(input).compile.toList.unsafeRunSync() + } + describe("when supplied a file") { + val input = Left(localFile) + it("should be marked for upload") { + assertResult(List(localFile))(invokeSubject(input)) + } + } + describe("when supplied S3MetaData") { + describe("when hash is different") { + val input = Right(S3MetaData(localFile, "", "doesn't match any hash", Instant.now)) + it("should be marked for upload") { + assertResult(List(localFile))(invokeSubject(input)) + } + } + describe("when hash is the same") { + val input = Right(S3MetaData(localFile, "", localHash, Instant.now)) + it("should not be marked for upload") { + assertResult(List())(invokeSubject(input)) + } + } + } + } + } +} diff --git a/src/test/scala/net/kemitix/s3thorp/test-file-for-hash.txt b/src/test/scala/net/kemitix/s3thorp/test-file-for-hash.txt new file mode 100644 index 0000000..941de6f --- /dev/null +++ b/src/test/scala/net/kemitix/s3thorp/test-file-for-hash.txt @@ -0,0 +1 @@ +This is a test file for checking the md5 hash generator.