Skip to content

Commit d68c267

Browse files
committed
Collect _model functions in a Model module
1 parent ff23630 commit d68c267

File tree

1 file changed

+116
-113
lines changed

1 file changed

+116
-113
lines changed

src/sys/stm_tests.ml

Lines changed: 116 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -99,30 +99,96 @@ struct
9999

100100
let init_state = Directory {fs_map = Map_names.empty}
101101

102-
let rec find_opt_model fs path =
103-
match fs with
104-
| File ->
105-
if path = []
106-
then Some fs
107-
else None
108-
| Directory d ->
109-
(match path with
110-
| [] -> Some (Directory d)
111-
| hd :: tl ->
112-
(match Map_names.find_opt hd d.fs_map with
113-
| None -> None
114-
| Some fs -> find_opt_model fs tl))
115-
116-
let mem_model fs path = find_opt_model fs path <> None
102+
module Model =
103+
struct
104+
let rec find_opt fs path =
105+
match fs with
106+
| File ->
107+
if path = []
108+
then Some fs
109+
else None
110+
| Directory d ->
111+
(match path with
112+
| [] -> Some (Directory d)
113+
| hd :: tl ->
114+
(match Map_names.find_opt hd d.fs_map with
115+
| None -> None
116+
| Some fs -> find_opt fs tl))
117+
118+
let mem fs path = find_opt fs path <> None
119+
120+
(* generic removal function *)
121+
let rec remove fs path file_name =
122+
match fs with
123+
| File -> fs
124+
| Directory d ->
125+
(match path with
126+
| [] ->
127+
(match Map_names.find_opt file_name d.fs_map with
128+
| None
129+
| Some _ -> Directory { fs_map = Map_names.remove file_name d.fs_map })
130+
| dir::dirs ->
131+
Directory
132+
{ fs_map = Map_names.update dir (function
133+
| None -> None
134+
| Some File -> Some File
135+
| Some (Directory _ as d') -> Some (remove d' dirs file_name)) d.fs_map
136+
})
137+
138+
let readdir fs path =
139+
match find_opt fs path with
140+
| None -> None
141+
| Some fs ->
142+
(match fs with
143+
| File -> None
144+
| Directory d -> Some (Map_names.fold (fun k _ l -> k::l) d.fs_map []))
145+
146+
(* generic insertion function *)
147+
let rec insert fs path new_file_name sub_tree =
148+
match fs with
149+
| File -> fs
150+
| Directory d ->
151+
(match path with
152+
| [] ->
153+
Directory {fs_map = Map_names.add new_file_name sub_tree d.fs_map}
154+
| next_in_path :: tl_path ->
155+
(match Map_names.find_opt next_in_path d.fs_map with
156+
| None -> fs
157+
| Some sub_fs ->
158+
let nfs = insert sub_fs tl_path new_file_name sub_tree in
159+
if nfs = sub_fs
160+
then fs
161+
else Directory {fs_map = update_map_name d.fs_map next_in_path nfs}))
162+
163+
let separate_path path =
164+
match List.rev path with
165+
| [] -> None
166+
| name::rev_path -> Some (List.rev rev_path, name)
167+
168+
let rename fs old_path new_path =
169+
match separate_path old_path, separate_path new_path with
170+
| None, _
171+
| _, None -> fs
172+
| Some (old_path_pref, old_name), Some (new_path_pref, new_name) ->
173+
(match find_opt fs new_path_pref with
174+
| None
175+
| Some File -> fs
176+
| Some (Directory _) ->
177+
(match find_opt fs old_path with
178+
| None -> fs
179+
| Some sub_fs ->
180+
let fs' = remove fs old_path_pref old_name in
181+
insert fs' new_path_pref new_name sub_fs))
182+
end
117183

118184
let path_is_a_dir fs path =
119-
match find_opt_model fs path with
185+
match Model.find_opt fs path with
120186
| None
121187
| Some File -> false
122188
| Some (Directory _) -> true
123189

124190
let path_is_a_file fs path =
125-
match find_opt_model fs path with
191+
match Model.find_opt fs path with
126192
| None
127193
| Some (Directory _) -> false
128194
| Some File -> true
@@ -132,107 +198,44 @@ struct
132198
| [_] -> []
133199
| n::ns -> [n]::(List.map (fun p -> n::p) (path_prefixes ns))
134200

135-
let separate_path path =
136-
match List.rev path with
137-
| [] -> None
138-
| name::rev_path -> Some (List.rev rev_path, name)
139-
140201
let rec is_true_prefix path1 path2 = match path1, path2 with
141202
| [], [] -> false
142203
| [], _::_ -> true
143204
| _::_, [] -> false
144205
| n1::p1, n2::p2 -> n1=n2 && is_true_prefix p1 p2
145206

146-
(* generic removal function *)
147-
let rec remove_model fs path file_name =
148-
match fs with
149-
| File -> fs
150-
| Directory d ->
151-
(match path with
152-
| [] ->
153-
(match Map_names.find_opt file_name d.fs_map with
154-
| None
155-
| Some _ -> Directory { fs_map = Map_names.remove file_name d.fs_map })
156-
| dir::dirs ->
157-
Directory
158-
{ fs_map = Map_names.update dir (function
159-
| None -> None
160-
| Some File -> Some File
161-
| Some (Directory _ as d') -> Some (remove_model d' dirs file_name)) d.fs_map
162-
})
163-
164-
let readdir_model fs path =
165-
match find_opt_model fs path with
166-
| None -> None
167-
| Some fs ->
168-
(match fs with
169-
| File -> None
170-
| Directory d -> Some (Map_names.fold (fun k _ l -> k::l) d.fs_map []))
171-
172-
(* generic insertion function *)
173-
let rec insert_model fs path new_file_name sub_tree =
174-
match fs with
175-
| File -> fs
176-
| Directory d ->
177-
(match path with
178-
| [] ->
179-
Directory {fs_map = Map_names.add new_file_name sub_tree d.fs_map}
180-
| next_in_path :: tl_path ->
181-
(match Map_names.find_opt next_in_path d.fs_map with
182-
| None -> fs
183-
| Some sub_fs ->
184-
let nfs = insert_model sub_fs tl_path new_file_name sub_tree in
185-
if nfs = sub_fs
186-
then fs
187-
else Directory {fs_map = update_map_name d.fs_map next_in_path nfs}))
188-
189-
let rename_model fs old_path new_path =
190-
match separate_path old_path, separate_path new_path with
191-
| None, _
192-
| _, None -> fs
193-
| Some (old_path_pref, old_name), Some (new_path_pref, new_name) ->
194-
(match find_opt_model fs new_path_pref with
195-
| None
196-
| Some File -> fs
197-
| Some (Directory _) ->
198-
(match find_opt_model fs old_path with
199-
| None -> fs
200-
| Some sub_fs ->
201-
let fs' = remove_model fs old_path_pref old_name in
202-
insert_model fs' new_path_pref new_name sub_fs))
203-
204207
let next_state c fs =
205208
match c with
206209
| File_exists _path -> fs
207210
| Mkdir (path, new_dir_name) ->
208-
if mem_model fs (path @ [new_dir_name])
211+
if Model.mem fs (path @ [new_dir_name])
209212
then fs
210-
else insert_model fs path new_dir_name (Directory {fs_map = Map_names.empty})
213+
else Model.insert fs path new_dir_name (Directory {fs_map = Map_names.empty})
211214
| Remove (path, file_name) ->
212-
if find_opt_model fs (path @ [file_name]) = Some File
213-
then remove_model fs path file_name
215+
if Model.find_opt fs (path @ [file_name]) = Some File
216+
then Model.remove fs path file_name
214217
else fs
215218
| Rename (old_path, new_path) ->
216219
if is_true_prefix old_path new_path
217220
then fs
218221
else
219-
(match find_opt_model fs old_path with
222+
(match Model.find_opt fs old_path with
220223
| None -> fs
221224
| Some File ->
222-
if (not (mem_model fs new_path) || path_is_a_file fs new_path) then rename_model fs old_path new_path else fs
225+
if (not (Model.mem fs new_path) || path_is_a_file fs new_path) then Model.rename fs old_path new_path else fs
223226
| Some (Directory _) ->
224-
if (not (mem_model fs new_path) || readdir_model fs new_path = Some []) then rename_model fs old_path new_path else fs)
227+
if (not (Model.mem fs new_path) || Model.readdir fs new_path = Some []) then Model.rename fs old_path new_path else fs)
225228
| Is_directory _path -> fs
226229
| Rmdir (path,delete_dir_name) ->
227230
let complete_path = path @ [delete_dir_name] in
228-
if mem_model fs complete_path && readdir_model fs complete_path = Some []
229-
then remove_model fs path delete_dir_name
231+
if Model.mem fs complete_path && Model.readdir fs complete_path = Some []
232+
then Model.remove fs path delete_dir_name
230233
else fs
231234
| Readdir _path -> fs
232235
| Mkfile (path, new_file_name) ->
233-
if mem_model fs (path @ [new_file_name])
236+
if Model.mem fs (path @ [new_file_name])
234237
then fs
235-
else insert_model fs path new_file_name File
238+
else Model.insert fs path new_file_name File
236239

237240
let init_sut () =
238241
try Sys.mkdir sandbox_root 0o700
@@ -270,24 +273,24 @@ struct
270273

271274
let postcond c (fs: filesys) res =
272275
match c, res with
273-
| File_exists path, Res ((Bool,_),b) -> b = mem_model fs path
276+
| File_exists path, Res ((Bool,_),b) -> b = Model.mem fs path
274277
| Is_directory path, Res ((Result (Bool,Exn),_),res) ->
275278
(match res with
276279
| Ok b ->
277-
(match find_opt_model fs path with
280+
(match Model.find_opt fs path with
278281
| Some (Directory _) -> b = true
279282
| Some File -> b = false
280283
| None -> false)
281284
| Error (Sys_error s) ->
282-
(s = (p path) ^ ": No such file or directory" && not (mem_model fs path)) ||
285+
(s = (p path) ^ ": No such file or directory" && not (Model.mem fs path)) ||
283286
(s = p path ^ ": Not a directory" && List.exists (fun pref -> not (path_is_a_dir fs pref)) (path_prefixes path))
284287
| _ -> false)
285288
| Remove (path, file_name), Res ((Result (Unit,Exn),_), res) ->
286289
let complete_path = (path @ [file_name]) in
287290
(match res with
288-
| Ok () -> mem_model fs complete_path && path_is_a_dir fs path && not (path_is_a_dir fs complete_path)
291+
| Ok () -> Model.mem fs complete_path && path_is_a_dir fs path && not (path_is_a_dir fs complete_path)
289292
| Error (Sys_error s) ->
290-
(s = (p complete_path) ^ ": No such file or directory" && not (mem_model fs complete_path)) ||
293+
(s = (p complete_path) ^ ": No such file or directory" && not (Model.mem fs complete_path)) ||
291294
(s = (p complete_path) ^ ": Is a directory" && path_is_a_dir fs complete_path) || (*Linux*)
292295
(s = (p complete_path) ^ ": Operation not permitted" && path_is_a_dir fs complete_path) || (*macOS*)
293296
(s = (p complete_path) ^ ": Permission denied" && path_is_a_dir fs complete_path) || (*Win*)
@@ -296,18 +299,18 @@ struct
296299
)
297300
| Rename (old_path, new_path), Res ((Result (Unit,Exn),_), res) ->
298301
(match res with
299-
| Ok () -> mem_model fs old_path
302+
| Ok () -> Model.mem fs old_path
300303
| Error (Sys_error s) ->
301304
(s = "No such file or directory" &&
302-
not (mem_model fs old_path) || List.exists (fun pref -> not (path_is_a_dir fs pref)) (path_prefixes new_path)) ||
305+
not (Model.mem fs old_path) || List.exists (fun pref -> not (path_is_a_dir fs pref)) (path_prefixes new_path)) ||
303306
(s = "Invalid argument" && is_true_prefix old_path new_path) ||
304307
(s = "Not a directory" &&
305308
List.exists (path_is_a_file fs) (path_prefixes old_path) ||
306309
List.exists (path_is_a_file fs) (path_prefixes new_path) ||
307-
path_is_a_dir fs old_path && mem_model fs new_path && not (path_is_a_dir fs new_path)) ||
310+
path_is_a_dir fs old_path && Model.mem fs new_path && not (path_is_a_dir fs new_path)) ||
308311
(s = "Is a directory" && path_is_a_dir fs new_path) ||
309312
(s = "Directory not empty" &&
310-
is_true_prefix new_path old_path || (path_is_a_dir fs new_path && not (readdir_model fs new_path = Some [])))
313+
is_true_prefix new_path old_path || (path_is_a_dir fs new_path && not (Model.readdir fs new_path = Some [])))
311314
| Error _ -> false)
312315
| Mkdir (path, new_dir_name), Res ((Result (Unit,Exn),_), res) ->
313316
let complete_path = (path @ [new_dir_name]) in
@@ -316,47 +319,47 @@ struct
316319
(match err with
317320
| Sys_error s ->
318321
(s = (p complete_path) ^ ": Permission denied") ||
319-
(s = (p complete_path) ^ ": File exists" && mem_model fs complete_path) ||
322+
(s = (p complete_path) ^ ": File exists" && Model.mem fs complete_path) ||
320323
((s = (p complete_path) ^ ": No such file or directory"
321-
|| s = (p complete_path) ^ ": Invalid argument") && not (mem_model fs path)) ||
324+
|| s = (p complete_path) ^ ": Invalid argument") && not (Model.mem fs path)) ||
322325
if Sys.win32 && not (path_is_a_dir fs complete_path)
323326
then s = (p complete_path) ^ ": No such file or directory"
324327
else s = (p complete_path) ^ ": Not a directory"
325328
| _ -> false)
326-
| Ok () -> mem_model fs path && path_is_a_dir fs path && not (mem_model fs complete_path))
329+
| Ok () -> Model.mem fs path && path_is_a_dir fs path && not (Model.mem fs complete_path))
327330
| Rmdir (path, delete_dir_name), Res ((Result (Unit,Exn),_), res) ->
328331
let complete_path = (path @ [delete_dir_name]) in
329332
(match res with
330333
| Error err ->
331334
(match err with
332335
| Sys_error s ->
333336
(s = (p complete_path) ^ ": Permission denied") ||
334-
(s = (p complete_path) ^ ": Directory not empty" && not (readdir_model fs complete_path = Some [])) ||
335-
(s = (p complete_path) ^ ": No such file or directory" && not (mem_model fs complete_path)) ||
337+
(s = (p complete_path) ^ ": Directory not empty" && not (Model.readdir fs complete_path = Some [])) ||
338+
(s = (p complete_path) ^ ": No such file or directory" && not (Model.mem fs complete_path)) ||
336339
if Sys.win32 && not (path_is_a_dir fs complete_path) (* if not a directory *)
337340
then s = (p complete_path) ^ ": Invalid argument"
338341
else s = (p complete_path) ^ ": Not a directory"
339342
| _ -> false)
340343
| Ok () ->
341-
mem_model fs complete_path && path_is_a_dir fs complete_path && readdir_model fs complete_path = Some [])
344+
Model.mem fs complete_path && path_is_a_dir fs complete_path && Model.readdir fs complete_path = Some [])
342345
| Readdir path, Res ((Result (Array String,Exn),_), res) ->
343346
(match res with
344347
| Error err ->
345348
(match err with
346349
| Sys_error s ->
347350
(s = (p path) ^ ": Permission denied") ||
348-
(s = (p path) ^ ": No such file or directory" && not (mem_model fs path)) ||
351+
(s = (p path) ^ ": No such file or directory" && not (Model.mem fs path)) ||
349352
if Sys.win32 && not (path_is_a_dir fs path) (* if not a directory *)
350353
then s = (p path) ^ ": Invalid argument"
351354
else s = (p path) ^ ": Not a directory"
352355
| _ -> false)
353356
| Ok array_of_subdir ->
354357
(* Temporary work around for mingW, see https://github.com/ocaml/ocaml/issues/11829 *)
355-
if Sys.win32 && not (mem_model fs path)
358+
if Sys.win32 && not (Model.mem fs path)
356359
then array_of_subdir = [||]
357360
else
358-
(mem_model fs path && path_is_a_dir fs path &&
359-
(match readdir_model fs path with
361+
(Model.mem fs path && path_is_a_dir fs path &&
362+
(match Model.readdir fs path with
360363
| None -> false
361364
| Some l ->
362365
List.sort String.compare l
@@ -384,11 +387,11 @@ struct
384387
| Error err -> (
385388
match err with
386389
| Sys_error s ->
387-
(mem_model fs complete_path && match_msgs s msgs_already_exists)
388-
|| (not (mem_model fs path) && match_msgs s msgs_non_existent_dir)
390+
(Model.mem fs complete_path && match_msgs s msgs_already_exists)
391+
|| (not (Model.mem fs path) && match_msgs s msgs_non_existent_dir)
389392
|| (not (path_is_a_dir fs path) && match_msg s msg_path_not_dir)
390393
| _ -> false)
391-
| Ok () -> path_is_a_dir fs path && not (mem_model fs complete_path))
394+
| Ok () -> path_is_a_dir fs path && not (Model.mem fs complete_path))
392395
| _,_ -> false
393396
end
394397

0 commit comments

Comments
 (0)