···171171 Fmt.pr "Connected.@.";
172172 (match Qemu.Vm.query_status vm with
173173 | Ok status -> Fmt.pr "Status: %a@." Qemu.Qmp.Status.pp status
174174- | Error e -> Fmt.epr "Status error: %s@." e);
174174+ | Error e ->
175175+ Fmt.epr "Status error: %s@." e);
175176 `Ok ()))
176177 $ name_arg $ cpus_arg $ memory_arg $ kernel_arg $ initrd_arg $ cmdline_arg
177178 $ disk_arg $ accel_arg $ kvm_arg $ no_kvm_arg $ socket_arg)
···376377 Fmt.epr "QMP error: %a@." Qemu.Qmp.Error.pp e;
377378 `Error (false, "QMP error")
378379 | Ok (Ok json) ->
379379- (match Json_bytesrw.encode_string Json.json json with
380380+ (match Json.to_string Json.Codec.Value.t json with
380381 | Ok s -> Fmt.pr "%s@." s
381381- | Error e -> Fmt.epr "JSON error: %s@." e);
382382+ | Error e ->
383383+ Fmt.epr "JSON error: %s@." (Json.Error.to_string e));
382384 `Ok ())))
383385 $ name_arg $ socket_arg $ command_arg)
384386 in
+79-73
lib/qmp_protocol.ml
···2222 { qemu = { major; minor; micro }; package }
23232424 let qemu_jsont =
2525- Json.Object.map ~kind:"qemu_version" (fun major minor micro ->
2525+ Json.Codec.Object.map ~kind:"qemu_version" (fun major minor micro ->
2626 { major; minor; micro })
2727- |> Json.Object.mem "major" Json.int ~enc:(fun v -> v.major)
2828- |> Json.Object.mem "minor" Json.int ~enc:(fun v -> v.minor)
2929- |> Json.Object.mem "micro" Json.int ~enc:(fun v -> v.micro)
3030- |> Json.Object.skip_unknown |> Json.Object.finish
2727+ |> Json.Codec.Object.mem "major" Json.Codec.int ~enc:(fun v -> v.major)
2828+ |> Json.Codec.Object.mem "minor" Json.Codec.int ~enc:(fun v -> v.minor)
2929+ |> Json.Codec.Object.mem "micro" Json.Codec.int ~enc:(fun v -> v.micro)
3030+ |> Json.Codec.Object.skip_unknown |> Json.Codec.Object.finish
31313232 let jsont =
3333- Json.Object.map ~kind:"version" (fun qemu package -> { qemu; package })
3434- |> Json.Object.mem "qemu" qemu_jsont ~enc:(fun v -> v.qemu)
3535- |> Json.Object.mem "package" Json.string ~enc:(fun v -> v.package)
3636- |> Json.Object.skip_unknown |> Json.Object.finish
3333+ Json.Codec.Object.map ~kind:"version" (fun qemu package ->
3434+ { qemu; package })
3535+ |> Json.Codec.Object.mem "qemu" qemu_jsont ~enc:(fun v -> v.qemu)
3636+ |> Json.Codec.Object.mem "package" Json.Codec.string ~enc:(fun v ->
3737+ v.package)
3838+ |> Json.Codec.Object.skip_unknown |> Json.Codec.Object.finish
37393840 let pp ppf v =
3941 Fmt.pf ppf "%d.%d.%d%s" v.qemu.major v.qemu.minor v.qemu.micro
···4547 type t = { qmp : qmp_info }
46484749 let qmp_info_jsont =
4848- Json.Object.map ~kind:"qmp_info" (fun version capabilities ->
5050+ Json.Codec.Object.map ~kind:"qmp_info" (fun version capabilities ->
4951 { version; capabilities })
5050- |> Json.Object.mem "version" Version.jsont ~enc:(fun q -> q.version)
5151- |> Json.Object.mem "capabilities" (Json.list Json.string) ~enc:(fun q ->
5252- q.capabilities)
5353- |> Json.Object.skip_unknown |> Json.Object.finish
5252+ |> Json.Codec.Object.mem "version" Version.jsont ~enc:(fun q -> q.version)
5353+ |> Json.Codec.Object.mem "capabilities" (Json.Codec.list Json.Codec.string)
5454+ ~enc:(fun q -> q.capabilities)
5555+ |> Json.Codec.Object.skip_unknown |> Json.Codec.Object.finish
54565557 let jsont =
5656- Json.Object.map ~kind:"greeting" (fun qmp -> { qmp })
5757- |> Json.Object.mem "QMP" qmp_info_jsont ~enc:(fun g -> g.qmp)
5858- |> Json.Object.skip_unknown |> Json.Object.finish
5858+ Json.Codec.Object.map ~kind:"greeting" (fun qmp -> { qmp })
5959+ |> Json.Codec.Object.mem "QMP" qmp_info_jsont ~enc:(fun g -> g.qmp)
6060+ |> Json.Codec.Object.skip_unknown |> Json.Codec.Object.finish
59616062 let version t = t.qmp.version
6163 let capabilities t = t.qmp.capabilities
···6567 type t = { seconds : int; microseconds : int }
66686769 let jsont =
6868- Json.Object.map ~kind:"timestamp" (fun seconds microseconds ->
7070+ Json.Codec.Object.map ~kind:"timestamp" (fun seconds microseconds ->
6971 { seconds; microseconds })
7070- |> Json.Object.mem "seconds" Json.int ~enc:(fun t -> t.seconds)
7171- |> Json.Object.mem "microseconds" Json.int ~enc:(fun t -> t.microseconds)
7272- |> Json.Object.skip_unknown |> Json.Object.finish
7272+ |> Json.Codec.Object.mem "seconds" Json.Codec.int ~enc:(fun t -> t.seconds)
7373+ |> Json.Codec.Object.mem "microseconds" Json.Codec.int ~enc:(fun t ->
7474+ t.microseconds)
7575+ |> Json.Codec.Object.skip_unknown |> Json.Codec.Object.finish
73767477 let to_float t = Float.of_int t.seconds +. (Float.of_int t.microseconds /. 1e6)
7578end
···7881 type t = { class_ : string; desc : string }
79828083 let jsont =
8181- Json.Object.map ~kind:"qmp_error" (fun class_ desc -> { class_; desc })
8282- |> Json.Object.mem "class" Json.string ~enc:(fun e -> e.class_)
8383- |> Json.Object.mem "desc" Json.string ~enc:(fun e -> e.desc)
8484- |> Json.Object.skip_unknown |> Json.Object.finish
8484+ Json.Codec.Object.map ~kind:"qmp_error" (fun class_ desc ->
8585+ { class_; desc })
8686+ |> Json.Codec.Object.mem "class" Json.Codec.string ~enc:(fun e -> e.class_)
8787+ |> Json.Codec.Object.mem "desc" Json.Codec.string ~enc:(fun e -> e.desc)
8888+ |> Json.Codec.Object.skip_unknown |> Json.Codec.Object.finish
85898690 let pp ppf e = Fmt.pf ppf "%s: %s" e.class_ e.desc
8791end
···9094 type t = { event : string; data : Json.t option; timestamp : Timestamp.t }
91959296 let jsont =
9393- Json.Object.map ~kind:"event" (fun event data timestamp ->
9797+ Json.Codec.Object.map ~kind:"event" (fun event data timestamp ->
9498 { event; data; timestamp })
9595- |> Json.Object.mem "event" Json.string ~enc:(fun e -> e.event)
9696- |> Json.Object.opt_mem "data" Json.json ~enc:(fun e -> e.data)
9797- |> Json.Object.mem "timestamp" Timestamp.jsont ~enc:(fun e -> e.timestamp)
9898- |> Json.Object.skip_unknown |> Json.Object.finish
9999+ |> Json.Codec.Object.mem "event" Json.Codec.string ~enc:(fun e -> e.event)
100100+ |> Json.Codec.Object.opt_mem "data" Json.Codec.Value.t ~enc:(fun e ->
101101+ e.data)
102102+ |> Json.Codec.Object.mem "timestamp" Timestamp.jsont ~enc:(fun e ->
103103+ e.timestamp)
104104+ |> Json.Codec.Object.skip_unknown |> Json.Codec.Object.finish
99105100106 let name t = t.event
101107 let data t = t.data
···105111(** {1 Commands} *)
106112107113module Command = struct
108108- type t = {
109109- execute : string;
110110- arguments : Json.t option;
111111- id : string option;
112112- }
114114+ type t = { execute : string; arguments : Json.t option; id : string option }
113115114116 let make ?arguments ?id execute = { execute; arguments; id }
115117116118 let jsont =
117117- Json.Object.map ~kind:"command" (fun execute arguments id ->
119119+ Json.Codec.Object.map ~kind:"command" (fun execute arguments id ->
118120 { execute; arguments; id })
119119- |> Json.Object.mem "execute" Json.string ~enc:(fun c -> c.execute)
120120- |> Json.Object.opt_mem "arguments" Json.json ~enc:(fun c -> c.arguments)
121121- |> Json.Object.opt_mem "id" Json.string ~enc:(fun c -> c.id)
122122- |> Json.Object.skip_unknown |> Json.Object.finish
121121+ |> Json.Codec.Object.mem "execute" Json.Codec.string ~enc:(fun c ->
122122+ c.execute)
123123+ |> Json.Codec.Object.opt_mem "arguments" Json.Codec.Value.t ~enc:(fun c ->
124124+ c.arguments)
125125+ |> Json.Codec.Object.opt_mem "id" Json.Codec.string ~enc:(fun c -> c.id)
126126+ |> Json.Codec.Object.skip_unknown |> Json.Codec.Object.finish
123127124128 let to_json t =
125125- match Json.Value.encode jsont t with
129129+ match Json.encode jsont t with
126130 | Ok json -> json
127127- | Error e -> Fmt.failwith "Failed to encode command: %s" e
131131+ | Error e ->
132132+ Fmt.failwith "Failed to encode command: %s" (Json.Error.to_string e)
128133129134 (* Common commands *)
130135 let qmp_capabilities = make "qmp_capabilities"
···147152 type t = Success of success | Error of error_response
148153149154 let success_jsont : success Json.codec =
150150- Json.Object.map ~kind:"success" (fun return success_id ->
155155+ Json.Codec.Object.map ~kind:"success" (fun return success_id ->
151156 { return; success_id })
152152- |> Json.Object.mem "return" Json.json ~enc:(fun s -> s.return)
153153- |> Json.Object.opt_mem "id" Json.string ~enc:(fun s -> s.success_id)
154154- |> Json.Object.skip_unknown |> Json.Object.finish
157157+ |> Json.Codec.Object.mem "return" Json.Codec.Value.t ~enc:(fun s ->
158158+ s.return)
159159+ |> Json.Codec.Object.opt_mem "id" Json.Codec.string ~enc:(fun s ->
160160+ s.success_id)
161161+ |> Json.Codec.Object.skip_unknown |> Json.Codec.Object.finish
155162156163 let error_jsont : error_response Json.codec =
157157- Json.Object.map ~kind:"error_response" (fun qmp_error error_id ->
164164+ Json.Codec.Object.map ~kind:"error_response" (fun qmp_error error_id ->
158165 { qmp_error; error_id })
159159- |> Json.Object.mem "error" Error.jsont ~enc:(fun e -> e.qmp_error)
160160- |> Json.Object.opt_mem "id" Json.string ~enc:(fun e -> e.error_id)
161161- |> Json.Object.skip_unknown |> Json.Object.finish
166166+ |> Json.Codec.Object.mem "error" Error.jsont ~enc:(fun e -> e.qmp_error)
167167+ |> Json.Codec.Object.opt_mem "id" Json.Codec.string ~enc:(fun e ->
168168+ e.error_id)
169169+ |> Json.Codec.Object.skip_unknown |> Json.Codec.Object.finish
162170end
163171164172(** {1 Message parsing} *)
···172180173181 (* Helper to check if an object has a member *)
174182 let has_member name = function
175175- | Json.Object (mems, _) -> Option.is_some (Json.Value.find_mem name mems)
183183+ | Json.Object (mems, _) -> Option.is_some (Json.find_mem name mems)
176184 | _ -> false
177185178178- let err_invalid_greeting e = Result.error (Fmt.str "Invalid greeting: %s" e)
179179- let err_invalid_event e = Result.error (Fmt.str "Invalid event: %s" e)
180180- let err_invalid_success e = Result.error (Fmt.str "Invalid success: %s" e)
181181- let err_invalid_error e = Result.error (Fmt.str "Invalid error: %s" e)
182182- let err_json_parse e = Result.error (Fmt.str "JSON parse error: %s" e)
186186+ let err e = Result.Error (Json.Error.to_string e)
183187184188 let of_json json =
185189 (* Try to detect message type by checking for key fields *)
186190 if has_member "QMP" json then
187187- match Json.Value.decode Greeting.jsont json with
191191+ match Json.decode Greeting.jsont json with
188192 | Ok g -> Ok (Greeting g)
189189- | Error e -> err_invalid_greeting e
193193+ | Error e -> err e
190194 else if has_member "event" json then
191191- match Json.Value.decode Event.jsont json with
195195+ match Json.decode Event.jsont json with
192196 | Ok e -> Ok (Event e)
193193- | Error e -> err_invalid_event e
197197+ | Error e -> err e
194198 else if has_member "return" json then
195195- match Json.Value.decode Response.success_jsont json with
199199+ match Json.decode Response.success_jsont json with
196200 | Ok s -> Ok (Success s)
197197- | Error e -> err_invalid_success e
201201+ | Error e -> err e
198202 else if has_member "error" json then
199199- match Json.Value.decode Response.error_jsont json with
203203+ match Json.decode Response.error_jsont json with
200204 | Ok e -> Ok (Error e)
201201- | Error e -> err_invalid_error e
205205+ | Error e -> err e
202206 else Error "Unknown QMP message type"
203207204208 let of_string s =
205205- match Json_bytesrw.decode_string Json.json s with
209209+ match Json.of_string Json.Codec.Value.t s with
206210 | Ok json -> of_json json
207207- | Error e -> err_json_parse e
211211+ | Error e -> err e
208212end
209213210214(** {1 Status types} *)
···268272 type t = { running : bool; singlestep : bool; status : run_state }
269273270274 let run_state_jsont =
271271- Json.enum ~kind:"run_state"
275275+ Json.Codec.enum ~kind:"run_state"
272276 [
273277 ("debug", Debug);
274278 ("inmigrate", Inmigrate);
···289293 ]
290294291295 let jsont =
292292- Json.Object.map ~kind:"status" (fun running singlestep status ->
296296+ Json.Codec.Object.map ~kind:"status" (fun running singlestep status ->
293297 { running; singlestep; status })
294294- |> Json.Object.mem "running" Json.bool ~enc:(fun s -> s.running)
295295- |> Json.Object.mem "singlestep" Json.bool ~enc:(fun s -> s.singlestep)
296296- |> Json.Object.mem "status" run_state_jsont ~enc:(fun s -> s.status)
297297- |> Json.Object.skip_unknown |> Json.Object.finish
298298+ |> Json.Codec.Object.mem "running" Json.Codec.bool ~enc:(fun s -> s.running)
299299+ |> Json.Codec.Object.mem "singlestep" Json.Codec.bool ~enc:(fun s ->
300300+ s.singlestep)
301301+ |> Json.Codec.Object.mem "status" run_state_jsont ~enc:(fun s -> s.status)
302302+ |> Json.Codec.Object.skip_unknown |> Json.Codec.Object.finish
298303299299- let of_json json = Json.Value.decode jsont json
304304+ let of_json json =
305305+ Result.map_error Json.Error.to_string (Json.decode jsont json)
300306301307 let pp ppf t =
302308 Fmt.pf ppf "%s%s"
+5-5
lib/vm.ml
···1010module Log = (val Logs.src_log src)
11111212let err_qmp e = Error (Fmt.str "%a" Qmp_protocol.Error.pp e)
1313+1314let err_greeting_read e = Error (Fmt.str "Failed to read greeting: %s" e)
14151516let err_capabilities e =
···242243 type t = {
243244 socket : Eio.Flow.two_way_ty Eio.Resource.t;
244245 buf_read : Eio.Buf_read.t;
245245- mutable greeting : Qmp_protocol.Greeting.t option;
246246 }
247247248248 let connect ~sw ~net socket_path =
···250250 Log.debug (fun m -> m "Connecting to QMP socket: %s" socket_path);
251251 let socket = Eio.Net.connect ~sw net addr in
252252 let buf_read = Eio.Buf_read.of_flow socket ~max_size:65536 in
253253- { socket :> Eio.Flow.two_way_ty Eio.Resource.t; buf_read; greeting = None }
253253+ { socket :> Eio.Flow.two_way_ty Eio.Resource.t; buf_read }
254254255255 let read_line t =
256256 try Some (Eio.Buf_read.line t.buf_read) with End_of_file -> None
···264264265265 let send_command t cmd =
266266 let json = Qmp_protocol.Command.to_json cmd in
267267- match Json_bytesrw.encode_string Json.json json with
267267+ match Json.to_string Json.Codec.Value.t json with
268268 | Ok s ->
269269 Log.debug (fun m -> m "Sending: %s" s);
270270 write_line t s
271271- | Error e -> Fmt.failwith "Failed to encode command: %s" e
271271+ | Error e ->
272272+ Fmt.failwith "Failed to encode command: %s" (Json.Error.to_string e)
272273273274 let receive_response t =
274275 let rec loop () =
···292293 match read_message t with
293294 | Error e -> err_greeting_read e
294295 | Ok (Qmp_protocol.Message.Greeting g) -> (
295295- t.greeting <- Some g;
296296 Log.info (fun m ->
297297 m "Connected to QEMU %a" Qmp_protocol.Version.pp
298298 (Qmp_protocol.Greeting.version g));
+16-14
test/test_qemu.ml
···1111module Qmp = Qemu.Qmp
12121313let parse_json s =
1414- match Json_bytesrw.decode_string Json.json s with
1414+ match Json.of_string Json.Codec.Value.t s with
1515 | Ok json -> json
1616- | Error e -> failwith e
1616+ | Error e -> failwith (Json.Error.to_string e)
17171818let check_message_ok msg json =
1919 match Qmp.Message.of_string json with
···271271let test_command_encode () =
272272 let cmd = Qmp.Command.query_status in
273273 let json = Qmp.Command.to_json cmd in
274274- match Json_bytesrw.encode_string Json.json json with
274274+ match Json.to_string Json.Codec.Value.t json with
275275 | Ok s ->
276276 Alcotest.(check bool)
277277 "contains execute" true
278278 (String.sub s 0 10 = "{\"execute\"")
279279- | Error e -> Alcotest.fail e
279279+ | Error e -> Alcotest.fail (Json.Error.to_string e)
280280281281let test_command_with_id () =
282282 let cmd = Qmp.Command.make ~id:"cookie#1" "query-name" in
283283 let json = Qmp.Command.to_json cmd in
284284 (* Roundtrip through Command codec *)
285285- match Json_bytesrw.encode_string Json.json json with
285285+ match Json.to_string Json.Codec.Value.t json with
286286 | Ok s -> (
287287- match Json_bytesrw.decode_string Qmp.Command.jsont s with
287287+ match Json.of_string Qmp.Command.jsont s with
288288 | Ok cmd' ->
289289 (* Encode again and check it still contains our id *)
290290 let json' = Qmp.Command.to_json cmd' in
291291 let s' =
292292- match Json_bytesrw.encode_string Json.json json' with
292292+ match Json.to_string Json.Codec.Value.t json' with
293293 | Ok s -> s
294294- | Error e -> Alcotest.failf "re-encode: %s" e
294294+ | Error e -> Alcotest.failf "re-encode: %s" (Json.Error.to_string e)
295295 in
296296 (* Both serializations should match *)
297297 Alcotest.(check string) "roundtrip" s s'
298298- | Error e -> Alcotest.failf "decode: %s" e)
299299- | Error e -> Alcotest.fail e
298298+ | Error e -> Alcotest.failf "decode: %s" (Json.Error.to_string e))
299299+ | Error e -> Alcotest.fail (Json.Error.to_string e)
300300301301let test_command_roundtrip () =
302302 let cmds =
···318318 List.iter
319319 (fun cmd ->
320320 let json = Qmp.Command.to_json cmd in
321321- match Json_bytesrw.encode_string Json.json json with
321321+ match Json.to_string Json.Codec.Value.t json with
322322 | Ok s -> (
323323- match Json_bytesrw.decode_string Qmp.Command.jsont s with
323323+ match Json.of_string Qmp.Command.jsont s with
324324 | Ok _ -> ()
325325- | Error e -> Alcotest.failf "roundtrip decode: %s" e)
326326- | Error e -> Alcotest.failf "roundtrip encode: %s" e)
325325+ | Error e ->
326326+ Alcotest.failf "roundtrip decode: %s" (Json.Error.to_string e))
327327+ | Error e ->
328328+ Alcotest.failf "roundtrip encode: %s" (Json.Error.to_string e))
327329 cmds
328330329331(* {1 Status parsing tests} *)
+20-20
test/test_qmp_protocol.ml
···1818module Qmp = Qemu.Qmp
19192020let parse_json s =
2121- match Json_bytesrw.decode_string Json.json s with
2121+ match Json.of_string Json.Codec.Value.t s with
2222 | Ok json -> json
2323- | Error e -> failwith e
2323+ | Error e -> failwith (Json.Error.to_string e)
24242525let encode_json json =
2626- match Json_bytesrw.encode_string Json.json json with
2626+ match Json.to_string Json.Codec.Value.t json with
2727 | Ok s -> s
2828- | Error e -> failwith e
2828+ | Error e -> failwith (Json.Error.to_string e)
29293030(* {1 Version codec tests} *)
31313232let test_version_make_roundtrip () =
3333 (* make -> jsont encode -> jsont decode -> check fields *)
3434 let v = Qmp.Version.make 9 0 0 "v9.0.0" in
3535- let json = Json.Value.encode Qmp.Version.jsont v in
3535+ let json = Json.encode Qmp.Version.jsont v in
3636 match json with
3737 | Ok json -> (
3838- match Json.Value.decode Qmp.Version.jsont json with
3838+ match Json.decode Qmp.Version.jsont json with
3939 | Ok v' ->
4040 Alcotest.(check int) "major" 9 v'.qemu.major;
4141 Alcotest.(check int) "minor" 0 v'.qemu.minor;
4242 Alcotest.(check int) "micro" 0 v'.qemu.micro;
4343 Alcotest.(check string) "package" "v9.0.0" v'.package
4444- | Error e -> Alcotest.failf "decode: %s" e)
4545- | Error e -> Alcotest.failf "encode: %s" e
4444+ | Error e -> Alcotest.failf "decode: %s" (Json.Error.to_string e))
4545+ | Error e -> Alcotest.failf "encode: %s" (Json.Error.to_string e)
46464747let test_version_high_numbers () =
4848 let v = Qmp.Version.make 99 12 3 "custom-build-2025" in
···5555 parse_json
5656 {|{"qemu": {"major": 7, "minor": 2, "micro": 5}, "package": "Debian 1:7.2+dfsg-7"}|}
5757 in
5858- match Json.Value.decode Qmp.Version.jsont json with
5858+ match Json.decode Qmp.Version.jsont json with
5959 | Ok v ->
6060 Alcotest.(check int) "major" 7 v.qemu.major;
6161 Alcotest.(check int) "minor" 2 v.qemu.minor;
6262 Alcotest.(check int) "micro" 5 v.qemu.micro;
6363 Alcotest.(check string) "package" "Debian 1:7.2+dfsg-7" v.package
6464- | Error e -> Alcotest.failf "decode: %s" e
6464+ | Error e -> Alcotest.failf "decode: %s" (Json.Error.to_string e)
65656666let test_version_extra_fields_ignored () =
6767 (* Jsont skip_unknown should tolerate extra fields *)
···6969 parse_json
7070 {|{"qemu": {"major": 8, "minor": 0, "micro": 0, "extra": true}, "package": "", "build-date": "2023-04"}|}
7171 in
7272- match Json.Value.decode Qmp.Version.jsont json with
7272+ match Json.decode Qmp.Version.jsont json with
7373 | Ok v ->
7474 Alcotest.(check int) "major" 8 v.qemu.major;
7575 Alcotest.(check string) "package" "" v.package
7676- | Error e -> Alcotest.failf "decode: %s" e
7676+ | Error e -> Alcotest.failf "decode: %s" (Json.Error.to_string e)
77777878(* {1 Greeting tests -- QEMU 9.0 spec vector} *)
7979···163163 (* The serialized form should contain "device_del" and the argument *)
164164 Alcotest.(check bool) "has execute" true (String.length s > 0);
165165 (* Roundtrip through codec *)
166166- match Json_bytesrw.decode_string Qmp.Command.jsont s with
166166+ match Json.of_string Qmp.Command.jsont s with
167167 | Ok _ -> ()
168168- | Error e -> Alcotest.failf "roundtrip: %s" e
168168+ | Error e -> Alcotest.failf "roundtrip: %s" (Json.Error.to_string e)
169169170170let test_command_with_id_args () =
171171 let args = parse_json {|{"protocol": "tcp", "hostname": "localhost"}|} in
172172 let cmd = Qmp.Command.make ~arguments:args ~id:"migrate-1" "migrate" in
173173 let json = Qmp.Command.to_json cmd in
174174 let s = encode_json json in
175175- match Json_bytesrw.decode_string Qmp.Command.jsont s with
175175+ match Json.of_string Qmp.Command.jsont s with
176176 | Ok _ -> ()
177177- | Error e -> Alcotest.failf "roundtrip: %s" e
177177+ | Error e -> Alcotest.failf "roundtrip: %s" (Json.Error.to_string e)
178178179179let test_command_blockdev_add () =
180180 (* More complex arguments -- blockdev-add with nested config *)
···185185 let cmd = Qmp.Command.make ~arguments:args "blockdev-add" in
186186 let json = Qmp.Command.to_json cmd in
187187 let s = encode_json json in
188188- match Json_bytesrw.decode_string Qmp.Command.jsont s with
188188+ match Json.of_string Qmp.Command.jsont s with
189189 | Ok _ -> ()
190190- | Error e -> Alcotest.failf "roundtrip: %s" e
190190+ | Error e -> Alcotest.failf "roundtrip: %s" (Json.Error.to_string e)
191191192192(* {1 Status run_state string roundtrip} *)
193193···303303304304let test_timestamp_jsont_roundtrip () =
305305 let json = parse_json {|{"seconds": 1267040730, "microseconds": 682951}|} in
306306- match Json.Value.decode Qmp.Timestamp.jsont json with
306306+ match Json.decode Qmp.Timestamp.jsont json with
307307 | Ok ts ->
308308 Alcotest.(check int) "seconds" 1267040730 ts.seconds;
309309 Alcotest.(check int) "microseconds" 682951 ts.microseconds
310310- | Error e -> Alcotest.failf "decode: %s" e
310310+ | Error e -> Alcotest.failf "decode: %s" (Json.Error.to_string e)
311311312312(* {1 Event data extraction} *)
313313