Skip to content

Commit a91635e

Browse files
authored
Merge pull request #5784 from Vincent-lau/private/shul2/check-param
Add new check for new parameters' default value
2 parents d7ce84f + 0416e2a commit a91635e

File tree

4 files changed

+80
-24
lines changed

4 files changed

+80
-24
lines changed

ocaml/idl/dm_api.ml

Lines changed: 41 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -364,33 +364,19 @@ let check api emergency_calls =
364364
in
365365
(* Sanity check 7: message parameters must be in increasing order of in_product_since *)
366366
let are_in_vsn_order ps =
367-
let rec getlast l =
368-
(* TODO: move to standard library *)
369-
match l with
370-
| [x] ->
371-
x
372-
| _ :: xs ->
373-
getlast xs
374-
| [] ->
375-
raise (Invalid_argument "getlast")
376-
in
377367
let release_lt x y = release_leq x y && x <> y in
378368
let in_since releases =
379369
(* been in since the lowest of releases *)
380-
let rec find_smallest sofar l =
381-
match l with
382-
| [] ->
383-
sofar
384-
| "closed" :: xs ->
385-
find_smallest sofar xs
386-
(* closed is not a real release, so skip it *)
387-
| x :: xs ->
388-
if release_lt x sofar then
389-
find_smallest x xs
390-
else
391-
find_smallest sofar xs
392-
in
393-
find_smallest (getlast release_order |> code_name_of_release) releases
370+
List.fold_left
371+
(fun sofar r ->
372+
match r with
373+
| "closed" ->
374+
sofar (* closed is not a real release, so skip it *)
375+
| r ->
376+
if release_lt r sofar then r else sofar
377+
)
378+
(Xapi_stdext_std.Listext.List.last release_order |> code_name_of_release)
379+
releases
394380
in
395381
let rec check_vsns max_release_sofar ps =
396382
match ps with
@@ -444,4 +430,35 @@ let check api emergency_calls =
444430
)
445431
system
446432
in
433+
(* Sanity check 9: New parameters must have a default value: we partially check
434+
this by checking in the list of parameters, after we have seen a parameter with
435+
a default value, other parameters after it must have defaults as well. Unfortunately
436+
checking parameters with newer releases does not work well as there are existing
437+
parameters with new releases but no default. *)
438+
let _ =
439+
let new_param_has_default obj_name msg_name ps =
440+
let _ : bool =
441+
List.fold_left
442+
(fun seen_default p ->
443+
if seen_default && Option.is_none p.param_default then
444+
Printf.sprintf
445+
"Obj %s Msg %s parameters %s does not have default values"
446+
obj_name msg_name p.param_name
447+
|> failwith ;
448+
449+
Option.is_some p.param_default
450+
)
451+
false ps
452+
in
453+
()
454+
in
455+
456+
List.iter
457+
(fun obj ->
458+
List.iter
459+
(fun msg -> new_param_has_default obj.name msg.msg_name msg.msg_params)
460+
obj.messages
461+
)
462+
system
463+
in
447464
()

ocaml/libs/xapi-stdext/lib/xapi-stdext-std/listext.ml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,14 @@ module List = struct
7676
in
7777
loop 0 list
7878

79+
let rec last = function
80+
| [] ->
81+
invalid_arg "last: empty list"
82+
| [x] ->
83+
x
84+
| _ :: xs ->
85+
last xs
86+
7987
let sub i j l = drop i l |> take (j - max i 0)
8088

8189
let rec chop i l =

ocaml/libs/xapi-stdext/lib/xapi-stdext-std/listext.mli

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ module List : sig
2727
(** [drop n list] returns the list without the first [n] elements of [list]
2828
(or [] if list is shorter). *)
2929

30+
val last : 'a list -> 'a
31+
(** [last l] returns the last element of a list or raise Invalid_argument if
32+
the list is empty *)
33+
3034
val rev_mapi : (int -> 'a -> 'b) -> 'a list -> 'b list
3135
(** [rev_map f l] gives the same result as {!Stdlib.List.rev}[ (]
3236
{!Stdlib.List.mapi}[ f l)], but is tail-recursive and more efficient. *)

ocaml/libs/xapi-stdext/lib/xapi-stdext-std/listext_test.ml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@
1313

1414
module Listext = Xapi_stdext_std.Listext.List
1515

16+
let test_last_list tested_f (name, case, expected) =
17+
let check () = Alcotest.(check @@ int) name expected (tested_f case) in
18+
(name, `Quick, check)
19+
1620
let test_list tested_f (name, case, expected) =
1721
let check () = Alcotest.(check @@ list int) name expected (tested_f case) in
1822
(name, `Quick, check)
@@ -109,6 +113,28 @@ let test_drop =
109113
let tests = List.map test specs in
110114
("drop", tests)
111115

116+
let test_last =
117+
let specs = [([1], 0, 1); ([1; 2; 3], 1, 3)] in
118+
let error_specs = [([], -1, Invalid_argument "last: empty list")] in
119+
let test_good (whole, number, expected) =
120+
let name =
121+
Printf.sprintf "get last %i from [%s]" number
122+
(String.concat "; " (List.map string_of_int whole))
123+
in
124+
test_last_list Listext.last (name, whole, expected)
125+
in
126+
let tests = List.map test_good specs in
127+
let error_test (whole, number, error) =
128+
let name =
129+
Printf.sprintf "last [%s] with %i fails"
130+
(String.concat "; " (List.map string_of_int whole))
131+
number
132+
in
133+
test_error (fun ls () -> ignore (Listext.last ls)) (name, whole, error)
134+
in
135+
let error_tests = List.map error_test error_specs in
136+
("last", tests @ error_tests)
137+
112138
let test_chop =
113139
let specs =
114140
[
@@ -233,6 +259,7 @@ let () =
233259
test_iteri_right
234260
; test_take
235261
; test_drop
262+
; test_last
236263
; test_chop
237264
; test_sub
238265
; test_find_minimum_int

0 commit comments

Comments
 (0)