Page Menu
Home
ClusterLabs Projects
Search
Configure Global Search
Log In
Files
F1841629
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
10 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/.gitignore b/.gitignore
index a1bbe1eab8..7de6e416f1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,243 +1,244 @@
# Common
\#*
.\#*
GPATH
GRTAGS
GTAGS
TAGS
Makefile
Makefile.in
.deps
.dirstamp
.libs
*.pc
*.pyc
*.bz2
*.tar.gz
*.tgz
*.la
*.lo
*.o
*~
*.gcda
*.gcno
# Autobuild
aclocal.m4
autoconf
autoheader
autom4te.cache/
automake
build.counter
compile
/confdefs.h
config.guess
config.log
config.status
config.sub
configure
/conftest*
depcomp
install-sh
include/stamp-*
libtool
libtool.m4
ltdl.m4
libltdl
ltmain.sh
missing
py-compile
/m4/argz.m4
/m4/ltargz.m4
/m4/ltoptions.m4
/m4/ltsugar.m4
/m4/ltversion.m4
/m4/lt~obsolete.m4
test-driver
ylwrap
# Configure targets
/cts/CTS.py
/cts/CTSlab.py
/cts/CTSvars.py
/cts/LSBDummy
/cts/OCFIPraTest.py
/cts/benchmark/clubench
/cts/cluster_test
/cts/cts
/cts/cts-cli
/cts/cts-coverage
/cts/cts-exec
/cts/cts-fencing
/cts/cts-log-watcher
/cts/cts-regression
/cts/cts-scheduler
/cts/cts-support
/cts/fence_dummy
/cts/lxc_autogen.sh
/cts/pacemaker-cts-dummyd
/cts/pacemaker-cts-dummyd@.service
/daemons/execd/pacemaker_remote
/daemons/execd/pacemaker_remote.service
/daemons/fenced/fence_legacy
/daemons/pacemakerd/pacemaker
/daemons/pacemakerd/pacemaker.combined.upstart
/daemons/pacemakerd/pacemaker.service
/daemons/pacemakerd/pacemaker.upstart
/doc/Doxyfile
/extra/logrotate/pacemaker
/extra/resources/ClusterMon
/extra/resources/HealthSMART
/extra/resources/SysInfo
/extra/resources/ifspeed
/extra/resources/o2cb
include/config.h
include/config.h.in
include/crm_config.h
publican.cfg
/tools/cibsecret
/tools/crm_error
/tools/crm_failcount
/tools/crm_master
/tools/crm_mon.service
/tools/crm_mon.upstart
/tools/crm_report
/tools/crm_rule
/tools/crm_standby
/tools/pcmk_simtimes
/tools/report.collector
/tools/report.common
# Build targets
*.7
*.7.xml
*.7.html
*.8
*.8.xml
*.8.html
/daemons/attrd/pacemaker-attrd
/daemons/based/pacemaker-based
/daemons/based/cibmon
/daemons/controld/pacemaker-controld
/daemons/execd/cts-exec-helper
/daemons/execd/pacemaker-execd
/daemons/execd/pacemaker-remoted
/daemons/fenced/cts-fence-helper
/daemons/fenced/pacemaker-fenced
/daemons/fenced/pacemaker-fenced.xml
/daemons/pacemakerd/pacemakerd
/daemons/schedulerd/pacemaker-schedulerd
/daemons/schedulerd/pacemaker-schedulerd.xml
/doc/*/tmp/**
/doc/*/publish
/doc/*.build
/doc/*/en-US/Ap-*.xml
/doc/*/en-US/Ch-*.xml
/doc/.ABI-build
/doc/HTML
/doc/abi_dumps
/doc/abi-check
/doc/api/*
/doc/compat_reports
/doc/crm_fencing.html
/doc/publican-catalog*
/doc/shared/en-US/*.xml
/doc/shared/en-US/images/pcmk-*.png
/doc/shared/en-US/images/Policy-Engine-*.png
/doc/sphinx/*/_build
/doc/sphinx/*/conf.py
/lib/common/md5.c
/maint/testcc_helper.cc
/maint/testcc_*_h
/maint/mocked/based
scratch
/tools/attrd_updater
/tools/cibadmin
/tools/crmadmin
/tools/crm_attribute
/tools/crm_diff
/tools/crm_mon
/tools/crm_node
/tools/crm_resource
/tools/crm_shadow
/tools/crm_simulate
/tools/crm_ticket
/tools/crm_verify
/tools/iso8601
/tools/stonith_admin
xml/crm.dtd
xml/pacemaker*.rng
xml/versions.rng
xml/api/api-result*.rng
lib/gnu/libgnu.a
lib/gnu/stdalign.h
*.coverity
# Packager artifacts
*.rpm
/mock
/pacemaker.spec
/rpm/[A-Z]*
# make dist/export working directory
pacemaker-[a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9]
# Test detritus
/cts/.regression.failed.diff
/cts/scheduler/*.ref
/cts/scheduler/*.up
/cts/scheduler/*.up.err
/cts/scheduler/bug-rh-1097457.log
/cts/scheduler/bug-rh-1097457.trs
/cts/scheduler/shadow.*
/cts/test-suite.log
/xml/test-*/*.up
/xml/test-*/*.up.err
/xml/assets/*.rng
/xml/assets/diffview.js
/xml/assets/xmlcatalog
# Test results
*.log
*.trs
+/lib/common/tests/strings/pcmk__scan_double
/lib/common/tests/strings/pcmk__parse_ll_range
/lib/common/tests/strings/pcmk__str_any_of
/lib/common/tests/strings/pcmk__strcmp
/lib/common/tests/utils/pcmk_str_is_infinity
/lib/common/tests/utils/pcmk_str_is_minus_infinity
/lib/pengine/tests/rules/pe_cron_range_satisfied
# Release maintenance detritus
/maint/gnulib
# Formerly built files (helps when jumping back and forth in checkout)
/.ABI-build
/Doxyfile
/HTML
/abi_dumps
/abi-check
/compat_reports
/attrd
/cib
/coverage.sh
/crmd
/cts/HBDummy
/doc/Clusters_from_Scratch.txt
/doc/Pacemaker_Explained.txt
/doc/acls.html
/fencing
/lrmd
/mcp
/pacemaker-*.spec
/pengine
#Other
coverity-*
logs
*.patch
*.diff
*.sed
*.orig
*.rej
*.swp
diff --git a/lib/common/tests/strings/Makefile.am b/lib/common/tests/strings/Makefile.am
index 11c3bd3c00..5c5e29181e 100644
--- a/lib/common/tests/strings/Makefile.am
+++ b/lib/common/tests/strings/Makefile.am
@@ -1,21 +1,22 @@
AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/include
LDADD = $(top_builddir)/lib/common/libcrmcommon.la
include $(top_srcdir)/mk/glib-tap.mk
# Add each test program here. Each test should be written as a little standalone
# program using the glib unit testing functions. See the documentation for more
# information.
#
# https://developer.gnome.org/glib/unstable/glib-Testing.html
-test_programs = pcmk__parse_ll_range \
+test_programs = pcmk__scan_double \
+ pcmk__parse_ll_range \
pcmk__str_any_of \
pcmk__strcmp
# If any extra data needs to be added to the source distribution, add it to the
# following list.
dist_test_data =
# If any extra data needs to be used by tests but should not be added to the
# source distribution, add it to the following list.
test_data =
diff --git a/lib/common/tests/strings/pcmk__scan_double.c b/lib/common/tests/strings/pcmk__scan_double.c
new file mode 100644
index 0000000000..1e6138a2e6
--- /dev/null
+++ b/lib/common/tests/strings/pcmk__scan_double.c
@@ -0,0 +1,161 @@
+#include <float.h> // DBL_MAX, etc.
+#include <math.h> // fabs()
+
+#include <glib.h>
+
+#include <crm_internal.h>
+
+// Ensure plenty of characters for %f display
+#define LOCAL_BUF_SIZE 2 * DBL_MAX_10_EXP
+
+/*
+ * Avoids compiler warnings for floating-point equality checks.
+ * Use for comparing numbers (e.g., 1.0 == 1.0), not expression values.
+ */
+#define ASSERT_DBL_EQ(d1, d2) g_assert_cmpfloat(fabs(d1 - d2), \
+ <, DBL_EPSILON);
+
+static void
+empty_input_string(void)
+{
+ double result;
+
+ // Without default_text
+ g_assert_cmpint(pcmk__scan_double(NULL, &result, NULL, NULL), ==, EINVAL);
+ ASSERT_DBL_EQ(result, PCMK__PARSE_DBL_DEFAULT);
+
+ g_assert_cmpint(pcmk__scan_double("", &result, NULL, NULL), ==, EINVAL);
+ ASSERT_DBL_EQ(result, PCMK__PARSE_DBL_DEFAULT);
+
+ // With default_text
+ g_assert_cmpint(pcmk__scan_double(NULL, &result, "2.0", NULL), ==,
+ pcmk_rc_ok);
+ ASSERT_DBL_EQ(result, 2.0);
+
+ g_assert_cmpint(pcmk__scan_double("", &result, "2.0", NULL), ==, EINVAL);
+ ASSERT_DBL_EQ(result, PCMK__PARSE_DBL_DEFAULT);
+}
+
+static void
+bad_input_string(void)
+{
+ double result;
+
+ // Without default text
+ g_assert_cmpint(pcmk__scan_double("asdf", &result, NULL, NULL), ==, EINVAL);
+ ASSERT_DBL_EQ(result, PCMK__PARSE_DBL_DEFAULT);
+
+ g_assert_cmpint(pcmk__scan_double("as2.0", &result, NULL, NULL), ==,
+ EINVAL);
+ ASSERT_DBL_EQ(result, PCMK__PARSE_DBL_DEFAULT);
+
+ // With default text (not used)
+ g_assert_cmpint(pcmk__scan_double("asdf", &result, "2.0", NULL), ==,
+ EINVAL);
+ ASSERT_DBL_EQ(result, PCMK__PARSE_DBL_DEFAULT);
+
+ g_assert_cmpint(pcmk__scan_double("as2.0", &result, "2.0", NULL), ==,
+ EINVAL);
+ ASSERT_DBL_EQ(result, PCMK__PARSE_DBL_DEFAULT);
+}
+
+static void
+trailing_chars(void)
+{
+ double result;
+
+ g_assert_cmpint(pcmk__scan_double("2.0asdf", &result, NULL, NULL), ==,
+ pcmk_rc_ok);
+ ASSERT_DBL_EQ(result, 2.0);
+}
+
+static void
+typical_case(void)
+{
+ char str[LOCAL_BUF_SIZE];
+ double result;
+
+ g_assert_cmpint(pcmk__scan_double("0.0", &result, NULL, NULL), ==,
+ pcmk_rc_ok);
+ ASSERT_DBL_EQ(result, 0.0);
+
+ g_assert_cmpint(pcmk__scan_double("1.0", &result, NULL, NULL), ==,
+ pcmk_rc_ok);
+ ASSERT_DBL_EQ(result, 1.0);
+
+ g_assert_cmpint(pcmk__scan_double("-1.0", &result, NULL, NULL), ==,
+ pcmk_rc_ok);
+ ASSERT_DBL_EQ(result, -1.0);
+
+ snprintf(str, LOCAL_BUF_SIZE, "%f", DBL_MAX);
+ g_assert_cmpint(pcmk__scan_double(str, &result, NULL, NULL), ==,
+ pcmk_rc_ok);
+ ASSERT_DBL_EQ(result, DBL_MAX);
+
+ snprintf(str, LOCAL_BUF_SIZE, "%f", -DBL_MAX);
+ g_assert_cmpint(pcmk__scan_double(str, &result, NULL, NULL), ==,
+ pcmk_rc_ok);
+ ASSERT_DBL_EQ(result, -DBL_MAX);
+}
+
+static void
+double_overflow(void)
+{
+ char str[LOCAL_BUF_SIZE];
+ double result;
+
+ /*
+ * 1e(DBL_MAX_10_EXP + 1) produces an inf value
+ * Can't use ASSERT_DBL_EQ() because (inf - inf) == NaN
+ */
+ snprintf(str, LOCAL_BUF_SIZE, "1e%d", DBL_MAX_10_EXP + 1);
+ g_assert_cmpint(pcmk__scan_double(str, &result, NULL, NULL), ==, EOVERFLOW);
+ g_assert_cmpfloat(result, >, DBL_MAX);
+
+ snprintf(str, LOCAL_BUF_SIZE, "-1e%d", DBL_MAX_10_EXP + 1);
+ g_assert_cmpint(pcmk__scan_double(str, &result, NULL, NULL), ==, EOVERFLOW);
+ g_assert_cmpfloat(result, <, -DBL_MAX);
+}
+
+static void
+double_underflow(void)
+{
+ char str[LOCAL_BUF_SIZE];
+ double result;
+
+ /*
+ * 1e(DBL_MIN_10_EXP - 1) produces a denormalized value (between 0
+ * and DBL_MIN)
+ *
+ * C99/C11: result will be **no greater than** DBL_MIN
+ */
+ snprintf(str, LOCAL_BUF_SIZE, "1e%d", DBL_MIN_10_EXP - 1);
+ g_assert_cmpint(pcmk__scan_double(str, &result, NULL, NULL), ==,
+ pcmk_rc_underflow);
+ g_assert_cmpfloat(result, >=, 0.0);
+ g_assert_cmpfloat(result, <=, DBL_MIN);
+
+ snprintf(str, LOCAL_BUF_SIZE, "-1e%d", DBL_MIN_10_EXP - 1);
+ g_assert_cmpint(pcmk__scan_double(str, &result, NULL, NULL), ==,
+ pcmk_rc_underflow);
+ g_assert_cmpfloat(result, <=, 0.0);
+ g_assert_cmpfloat(result, >=, -DBL_MIN);
+}
+
+int main(int argc, char **argv)
+{
+ g_test_init(&argc, &argv, NULL);
+
+ // Test for input string issues
+ g_test_add_func("/common/strings/double/empty_input", empty_input_string);
+ g_test_add_func("/common/strings/double/bad_input", bad_input_string);
+ g_test_add_func("/common/strings/double/trailing_chars", trailing_chars);
+
+ // Test for numeric issues
+ g_test_add_func("/common/strings/double/typical", typical_case);
+ g_test_add_func("/common/strings/double/overflow", double_overflow);
+ g_test_add_func("/common/strings/double/underflow", double_underflow);
+
+ return g_test_run();
+}
+
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sat, Nov 23, 6:53 AM (1 d, 18 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1013446
Default Alt Text
(10 KB)
Attached To
Mode
rP Pacemaker
Attached
Detach File
Event Timeline
Log In to Comment