tdef: Introduce min_val and max_val fields

This is useful for timers expected to have a range of valid or expected
values.

Validation is done at runtime when timer values are set by the app or by
the user through the VTY.

Related: OS#4190
Change-Id: I4661ac41c29a009a1d5fc57d87aaee6041c7d1b2
diff --git a/tests/tdef/tdef_test.c b/tests/tdef/tdef_test.c
index 12ca802..60066b1 100644
--- a/tests/tdef/tdef_test.c
+++ b/tests/tdef/tdef_test.c
@@ -41,7 +41,7 @@
 	{ .T=3, .default_val=100, .unit=OSMO_TDEF_M, .desc="100m" },
 	{ .T=4, .default_val=100, .unit=OSMO_TDEF_CUSTOM, .desc="100 potatoes" },
 
-	{ .T=7, .default_val=50, .desc="Water Boiling Timeout" },  // default is .unit=OSMO_TDEF_S == 0
+	{ .T=7, .default_val=50, .desc="Water Boiling Timeout", .min_val=20, .max_val=800 },  // default is .unit=OSMO_TDEF_S == 0
 	{ .T=8, .default_val=300, .desc="Tea brewing" },
 	{ .T=9, .default_val=5, .unit=OSMO_TDEF_M, .desc="Let tea cool down before drinking" },
 	{ .T=10, .default_val=20, .unit=OSMO_TDEF_M, .desc="Forgot to drink tea while it's warm" },
@@ -143,8 +143,9 @@
 	struct osmo_tdef *t;
 	printf("\n%s()\n", __func__);
 
-	t = osmo_tdef_get_entry(tdefs, 7);
 	printf("setting 7 = 42\n");
+	t = osmo_tdef_get_entry(tdefs, 7);
+	OSMO_ASSERT(osmo_tdef_val_in_range(t, 42));
 	t->val = 42;
 	print_tdef_info(7);
 	print_tdef_get_short(tdefs, 7, OSMO_TDEF_MS);
@@ -153,7 +154,25 @@
 	print_tdef_get_short(tdefs, 7, OSMO_TDEF_CUSTOM);
 
 	printf("setting 7 = 420\n");
-	t->val = 420;
+	OSMO_ASSERT(osmo_tdef_set(tdefs, 7, 420, OSMO_TDEF_S) == 0);
+	print_tdef_info(7);
+	print_tdef_get_short(tdefs, 7, OSMO_TDEF_MS);
+	print_tdef_get_short(tdefs, 7, OSMO_TDEF_S);
+	print_tdef_get_short(tdefs, 7, OSMO_TDEF_M);
+	print_tdef_get_short(tdefs, 7, OSMO_TDEF_CUSTOM);
+
+	printf("setting 7 = 10 (ERANGE)\n");
+	OSMO_ASSERT(!osmo_tdef_val_in_range(t, 10));
+	OSMO_ASSERT(osmo_tdef_set(tdefs, 7, 10, OSMO_TDEF_S) == -ERANGE);
+	print_tdef_info(7);
+	print_tdef_get_short(tdefs, 7, OSMO_TDEF_MS);
+	print_tdef_get_short(tdefs, 7, OSMO_TDEF_S);
+	print_tdef_get_short(tdefs, 7, OSMO_TDEF_M);
+	print_tdef_get_short(tdefs, 7, OSMO_TDEF_CUSTOM);
+
+	printf("setting 7 = 900 (ERANGE)\n");
+	OSMO_ASSERT(!osmo_tdef_val_in_range(t, 900));
+	OSMO_ASSERT(osmo_tdef_set(tdefs, 7, 900, OSMO_TDEF_S) == -ERANGE);
 	print_tdef_info(7);
 	print_tdef_get_short(tdefs, 7, OSMO_TDEF_MS);
 	print_tdef_get_short(tdefs, 7, OSMO_TDEF_S);
diff --git a/tests/tdef/tdef_test.ok b/tests/tdef/tdef_test.ok
index d9ef99b..2a3617e 100644
--- a/tests/tdef/tdef_test.ok
+++ b/tests/tdef/tdef_test.ok
@@ -105,6 +105,18 @@
 osmo_tdef_get(7, s)	= 420
 osmo_tdef_get(7, m)	= 7
 osmo_tdef_get(7, custom-unit)	= 420
+setting 7 = 10 (ERANGE)
+T7=420s(def=50)
+osmo_tdef_get(7, ms)	= 420000
+osmo_tdef_get(7, s)	= 420
+osmo_tdef_get(7, m)	= 7
+osmo_tdef_get(7, custom-unit)	= 420
+setting 7 = 900 (ERANGE)
+T7=420s(def=50)
+osmo_tdef_get(7, ms)	= 420000
+osmo_tdef_get(7, s)	= 420
+osmo_tdef_get(7, m)	= 7
+osmo_tdef_get(7, custom-unit)	= 420
 resetting
 T7=50s
 osmo_tdef_get(7, s)	= 50
diff --git a/tests/tdef/tdef_vty_test_config_root.c b/tests/tdef/tdef_vty_test_config_root.c
index d69e028..92113e8 100644
--- a/tests/tdef/tdef_vty_test_config_root.c
+++ b/tests/tdef/tdef_vty_test_config_root.c
@@ -55,6 +55,9 @@
 	{ .T=4, .default_val=100, .unit=OSMO_TDEF_CUSTOM, .desc="Testing a hundred potatoes" },
 	{ .T=0x7fffffff, .default_val=0xffffffff, .unit=OSMO_TDEF_M, .desc="Very large" },
 	{ .T=-23, .default_val=239471, .desc="Negative T number" },
+	{ .T=30, .default_val=50, .desc="Testing range min", .min_val=20 },
+	{ .T=31, .default_val=50, .desc="Testing range max", .max_val=52 },
+	{ .T=32, .default_val=50, .desc="Testing range both", .min_val=20, .max_val=52 },
 	{}  //  <-- important! last entry shall be zero
 };
 
diff --git a/tests/tdef/tdef_vty_test_config_root.vty b/tests/tdef/tdef_vty_test_config_root.vty
index f3aba0f..6a53b80 100644
--- a/tests/tdef/tdef_vty_test_config_root.vty
+++ b/tests/tdef/tdef_vty_test_config_root.vty
@@ -22,6 +22,9 @@
 test: T4 = 100	Testing a hundred potatoes (default: 100)
 test: T2147483647 = 4294967295 m	Very large (default: 4294967295 m)
 test: X23 = 239471 s	Negative T number (default: 239471 s)
+test: T30 = 50 s	Testing range min (default: 50 s, range: [20 .. inf])
+test: T31 = 50 s	Testing range max (default: 50 s, range: [0 .. 52])
+test: T32 = 50 s	Testing range both (default: 50 s, range: [20 .. 52])
 software: T1 = 30 m	Write code (default: 30 m)
 software: T2 = 20 ms	Hit segfault (default: 20 ms)
 software: T3 = 480 m	Fix bugs (default: 480 m)
@@ -38,6 +41,9 @@
 test: T4 = 100	Testing a hundred potatoes (default: 100)
 test: T2147483647 = 4294967295 m	Very large (default: 4294967295 m)
 test: X23 = 239471 s	Negative T number (default: 239471 s)
+test: T30 = 50 s	Testing range min (default: 50 s, range: [20 .. inf])
+test: T31 = 50 s	Testing range max (default: 50 s, range: [0 .. 52])
+test: T32 = 50 s	Testing range both (default: 50 s, range: [20 .. 52])
 software: T1 = 30 m	Write code (default: 30 m)
 software: T2 = 20 ms	Hit segfault (default: 20 ms)
 software: T3 = 480 m	Fix bugs (default: 480 m)
@@ -83,6 +89,9 @@
 test: T4 = 100	Testing a hundred potatoes (default: 100)
 test: T2147483647 = 4294967295 m	Very large (default: 4294967295 m)
 test: X23 = 239471 s	Negative T number (default: 239471 s)
+test: T30 = 50 s	Testing range min (default: 50 s, range: [20 .. inf])
+test: T31 = 50 s	Testing range max (default: 50 s, range: [0 .. 52])
+test: T32 = 50 s	Testing range both (default: 50 s, range: [20 .. 52])
 software: T1 = 30 m	Write code (default: 30 m)
 software: T2 = 20 ms	Hit segfault (default: 20 ms)
 software: T3 = 480 m	Fix bugs (default: 480 m)
@@ -167,6 +176,32 @@
 tdef_vty_test(config)# timer te T2 100
 % Ambiguous command.
 
+tdef_vty_test(config)# timer test 30 40
+tdef_vty_test(config)# timer test 30 60
+tdef_vty_test(config)# timer test 30 10
+% Timer T30 value 10 is out of range [20 .. inf]
+
+tdef_vty_test(config)# timer test 31 40
+tdef_vty_test(config)# timer test 31 60
+% Timer T31 value 60 is out of range [0 .. 52]
+tdef_vty_test(config)# timer test 31 10
+
+tdef_vty_test(config)# timer test 32 40
+tdef_vty_test(config)# timer test 32 60
+% Timer T32 value 60 is out of range [20 .. 52]
+tdef_vty_test(config)# timer test 32 10
+% Timer T32 value 10 is out of range [20 .. 52]
+
+tdef_vty_test(config)# timer test
+test: T1 = 100 s	Testing a hundred seconds (default: 100 s)
+test: T2 = 100 ms	Testing a hundred milliseconds (default: 100 ms)
+test: T3 = 100 m	Testing a hundred minutes (default: 100 m)
+test: T4 = 100	Testing a hundred potatoes (default: 100)
+test: T2147483647 = 4294967295 m	Very large (default: 4294967295 m)
+test: X23 = 239471 s	Negative T number (default: 239471 s)
+test: T30 = 60 s	Testing range min (default: 50 s, range: [20 .. inf])
+test: T31 = 10 s	Testing range max (default: 50 s, range: [0 .. 52])
+test: T32 = 40 s	Testing range both (default: 50 s, range: [20 .. 52])
 
 tdef_vty_test(config)# do show timer software
 software: T1 = 30 m	Write code (default: 30 m)
@@ -230,6 +265,9 @@
 test: T4 = 100	Testing a hundred potatoes (default: 100)
 test: T2147483647 = 4294967295 m	Very large (default: 4294967295 m)
 test: X23 = 239471 s	Negative T number (default: 239471 s)
+test: T30 = 60 s	Testing range min (default: 50 s, range: [20 .. inf])
+test: T31 = 10 s	Testing range max (default: 50 s, range: [0 .. 52])
+test: T32 = 40 s	Testing range both (default: 50 s, range: [20 .. 52])
 software: T1 = 13 m	Write code (default: 30 m)
 software: T2 = 0 ms	Hit segfault (default: 20 ms)
 software: T3 = 23 m	Fix bugs (default: 480 m)
@@ -245,6 +283,9 @@
 test: T4 = 100	Testing a hundred potatoes (default: 100)
 test: T2147483647 = 4294967295 m	Very large (default: 4294967295 m)
 test: X23 = 239471 s	Negative T number (default: 239471 s)
+test: T30 = 60 s	Testing range min (default: 50 s, range: [20 .. inf])
+test: T31 = 10 s	Testing range max (default: 50 s, range: [0 .. 52])
+test: T32 = 40 s	Testing range both (default: 50 s, range: [20 .. 52])
 software: T1 = 13 m	Write code (default: 30 m)
 software: T2 = 0 ms	Hit segfault (default: 20 ms)
 software: T3 = 23 m	Fix bugs (default: 480 m)
@@ -252,6 +293,9 @@
 tdef_vty_test(config)# show running-config
 ... !timer
 timer tea T3 32
+timer test T30 60
+timer test T31 10
+timer test T32 40
 timer software T1 13
 timer software T2 0
 timer software T3 23
@@ -261,6 +305,9 @@
 tdef_vty_test(config)# timer software T1 default
 tdef_vty_test(config)# show running-config
 ... !timer
+timer test T30 60
+timer test T31 10
+timer test T32 40
 timer software T2 0
 timer software T3 23
 ... !timer
@@ -269,5 +316,8 @@
 tdef_vty_test(config)# timer software 2 default
 tdef_vty_test(config)# show running-config
 ... !timer
+timer test T30 60
+timer test T31 10
+timer test T32 40
 timer software T3 23
 ... !timer