This commit is contained in:
swrup 2025-11-11 02:07:51 +01:00
parent aa2ff7b2f0
commit 2f3113f55d
11742 changed files with 1223940 additions and 0 deletions

View file

@ -0,0 +1,31 @@
open Cmdliner
let opt =
let doc = Arg.info ~doc:"An optional key." [ "opt" ] in
Arg.(value & opt string "default" doc)
let opt_all =
let doc = Arg.info ~doc:"All the optional keys." [ "opt-all" ] in
Arg.(value & opt_all string [] doc)
let flag =
let doc = Arg.info ~doc:"A flag." [ "flag" ] in
Arg.(value & flag doc)
let required =
let doc = Arg.info ~doc:"A required key." [ "required" ] in
Arg.(required & opt (some string) None doc)
let hello =
let doc = Arg.info ~doc:"How to say hello." [ "hello" ] in
Arg.(value @@ opt string "Hello World!" doc)
let arg =
let doc =
Arg.info ~docs:"APPLICATION OPTIONS" ~doc:"A runtime argument." [ "arg" ]
in
Arg.(value & opt string "-" doc)
module Make (_ : sig end) = struct
let start () hello arg = Fmt.pr "Success: hello=%s arg=%s\n%!" hello arg
end

View file

@ -0,0 +1,30 @@
open Functoria
open E2e
let opt = runtime_arg ~pos:__POS__ "App.opt"
let opt_all = runtime_arg ~pos:__POS__ "App.opt_all"
let flag = runtime_arg ~pos:__POS__ "App.flag"
let required = runtime_arg ~pos:__POS__ "App.required"
let runtime_args =
[ runtime_arg ~pos:__POS__ "App.hello"; runtime_arg ~pos:__POS__ "App.arg" ]
let keys =
let connect _ _ = function
| [ opt; opt_all; flag; required ] ->
code ~pos:__POS__
{|
let _ : string = %s
and _ : string list = %s
and _ : bool = %s
and _ : string = %s
in
return ()|}
opt opt_all flag required
| _ -> failwith "keys: connect needs exactly 4 arguments"
in
let runtime_args = [ opt; opt_all; flag; required ] in
impl ~connect ~runtime_args "Unit" job
let main = main ~runtime_args ~pos:__POS__ "App.Make" (job @-> job)
let () = register "noop" [ main $ keys ]

View file

@ -0,0 +1,73 @@
Build an application.
$ ./test.exe configure --file app/config.ml
test.exe: [WARNING] Skipping version check, since our_version ("1.0~test") fails to parse: only digits and . allowed in version
$ make build
dune build --profile release --root . app/dist
Your unikernel binary is now ready in app/dist/noop
Execute the binary using solo5-hvt, solo5-spt, xl, ...
$ ls -a app/
.
..
app.ml
config.ml
dist
dune
dune.build
dune.config
main.exe
test
$ ls -a app/test
.
..
context
dune-workspace.config
main.ml
noop.opam
vote
warn_error
$ ./app/main.exe --required=foo
Success: hello=Hello World! arg=-
$ ./test.exe clean --file app/config.ml
$ ls -a app/
.
..
app.ml
config.ml
Test `--output`:
$ ./test.exe configure --file app/config.ml -o toto
test.exe: [WARNING] Skipping version check, since our_version ("1.0~test") fails to parse: only digits and . allowed in version
$ make build
dune build --profile release --root . app/dist
Your unikernel binary is now ready in app/dist/toto
Execute the binary using solo5-hvt, solo5-spt, xl, ...
$ ls -a app/
.
..
app.ml
config.ml
dist
dune
dune.build
dune.config
test
toto.exe
$ ls -a app/test
.
..
context
dune-workspace.config
noop.opam
toto.ml
vote
warn_error
$ ./app/toto.exe --required=foo
Success: hello=Hello World! arg=-
$ ./test.exe clean --file app/config.ml
$ ls -a app/
.
..
app.ml
config.ml

View file

@ -0,0 +1,10 @@
Test that the cache is escaping entries correctly:
$ ./test.exe configure --file app/config.ml --vote="foo;;bar;;;\n\nllll;;;sdaads;;\n\t\0"
test.exe: [WARNING] Skipping version check, since our_version ("1.0~test") fails to parse: only digits and . allowed in version
$ make build
dune build --profile release --root . app/dist
Your unikernel binary is now ready in app/dist/noop
Execute the binary using solo5-hvt, solo5-spt, xl, ...
$ cat app/test/vote
foo;;bar;;;\n\nllll;;;sdaads;;\n\t\0

View file

@ -0,0 +1,96 @@
Make sure that clean remove everything:
$ ./test.exe configure --file app/config.ml
test.exe: [WARNING] Skipping version check, since our_version ("1.0~test") fails to parse: only digits and . allowed in version
$ ls -a app
.
..
app.ml
config.ml
dist
dune
dune.build
dune.config
test
$ ls -a app/test
.
..
context
dune-workspace.config
main.ml
noop.opam
vote
warn_error
$ ./test.exe clean -v --file app/config.ml
test.exe: [INFO] run: clean:
{ "context" = ;
"config_file" = app/config.ml;
"output" = None;
"dry_run" = false }
test.exe: [INFO] Generating: app/test/dune-workspace.config (base)
test.exe: [INFO] Generating: dune-project (base)
test.exe: [INFO] Generating: app/dune.config (base)
config.exe: [INFO] reading cache app/test/context
config.exe: [INFO] Name noop
Keys vote=cat (default),
warn_error=false (default)
test.exe: [INFO] Skipped ./app
test.exe: [INFO] Skipped ./context
test.exe: [INFO] Skipped ./errors
test.exe: [INFO] Skipped ./help.exe
test.exe: [INFO] Skipped ./lib
test.exe: [INFO] Skipped ./test.exe
$ ls -a app
.
..
app.ml
config.ml
Check that clean works with `--output`:
$ ./test.exe configure --file app/config.ml --output=toto
test.exe: [WARNING] Skipping version check, since our_version ("1.0~test") fails to parse: only digits and . allowed in version
$ ls -a app
.
..
app.ml
config.ml
dist
dune
dune.build
dune.config
test
$ ls -a app/test
.
..
context
dune-workspace.config
noop.opam
toto.ml
vote
warn_error
$ ./test.exe clean -v --file app/config.ml
test.exe: [INFO] run: clean:
{ "context" = ;
"config_file" = app/config.ml;
"output" = None;
"dry_run" = false }
test.exe: [INFO] Generating: app/test/dune-workspace.config (base)
test.exe: [INFO] Generating: dune-project (base)
test.exe: [INFO] Generating: app/dune.config (base)
config.exe: [INFO] reading cache app/test/context
config.exe: [INFO] Name noop
Keys vote=cat (default),
warn_error=false (default)
Output toto
test.exe: [INFO] Skipped ./app
test.exe: [INFO] Skipped ./context
test.exe: [INFO] Skipped ./errors
test.exe: [INFO] Skipped ./help.exe
test.exe: [INFO] Skipped ./lib
test.exe: [INFO] Skipped ./test.exe
$ ls -a app
.
..
app.ml
config.ml

View file

@ -0,0 +1,89 @@
Check that configure generates the file in the right dir when `--file`
is passed:
$ ./test.exe configure -v --file app/config.ml
test.exe: [INFO] run: configure:
{ "args" =
{ "context" = ;
"config_file" = app/config.ml;
"output" = None;
"dry_run" = false };
"depext" = true }
test.exe: [WARNING] Skipping version check, since our_version ("1.0~test") fails to parse: only digits and . allowed in version
test.exe: [INFO] Generating: app/test/dune-workspace.config (base)
test.exe: [INFO] Generating: dune-project (base)
test.exe: [INFO] Generating: app/dune.config (base)
test.exe: [INFO] Preserving arguments in app/test/context:
[|"./test.exe"; "configure"; "-v"; "--file";
"app/config.ml"|]
test.exe: [INFO] Set-up config skeleton.
config.exe: [INFO] reading cache app/test/context
config.exe: [INFO] Name noop
Keys vote=cat (default),
warn_error=false (default)
config.exe: [INFO] Generating: noop.opam (opam)
config.exe: [INFO] in dir { "context" = ;
"config_file" = app/config.ml;
"output" = None;
"dry_run" = false }
config.exe: [INFO] Generating: main.ml (main file)
config.exe: [INFO] Generating: dune.build (dune.build)
config.exe: [INFO] Generating: dune-workspace (dune-workspace)
config.exe: [INFO] Generating: dune-project (dune-project)
config.exe: [INFO] Generating: dune (dune.dist)
$ ls -a app/
.
..
app.ml
config.ml
dist
dune
dune.build
dune.config
test
$ ls -a app/test
.
..
context
dune-workspace.config
main.ml
noop.opam
vote
warn_error
$ ./test.exe clean --file app/config.ml
Check that configure create the correct context file:
$ ./test.exe configure --file=app/config.ml
test.exe: [WARNING] Skipping version check, since our_version ("1.0~test") fails to parse: only digits and . allowed in version
$ cat app/test/context
configure
--file=app/config.ml
$ rm -rf custom_build_
$ ./test.exe configure --file=app/config.ml
test.exe: [WARNING] Skipping version check, since our_version ("1.0~test") fails to parse: only digits and . allowed in version
$ cat app/test/context
configure
--file=app/config.ml
$ ./test.exe clean --file=app/config.ml
Check that `test help configure` and `test configure --help` have the
same output.
$ ./test.exe help configure --file=app/config.ml --help=plain > h1
$ ./test.exe configure --help=plain --file=app/config.ml > h2
$ ./help.exe diff h1 h2
Check that `test help configure` works when no config.ml file is present.
$ ./test.exe configure --help=plain > h0
$ ./help.exe show h0 SYNOPSIS | xargs
test configure [OPTION]
Check that errors are reported correcty:
$ ./test.exe configure a b c --file=app/config.ml 2>&1 | tr -d \'
test.exe: [WARNING] Skipping version check, since our_version ("1.0~test") fails to parse: only digits and . allowed in version
Usage: test configure [--help] [OPTION]
test: too many arguments, dont know what to do with a, b, c

View file

@ -0,0 +1,57 @@
Query package - no target - x.context
$ ./test.exe query packages --context-file=context/x.context -f context/config.ml
"fmt" { ?monorepo }
"mirage-runtime" { ?monorepo }
"x" { ?monorepo }
Query package - no target - y.context
$ ./test.exe query packages --context-file=context/y.context -f context/config.ml
"fmt" { ?monorepo }
"mirage-runtime" { ?monorepo }
"y" { ?monorepo }
Query package - x target - y.context
$ ./test.exe query packages -t x --context-file=context/y.context -f context/config.ml
"fmt" { ?monorepo }
"mirage-runtime" { ?monorepo }
"x" { ?monorepo }
Query package - y target - x.context
$ ./test.exe query packages -t y --context-file=context/x.context -f context/config.ml
"fmt" { ?monorepo }
"mirage-runtime" { ?monorepo }
"y" { ?monorepo }
Describe - no target - x.context
$ ./test.exe describe --context-file=context/x.context -f context/config.ml
Name noop
Keys target=x,
vote=cat (default),
warn_error=false (default)
Describe - no target - y.context
$ ./test.exe describe --context-file=context/y.context -f context/config.ml
Name noop
Keys target=y,
vote=cat (default),
warn_error=false (default)
Describe - x target - y.context
$ ./test.exe describe -t x --context-file=context/y.context -f context/config.ml
Name noop
Keys target=x,
vote=cat (default),
warn_error=false (default)
Describe - y target - x.context
$ ./test.exe describe -t y --context-file=context/x.context -f context/config.ml
Name noop
Keys target=y,
vote=cat (default),
warn_error=false (default)
Bad context cache
$ ./test.exe configure -t nonexistent --context-file=context/z.context -f context/config.ml 2>&1 | tr -d \'
test.exe: [WARNING] Skipping version check, since our_version ("1.0~test") fails to parse: only digits and . allowed in version
Usage: test configure [--help] [-t ENUM] [OPTION]
test: option -t: invalid value nonexistent, expected either y or x

View file

@ -0,0 +1,17 @@
open E2e
open Functoria
open Cmdliner
let x = Impl.v ~packages:[ package "x" ] "X" job
let y = Impl.v ~packages:[ package "y" ] "Y" job
let target_conv : [ `X | `Y ] Cmdliner.Arg.conv =
Cmdliner.Arg.enum [ ("y", `Y); ("x", `X) ]
let target =
let doc = Arg.info ~doc:"Target." [ "t" ] in
let key = Key.Arg.opt target_conv `X doc in
Key.create "target" key
let main = match_impl (Key.value target) ~default:y [ (`X, x) ]
let () = register ~src:`None "noop" [ main ]

View file

@ -0,0 +1,2 @@
-t
x

View file

@ -0,0 +1,2 @@
-t
y

View file

@ -0,0 +1,2 @@
-t
nonexistent

View file

@ -0,0 +1,24 @@
Test that `describe` works as expected:
$ ./test.exe describe --file app/config.ml
Name noop
Keys vote=cat (default),
warn_error=false (default)
$ ./test.exe describe -v --file app/config.ml
test.exe: [INFO] run: describe:
{ "args" =
{ "context" = ;
"config_file" = app/config.ml;
"output" = None;
"dry_run" = false };
"dotcmd" = "xdot";
"dot" = false;
"eval" = None }
test.exe: [INFO] Generating: app/test/dune-workspace.config (base)
test.exe: [INFO] Generating: dune-project (base)
test.exe: [INFO] Generating: app/dune.config (base)
Name noop
Keys vote=cat (default),
warn_error=false (default)
Libraries fmt, mirage-runtime.functoria
Packages fmt { ?monorepo }, mirage-runtime { ?monorepo }

View file

@ -0,0 +1,23 @@
(executable
(name test)
(modules test)
(libraries e2e alcotest cmdliner rresult astring))
(executable
(name help)
(modules help)
(libraries astring fmt))
(cram
(deps
test.exe
help.exe
(source_tree app)
(source_tree lib)
(source_tree errors)
(source_tree context)
(package mirage)
(package mirage-runtime))
(enabled_if
(<> %{architecture} "i386"))
(package mirage))

View file

@ -0,0 +1,53 @@
Check the locations of error messages when something is wrong in the body
of a device's connect function:
$ ./test.exe configure -f errors/in_device.ml
test.exe: [WARNING] Skipping version check, since our_version ("1.0~test") fails to parse: only digits and . allowed in version
$ dune build
File "errors/in_device.ml", line 6, characters 2-26:
Error: Unbound value Unikernel_make__4.start'
Hint: Did you mean start?
[1]
$ ./test.exe clean -f errors/in_device.ml
Check what happens when the number of the arguments passed to the functor is
not the right ones. First, too many parameters:
$ ./test.exe configure -f errors/in_functor_too_many.ml
test.exe: [WARNING] Skipping version check, since our_version ("1.0~test") fails to parse: only digits and . allowed in version
$ dune build 2>&1 | head -n1 | cut -d',' -f'-2'
File "errors/test/main.ml", line 10
$ ./test.exe clean -f errors/in_functor_too_many.ml
Then, not enough:
$ ./test.exe configure -f errors/in_functor_not_enough.ml
test.exe: [WARNING] Skipping version check, since our_version ("1.0~test") fails to parse: only digits and . allowed in version
$ dune build
File "errors/test/main.ml", line 34, characters 3-26:
Error: The module Unikernel_make__4 is a functor, it cannot have any components
[1]
$ ./test.exe clean -f errors/in_functor_not_enough.ml
Also check that we have proper errors when the config file is missing:
Configure failure
$ ./test.exe configure --vote=dog
configuration file config.ml missing
[1]
Query failure
$ ./test.exe query --vote=dog
configuration file config.ml missing
[1]
Describe failure
$ ./test.exe describe --vote=dog
configuration file config.ml missing
[1]
Clean does not fail
$ ./test.exe clean --vote=dog
Help does not fail
$ ./test.exe help --man-format=plain > /dev/null

View file

@ -0,0 +1,11 @@
open Functoria
open E2e
let device =
let connect _ modname = function
| [ _; _ ] -> code ~pos:__POS__ "%s.start' () ()" modname
| _ -> assert false
in
impl ~connect "Unikernel.Make" (job @-> job @-> job)
let () = register "my-app" [ device $ noop $ noop ]

View file

@ -0,0 +1,3 @@
module Make (_ : sig end) (_ : sig end) = struct
let start _ _ = ()
end

View file

@ -0,0 +1,5 @@
open Functoria
open E2e
let device = main "Unikernel.Make" (job @-> job)
let () = register "my-app" [ device $ noop ]

View file

@ -0,0 +1,3 @@
module Make (_ : sig end) (_ : sig end) = struct
let start _ _ = ()
end

View file

@ -0,0 +1,5 @@
open Functoria
open E2e
let device = main "Unikernel.Make" (job @-> job @-> job @-> job)
let () = register "my-app" [ device $ noop $ noop $ noop ]

View file

@ -0,0 +1,3 @@
module Make (_ : sig end) (_ : sig end) = struct
let start _ _ = ()
end

View file

@ -0,0 +1,3 @@
module Make (_ : sig end) (_ : sig end) = struct
let start _ _ = ()
end

View file

@ -0,0 +1,77 @@
(*
* Copyright (c) 2015 Jeremy Yallop
* Copyright (c) 2021 Thomas Gazagnaire <thomas@gazagnaire.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*)
open Astring
(* cut a man page into sections *)
let by_sections s =
let lines = String.cuts ~sep:"\n" s in
let return l =
match List.rev l with [] -> assert false | h :: t -> (h, t)
in
let rec aux current sections = function
| [] -> List.rev (return current :: sections)
| h :: t ->
if
String.length h > 1
&& String.for_all (fun x -> Char.Ascii.(is_upper x || is_white x)) h
then aux [ h ] (return current :: sections) t
else aux (h :: current) sections t
in
aux [ "INIT" ] [] lines
let sections = [ "CONFIGURE OPTIONS"; "APPLICATION OPTIONS"; "COMMON OPTIONS" ]
let read file =
let ic = open_in_bin file in
let str = really_input_string ic (in_channel_length ic) in
close_in ic;
by_sections str
let err_usage () =
Fmt.pr "[usage]: ./help.exe [diff|show] PARAMS\n";
exit 1
let () =
if Array.length Sys.argv <> 4 then err_usage ()
else
match Sys.argv.(1) with
| "diff" ->
let s1 = read Sys.argv.(2) in
let s2 = read Sys.argv.(3) in
List.iter
(fun name ->
match (List.assoc_opt name s1, List.assoc_opt name s2) with
| Some s1, Some s2 ->
if List.length s1 <> List.length s2 then
Fmt.failwith "Number of lines in %S differs" name
else
List.iter2
(fun s1 s2 ->
if s1 <> s2 then
Fmt.failwith "Lines in section %S differ:\n %S\n %S\n"
name s1 s2)
s1 s2
| _ -> Fmt.failwith "Section %S differs" name)
sections
| "show" -> (
let s1 = read Sys.argv.(2) in
let name = Sys.argv.(3) in
match List.assoc_opt name s1 with
| None -> ()
| Some s -> List.iter print_endline s)
| _ -> err_usage ()

View file

@ -0,0 +1,186 @@
Test that the help command works without config file:
$ ./test.exe help -v --help=plain
test.exe: [INFO] run: help:
{ "context" = ;
"config_file" = config.ml;
"output" = None;
"dry_run" = false }
NAME
test-help - Display help about test commands.
SYNOPSIS
test help [--man-format=FMT] [OPTION] [TOPIC]
DESCRIPTION
Prints help.
Use `test help topics' to get the full list of help topics.
DESCRIBE OPTIONS
--eval
Fully evaluate the graph before showing it. The default when the
unikernel has already been configured.
--no-eval
Do not evaluate the graph before showing it. See --eval. The
default when the unikernel has not been configured.
CONFIGURE OPTIONS
--context-file=FILE (absent=test.context)
The context file to use.
--depext
Enable call to `opam depext' in the project Makefile.
--dry-run
Display I/O actions instead of executing them.
--extra-repos=NAME1:URL1,NAME2:URL2,...
(absent=opam-overlays:https://github.com/dune-universe/opam-overlays.git,mirage-overlays:https://github.com/dune-universe/mirage-opam-overlays.git
or MIRAGE_EXTRA_REPOS env)
Additional opam-repositories to use when using `opam monorepo
lock' to gather local sources. Default:
https://github.com/dune-universe/opam-overlays.git &
https://github.com/dune-universe/mirage-opam-overlays.git.
-f FILE, --file=FILE, --config-file=FILE (absent=config.ml)
The configuration file to use.
--no-depext
Disable call to `opam depext' in the project Makefile.
--no-extra-repo
Disable the use of any overlay repository.
-o FILE, --output=FILE
Name of the output file.
APPLICATION OPTIONS
--vote=VOTE (absent=cat)
Vote.
--warn-error=BOOL (absent=false)
Enable -warn-error when compiling OCaml sources.
ARGUMENTS
TOPIC
The topic to get help on.
OPTIONS
--man-format=FMT (absent=pager)
Show output in format FMT. The value FMT must be one of auto,
pager, groff or plain. With auto, the format is pager or plain
whenever the TERM env var is dumb or undefined.
COMMON OPTIONS
--color=WHEN (absent=auto)
Colorize the output. WHEN must be one of auto, always or never.
--help[=FMT] (default=auto)
Show this help in format FMT. The value FMT must be one of auto,
pager, groff or plain. With auto, the format is pager or plain
whenever the TERM env var is dumb or undefined.
-q, --quiet
Be quiet. Takes over -v and --verbosity.
-v, --verbose
Increase verbosity. Repeatable, but more than twice does not bring
more.
--verbosity=LEVEL (absent=warning)
Be more or less verbose. LEVEL must be one of quiet, error,
warning, info or debug. Takes over -v.
--version
Show version information.
EXIT STATUS
test help exits with:
0 on success.
123 on indiscriminate errors reported on standard error.
124 on command line parsing errors.
125 on unexpected internal errors (bugs).
ENVIRONMENT
These environment variables affect the execution of test help:
MIRAGE_EXTRA_REPOS
See option --extra-repos.
SEE ALSO
test(1)
As well as the default command:
$ ./test.exe -v
NAME
test - The test application builder
SYNOPSIS
test [COMMAND]
DESCRIPTION
The test application builder. It glues together a set of libraries and
configuration (e.g. network and storage) into a standalone unikernel
or UNIX binary.
Use test help <command> for more information on a specific command.
COMMANDS
clean [OPTION]
Clean the files produced by test for a given application.
configure [OPTION]
Configure a test application.
describe [OPTION]
Describe a test application.
help [--man-format=FMT] [OPTION] [TOPIC]
Display help about test commands.
query [OPTION] [INFO]
Query information about the test application.
COMMON OPTIONS
--color=WHEN (absent=auto)
Colorize the output. WHEN must be one of auto, always or never.
--help[=FMT] (default=auto)
Show this help in format FMT. The value FMT must be one of auto,
pager, groff or plain. With auto, the format is pager or plain
whenever the TERM env var is dumb or undefined.
-q, --quiet
Be quiet. Takes over -v and --verbosity.
-v, --verbose
Increase verbosity. Repeatable, but more than twice does not bring
more.
--verbosity=LEVEL (absent=warning)
Be more or less verbose. LEVEL must be one of quiet, error,
warning, info or debug. Takes over -v.
--version
Show version information.
EXIT STATUS
test exits with:
0 on success.
123 on indiscriminate errors reported on standard error.
124 on command line parsing errors.
125 on unexpected internal errors (bugs).

View file

@ -0,0 +1,22 @@
Test keys.
$ ./test.exe configure --file app/config.ml
test.exe: [WARNING] Skipping version check, since our_version ("1.0~test") fails to parse: only digits and . allowed in version
$ make build
dune build --profile release --root . app/dist
Your unikernel binary is now ready in app/dist/noop
Execute the binary using solo5-hvt, solo5-spt, xl, ...
$ cat app/test/vote
cat
$ ./test.exe clean --file app/config.ml
Change the key at configure time:
$ ./test.exe configure --file app/config.ml --vote=dog
test.exe: [WARNING] Skipping version check, since our_version ("1.0~test") fails to parse: only digits and . allowed in version
$ make build
dune build --profile release --root . app/dist
Your unikernel binary is now ready in app/dist/noop
Execute the binary using solo5-hvt, solo5-spt, xl, ...
$ cat app/test/vote
dog

View file

@ -0,0 +1,3 @@
(library
(name e2e)
(libraries mirage.functoria))

View file

@ -0,0 +1,78 @@
open Functoria
open Cmdliner
module Key = Key
let docs = "APPLICATION OPTIONS"
let warn_error =
let doc = "Enable -warn-error when compiling OCaml sources." in
let doc = Arg.info ~docv:"BOOL" ~doc ~docs [ "warn-error" ] in
let key = Key.Arg.opt Arg.bool false doc in
Key.create "warn_error" key
let vote =
let doc = "Vote." in
let doc = Arg.info ~docv:"VOTE" ~doc ~docs [ "vote" ] in
let key = Key.Arg.opt Arg.string "cat" doc in
Key.create "vote" key
let file_of_key k = Fpath.v Key.(name @@ v k)
let write_key i k f =
let context = Info.context i in
let file = file_of_key k in
let contents = f (Key.get context k) in
Action.write_file file contents
module C = struct
open Action.Syntax
let prelude _ =
"let (>>=) x f = f x\ntype 'a io = 'a\nlet return x = x\nlet run x = x"
let name = "test"
let version = "1.0~test"
let packages = [ package ~sublibs:[ "functoria" ] "mirage"; package "e2e" ]
let keys = Key.[ v vote; v warn_error ]
let connect _ _ _ = code ~pos:__POS__ "()"
let main i = Fpath.(basename @@ rem_ext @@ Info.main i)
let config i = Fpath.(basename @@ rem_ext @@ Info.config_file i)
let dune i =
let dune =
Dune.stanzaf
{|
(executable
(name %s)
(modules (:standard \ %s))
(promote (until-clean))
(libraries cmdliner fmt mirage-runtime.functoria))
|}
(main i) (config i)
in
[ dune ]
let configure i =
let* () = write_key i vote (fun x -> x) in
write_key i warn_error string_of_bool
let create jobs =
let packages = [ package "fmt" ] in
let extra_deps = List.map dep jobs in
let install i = Install.v ~bin:[ Fpath.(v (main i) + "exe", v "e2e") ] () in
impl ~keys ~packages ~connect ~dune ~configure ~extra_deps ~install "E2e"
job
let name_of_target i = Info.name i
let target_filename = name_of_target
let dune_project = []
let dune_workspace = None
let context_name _ = "default"
end
include Lib.Make (C)
include Tool.Make (C)
let register ?(init = []) ?src name typ =
let init = runtime_args sys_argv :: init in
register ~init ?src name typ

View file

@ -0,0 +1,10 @@
open Functoria.DSL
val register :
?init:job impl list ->
?src:[ `Auto | `None | `Some of string ] ->
string ->
job impl list ->
unit
val run : unit -> unit

View file

@ -0,0 +1,8 @@
Help query --man-format=plain
$ ./test.exe help query --man-format=plain > d1
Help query --help=plain
$ ./test.exe query --help=plain > d2
No difference
$ diff d1 d2

View file

@ -0,0 +1,56 @@
Run an application
$ ./test.exe configure --file app/config.ml
test.exe: [WARNING] Skipping version check, since our_version ("1.0~test") fails to parse: only digits and . allowed in version
$ dune exec -- ./app/main.exe --arg=yo --required=bar
Success: hello=Hello World! arg=yo
$ dune exec -- ./app/main.exe --help=plain
NAME
noop
SYNOPSIS
noop [OPTION]
APPLICATION OPTIONS
--arg=VAL (absent=-)
A runtime argument.
OPTIONS
--flag
A flag.
--hello=VAL (absent=Hello World!)
How to say hello.
--opt=VAL (absent=default)
An optional key.
--opt-all=VAL
All the optional keys.
--required=VAL (required)
A required key.
COMMON OPTIONS
--help[=FMT] (default=auto)
Show this help in format FMT. The value FMT must be one of auto,
pager, groff or plain. With auto, the format is pager or plain
whenever the TERM env var is dumb or undefined.
EXIT STATUS
noop exits with:
0 on success.
1 on Solo5 internal error.
63 on showing this help.
64 on any argument parsing error.
125 on unexpected internal errors (bugs) while processing the boot
parameters.
255 on OCaml uncaught exception.
[63]

View file

@ -0,0 +1,18 @@
(*
* Copyright (c) 2015 Jeremy Yallop
* Copyright (c) 2021 Thomas Gazagnaire <thomas@gazagnaire.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*)
let () = E2e.run ()

View file

@ -0,0 +1 @@
(* empty *)