• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

MinaProtocol / mina / 507

19 Aug 2025 11:53PM UTC coverage: 33.38% (-28.0%) from 61.334%
507

push

buildkite

web-flow
Merge pull request #17640 from MinaProtocol/georgeee/compatible-to-develop-2025-08-19

Merge `compatible` to `develop` (19 August 2025, pt. 2)

24170 of 72408 relevant lines covered (33.38%)

24770.87 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

6.15
/src/lib/disk_cache/test_lib/disk_cache_test_lib.ml
1
open Async
40✔
2
open Core
3

4
module Mock = struct
5
  type t = { proof : Mina_stdlib.Bounded_types.String.Stable.V1.t }
40✔
6
  [@@deriving bin_io_unversioned]
160✔
7
end
8

9
module type S = sig
10
  module Cache : sig
11
    type t
12

13
    type id
14
  end
15

16
  val logger : Logger.t
17

18
  val simple_write :
19
       ?additional_checks:
20
         (Cache.t * Mock.t * Mock.t * Cache.id * Cache.id -> unit)
21
    -> unit
22
    -> unit
23

24
  val initialization_special_cases : unit -> unit
25

26
  (** [remove_data_on_gc ?gc_strict ())] test behavior of cache on GC.
27
      If [gc_strict] is set to [false], then we won't check if the cache is
28
      empty after GC.
29
   *)
30
  val remove_data_on_gc : ?gc_strict:bool -> unit -> unit
31
end
32

33
module type S_extended = sig
34
  include S
35

36
  val simple_write_with_iteration : unit -> unit
37
end
38

39
module Make_impl (Cache : Disk_cache_intf.S_with_count with module Data := Mock) :
40
  S with module Cache := Cache = struct
41
  let () =
42
    Core.Backtrace.elide := false ;
43
    Async.Scheduler.set_record_backtraces true
×
44

45
  let logger = Logger.null ()
×
46

47
  let initialize_cache_or_fail tmpd ~logger =
48
    let open Deferred.Let_syntax in
×
49
    let%bind cache_res = Cache.initialize tmpd ~logger in
×
50
    match cache_res with
×
51
    | Ok cache ->
×
52
        return cache
53
    | Error _err ->
×
54
        failwith "error during initialization"
55

56
  let simple_write_impl ?(additional_checks = const ()) tmp_dir =
×
57
    let%map cache = initialize_cache_or_fail tmp_dir ~logger in
×
58

59
    let proof1 = Mock.{ proof = "dummy" } in
×
60
    let proof2 = Mock.{ proof = "smart" } in
61

62
    let id1 = Cache.put cache proof1 in
63
    let id2 = Cache.put cache proof2 in
×
64

65
    additional_checks (cache, proof1, proof2, id1, id2) ;
×
66

67
    [%test_eq: int] (Cache.count cache) 2
×
68
      ~message:"cache should contain only 2 elements" ;
69

70
    let proof_from_cache1 = Cache.get cache id1 in
×
71
    [%test_eq: string] proof1.proof proof_from_cache1.proof
×
72
      ~message:"invalid proof from cache" ;
73

74
    let proof_from_cache2 = Cache.get cache id2 in
×
75
    [%test_eq: string] proof2.proof proof_from_cache2.proof
×
76
      ~message:"invalid proof from cache"
77

78
  let simple_write ?additional_checks () =
79
    Async.Thread_safe.block_on_async_exn
×
80
    @@ fun () ->
81
    Mina_stdlib_unix.File_system.with_temp_dir "disk_cache"
×
82
      ~f:(simple_write_impl ?additional_checks)
83

84
  let remove_data_on_gc_impl ~gc_strict tmp_dir =
85
    let%map cache = initialize_cache_or_fail tmp_dir ~logger in
×
86

87
    let proof = Mock.{ proof = "dummy" } in
×
88

89
    (let id = Cache.put cache proof in
90

91
     [%test_eq: int] (Cache.count cache) 1
×
92
       ~message:"cache should contain only 1 element" ;
93

94
     let proof_from_cache = Cache.get cache id in
×
95
     [%test_eq: string] proof.proof proof_from_cache.proof
×
96
       ~message:"invalid proof from cache" ) ;
97

98
    if gc_strict then (
×
99
      Gc.compact () ;
100
      [%test_eq: int] (Cache.count cache) 0
×
101
        ~message:"cache should be empty after garbage collector run" )
102

103
  let remove_data_on_gc ?(gc_strict = true) () =
×
104
    Async.Thread_safe.block_on_async_exn
×
105
    @@ fun () ->
106
    Mina_stdlib_unix.File_system.with_temp_dir "disk_cache-remove_data_on_gc"
×
107
      ~f:(remove_data_on_gc_impl ~gc_strict)
108

109
  let initialize_and_expect_failure path ~logger =
110
    let%bind cache_res = Cache.initialize path ~logger in
×
111
    match cache_res with
×
112
    | Ok _ ->
×
113
        failwith "unexpected initialization success"
114
    | Error _err ->
×
115
        return ()
116

117
  let initialization_special_cases_impl tmp_dir =
118
    (* create a directory with 0x000 permissions and initialize from it *)
119
    let%bind () =
120
      let perm_denied_dir = tmp_dir ^/ "permission_denied" in
121
      Core.Unix.mkdir ~perm:0o000 perm_denied_dir ;
×
122
      let unreachable = perm_denied_dir ^/ "some_unreachable_path" in
×
123
      initialize_and_expect_failure unreachable ~logger
×
124
    in
125

126
    (* create a directory, create a symlink to it and initialize from a synlimk *)
127
    let%bind () =
128
      let some_dir_name = "some_dir" in
129
      let some_dir = tmp_dir ^/ some_dir_name in
130
      Core.Unix.mkdir some_dir ;
×
131
      let dir_symlink = tmp_dir ^/ "dir_link" in
×
132
      Core.Unix.symlink ~target:some_dir_name ~link_name:dir_symlink ;
×
133
      Cache.initialize dir_symlink ~logger
×
134
      >>| function
×
135
      | Ok _ ->
×
136
          ()
137
      | Error _ ->
×
138
          failwith "unexpected initialization failure for dir symlink"
139
    in
140

141
    (* create a symlink to a non-existent file, try to initialize from symlink *)
142
    let%bind () =
143
      let corrupt_symlink = tmp_dir ^/ "corrupt_link" in
144
      Core.Unix.symlink ~target:"doesnt_exist" ~link_name:corrupt_symlink ;
×
145
      initialize_and_expect_failure corrupt_symlink ~logger
×
146
    in
147

148
    (* create a file and initialize from it *)
149
    let%bind some_file_name =
150
      let some_file_name = "file.txt" in
151
      let some_file = tmp_dir ^/ some_file_name in
152
      Out_channel.write_all some_file ~data:"yo" ;
×
153
      initialize_and_expect_failure some_file ~logger >>| const some_file_name
×
154
    in
155

156
    (* create a symlink to an existing file, try to initialize from symlink *)
157
    let symlink = tmp_dir ^/ "link" in
×
158
    Core.Unix.symlink ~target:some_file_name ~link_name:symlink ;
×
159
    initialize_and_expect_failure symlink ~logger
160

161
  let initialization_special_cases () =
162
    Async.Thread_safe.block_on_async_exn
×
163
    @@ fun () ->
164
    Mina_stdlib_unix.File_system.with_temp_dir
×
165
      "disk_cache-invalid-initialization" ~f:initialization_special_cases_impl
166
end
167

168
module Make (Disk_cache : Disk_cache_intf.F_with_count) :
169
  S with module Cache := Disk_cache(Mock) = struct
170
  include Make_impl (Disk_cache (Mock))
171
end
172

173
module Make_extended (Disk_cache : Disk_cache_intf.F_extended) :
174
  S_extended with module Cache := Disk_cache(Mock) = struct
175
  module Cache = Disk_cache (Mock)
176
  include Make_impl (Cache)
177

178
  let iteration_checks (cache, proof1, proof2, id1, id2) =
179
    let id1_not_visited = ref true in
×
180
    let id2_not_visited = ref true in
181
    Cache.iteri cache ~f:(fun id content ->
182
        let expected_content =
×
183
          if id = Cache.int_of_id id1 then (
×
184
            assert !id1_not_visited ;
×
185
            id1_not_visited := false ;
186
            proof1 )
187
          else if id = Cache.int_of_id id2 then (
×
188
            assert !id2_not_visited ;
×
189
            id2_not_visited := false ;
190
            proof2 )
191
          else failwith "unexpected key in iteration"
×
192
        in
193
        [%test_eq: string] content.Mock.proof expected_content.Mock.proof ;
×
194
        `Continue ) ;
×
195
    assert ((not !id1_not_visited) && not !id2_not_visited)
×
196

197
  let simple_write_with_iteration =
198
    simple_write ~additional_checks:iteration_checks
199
end
80✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc