blob: 507577c6d617b8e5469265bc884f72c58415fd32 [file]
-- Licensed to the Apache Software Foundation (ASF) under one
-- or more contributor license agreements. See the NOTICE file
-- distributed with this work for additional information
-- regarding copyright ownership. The ASF licenses this file
-- to you under the Apache License, Version 2.0 (the
-- "License"); you may not use this file except in compliance
-- with the License. You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing,
-- software distributed under the License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-- KIND, either express or implied. See the License for the
-- specific language governing permissions and limitations
-- under the License.
module BasicTest (basicTests) where
import Control.Monad.IO.Class (MonadIO, liftIO)
import OpenDAL
import Test.Tasty
import Test.Tasty.HUnit
basicTests :: TestTree
basicTests =
testGroup
"Basic Tests"
[ testCase "testBasicOperation" testRawOperation,
testCase "testMonad" testMonad,
testCase "testError" testError,
testCase "testWriter" testWriter,
testCase "testWriterAppend" testWriterAppend,
testCase "testAppendOperation" testAppendOperation,
testCase "testLister" testLister,
testCase "testCopyRename" testCopyRename,
testCase "testRemoveAll" testRemoveAll,
testCase "testOperatorInfo" testOperatorInfo
]
testRawOperation :: Assertion
testRawOperation = do
Right op <- newOperator "memory"
writeOpRaw op "key1" "value1" ?= Right ()
writeOpRaw op "key2" "value2" ?= Right ()
readOpRaw op "key1" ?= Right "value1"
readOpRaw op "key2" ?= Right "value2"
isExistOpRaw op "key1" ?= Right True
isExistOpRaw op "key2" ?= Right True
createDirOpRaw op "dir1/" ?= Right ()
isExistOpRaw op "dir1/" ?= Right True
statOpRaw op "key1" >>= \case
Right meta -> meta @?= except_meta
Left _ -> assertFailure "should not reach here"
deleteOpRaw op "key1" ?= Right ()
isExistOpRaw op "key1" ?= Right False
where
except_meta =
Metadata
{ mMode = File,
mCacheControl = Nothing,
mContentDisposition = Nothing,
mContentLength = 6,
mContentMD5 = Nothing,
mContentType = Nothing,
mETag = Nothing,
mLastModified = Nothing
}
testMonad :: Assertion
testMonad = do
Right op <- newOperator "memory"
runOp op operation ?= Right ()
where
operation = do
writeOp "key1" "value1"
writeOp "key2" "value2"
readOp "key1" ?= "value1"
readOp "key2" ?= "value2"
isExistOp "key1" ?= True
isExistOp "key2" ?= True
createDirOp "dir1/"
isExistOp "dir1/" ?= True
statOp "key1" ?= except_meta
deleteOp "key1"
isExistOp "key1" ?= False
except_meta =
Metadata
{ mMode = File,
mCacheControl = Nothing,
mContentDisposition = Nothing,
mContentLength = 6,
mContentMD5 = Nothing,
mContentType = Nothing,
mETag = Nothing,
mLastModified = Nothing
}
testError :: Assertion
testError = do
Right op <- newOperator "memory"
runOp op operation >>= \case
Left err -> errorCode err @?= NotFound
Right _ -> assertFailure "should not reach here"
where
operation = readOp "non-exist-path"
testWriter :: Assertion
testWriter = do
Right op <- newOperator "memory"
Right writer <- writerOpRaw op "test-writer-file" defaultWriterOption
writerWrite writer "Hello" ?= Right ()
writerWrite writer " " ?= Right ()
writerWrite writer "World!" ?= Right ()
writerClose writer >>= \case
Right meta -> mContentLength meta @?= 12
Left err -> assertFailure $ "Failed to close writer: " ++ show err
readOpRaw op "test-writer-file" ?= Right "Hello World!"
testWriterAppend :: Assertion
testWriterAppend = do
Right op <- newOperator "memory"
-- First write some initial content
writeOpRaw op "append-file" "Initial content" ?= Right ()
-- Create append writer and add more content
result <- writerOpRaw op "append-file" appendWriterOption
case result of
Right writer -> do
writerWrite writer " appended" ?= Right ()
writerClose writer >>= \case
Right meta -> mContentLength meta @?= 24
Left err -> assertFailure $ "Failed to close append writer: " ++ show err
readOpRaw op "append-file" ?= Right "Initial content appended"
Left err -> case errorCode err of
Unsupported -> putStrLn "Append writer not supported by memory backend - skipping"
_ -> assertFailure $ "Failed to create append writer: " ++ show err
testAppendOperation :: Assertion
testAppendOperation = do
Right op <- newOperator "memory"
-- Write initial content
writeOpRaw op "append-test" "Hello" ?= Right ()
-- Demonstrate append using writer API
result <- writerOpRaw op "append-test" appendWriterOption
case result of
Right writer -> do
writerWrite writer " World" ?= Right ()
writerClose writer >>= \case
Right _ -> readOpRaw op "append-test" ?= Right "Hello World"
Left err -> assertFailure $ "Failed to close append writer: " ++ show err
Left err -> case errorCode err of
Unsupported -> do
putStrLn "Append writer not supported by memory backend - demonstrating manual append"
-- Manual append: read existing content, append new content, write back
Right existingContent <- readOpRaw op "append-test"
let newContent = existingContent <> " World"
writeOpRaw op "append-test" newContent ?= Right ()
readOpRaw op "append-test" ?= Right "Hello World"
_ -> assertFailure $ "Failed to create append writer: " ++ show err
testLister :: Assertion
testLister = do
Right op <- newOperator "memory"
-- Create some test files and directories
writeOpRaw op "dir1/file1.txt" "content1" ?= Right ()
writeOpRaw op "dir1/file2.txt" "content2" ?= Right ()
writeOpRaw op "dir1/subdir/file3.txt" "content3" ?= Right ()
createDirOpRaw op "dir1/empty-dir/" ?= Right ()
-- Test listing
Right lister <- listOpRaw op "dir1/"
files <- collectListerItems lister
length files @?= 4 -- file1.txt, file2.txt, subdir/, empty-dir/
-- Test scanning (recursive)
Right scanner <- scanOpRaw op "dir1/"
allFiles <- collectListerItems scanner
length allFiles @?= 4 -- All files including nested ones
testCopyRename :: Assertion
testCopyRename = do
Right op <- newOperator "memory"
-- Create source file
writeOpRaw op "source.txt" "test content" ?= Right ()
-- Test copy - handle case where operation is not supported
copyResult <- copyOpRaw op "source.txt" "copy.txt"
case copyResult of
Right () -> do
readOpRaw op "copy.txt" ?= Right "test content"
isExistOpRaw op "source.txt" ?= Right True
Left err -> case errorCode err of
Unsupported -> putStrLn "Copy operation not supported by memory backend - skipping"
_ -> assertFailure $ "Unexpected error in copy: " ++ show err
-- Test rename - handle case where operation is not supported
renameResult <- renameOpRaw op "source.txt" "renamed.txt"
case renameResult of
Right () -> do
readOpRaw op "renamed.txt" ?= Right "test content"
isExistOpRaw op "source.txt" ?= Right False
Left err -> case errorCode err of
Unsupported -> putStrLn "Rename operation not supported by memory backend - skipping"
_ -> assertFailure $ "Unexpected error in rename: " ++ show err
testRemoveAll :: Assertion
testRemoveAll = do
Right op <- newOperator "memory"
-- Create directory structure
writeOpRaw op "remove-test/file1.txt" "content1" ?= Right ()
writeOpRaw op "remove-test/subdir/file2.txt" "content2" ?= Right ()
createDirOpRaw op "remove-test/empty/" ?= Right ()
-- Verify structure exists
isExistOpRaw op "remove-test/file1.txt" ?= Right True
isExistOpRaw op "remove-test/subdir/file2.txt" ?= Right True
-- Remove all
removeAllOpRaw op "remove-test/" ?= Right ()
-- Verify everything is gone
isExistOpRaw op "remove-test/file1.txt" ?= Right False
isExistOpRaw op "remove-test/subdir/file2.txt" ?= Right False
isExistOpRaw op "remove-test/" ?= Right False
testOperatorInfo :: Assertion
testOperatorInfo = do
Right op <- newOperator "memory"
operatorInfoRaw op ?= Right "memory"
-- Helper function to collect all items from a lister
collectListerItems :: Lister -> IO [String]
collectListerItems lister = go []
where
go acc = do
result <- nextLister lister
case result of
Right (Just item) -> go (item : acc)
Right Nothing -> return $ reverse acc
Left err -> assertFailure $ "Lister error: " ++ show err
-- helper function
(?=) :: (MonadIO m, Eq a, Show a) => m a -> a -> m ()
result ?= except = result >>= liftIO . (@?= except)