Page MenuHomeClusterLabs Projects

No OneTemporary

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

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)

Event Timeline