mirror of
https://github.com/libguestfs/libguestfs.git
synced 2026-03-22 07:03:38 +00:00
builder: add Index.write_entry function
Add a function to properly write virt-builder source index entries. Note that this function is very similar to Index.print_entry that is meant for debugging purposes.
This commit is contained in:
committed by
Richard W.M. Jones
parent
0933d2d818
commit
7e3689bfe0
1
.gitignore
vendored
1
.gitignore
vendored
@@ -90,6 +90,7 @@ Makefile.in
|
||||
/builder/*.img
|
||||
/builder/index-parse.c
|
||||
/builder/index-parse.h
|
||||
/builder/index_parser_tests
|
||||
/builder/index-scan.c
|
||||
/builder/libguestfs.conf
|
||||
/builder/opensuse.conf
|
||||
|
||||
@@ -21,6 +21,7 @@ AM_YFLAGS = -d
|
||||
|
||||
EXTRA_DIST = \
|
||||
$(SOURCES_MLI) $(SOURCES_ML) $(SOURCES_C) \
|
||||
index_parser_tests.ml \
|
||||
libguestfs.gpg \
|
||||
opensuse.gpg \
|
||||
test-console.sh \
|
||||
@@ -240,13 +241,38 @@ yajl_tests_BOBJECTS = \
|
||||
yajl_tests.cmo
|
||||
yajl_tests_XOBJECTS = $(yajl_tests_BOBJECTS:.cmo=.cmx)
|
||||
|
||||
index_parser_tests_SOURCES = \
|
||||
index-scan.c \
|
||||
index-struct.c \
|
||||
index-parser-c.c \
|
||||
index-parse.c \
|
||||
yajl-c.c
|
||||
index_parser_tests_CPPFLAGS = $(virt_builder_CPPFLAGS)
|
||||
index_parser_tests_BOBJECTS = \
|
||||
yajl.cmo \
|
||||
utils.cmo \
|
||||
cache.cmo \
|
||||
downloader.cmo \
|
||||
sigchecker.cmo \
|
||||
index.cmo \
|
||||
ini_reader.cmo \
|
||||
index_parser.cmo \
|
||||
index_parser_tests.cmo
|
||||
index_parser_tests_XOBJECTS = $(index_parser_tests_BOBJECTS:.cmo=.cmx)
|
||||
|
||||
# Can't call the following as <test>_OBJECTS because automake gets confused.
|
||||
if HAVE_OCAMLOPT
|
||||
yajl_tests_THEOBJECTS = $(yajl_tests_XOBJECTS)
|
||||
yajl_tests.cmx: OCAMLPACKAGES += $(OCAMLPACKAGES_TESTS)
|
||||
|
||||
index_parser_tests_THEOBJECTS = $(index_parser_tests_XOBJECTS)
|
||||
index_parser_tests.cmx: OCAMLPACKAGES += $(OCAMLPACKAGES_TESTS)
|
||||
else
|
||||
yajl_tests_THEOBJECTS = $(yajl_tests_BOBJECTS)
|
||||
yajl_tests.cmo: OCAMLPACKAGES += $(OCAMLPACKAGES_TESTS)
|
||||
|
||||
index_parser_tests_THEOBJECTS = $(index_parser_tests_BOBJECTS)
|
||||
index_parser_tests.cmo: OCAMLPACKAGES += $(OCAMLPACKAGES_TESTS)
|
||||
endif
|
||||
|
||||
yajl_tests_DEPENDENCIES = \
|
||||
@@ -262,6 +288,15 @@ yajl_tests_LINK = \
|
||||
$(OCAMLFIND) $(BEST) $(OCAMLFLAGS) $(OCAMLPACKAGES) $(OCAMLPACKAGES_TESTS) $(OCAMLLINKFLAGS) \
|
||||
$(yajl_tests_THEOBJECTS) -o $@
|
||||
|
||||
index_parser_tests_DEPENDENCIES = \
|
||||
$(index_parser_tests_THEOBJECTS) \
|
||||
../common/mltools/mltools.$(MLARCHIVE) \
|
||||
$(top_srcdir)/ocaml-link.sh
|
||||
index_parser_tests_LINK = \
|
||||
$(top_srcdir)/ocaml-link.sh -cclib '$(OCAMLCLIBS)' -- \
|
||||
$(OCAMLFIND) $(BEST) $(OCAMLFLAGS) $(OCAMLPACKAGES) $(OCAMLPACKAGES_TESTS) $(OCAMLLINKFLAGS) \
|
||||
$(index_parser_tests_THEOBJECTS) -o $@
|
||||
|
||||
TESTS = \
|
||||
test-docs.sh \
|
||||
test-virt-builder-list.sh \
|
||||
@@ -275,8 +310,8 @@ if ENABLE_APPLIANCE
|
||||
TESTS += test-virt-builder.sh
|
||||
endif ENABLE_APPLIANCE
|
||||
if HAVE_OCAML_PKG_OUNIT
|
||||
check_PROGRAMS += yajl_tests
|
||||
TESTS += yajl_tests
|
||||
check_PROGRAMS += yajl_tests index_parser_tests
|
||||
TESTS += yajl_tests index_parser_tests
|
||||
endif
|
||||
|
||||
check-valgrind:
|
||||
|
||||
@@ -39,3 +39,6 @@ and entry = {
|
||||
}
|
||||
|
||||
val print_entry : out_channel -> (string * entry) -> unit
|
||||
(** Debugging helper function dumping an index entry to a stream.
|
||||
To write entries for non-debugging purpose, use the
|
||||
[Index_parser.write_entry] function. *)
|
||||
|
||||
@@ -226,3 +226,46 @@ let get_index ~downloader ~sigchecker { Sources.uri; proxy } =
|
||||
in
|
||||
|
||||
get_index ()
|
||||
|
||||
let write_entry chan (name, { Index.printable_name; file_uri; arch; osinfo;
|
||||
signature_uri; checksums; revision; format; size;
|
||||
compressed_size; expand; lvexpand; notes;
|
||||
aliases; hidden}) =
|
||||
let fp fs = fprintf chan fs in
|
||||
fp "[%s]\n" name;
|
||||
Option.may (fp "name=%s\n") printable_name;
|
||||
Option.may (fp "osinfo=%s\n") osinfo;
|
||||
fp "file=%s\n" file_uri;
|
||||
fp "arch=%s\n" arch;
|
||||
Option.may (fp "sig=%s\n") signature_uri;
|
||||
(match checksums with
|
||||
| None -> ()
|
||||
| Some checksums ->
|
||||
List.iter (
|
||||
fun c ->
|
||||
fp "checksum[%s]=%s\n"
|
||||
(Checksums.string_of_csum_t c) (Checksums.string_of_csum c)
|
||||
) checksums
|
||||
);
|
||||
fp "revision=%s\n" (string_of_revision revision);
|
||||
Option.may (fp "format=%s\n") format;
|
||||
fp "size=%Ld\n" size;
|
||||
Option.may (fp "compressed_size=%Ld\n") compressed_size;
|
||||
Option.may (fp "expand=%s\n") expand;
|
||||
Option.may (fp "lvexpand=%s\n") lvexpand;
|
||||
|
||||
let format_notes notes =
|
||||
String.concat "\n " (String.nsplit "\n" notes) in
|
||||
|
||||
List.iter (
|
||||
fun (lang, notes) ->
|
||||
match lang with
|
||||
| "" -> fp "notes=%s\n" (format_notes notes)
|
||||
| lang -> fp "notes[%s]=%s\n" lang (format_notes notes)
|
||||
) notes;
|
||||
(match aliases with
|
||||
| None -> ()
|
||||
| Some l -> fp "aliases=%s\n" (String.concat " " l)
|
||||
);
|
||||
if hidden then fp "hidden=true\n";
|
||||
fp "\n"
|
||||
|
||||
@@ -17,3 +17,7 @@
|
||||
*)
|
||||
|
||||
val get_index : downloader:Downloader.t -> sigchecker:Sigchecker.t -> Sources.source -> Index.index
|
||||
|
||||
val write_entry : out_channel -> (string * Index.entry) -> unit
|
||||
(** [write_entry chan entry] writes the index entry to the chan output
|
||||
stream.*)
|
||||
|
||||
130
builder/index_parser_tests.ml
Normal file
130
builder/index_parser_tests.ml
Normal file
@@ -0,0 +1,130 @@
|
||||
(* builder
|
||||
* Copyright (C) 2017 SUSE Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*)
|
||||
|
||||
(* This file tests the Index_parser module. *)
|
||||
|
||||
open Printf
|
||||
|
||||
open OUnit2
|
||||
|
||||
open Std_utils
|
||||
open Unix_utils
|
||||
open Tools_utils
|
||||
|
||||
let tmpdir =
|
||||
let tmpdir = Mkdtemp.temp_dir "guestfs-tests." in
|
||||
rmdir_on_exit tmpdir;
|
||||
tmpdir
|
||||
|
||||
let dummy_sigchecker = Sigchecker.create ~gpg:"gpg"
|
||||
~check_signature:false
|
||||
~gpgkey:Utils.No_Key
|
||||
~tmpdir
|
||||
|
||||
let dummy_downloader = Downloader.create ~curl:"do-not-use-curl"
|
||||
~cache:None ~tmpdir
|
||||
|
||||
(* Utils. *)
|
||||
let write_entries file entries =
|
||||
let chan = open_out (tmpdir // file) in
|
||||
List.iter (Index_parser.write_entry chan) entries;
|
||||
close_out chan
|
||||
|
||||
let read_file file =
|
||||
read_whole_file (tmpdir // "out")
|
||||
|
||||
let parse_file file =
|
||||
let source = { Sources.name = "input";
|
||||
uri = tmpdir // file;
|
||||
gpgkey = Utils.No_Key;
|
||||
proxy = Curl.SystemProxy;
|
||||
format = Sources.FormatNative } in
|
||||
let entries = Index_parser.get_index ~downloader:dummy_downloader
|
||||
~sigchecker:dummy_sigchecker
|
||||
source in
|
||||
List.map (
|
||||
fun (id, e) -> (id, { e with Index.file_uri = Filename.basename e.Index.file_uri })
|
||||
) entries
|
||||
|
||||
let format_entries entries =
|
||||
let format_entry entry =
|
||||
write_entries "out" [entry];
|
||||
read_file "out" in
|
||||
List.map format_entry entries
|
||||
|
||||
let assert_equal_string = assert_equal ~printer:(fun x -> sprintf "\"%s\"" x)
|
||||
let assert_equal_list formatter =
|
||||
let printer = (
|
||||
fun x -> "(" ^ (String.escaped (String.concat "," (formatter x))) ^ ")"
|
||||
) in
|
||||
assert_equal ~printer
|
||||
|
||||
let test_write_complete ctx =
|
||||
let entry =
|
||||
("test-id", { Index.printable_name = Some "test_name";
|
||||
osinfo = Some "osinfo_data";
|
||||
file_uri = "image_path";
|
||||
arch = "test_arch";
|
||||
signature_uri = None;
|
||||
checksums = Some [Checksums.SHA512 "512checksum"];
|
||||
revision = Utils.Rev_int 42;
|
||||
format = Some "qcow2";
|
||||
size = Int64.of_int 123456;
|
||||
compressed_size = Some (Int64.of_int 12345);
|
||||
expand = Some "/dev/sda1";
|
||||
lvexpand = Some "/some/lv";
|
||||
notes = [ ("", "Notes split\non several lines\n\n with starting space ") ];
|
||||
hidden = false;
|
||||
aliases = Some ["alias1"; "alias2"];
|
||||
sigchecker = dummy_sigchecker;
|
||||
proxy = Curl.SystemProxy }) in
|
||||
|
||||
write_entries "out" [entry];
|
||||
let actual = read_file "out" in
|
||||
let expected = "[test-id]
|
||||
name=test_name
|
||||
osinfo=osinfo_data
|
||||
file=image_path
|
||||
arch=test_arch
|
||||
checksum[sha512]=512checksum
|
||||
revision=42
|
||||
format=qcow2
|
||||
size=123456
|
||||
compressed_size=12345
|
||||
expand=/dev/sda1
|
||||
lvexpand=/some/lv
|
||||
notes=Notes split
|
||||
on several lines
|
||||
|
||||
with starting space
|
||||
aliases=alias1 alias2
|
||||
|
||||
" in
|
||||
assert_equal_string expected actual;
|
||||
|
||||
let parsed_entries = parse_file "out" in
|
||||
assert_equal_list format_entries [entry] parsed_entries
|
||||
|
||||
let suite =
|
||||
"builder Index_parser" >:::
|
||||
[
|
||||
"write.complete" >:: test_write_complete;
|
||||
]
|
||||
|
||||
let () =
|
||||
run_test_tt_main suite
|
||||
Reference in New Issue
Block a user