<p>pespin <strong>merged</strong> this change.</p><p><a href="https://gerrit.osmocom.org/c/libosmocore/+/15546">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  laforge: Looks good to me, but someone else must approve
  fixeria: Looks good to me, but someone else must approve
  pespin: Looks good to me, approved
  Jenkins Builder: Verified

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">tdef: Introduce min_val and max_val fields<br><br>This is useful for timers expected to have a range of valid or expected<br>values.<br><br>Validation is done at runtime when timer values are set by the app or by<br>the user through the VTY.<br><br>Related: OS#4190<br>Change-Id: I4661ac41c29a009a1d5fc57d87aaee6041c7d1b2<br>---<br>M TODO-RELEASE<br>M include/osmocom/core/tdef.h<br>M src/tdef.c<br>M src/vty/tdef_vty.c<br>M tests/tdef/tdef_test.c<br>M tests/tdef/tdef_test.ok<br>M tests/tdef/tdef_vty_test_config_root.c<br>M tests/tdef/tdef_vty_test_config_root.vty<br>8 files changed, 175 insertions(+), 13 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/TODO-RELEASE b/TODO-RELEASE</span><br><span>index 665ecf7..547b5a9 100644</span><br><span>--- a/TODO-RELEASE</span><br><span>+++ b/TODO-RELEASE</span><br><span>@@ -8,3 +8,4 @@</span><br><span> # If any interfaces have been removed or changed since the last public release: c:r:0.</span><br><span> #library   what                    description / commit summary line</span><br><span> core               osmo_tdef_get()         change val_if_not_present arg from unsigned long to long to allow passing -1</span><br><span style="color: hsl(120, 100%, 40%);">+core              struct osmo_tdef        fields min_val,max_val added, ABI break (arrays of structs used in programs)</span><br><span>diff --git a/include/osmocom/core/tdef.h b/include/osmocom/core/tdef.h</span><br><span>index 8155688..54819d9 100644</span><br><span>--- a/include/osmocom/core/tdef.h</span><br><span>+++ b/include/osmocom/core/tdef.h</span><br><span>@@ -77,6 +77,10 @@</span><br><span>   /*! Currently active timeout value, e.g. set by user config. This is the only mutable member: a user may</span><br><span>      * configure the timeout value, but neither unit nor any other field. */</span><br><span>     unsigned long val;</span><br><span style="color: hsl(120, 100%, 40%);">+    /*! Minimum timer value (in this tdef unit), checked if set (not zero). */</span><br><span style="color: hsl(120, 100%, 40%);">+    unsigned long min_val;</span><br><span style="color: hsl(120, 100%, 40%);">+        /*! Maximum timer value (in this tdef unit), checked if set (not zero). */</span><br><span style="color: hsl(120, 100%, 40%);">+    unsigned long max_val;</span><br><span> };</span><br><span> </span><br><span> /*! Iterate an array of struct osmo_tdef, the last item should be fully zero, i.e. "{}".</span><br><span>@@ -98,6 +102,8 @@</span><br><span>                      long val_if_not_present);</span><br><span> struct osmo_tdef *osmo_tdef_get_entry(struct osmo_tdef *tdefs, int T);</span><br><span> int osmo_tdef_set(struct osmo_tdef *tdefs, int T, unsigned long val, enum osmo_tdef_unit val_unit);</span><br><span style="color: hsl(120, 100%, 40%);">+bool osmo_tdef_val_in_range(struct osmo_tdef *tdef, unsigned long new_val);</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_tdef_range_str_buf(char *buf, size_t buf_len, struct osmo_tdef *t);</span><br><span> </span><br><span> /*! Using osmo_tdef for osmo_fsm_inst: array entry for a mapping of state numbers to timeout definitions.</span><br><span>  * For a usage example, see osmo_tdef_get_state_timeout() and test_tdef_state_timeout() in tdef_test.c. */</span><br><span>diff --git a/src/tdef.c b/src/tdef.c</span><br><span>index ab6a51b..94d987f 100644</span><br><span>--- a/src/tdef.c</span><br><span>+++ b/src/tdef.c</span><br><span>@@ -136,14 +136,22 @@</span><br><span> </span><br><span> /*! Set all osmo_tdef values to the default_val.</span><br><span>  * It is convenient to define a tdefs array by setting only the default_val, and calling osmo_tdefs_reset() once for</span><br><span style="color: hsl(0, 100%, 40%);">- * program startup. (See also osmo_tdef_vty_init())</span><br><span style="color: hsl(120, 100%, 40%);">+ * program startup. (See also osmo_tdef_vty_init()).</span><br><span style="color: hsl(120, 100%, 40%);">+ * During call to this function, default values are verified to be inside valid range; process is aborted otherwise.</span><br><span>  * \param[in] tdefs  Array of timer definitions, last entry being fully zero.</span><br><span>  */</span><br><span> void osmo_tdefs_reset(struct osmo_tdef *tdefs)</span><br><span> {</span><br><span>  struct osmo_tdef *t;</span><br><span style="color: hsl(0, 100%, 40%);">-    osmo_tdef_for_each(t, tdefs)</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_tdef_for_each(t, tdefs) {</span><br><span style="color: hsl(120, 100%, 40%);">+                if (!osmo_tdef_val_in_range(t, t->default_val)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                  char range_str[64];</span><br><span style="color: hsl(120, 100%, 40%);">+                   osmo_tdef_range_str_buf(range_str, sizeof(range_str), t);</span><br><span style="color: hsl(120, 100%, 40%);">+                     osmo_panic("%s:%d Timer " OSMO_T_FMT " contains default value %lu not in range %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                                __FILE__, __LINE__, OSMO_T_FMT_ARGS(t->T), t->default_val, range_str);</span><br><span style="color: hsl(120, 100%, 40%);">+               }</span><br><span>            t->val = t->default_val;</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span> }</span><br><span> </span><br><span> /*! Return the value of a T timer from a list of osmo_tdef, in the given unit.</span><br><span>@@ -221,13 +229,55 @@</span><br><span>  */</span><br><span> int osmo_tdef_set(struct osmo_tdef *tdefs, int T, unsigned long val, enum osmo_tdef_unit val_unit)</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+        unsigned long new_val;</span><br><span>       struct osmo_tdef *t = osmo_tdef_get_entry(tdefs, T);</span><br><span>         if (!t)</span><br><span>              return -EEXIST;</span><br><span style="color: hsl(0, 100%, 40%);">- t->val = osmo_tdef_round(val, val_unit, t->unit);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     new_val = osmo_tdef_round(val, val_unit, t->unit);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!osmo_tdef_val_in_range(t, new_val))</span><br><span style="color: hsl(120, 100%, 40%);">+              return -ERANGE;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     t->val = new_val;</span><br><span>         return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/*! Check if value new_val is in range of valid possible values for timer entry tdef.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] tdef  Timer entry from a timer definition table.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] new_val  The value whose validity to check, in units as per this timer entry.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \return true if inside range, false otherwise.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+bool osmo_tdef_val_in_range(struct osmo_tdef *tdef, unsigned long new_val)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ return new_val >= tdef->min_val && (!tdef->max_val || new_val <= tdef->max_val);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! Write string representation of osmo_tdef range into buf.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] buf  The buffer where the string representation is stored.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] buf_len  Length of buffer in bytes.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] tdef  Timer entry from a timer definition table.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \return The number of characters printed on success, negative on error. See snprintf().</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_tdef_range_str_buf(char *buf, size_t buf_len, struct osmo_tdef *t)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      int ret, len = 0, offset = 0, rem = buf_len;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        buf[0] = '\0';</span><br><span style="color: hsl(120, 100%, 40%);">+        ret = snprintf(buf + offset, rem, "[%lu .. ", t->min_val);</span><br><span style="color: hsl(120, 100%, 40%);">+       if (ret < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+               return ret;</span><br><span style="color: hsl(120, 100%, 40%);">+   OSMO_SNPRINTF_RET(ret, rem, offset, len);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (t->max_val)</span><br><span style="color: hsl(120, 100%, 40%);">+            ret = snprintf(buf + offset, rem, "%lu]", t->max_val);</span><br><span style="color: hsl(120, 100%, 40%);">+   else</span><br><span style="color: hsl(120, 100%, 40%);">+          ret = snprintf(buf + offset, rem, "inf]");</span><br><span style="color: hsl(120, 100%, 40%);">+  if (ret < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+               return ret;</span><br><span style="color: hsl(120, 100%, 40%);">+   OSMO_SNPRINTF_RET(ret, rem, offset, len);</span><br><span style="color: hsl(120, 100%, 40%);">+     return ret;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /*! Using osmo_tdef for osmo_fsm_inst: find a given state's osmo_tdef_state_timeout entry.</span><br><span>  *</span><br><span>  * The timeouts_array shall contain exactly 32 elements, regardless whether only some of them are actually populated</span><br><span>diff --git a/src/vty/tdef_vty.c b/src/vty/tdef_vty.c</span><br><span>index eb05c3c..4549a61 100644</span><br><span>--- a/src/vty/tdef_vty.c</span><br><span>+++ b/src/vty/tdef_vty.c</span><br><span>@@ -115,12 +115,22 @@</span><br><span>  */</span><br><span> int osmo_tdef_vty_set_cmd(struct vty *vty, struct osmo_tdef *tdefs, const char **args)</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+   unsigned long new_val;</span><br><span>       const char *T_arg = args[0];</span><br><span>         const char *val_arg = args[1];</span><br><span>       struct osmo_tdef *t = osmo_tdef_vty_parse_T_arg(vty, tdefs, T_arg);</span><br><span>  if (!t)</span><br><span>              return CMD_WARNING;</span><br><span style="color: hsl(0, 100%, 40%);">-     t->val = osmo_tdef_vty_parse_val_arg(val_arg, t->default_val);</span><br><span style="color: hsl(120, 100%, 40%);">+  new_val = osmo_tdef_vty_parse_val_arg(val_arg, t->default_val);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  if (!osmo_tdef_val_in_range(t, new_val)) {</span><br><span style="color: hsl(120, 100%, 40%);">+            char range_str[64];</span><br><span style="color: hsl(120, 100%, 40%);">+           osmo_tdef_range_str_buf(range_str, sizeof(range_str), t);</span><br><span style="color: hsl(120, 100%, 40%);">+             vty_out(vty, "%% Timer " OSMO_T_FMT " value %lu is out of range %s%s",</span><br><span style="color: hsl(120, 100%, 40%);">+                    OSMO_T_FMT_ARGS(t->T), new_val, range_str, VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+           return CMD_WARNING;</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+     t->val = new_val;</span><br><span>         return CMD_SUCCESS;</span><br><span> }</span><br><span> </span><br><span>@@ -161,18 +171,29 @@</span><br><span>  */</span><br><span> void osmo_tdef_vty_out_one_va(struct vty *vty, struct osmo_tdef *t, const char *prefix_fmt, va_list va)</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+   char range_str[64];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>        if (!t) {</span><br><span>            vty_out(vty, "%% Error: no such timer%s", VTY_NEWLINE);</span><br><span>            return;</span><br><span>      }</span><br><span>    if (prefix_fmt)</span><br><span>              vty_out_va(vty, prefix_fmt, va);</span><br><span style="color: hsl(0, 100%, 40%);">-        vty_out(vty, OSMO_T_FMT " = %lu%s%s\t%s (default: %lu%s%s)%s",</span><br><span style="color: hsl(0, 100%, 40%);">-                OSMO_T_FMT_ARGS(t->T), t->val,</span><br><span style="color: hsl(0, 100%, 40%);">-            t->unit == OSMO_TDEF_CUSTOM ? "" : " ", t->unit == OSMO_TDEF_CUSTOM ? "" : osmo_tdef_unit_name(t->unit),</span><br><span style="color: hsl(0, 100%, 40%);">-         t->desc, t->default_val,</span><br><span style="color: hsl(0, 100%, 40%);">-          t->unit == OSMO_TDEF_CUSTOM ? "" : " ", t->unit == OSMO_TDEF_CUSTOM ? "" : osmo_tdef_unit_name(t->unit),</span><br><span style="color: hsl(0, 100%, 40%);">-         VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       vty_out(vty, OSMO_T_FMT " = %lu", OSMO_T_FMT_ARGS(t->T), t->val);</span><br><span style="color: hsl(120, 100%, 40%);">+     if (t->unit != OSMO_TDEF_CUSTOM)</span><br><span style="color: hsl(120, 100%, 40%);">+           vty_out(vty, " %s", osmo_tdef_unit_name(t->unit));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     vty_out(vty, "\t%s (default: %lu", t->desc, t->default_val);</span><br><span style="color: hsl(120, 100%, 40%);">+  if (t->unit != OSMO_TDEF_CUSTOM)</span><br><span style="color: hsl(120, 100%, 40%);">+           vty_out(vty, " %s", osmo_tdef_unit_name(t->unit));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     if (t->min_val || t->max_val) {</span><br><span style="color: hsl(120, 100%, 40%);">+         osmo_tdef_range_str_buf(range_str, sizeof(range_str), t);</span><br><span style="color: hsl(120, 100%, 40%);">+             vty_out(vty, ", range: %s", range_str);</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   vty_out(vty, ")%s", VTY_NEWLINE);</span><br><span> }</span><br><span> </span><br><span> /*! Write to VTY the current status of one timer.</span><br><span>diff --git a/tests/tdef/tdef_test.c b/tests/tdef/tdef_test.c</span><br><span>index 12ca802..60066b1 100644</span><br><span>--- a/tests/tdef/tdef_test.c</span><br><span>+++ b/tests/tdef/tdef_test.c</span><br><span>@@ -41,7 +41,7 @@</span><br><span>   { .T=3, .default_val=100, .unit=OSMO_TDEF_M, .desc="100m" },</span><br><span>       { .T=4, .default_val=100, .unit=OSMO_TDEF_CUSTOM, .desc="100 potatoes" },</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- { .T=7, .default_val=50, .desc="Water Boiling Timeout" },  // default is .unit=OSMO_TDEF_S == 0</span><br><span style="color: hsl(120, 100%, 40%);">+     { .T=7, .default_val=50, .desc="Water Boiling Timeout", .min_val=20, .max_val=800 },  // default is .unit=OSMO_TDEF_S == 0</span><br><span>         { .T=8, .default_val=300, .desc="Tea brewing" },</span><br><span>   { .T=9, .default_val=5, .unit=OSMO_TDEF_M, .desc="Let tea cool down before drinking" },</span><br><span>    { .T=10, .default_val=20, .unit=OSMO_TDEF_M, .desc="Forgot to drink tea while it's warm" },</span><br><span>@@ -143,8 +143,9 @@</span><br><span>      struct osmo_tdef *t;</span><br><span>         printf("\n%s()\n", __func__);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     t = osmo_tdef_get_entry(tdefs, 7);</span><br><span>   printf("setting 7 = 42\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ t = osmo_tdef_get_entry(tdefs, 7);</span><br><span style="color: hsl(120, 100%, 40%);">+    OSMO_ASSERT(osmo_tdef_val_in_range(t, 42));</span><br><span>  t->val = 42;</span><br><span>      print_tdef_info(7);</span><br><span>  print_tdef_get_short(tdefs, 7, OSMO_TDEF_MS);</span><br><span>@@ -153,7 +154,25 @@</span><br><span>         print_tdef_get_short(tdefs, 7, OSMO_TDEF_CUSTOM);</span><br><span> </span><br><span>        printf("setting 7 = 420\n");</span><br><span style="color: hsl(0, 100%, 40%);">-  t->val = 420;</span><br><span style="color: hsl(120, 100%, 40%);">+      OSMO_ASSERT(osmo_tdef_set(tdefs, 7, 420, OSMO_TDEF_S) == 0);</span><br><span style="color: hsl(120, 100%, 40%);">+  print_tdef_info(7);</span><br><span style="color: hsl(120, 100%, 40%);">+   print_tdef_get_short(tdefs, 7, OSMO_TDEF_MS);</span><br><span style="color: hsl(120, 100%, 40%);">+ print_tdef_get_short(tdefs, 7, OSMO_TDEF_S);</span><br><span style="color: hsl(120, 100%, 40%);">+  print_tdef_get_short(tdefs, 7, OSMO_TDEF_M);</span><br><span style="color: hsl(120, 100%, 40%);">+  print_tdef_get_short(tdefs, 7, OSMO_TDEF_CUSTOM);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   printf("setting 7 = 10 (ERANGE)\n");</span><br><span style="color: hsl(120, 100%, 40%);">+        OSMO_ASSERT(!osmo_tdef_val_in_range(t, 10));</span><br><span style="color: hsl(120, 100%, 40%);">+  OSMO_ASSERT(osmo_tdef_set(tdefs, 7, 10, OSMO_TDEF_S) == -ERANGE);</span><br><span style="color: hsl(120, 100%, 40%);">+     print_tdef_info(7);</span><br><span style="color: hsl(120, 100%, 40%);">+   print_tdef_get_short(tdefs, 7, OSMO_TDEF_MS);</span><br><span style="color: hsl(120, 100%, 40%);">+ print_tdef_get_short(tdefs, 7, OSMO_TDEF_S);</span><br><span style="color: hsl(120, 100%, 40%);">+  print_tdef_get_short(tdefs, 7, OSMO_TDEF_M);</span><br><span style="color: hsl(120, 100%, 40%);">+  print_tdef_get_short(tdefs, 7, OSMO_TDEF_CUSTOM);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   printf("setting 7 = 900 (ERANGE)\n");</span><br><span style="color: hsl(120, 100%, 40%);">+       OSMO_ASSERT(!osmo_tdef_val_in_range(t, 900));</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(osmo_tdef_set(tdefs, 7, 900, OSMO_TDEF_S) == -ERANGE);</span><br><span>   print_tdef_info(7);</span><br><span>  print_tdef_get_short(tdefs, 7, OSMO_TDEF_MS);</span><br><span>        print_tdef_get_short(tdefs, 7, OSMO_TDEF_S);</span><br><span>diff --git a/tests/tdef/tdef_test.ok b/tests/tdef/tdef_test.ok</span><br><span>index d9ef99b..2a3617e 100644</span><br><span>--- a/tests/tdef/tdef_test.ok</span><br><span>+++ b/tests/tdef/tdef_test.ok</span><br><span>@@ -105,6 +105,18 @@</span><br><span> osmo_tdef_get(7, s)     = 420</span><br><span> osmo_tdef_get(7, m)    = 7</span><br><span> osmo_tdef_get(7, custom-unit)    = 420</span><br><span style="color: hsl(120, 100%, 40%);">+setting 7 = 10 (ERANGE)</span><br><span style="color: hsl(120, 100%, 40%);">+T7=420s(def=50)</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_tdef_get(7, ms)   = 420000</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_tdef_get(7, s)   = 420</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_tdef_get(7, m)      = 7</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_tdef_get(7, custom-unit)      = 420</span><br><span style="color: hsl(120, 100%, 40%);">+setting 7 = 900 (ERANGE)</span><br><span style="color: hsl(120, 100%, 40%);">+T7=420s(def=50)</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_tdef_get(7, ms)  = 420000</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_tdef_get(7, s)   = 420</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_tdef_get(7, m)      = 7</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_tdef_get(7, custom-unit)      = 420</span><br><span> resetting</span><br><span> T7=50s</span><br><span> osmo_tdef_get(7, s)     = 50</span><br><span>diff --git a/tests/tdef/tdef_vty_test_config_root.c b/tests/tdef/tdef_vty_test_config_root.c</span><br><span>index d69e028..92113e8 100644</span><br><span>--- a/tests/tdef/tdef_vty_test_config_root.c</span><br><span>+++ b/tests/tdef/tdef_vty_test_config_root.c</span><br><span>@@ -55,6 +55,9 @@</span><br><span>        { .T=4, .default_val=100, .unit=OSMO_TDEF_CUSTOM, .desc="Testing a hundred potatoes" },</span><br><span>    { .T=0x7fffffff, .default_val=0xffffffff, .unit=OSMO_TDEF_M, .desc="Very large" },</span><br><span>         { .T=-23, .default_val=239471, .desc="Negative T number" },</span><br><span style="color: hsl(120, 100%, 40%);">+ { .T=30, .default_val=50, .desc="Testing range min", .min_val=20 },</span><br><span style="color: hsl(120, 100%, 40%);">+ { .T=31, .default_val=50, .desc="Testing range max", .max_val=52 },</span><br><span style="color: hsl(120, 100%, 40%);">+ { .T=32, .default_val=50, .desc="Testing range both", .min_val=20, .max_val=52 },</span><br><span>  {}  //  <-- important! last entry shall be zero</span><br><span> };</span><br><span> </span><br><span>diff --git a/tests/tdef/tdef_vty_test_config_root.vty b/tests/tdef/tdef_vty_test_config_root.vty</span><br><span>index f3aba0f..6a53b80 100644</span><br><span>--- a/tests/tdef/tdef_vty_test_config_root.vty</span><br><span>+++ b/tests/tdef/tdef_vty_test_config_root.vty</span><br><span>@@ -22,6 +22,9 @@</span><br><span> test: T4 = 100 Testing a hundred potatoes (default: 100)</span><br><span> test: T2147483647 = 4294967295 m   Very large (default: 4294967295 m)</span><br><span> test: X23 = 239471 s      Negative T number (default: 239471 s)</span><br><span style="color: hsl(120, 100%, 40%);">+test: T30 = 50 s Testing range min (default: 50 s, range: [20 .. inf])</span><br><span style="color: hsl(120, 100%, 40%);">+test: T31 = 50 s Testing range max (default: 50 s, range: [0 .. 52])</span><br><span style="color: hsl(120, 100%, 40%);">+test: T32 = 50 s   Testing range both (default: 50 s, range: [20 .. 52])</span><br><span> software: T1 = 30 m    Write code (default: 30 m)</span><br><span> software: T2 = 20 ms      Hit segfault (default: 20 ms)</span><br><span> software: T3 = 480 m   Fix bugs (default: 480 m)</span><br><span>@@ -38,6 +41,9 @@</span><br><span> test: T4 = 100 Testing a hundred potatoes (default: 100)</span><br><span> test: T2147483647 = 4294967295 m   Very large (default: 4294967295 m)</span><br><span> test: X23 = 239471 s      Negative T number (default: 239471 s)</span><br><span style="color: hsl(120, 100%, 40%);">+test: T30 = 50 s Testing range min (default: 50 s, range: [20 .. inf])</span><br><span style="color: hsl(120, 100%, 40%);">+test: T31 = 50 s Testing range max (default: 50 s, range: [0 .. 52])</span><br><span style="color: hsl(120, 100%, 40%);">+test: T32 = 50 s   Testing range both (default: 50 s, range: [20 .. 52])</span><br><span> software: T1 = 30 m    Write code (default: 30 m)</span><br><span> software: T2 = 20 ms      Hit segfault (default: 20 ms)</span><br><span> software: T3 = 480 m   Fix bugs (default: 480 m)</span><br><span>@@ -83,6 +89,9 @@</span><br><span> test: T4 = 100 Testing a hundred potatoes (default: 100)</span><br><span> test: T2147483647 = 4294967295 m   Very large (default: 4294967295 m)</span><br><span> test: X23 = 239471 s      Negative T number (default: 239471 s)</span><br><span style="color: hsl(120, 100%, 40%);">+test: T30 = 50 s Testing range min (default: 50 s, range: [20 .. inf])</span><br><span style="color: hsl(120, 100%, 40%);">+test: T31 = 50 s Testing range max (default: 50 s, range: [0 .. 52])</span><br><span style="color: hsl(120, 100%, 40%);">+test: T32 = 50 s   Testing range both (default: 50 s, range: [20 .. 52])</span><br><span> software: T1 = 30 m    Write code (default: 30 m)</span><br><span> software: T2 = 20 ms      Hit segfault (default: 20 ms)</span><br><span> software: T3 = 480 m   Fix bugs (default: 480 m)</span><br><span>@@ -167,6 +176,32 @@</span><br><span> tdef_vty_test(config)# timer te T2 100</span><br><span> % Ambiguous command.</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+tdef_vty_test(config)# timer test 30 40</span><br><span style="color: hsl(120, 100%, 40%);">+tdef_vty_test(config)# timer test 30 60</span><br><span style="color: hsl(120, 100%, 40%);">+tdef_vty_test(config)# timer test 30 10</span><br><span style="color: hsl(120, 100%, 40%);">+% Timer T30 value 10 is out of range [20 .. inf]</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+tdef_vty_test(config)# timer test 31 40</span><br><span style="color: hsl(120, 100%, 40%);">+tdef_vty_test(config)# timer test 31 60</span><br><span style="color: hsl(120, 100%, 40%);">+% Timer T31 value 60 is out of range [0 .. 52]</span><br><span style="color: hsl(120, 100%, 40%);">+tdef_vty_test(config)# timer test 31 10</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+tdef_vty_test(config)# timer test 32 40</span><br><span style="color: hsl(120, 100%, 40%);">+tdef_vty_test(config)# timer test 32 60</span><br><span style="color: hsl(120, 100%, 40%);">+% Timer T32 value 60 is out of range [20 .. 52]</span><br><span style="color: hsl(120, 100%, 40%);">+tdef_vty_test(config)# timer test 32 10</span><br><span style="color: hsl(120, 100%, 40%);">+% Timer T32 value 10 is out of range [20 .. 52]</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+tdef_vty_test(config)# timer test</span><br><span style="color: hsl(120, 100%, 40%);">+test: T1 = 100 s  Testing a hundred seconds (default: 100 s)</span><br><span style="color: hsl(120, 100%, 40%);">+test: T2 = 100 ms   Testing a hundred milliseconds (default: 100 ms)</span><br><span style="color: hsl(120, 100%, 40%);">+test: T3 = 100 m      Testing a hundred minutes (default: 100 m)</span><br><span style="color: hsl(120, 100%, 40%);">+test: T4 = 100      Testing a hundred potatoes (default: 100)</span><br><span style="color: hsl(120, 100%, 40%);">+test: T2147483647 = 4294967295 m     Very large (default: 4294967295 m)</span><br><span style="color: hsl(120, 100%, 40%);">+test: X23 = 239471 s        Negative T number (default: 239471 s)</span><br><span style="color: hsl(120, 100%, 40%);">+test: T30 = 60 s Testing range min (default: 50 s, range: [20 .. inf])</span><br><span style="color: hsl(120, 100%, 40%);">+test: T31 = 10 s Testing range max (default: 50 s, range: [0 .. 52])</span><br><span style="color: hsl(120, 100%, 40%);">+test: T32 = 40 s   Testing range both (default: 50 s, range: [20 .. 52])</span><br><span> </span><br><span> tdef_vty_test(config)# do show timer software</span><br><span> software: T1 = 30 m       Write code (default: 30 m)</span><br><span>@@ -230,6 +265,9 @@</span><br><span> test: T4 = 100      Testing a hundred potatoes (default: 100)</span><br><span> test: T2147483647 = 4294967295 m   Very large (default: 4294967295 m)</span><br><span> test: X23 = 239471 s      Negative T number (default: 239471 s)</span><br><span style="color: hsl(120, 100%, 40%);">+test: T30 = 60 s Testing range min (default: 50 s, range: [20 .. inf])</span><br><span style="color: hsl(120, 100%, 40%);">+test: T31 = 10 s Testing range max (default: 50 s, range: [0 .. 52])</span><br><span style="color: hsl(120, 100%, 40%);">+test: T32 = 40 s   Testing range both (default: 50 s, range: [20 .. 52])</span><br><span> software: T1 = 13 m    Write code (default: 30 m)</span><br><span> software: T2 = 0 ms       Hit segfault (default: 20 ms)</span><br><span> software: T3 = 23 m    Fix bugs (default: 480 m)</span><br><span>@@ -245,6 +283,9 @@</span><br><span> test: T4 = 100       Testing a hundred potatoes (default: 100)</span><br><span> test: T2147483647 = 4294967295 m   Very large (default: 4294967295 m)</span><br><span> test: X23 = 239471 s      Negative T number (default: 239471 s)</span><br><span style="color: hsl(120, 100%, 40%);">+test: T30 = 60 s Testing range min (default: 50 s, range: [20 .. inf])</span><br><span style="color: hsl(120, 100%, 40%);">+test: T31 = 10 s Testing range max (default: 50 s, range: [0 .. 52])</span><br><span style="color: hsl(120, 100%, 40%);">+test: T32 = 40 s   Testing range both (default: 50 s, range: [20 .. 52])</span><br><span> software: T1 = 13 m    Write code (default: 30 m)</span><br><span> software: T2 = 0 ms       Hit segfault (default: 20 ms)</span><br><span> software: T3 = 23 m    Fix bugs (default: 480 m)</span><br><span>@@ -252,6 +293,9 @@</span><br><span> tdef_vty_test(config)# show running-config</span><br><span> ... !timer</span><br><span> timer tea T3 32</span><br><span style="color: hsl(120, 100%, 40%);">+timer test T30 60</span><br><span style="color: hsl(120, 100%, 40%);">+timer test T31 10</span><br><span style="color: hsl(120, 100%, 40%);">+timer test T32 40</span><br><span> timer software T1 13</span><br><span> timer software T2 0</span><br><span> timer software T3 23</span><br><span>@@ -261,6 +305,9 @@</span><br><span> tdef_vty_test(config)# timer software T1 default</span><br><span> tdef_vty_test(config)# show running-config</span><br><span> ... !timer</span><br><span style="color: hsl(120, 100%, 40%);">+timer test T30 60</span><br><span style="color: hsl(120, 100%, 40%);">+timer test T31 10</span><br><span style="color: hsl(120, 100%, 40%);">+timer test T32 40</span><br><span> timer software T2 0</span><br><span> timer software T3 23</span><br><span> ... !timer</span><br><span>@@ -269,5 +316,8 @@</span><br><span> tdef_vty_test(config)# timer software 2 default</span><br><span> tdef_vty_test(config)# show running-config</span><br><span> ... !timer</span><br><span style="color: hsl(120, 100%, 40%);">+timer test T30 60</span><br><span style="color: hsl(120, 100%, 40%);">+timer test T31 10</span><br><span style="color: hsl(120, 100%, 40%);">+timer test T32 40</span><br><span> timer software T3 23</span><br><span> ... !timer</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/libosmocore/+/15546">change 15546</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/c/libosmocore/+/15546"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: libosmocore </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: I4661ac41c29a009a1d5fc57d87aaee6041c7d1b2 </div>
<div style="display:none"> Gerrit-Change-Number: 15546 </div>
<div style="display:none"> Gerrit-PatchSet: 8 </div>
<div style="display:none"> Gerrit-Owner: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder </div>
<div style="display:none"> Gerrit-Reviewer: fixeria <axilirator@gmail.com> </div>
<div style="display:none"> Gerrit-Reviewer: laforge <laforge@osmocom.org> </div>
<div style="display:none"> Gerrit-Reviewer: neels <nhofmeyr@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: osmith <osmith@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>