Add Whentools library, test, documentation.
authorRichard W.M. Jones <rjones@redhat.com>
Thu, 23 Feb 2012 15:07:23 +0000 (15:07 +0000)
committerRichard W.M. Jones <rjones@redhat.com>
Thu, 23 Feb 2012 16:08:09 +0000 (16:08 +0000)
14 files changed:
daemon/whenjobsd.ml
lib/Makefile.am
lib/whenfile.ml
lib/whenfile.mli
lib/whentools.ml [new file with mode: 0644]
lib/whentools.mli [new file with mode: 0644]
tests/jobs/Makefile.am
tests/jobs/t200_ocaml_jobnames.ml [new file with mode: 0644]
tests/jobs/t200_ocaml_jobnames.ml.expected [new file with mode: 0644]
tests/jobs/t201_ocaml_set_variable.ml [new file with mode: 0644]
tests/jobs/t201_ocaml_set_variable.ml.expected [new file with mode: 0644]
tests/parsing/test_load.ml
tools/whenjobs.ml
tools/whenjobs.pod

index 3f9fe89..164a7e2 100644 (file)
@@ -19,6 +19,9 @@
 open Unix
 open Printf
 
 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.
 let () =
   (* Running the daemon as root is a mistake.  It must be run as a
    * non-root user.
index 61d0ad6..76a2d26 100644 (file)
@@ -39,6 +39,8 @@ SOURCES = \
        whenproto_aux.mli \
        whenstate.ml \
        whenstate.mli \
        whenproto_aux.mli \
        whenstate.ml \
        whenstate.mli \
+       whentools.ml \
+       whentools.mli \
        whenutils.ml \
        whenutils.mli
 
        whenutils.ml \
        whenutils.mli
 
@@ -50,6 +52,7 @@ CMI_FILES = \
        whenlock.cmi \
        whenproto_aux.cmi \
        whenstate.cmi \
        whenlock.cmi \
        whenproto_aux.cmi \
        whenstate.cmi \
+       whentools.cmi \
        whenutils.cmi
 
 # In dependency order.
        whenutils.cmi
 
 # In dependency order.
@@ -60,6 +63,7 @@ OBJECTS = \
        whenexpr.cmo \
        whenstate.cmo \
        whenfile.cmo \
        whenexpr.cmo \
        whenstate.cmo \
        whenfile.cmo \
+       whentools.cmo \
        whenlock.cmo
 
 # Library.
        whenlock.cmo
 
 # Library.
index b109e66..1617c29 100644 (file)
@@ -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
 
               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
 let get_state () = !state
index 54ee52d..a66f865 100644 (file)
@@ -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. *)
     [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 (file)
index 0000000..979124f
--- /dev/null
@@ -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 (file)
index 0000000..8dd88cd
--- /dev/null
@@ -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}). *)
index 6c0c6b0..d80c09f 100644 (file)
 EXTRA_DIST = test_run.sh $(TESTS) $(TESTS:.ml=.ml.expected)
 
 TESTS_ENVIRONMENT = ./test_run.sh
 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
 
 
 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 (file)
index 0000000..c003700
--- /dev/null
@@ -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 (file)
index 0000000..0463a73
--- /dev/null
@@ -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 (file)
index 0000000..50ee5ab
--- /dev/null
@@ -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 (file)
index 0000000..1cad696
--- /dev/null
@@ -0,0 +1,3 @@
+1 job$1 99
+2 job$1 100
+3 job$2 101
index 9398eb4..5d4c47a 100644 (file)
@@ -18,6 +18,9 @@
 
 open Printf
 
 
 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.
  *)
 (* This program is passed a single argument, which is the .cmo file to
  * dynamically load.
  *)
index 3383c91..8472672 100644 (file)
@@ -20,6 +20,9 @@ open Big_int
 open Unix
 open Printf
 
 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 =
 let libdir = ref Libdir.libdir
 
 let jobsdir =
index 43fe847..368f413 100644 (file)
@@ -396,14 +396,18 @@ ran, then this evaluates to true, else false.
 
 This is the same as writing C<prev variable E<gt> variable>.
 
 
 This is the same as writing C<prev variable E<gt> variable>.
 
-B<Note:> There is a subtle and difficult problem with using the
-I<decreases> operator: The first time the expression is evaluated, the
-job has (by definition) not yet run.  Therefore C<prev variable>
-evaluates to C<""> (see definition of I<prev> above).  Since
-C<"" E<lt> everything>, the I<decreases> 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<Note:> There is a subtle gotcha with the I<decreases> operator: The
+first time the expression is evaluated, the job has (by definition)
+not yet run.  Therefore C<prev variable> evaluates to C<""> (see
+definition of I<prev> above).  Since it is always true that
+
+ "" < anything
+
+the I<decreases> 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</SETTING THE INITIAL VALUE OF VARIABLES> below).
 
 =item B<reloaded ()>
 
 
 =item B<reloaded ()>
 
@@ -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.
 
 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<decreases> 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<false>
 
 
 =item B<false>
 
@@ -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).
 
 C<"daily_disk_check"> (C<^> is the OCaml string concatenation
 operator).
 
+OCaml expressions have access to a library of functions called
+B<Whentools> 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.
 
 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<Whentools.set_variable*> functions as in
+this example:
+
+ let () =
+   Whentools.set_variable "name" "Richard";
+   Whentools.set_variable_int "counter" 0
+
+=head3 WHENTOOLS LIBRARY
 
 
+=over 4
+
+=item B<Whentools.set_variable> I<name> I<string>
+
+Set variable I<name> to the string.
+
+=item B<Whentools.set_variable_bool> I<name> I<b>
 
 
+Set variable I<name> to the boolean value I<b>.
 
 
+=item B<Whentools.set_variable_int> I<name> I<i>
 
 
+Set variable I<name> to the integer value I<i>.
 
 
+=item B<Whentools.set_variable_string> I<name> I<s>
 
 
+Set variable I<name> to the string value <s>.  This is
+the same as I<Whentools.set_variable>.
+
+=item B<Whentools.set_variable_float> I<name> I<f>
+
+Set variable I<name> to the floating point value I<f>.
+
+=back
 
 =head1 FILES
 
 
 =head1 FILES