From f56882eb71425b2100edea0cabb478457a8a6a16 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Thu, 23 Feb 2012 15:07:23 +0000 Subject: [PATCH] Add Whentools library, test, documentation. --- daemon/whenjobsd.ml | 3 ++ lib/Makefile.am | 4 ++ lib/whenfile.ml | 3 ++ lib/whenfile.mli | 3 ++ lib/whentools.ml | 38 ++++++++++++++++ lib/whentools.mli | 35 +++++++++++++++ tests/jobs/Makefile.am | 7 ++- tests/jobs/t200_ocaml_jobnames.ml | 35 +++++++++++++++ tests/jobs/t200_ocaml_jobnames.ml.expected | 2 + tests/jobs/t201_ocaml_set_variable.ml | 34 ++++++++++++++ tests/jobs/t201_ocaml_set_variable.ml.expected | 3 ++ tests/parsing/test_load.ml | 3 ++ tools/whenjobs.ml | 3 ++ tools/whenjobs.pod | 62 +++++++++++++++++++++----- 14 files changed, 223 insertions(+), 12 deletions(-) create mode 100644 lib/whentools.ml create mode 100644 lib/whentools.mli create mode 100644 tests/jobs/t200_ocaml_jobnames.ml create mode 100644 tests/jobs/t200_ocaml_jobnames.ml.expected create mode 100644 tests/jobs/t201_ocaml_set_variable.ml create mode 100644 tests/jobs/t201_ocaml_set_variable.ml.expected diff --git a/daemon/whenjobsd.ml b/daemon/whenjobsd.ml index 3f9fe89..164a7e2 100644 --- a/daemon/whenjobsd.ml +++ b/daemon/whenjobsd.ml @@ -19,6 +19,9 @@ open Unix open Printf +(* Ensures that Whentools module is linked to the daemon. *) +let _ = Whentools.set_variable + let () = (* Running the daemon as root is a mistake. It must be run as a * non-root user. diff --git a/lib/Makefile.am b/lib/Makefile.am index 61d0ad6..76a2d26 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -39,6 +39,8 @@ SOURCES = \ whenproto_aux.mli \ whenstate.ml \ whenstate.mli \ + whentools.ml \ + whentools.mli \ whenutils.ml \ whenutils.mli @@ -50,6 +52,7 @@ CMI_FILES = \ whenlock.cmi \ whenproto_aux.cmi \ whenstate.cmi \ + whentools.cmi \ whenutils.cmi # In dependency order. @@ -60,6 +63,7 @@ OBJECTS = \ whenexpr.cmo \ whenstate.cmo \ whenfile.cmo \ + whentools.cmo \ whenlock.cmo # Library. diff --git a/lib/whenfile.ml b/lib/whenfile.ml index b109e66..1617c29 100644 --- a/lib/whenfile.ml +++ b/lib/whenfile.ml @@ -36,4 +36,7 @@ let add_every_job _loc name e sh = job_cond = Every_job e; job_script = sh } in state := Whenstate.add_job !state job +let set_variable name value = + state := Whenstate.set_variable !state name value + let get_state () = !state diff --git a/lib/whenfile.mli b/lib/whenfile.mli index 54ee52d..a66f865 100644 --- a/lib/whenfile.mli +++ b/lib/whenfile.mli @@ -48,3 +48,6 @@ val add_every_job : Camlp4.PreCast.Loc.t -> string -> Whenexpr.periodexpr -> Whe [periodexpr] is the period, eg. 30 seconds. [sh] is the shell script fragment. *) + +val set_variable : string -> Whenexpr.variable -> unit +(** Set a variable during file load. *) diff --git a/lib/whentools.ml b/lib/whentools.ml new file mode 100644 index 0000000..979124f --- /dev/null +++ b/lib/whentools.ml @@ -0,0 +1,38 @@ +(* whenjobs + * Copyright (C) 2012 Red Hat 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. + *) + +open Big_int +open Whenexpr + +let set_variable name value = + check_valid_variable_name name; + Whenfile.set_variable name (T_string value) + +let set_variable_bool name value = + check_valid_variable_name name; + Whenfile.set_variable name (T_bool value) + +let set_variable_int name value = + check_valid_variable_name name; + Whenfile.set_variable name (T_int (big_int_of_int value)) + +let set_variable_string = set_variable + +let set_variable_float name value = + check_valid_variable_name name; + Whenfile.set_variable name (T_float value) diff --git a/lib/whentools.mli b/lib/whentools.mli new file mode 100644 index 0000000..8dd88cd --- /dev/null +++ b/lib/whentools.mli @@ -0,0 +1,35 @@ +(* whenjobs + * Copyright (C) 2012 Red Hat 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. + *) + +(** [Whentools] contains helper functions that jobs can call as they + are loading. *) + +val set_variable : string -> string -> unit +(** Set variable (just a wrapper around {!Whenfile.set_variable}). *) + +val set_variable_bool : string -> bool -> unit +(** Set variable (just a wrapper around {!Whenfile.set_variable}). *) + +val set_variable_int : string -> int -> unit +(** Set variable (just a wrapper around {!Whenfile.set_variable}). *) + +val set_variable_string : string -> string -> unit +(** Set variable (just a wrapper around {!Whenfile.set_variable}). *) + +val set_variable_float : string -> float -> unit +(** Set variable (just a wrapper around {!Whenfile.set_variable}). *) diff --git a/tests/jobs/Makefile.am b/tests/jobs/Makefile.am index 6c0c6b0..d80c09f 100644 --- a/tests/jobs/Makefile.am +++ b/tests/jobs/Makefile.am @@ -18,7 +18,12 @@ EXTRA_DIST = test_run.sh $(TESTS) $(TESTS:.ml=.ml.expected) TESTS_ENVIRONMENT = ./test_run.sh -TESTS = t100_counter.ml t101_updown.ml t102_manyjobs.ml +TESTS = \ + t100_counter.ml \ + t101_updown.ml \ + t102_manyjobs.ml \ + t200_ocaml_jobnames.ml \ + t201_ocaml_set_variable.ml OCAMLPACKAGES = -package unix,num,camlp4.lib,calendar,rpc -I ../../lib diff --git a/tests/jobs/t200_ocaml_jobnames.ml b/tests/jobs/t200_ocaml_jobnames.ml new file mode 100644 index 0000000..c003700 --- /dev/null +++ b/tests/jobs/t200_ocaml_jobnames.ml @@ -0,0 +1,35 @@ +(* whenjobs + * Copyright (C) 2012 Red Hat 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. + *) + +(* Test OCaml job names. *) + +let prefix = "prefix_" + +job (prefix ^ "job") +every 2 seconds : +<< + echo $JOBSERIAL $JOBNAME >\> $HOME/test_output + whenjobs --set counter 1 +>> + +job (prefix ^ "finished") +when counter == 1 : +<< + echo $JOBSERIAL $JOBNAME >\> $HOME/test_output + whenjobs --daemon-stop +>> diff --git a/tests/jobs/t200_ocaml_jobnames.ml.expected b/tests/jobs/t200_ocaml_jobnames.ml.expected new file mode 100644 index 0000000..0463a73 --- /dev/null +++ b/tests/jobs/t200_ocaml_jobnames.ml.expected @@ -0,0 +1,2 @@ +1 prefix_job +2 prefix_finished diff --git a/tests/jobs/t201_ocaml_set_variable.ml b/tests/jobs/t201_ocaml_set_variable.ml new file mode 100644 index 0000000..50ee5ab --- /dev/null +++ b/tests/jobs/t201_ocaml_set_variable.ml @@ -0,0 +1,34 @@ +(* whenjobs + * Copyright (C) 2012 Red Hat 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. + *) + +(* Test setting a variable. *) + +let () = + Whentools.set_variable_int "counter" 99 + +every second : +<< + echo $JOBSERIAL $JOBNAME $counter >\> $HOME/test_output + whenjobs --set counter $(($counter+1)) +>> + +when counter > 100 : +<< + echo $JOBSERIAL $JOBNAME $counter >\> $HOME/test_output + whenjobs --daemon-stop +>> diff --git a/tests/jobs/t201_ocaml_set_variable.ml.expected b/tests/jobs/t201_ocaml_set_variable.ml.expected new file mode 100644 index 0000000..1cad696 --- /dev/null +++ b/tests/jobs/t201_ocaml_set_variable.ml.expected @@ -0,0 +1,3 @@ +1 job$1 99 +2 job$1 100 +3 job$2 101 diff --git a/tests/parsing/test_load.ml b/tests/parsing/test_load.ml index 9398eb4..5d4c47a 100644 --- a/tests/parsing/test_load.ml +++ b/tests/parsing/test_load.ml @@ -18,6 +18,9 @@ open Printf +(* Ensures that Whentools module is linked to the program. *) +let _ = Whentools.set_variable + (* This program is passed a single argument, which is the .cmo file to * dynamically load. *) diff --git a/tools/whenjobs.ml b/tools/whenjobs.ml index 3383c91..8472672 100644 --- a/tools/whenjobs.ml +++ b/tools/whenjobs.ml @@ -20,6 +20,9 @@ open Big_int open Unix open Printf +(* Ensures that Whentools module is linked to the whenjobs tool. *) +let _ = Whentools.set_variable + let libdir = ref Libdir.libdir let jobsdir = diff --git a/tools/whenjobs.pod b/tools/whenjobs.pod index 43fe847..368f413 100644 --- a/tools/whenjobs.pod +++ b/tools/whenjobs.pod @@ -396,14 +396,18 @@ ran, then this evaluates to true, else false. This is the same as writing C variable>. -B There is a subtle and difficult problem with using the -I operator: The first time the expression is evaluated, the -job has (by definition) not yet run. Therefore C -evaluates to C<""> (see definition of I above). Since -C<"" E everything>, the I operator evaluates to -false, and since this usually means the job does not run, the -operator always evaluates to false. A future version of whenjobs -will address this problem. +B There is a subtle gotcha with the I operator: The +first time the expression is evaluated, the job has (by definition) +not yet run. Therefore C evaluates to C<""> (see +definition of I above). Since it is always true that + + "" < anything + +the I operator evaluates to false, and since this usually +means the job does not run, the operator always evaluates to false. + +To fix this, ensure that the variable is initialized (see +L below). =item B @@ -411,9 +415,7 @@ This evaluates to true the first time the expression is evaluated after the jobs file has been reloaded or the daemon restarted. Thereafter it evaluates to false. -You can use this to initialize variables, but note that this does not -solve the I operator problem described above, because -variables are initialized too late to affect that. +Don't use this to initialize variables: it won't do what you mean. =item B @@ -541,15 +543,53 @@ which creates two jobs called C<"daily_virus_scan"> and C<"daily_disk_check"> (C<^> is the OCaml string concatenation operator). +OCaml expressions have access to a library of functions called +B which is described below. It lets you set variables, +create jobs algorithmically, etc. + The OCaml expressions run once, when the jobs file is being loaded or reloaded. +=head3 SETTING THE INITIAL VALUE OF VARIABLES + +Variables are created when they are referenced, and until set they +have the value empty string (just like the shell). Across file +reloads, the previous values of variables is preserved. + +To initialize a variable to a known value when the jobs file is +loaded, call one of the C functions as in +this example: + + let () = + Whentools.set_variable "name" "Richard"; + Whentools.set_variable_int "counter" 0 + +=head3 WHENTOOLS LIBRARY +=over 4 + +=item B I I + +Set variable I to the string. + +=item B I I +Set variable I to the boolean value I. +=item B I I +Set variable I to the integer value I. +=item B I I +Set variable I to the string value . This is +the same as I. + +=item B I I + +Set variable I to the floating point value I. + +=back =head1 FILES -- 1.8.3.1