Skip to content

Commit 0a8cff4

Browse files
committed
WIP
1 parent 8aaf986 commit 0a8cff4

File tree

5 files changed

+74
-16
lines changed

5 files changed

+74
-16
lines changed

fs-api/fs-api.cabal

+11-8
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,6 @@ source-repository head
2323

2424
library
2525
hs-source-dirs: src
26-
27-
if os(windows)
28-
hs-source-dirs: src-win32
29-
30-
else
31-
hs-source-dirs: src-unix
32-
3326
exposed-modules:
3427
System.FS.API
3528
System.FS.API.Lazy
@@ -55,13 +48,23 @@ library
5548
, text >=1.2 && <2.2
5649

5750
if os(windows)
58-
build-depends: Win32 >=2.6.1.0
51+
hs-source-dirs: src-win32
52+
build-depends: Win32 >=2.6.1.0
5953

6054
else
55+
hs-source-dirs: src-unix
6156
build-depends:
6257
, unix
6358
, unix-bytestring >=0.4.0
6459

60+
exposed-modules: System.FS.IO.Internal.Error
61+
62+
if os(linux)
63+
hs-source-dirs: src-linux
64+
65+
else
66+
hs-source-dirs: src-macos
67+
6568
ghc-options:
6669
-Wall -Wcompat -Wincomplete-uni-patterns
6770
-Wincomplete-record-updates -Wpartial-fields -Widentities
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
module System.FS.IO.Internal.Error (sameError) where
2+
3+
import System.FS.API.Types (FsError, sameFsError)
4+
5+
sameError :: FsError -> FsError -> Bool
6+
sameError = sameFsError
7+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
module System.FS.IO.Internal.Error (sameError) where
2+
3+
import System.FS.API.Types (FsError (..), FsErrorType (..),
4+
sameFsError)
5+
6+
-- Check default implementation first using 'sameFsError', and otherwise permit
7+
-- some combinations of error types that are not structurally equal.
8+
sameError :: FsError -> FsError -> Bool
9+
sameError e1 e2 = sameFsError e1 e2
10+
|| (fsErrorPath e1 == fsErrorPath e2
11+
&& permitted (fsErrorType e1) (fsErrorType e2))
12+
where
13+
-- error types that are permitted to differ for technical reasons
14+
permitted ty1 ty2 = case (ty1, ty2) of
15+
(FsInsufficientPermissions , FsResourceInappropriateType) -> True
16+
(FsResourceInappropriateType, FsInsufficientPermissions ) -> True
17+
(_ , _ ) -> False

fs-api/src-unix/System/FS/IO/Internal.hs

+3-5
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,9 @@ import qualified Data.ByteString.Internal as Internal
2424
import Data.Int (Int64)
2525
import Data.Word (Word32, Word64, Word8)
2626
import Foreign (Ptr)
27-
import System.FS.API.Types (AllowExisting (..), FsError,
28-
OpenMode (..), SeekMode (..), sameFsError)
27+
import System.FS.API.Types (AllowExisting (..), OpenMode (..),
28+
SeekMode (..))
29+
import System.FS.IO.Internal.Error (sameError)
2930
import System.FS.IO.Internal.Handle
3031
import qualified System.Posix as Posix
3132
import System.Posix (Fd)
@@ -152,6 +153,3 @@ close h = closeHandleOS h Posix.closeFd
152153
getSize :: FHandle -> IO Word64
153154
getSize h = withOpenHandle "getSize" h $ \fd ->
154155
fromIntegral . Posix.fileSize <$> Posix.getFdStatus fd
155-
156-
sameError :: FsError -> FsError -> Bool
157-
sameError = sameFsError

fs-sim/test/Test/System/FS/StateMachine.hs

+36-3
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
{-# LANGUAGE UndecidableInstances #-}
1818

1919
{-# OPTIONS_GHC -Wno-orphans #-}
20+
{- HLINT ignore "Use camelCase" -}
2021

2122
-- | Tests for our filesystem abstractions.
2223
--
@@ -74,7 +75,7 @@ import Data.TreeDiff (ToExpr (..), defaultExprViaShow)
7475
import Data.Word (Word64)
7576
import qualified Generics.SOP as SOP
7677
import GHC.Generics
77-
import GHC.Stack
78+
import GHC.Stack hiding (prettyCallStack)
7879
import System.IO.Temp (withTempDirectory)
7980
import System.Random (getStdRandom, randomR)
8081
import Text.Read (readMaybe)
@@ -89,13 +90,14 @@ import qualified Test.StateMachine.Labelling as C
8990
import qualified Test.StateMachine.Sequential as QSM
9091
import qualified Test.StateMachine.Types as QSM
9192
import qualified Test.StateMachine.Types.Rank2 as Rank2
92-
import Test.Tasty (TestTree, testGroup)
93+
import Test.Tasty (TestTree, localOption, testGroup)
9394
import Test.Tasty.QuickCheck
9495

9596
import System.FS.API
9697
import System.FS.IO
9798
import qualified System.FS.IO.Internal as F
9899

100+
import Util.CallStack
99101
import Util.Condense
100102

101103
import System.FS.Sim.FsTree (FsTree (..))
@@ -1445,7 +1447,10 @@ showLabelledExamples = showLabelledExamples' Nothing 1000 (const True)
14451447

14461448
prop_sequential :: FilePath -> Property
14471449
prop_sequential tmpDir = withMaxSuccess 1000 $
1448-
QSM.forAllCommands (sm mountUnused) Nothing $ \cmds -> QC.monadicIO $ do
1450+
QSM.forAllCommands (sm mountUnused) Nothing $ runCmds tmpDir
1451+
1452+
runCmds :: FilePath -> QSM.Commands (At Cmd) (At Resp) -> Property
1453+
runCmds tmpDir cmds = QC.monadicIO $ do
14491454
(tstTmpDir, hist, res) <- QC.run $
14501455
withTempDirectory tmpDir "HasFS" $ \tstTmpDir -> do
14511456
let mount = MountPoint tstTmpDir
@@ -1467,6 +1472,8 @@ prop_sequential tmpDir = withMaxSuccess 1000 $
14671472
tests :: FilePath -> TestTree
14681473
tests tmpDir = testGroup "HasFS" [
14691474
testProperty "q-s-m" $ prop_sequential tmpDir
1475+
, localOption (QuickCheckTests 1)
1476+
$ testProperty "regression_removeFileOnDir" $ runCmds tmpDir regression_removeFileOnDir
14701477
]
14711478

14721479
-- | Unused mount mount
@@ -1479,6 +1486,32 @@ tests tmpDir = testGroup "HasFS" [
14791486
mountUnused :: MountPoint
14801487
mountUnused = error "mount point not used during command generation"
14811488

1489+
-- | The error numbers returned by Linux vs. MacOS differ when using
1490+
-- 'removeFile' on a directory.
1491+
regression_removeFileOnDir :: QSM.Commands (At Cmd) (At Resp)
1492+
regression_removeFileOnDir = QSM.Commands {unCommands = [
1493+
QSM.Command
1494+
(At {unAt =
1495+
CreateDirIfMissing
1496+
True
1497+
(PExpPath (mkFsPath ["x"]))})
1498+
(At {unAt = Resp {getResp =
1499+
Right (Path (QSM.Reference (QSM.Symbolic (QSM.Var 0))) ())}})
1500+
[QSM.Var 0]
1501+
, QSM.Command
1502+
(At {unAt =
1503+
RemoveFile
1504+
(PExpPath (mkFsPath ["x"]))})
1505+
(At {unAt = Resp {getResp =
1506+
Left (FsError {
1507+
fsErrorType = FsResourceInappropriateType
1508+
, fsErrorPath = FsErrorPath Nothing (mkFsPath ["x"])
1509+
, fsErrorString = "expected file"
1510+
, fsErrorNo = Nothing
1511+
, fsErrorStack = prettyCallStack, fsLimitation = False})}})
1512+
[]
1513+
]}
1514+
14821515
{-------------------------------------------------------------------------------
14831516
Debugging
14841517
-------------------------------------------------------------------------------}

0 commit comments

Comments
 (0)