module DeployerSpec where
import Check.Internal
import Check.Types
import Config
import Config.Types
import Data.Either (isLeft)
import Data.Maybe (isNothing)
import Deployer.Internal
import Deployer.Types
import Monad
import Parser.Gen
import System.Directory hiding (createDirectoryIfMissing)
import System.FilePath.Posix ((</>))
import System.Posix.Files
import Test.Hspec
import Test.QuickCheck
import Utils
spec :: Spec
spec = do
cleanSpec
deploymentSpec
completionSpec
cleanSpec :: Spec
cleanSpec = do
let sandbox = "test_sandbox"
let setup = createDirectoryIfMissing sandbox
let teardown = removeDirectoryRecursive sandbox
let clean :: SparkConfig -> CleanupInstruction -> IO ()
clean conf ci = runSparker conf (performClean ci) `shouldReturn` Right ()
beforeAll_ setup $ afterAll_ teardown $ do
describe "performClean" $ do
it "doesn't remove this file if that's not in the config" $ do
let c = defaultConfig { conf_deploy_replace_files = False }
withCurrentDirectory sandbox $ do
let file = "test.txt"
writeFile file "This is a test"
diagnoseFp file `shouldReturn` IsFile
clean c $ CleanFile file
diagnoseFp file `shouldReturn` IsFile
removeFile file
diagnoseFp file `shouldReturn` Nonexistent
it "removes this file if that's in the config" $ do
let c = defaultConfig { conf_deploy_replace_files = True }
withCurrentDirectory sandbox $ do
let file = "test.txt"
writeFile file "This is a test"
diagnoseFp file `shouldReturn` IsFile
clean c $ CleanFile file
diagnoseFp file `shouldReturn` Nonexistent
it "doesn't remove this directory if that's not in the config" $ do
let c = defaultConfig { conf_deploy_replace_directories = False }
withCurrentDirectory sandbox $ do
let dir = "testdirectory"
createDirectoryIfMissing dir
diagnoseFp dir `shouldReturn` IsDirectory
clean c $ CleanDirectory dir
diagnoseFp dir `shouldReturn` IsDirectory
removeDirectoryRecursive dir
diagnoseFp dir `shouldReturn` Nonexistent
it "removes this directory if that's in the config" $ do
let c = defaultConfig { conf_deploy_replace_directories = True }
withCurrentDirectory sandbox $ do
let dir = "testdirectory"
createDirectoryIfMissing dir
diagnoseFp dir `shouldReturn` IsDirectory
clean c $ CleanDirectory dir
diagnoseFp dir `shouldReturn` Nonexistent
it "doesn't remove this link if that's not in the config" $ do
let c = defaultConfig { conf_deploy_replace_links = False }
withCurrentDirectory sandbox $ do
let link = "testlink"
let file = "testfile"
writeFile file "This is a test"
createSymbolicLink file link
diagnoseFp link `shouldReturn` IsLinkTo file
clean c $ CleanLink link
diagnoseFp link `shouldReturn` IsLinkTo file
removeLink link
diagnoseFp link `shouldReturn` Nonexistent
removeFile file
diagnoseFp file `shouldReturn` Nonexistent
it "removes this link with an existent source if that's in the config" $ do
let c = defaultConfig { conf_deploy_replace_links = True }
withCurrentDirectory sandbox $ do
let link = "testlink"
let file = "testfile"
writeFile file "This is a test"
createSymbolicLink file link
diagnoseFp link `shouldReturn` IsLinkTo file
clean c $ CleanLink link
diagnoseFp link `shouldReturn` Nonexistent
removeFile file
diagnoseFp file `shouldReturn` Nonexistent
it "removes this link with a nonexistent source if that's in the config" $ do
let c = defaultConfig { conf_deploy_replace_links = True }
withCurrentDirectory sandbox $ do
let link = "testlink"
let file = "testfile"
createSymbolicLink file link
diagnoseFp link `shouldReturn` IsLinkTo file
diagnoseFp file `shouldReturn` Nonexistent
clean c $ CleanLink link
diagnoseFp link `shouldReturn` Nonexistent
diagnoseFp file `shouldReturn` Nonexistent
deploymentSpec :: Spec
deploymentSpec = do
let sandbox = "test_sandbox"
let setup = createDirectoryIfMissing sandbox
let teardown = removeDirectoryRecursive sandbox
beforeAll_ setup $ afterAll_ teardown $ do
describe "copy" $ do
it "succcesfully copies this file" $ do
withCurrentDirectory sandbox $ do
let src = "testfile"
let dst = "testcopy"
writeFile src "This is a file."
diagnoseFp src `shouldReturn` IsFile
diagnoseFp dst `shouldReturn` Nonexistent
-- Under test
copy src dst
diagnoseFp src `shouldReturn` IsFile
diagnoseFp dst `shouldReturn` IsFile
dsrc <- diagnose src
ddst <- diagnose dst
diagnosedHashDigest ddst `shouldBe` diagnosedHashDigest dsrc
removeFile src
removeFile dst
diagnoseFp src `shouldReturn` Nonexistent
diagnoseFp dst `shouldReturn` Nonexistent
it "succcesfully copies this directory" $ do
withCurrentDirectory sandbox $ do
let src = "testdir"
let dst = "testcopy"
createDirectoryIfMissing src
diagnoseFp src `shouldReturn` IsDirectory
diagnoseFp dst `shouldReturn` Nonexistent
-- Under test
copy src dst
diagnoseFp src `shouldReturn` IsDirectory
diagnoseFp dst `shouldReturn` IsDirectory
dsrc <- diagnose src
ddst <- diagnose dst
diagnosedHashDigest ddst `shouldBe` diagnosedHashDigest dsrc
removeDirectoryRecursive src
removeDirectoryRecursive dst
diagnoseFp src `shouldReturn` Nonexistent
diagnoseFp dst `shouldReturn` Nonexistent
describe "link" $ do
it "successfully links this file" $ do
withCurrentDirectory sandbox $ do
let src = "testfile"
let dst = "testlink"
diagnoseFp src `shouldReturn` Nonexistent
diagnoseFp dst `shouldReturn` Nonexistent
writeFile src "This is a test."
diagnoseFp src `shouldReturn` IsFile
diagnoseFp dst `shouldReturn` Nonexistent
-- Under test
link src dst
diagnoseFp src `shouldReturn` IsFile
diagnoseFp dst `shouldReturn` IsLinkTo src
removeFile src
removeLink dst
diagnoseFp src `shouldReturn` Nonexistent
diagnoseFp dst `shouldReturn` Nonexistent
it "successfully links this directory" $ do
withCurrentDirectory sandbox $ do
let src = "testdir"
let dst = "testlink"
diagnoseFp src `shouldReturn` Nonexistent
diagnoseFp dst `shouldReturn` Nonexistent
createDirectoryIfMissing src
diagnoseFp src `shouldReturn` IsDirectory
diagnoseFp dst `shouldReturn` Nonexistent
-- Under test
link src dst
diagnoseFp src `shouldReturn` IsDirectory
diagnoseFp dst `shouldReturn` IsLinkTo src
removeDirectoryRecursive src
removeLink dst
diagnoseFp src `shouldReturn` Nonexistent
diagnoseFp dst `shouldReturn` Nonexistent
completionSpec :: Spec
completionSpec = do
describe "complete" $ do
-- Necessary because not all utilities can handle paths with '~' in them.
it "replaces the home directory as specified for simple home directories and simple paths" $ do
forAll arbitrary $ \env ->
forAll generateWord $ \home ->
forAll generateWord $ \fp ->
complete home env ("~" </> fp) `shouldBe` Right (home </> fp)
describe "parseId" $ do
it "Works for these cases" $ do
parseId "" `shouldBe` []
parseId "file" `shouldBe` [Plain "file"]
parseId "something$(with)variable" `shouldBe` [Plain "something", Var "with", Plain "variable"]
parseId "$(one)$(two)$(three)" `shouldBe` [Var "one", Var "two", Var "three"]
describe "replaceId" $ do
it "leaves plain ID's unchanged in any environment" $ do
forAll arbitrary $ \env ->
forAll arbitrary $ \s ->
replaceId env (Plain s) `shouldBe` Right s
it "returns Left if a variable is not in the environment" $ do
forAll arbitrary $ \var ->
forAll (arbitrary `suchThat` (isNothing . lookup var)) $ \env ->
replaceId env (Var var) `shouldSatisfy` isLeft
it "replaces a variable if it's in the environment" $ do
forAll arbitrary $ \var ->
forAll arbitrary $ \val ->
forAll (arbitrary `suchThat` (isNothing . lookup var)) $ \env1 ->
forAll (arbitrary `suchThat` (isNothing . lookup var)) $ \env2 ->
replaceId (env1 ++ [(var, val)] ++ env2) (Var var) `shouldBe` Right val