From: Florian Forster Date: Sat, 6 Jun 2015 19:39:16 +0000 (+0200) Subject: Merge branch 'pr/1033' X-Git-Tag: collectd-5.6.0~704 X-Git-Url: https://git.octo.it/?a=commitdiff_plain;h=3f9f6b9bc37cfd8ee3eb7a21cb895ff524c533c8;hp=2c6f2a6c9ccfe8cfe4f605683e0e2e365da11f82;p=collectd.git Merge branch 'pr/1033' --- diff --git a/AUTHORS b/AUTHORS index 3f63c3dc..02b12568 100644 --- a/AUTHORS +++ b/AUTHORS @@ -78,6 +78,9 @@ Christophe Kalt Cyril Feraudet - ethstat plugin. +Dagobert Michelsen + - zone plugin. + Dan Berrange - uuid plugin. @@ -174,6 +177,9 @@ Marco Chiappero - ip6tables support in the iptables plugin. - openvpn plugin (support for more status file formats) +Mathijs Möhlmann + - zone plugin. + Michael Hanselmann - md plugin. diff --git a/ChangeLog b/ChangeLog index 28be899a..b0a997c5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,282 @@ +2015-05-27, Version 5.5.0 + * Build system: Ability to make out-of-tree builds has been fixed. + Thanks to Vincent Bernat. #792 + * Build system, Disk and Users plugins: Detection and use of libstatgrab + ≧ 0.90 has been added. Thanks to Vincent Bernat. #445, #795, #806, + #807, #908 + * Build system, Memory, CPU, TCPConns and Processes plugins: Numerous + fixes related to OpenBSD support have been added. Thanks to Landry + Breuil. #777, #778, #779, #808 + * Build system: Plugins now only export "module_register()". Thanks to + Florian Forster. + * Build system: Various cleanups and improvements have been done. Thanks + to Marc Fournier. + * collectd: Numerous internal changes and improvements to the daemon and + the plugin API have been make. Thanks to Florian Forster, Pierre-Yves + Ritschard and Alex Petrov. #512, #727 + * collectd: Numerous spelling mistakes have been corrected in comments + and documentation and several error messages have been improved. + Thanks to Ruben Kerkhof, Abhinav Upadhyay, Olivier Bazoud, Pierre-Yves + Ritschard, Tim Smith, Moshe Zada, Katelyn Perry and Marc Fournier. + * collectd: Rules/Targets can now be appended to existing Filter Chains. + Thanks to Marc Falzon. #444 + * collectd: Failing Filter Chains destinations will now log the list of + available write targets. Thanks to Wilfried Goesgens. #650, #1043 + * collectd: Support for process signaling and management by upstart and + systemd has been implemented for the Linux platform. Thanks to + Pierre-Yves Ritschard and Marc Fournier. #798, #811, #814 + * collectd: The "CollectInternalStats" option has been added. Thanks to + Yves Mettier. #691 + * collectd: The daemon source code and dependencies have moved to the + "src/daemon/" directory. Thanks to Florian Forster. + * collectd: The new "MaxReadInterval" option allows to cap the + exponential retry interval of plugins read errors. Thanks to Alexey + Remizov and Florian Forster. #713 + * collectd: The "-P" command-line option now has precedence over the + "PIDFile" option. Thanks to Thomas D. #553 + * collection.cgi: Various data-source related adjustments have been + made. Thanks to Fabiano Pires and Sebastian Harl. + * libcollectdclient: Now propagates errors when signing / encrypting + network packets. Thanks to Florian Forster. + * Configuration: Support for unquoted IPv6 addresses has been added. + Thanks to Sebastian Harl. #489 + * Documentation: Various improvements have been done. Thanks to Florian + Forster and Marc Fournier. + * Examples: the sample C plugin has been updated to the current plugin + API. Thanks to Sebastian Harl. + * Licensing: The following components have been relicensed to the MIT + license: the Apple Sensors, Ascent, DBI, E-Mail, Entropy, GenericJMX, + gmond, LogFile, nginx, Notify Desktop, NTPd, NUT, olsrd, Perl, Ping, + PostgreSQL, Protocols, RouterOS, RRDCacheD, SNMP, StatsD, SysLog, + Table, Tail, UnixSock, vmem, VServer, Wireless, Write Riemann and XMMS + plugins, the core collectd daemon, the collectdmon, collectd-nagios + and collectd-tg utilities, all the Targets and Matches, liboconfig, + most of the "utils_*" files and the plugin API. + * Tests: A test suite has been added. Thanks to Florian Forster. + * Threshold: The hysteresis calculation has been made more reliable. + Thanks to Jan Kundrát. #581 + * Threshold: Various fixes and improvements have been made. Thanks to + Manuel Luis Sanmartín Rozada. #649, #644 + * AMQP plugin: The "ConnectionRetryDelay" option has been added, + allowing to delay reconnection. Thanks to Yoga Ramalingam and Marc + Fournier. #833 + * AMQP plugin: The "QueueDurable" and "QueueAutoDelete" options have + been added, giving control over queue creation and deletion. Thanks to + David Blundell and Marc Fournier. #623 + * Apache, Ascent, BIND, cURL, cURL-JSON, cURL-XML, nginx and Write HTTP + plugins: Customizing the "User-Agent" field is now possible at + compile-time. Thanks to Jeremy Katz. #440 + * Apache, Ascent, BIND, cURL, cURL-JSON, cURL-XML, nginx plugins: The + connection will be reset if it hasn't completed within the configured + "Interval". The new "Timeout" option gives control over this behavior. + Thanks to Jan Kundrát and Marc Fournier. #982, #983, #993 + * Apache, Ascent, cURL, cURL-JSON, cURL-XML, nginx, Write HTTP plugins: + Allow usernames and passwords to contain colons if built against + libcurl ≧ 7.19.1. Thanks to Marc Fournier. #695, #947 + * Apache plugin: The "SSLCiphers" option gives control over the + encryption algorithms to use with TLS connections. Thanks to Toni + Moreno. #946 + * Barometer plugin: This new plugin reads sensor data from various + Freescale and Bosch digital barometers. Thanks to Tomas Menzl. #69, + #693 + * Battery plugin: Reporting values as percentages and reporting degraded + batteries has been added. Thanks to Florian Forster. + * Battery plugin: Support for reading values from sysfs on Linux has + been added. Thanks to Andy Parkins, Nicholas Humfrey, Peter Wu and + Florian Forster. #725, #810, #998 + * Battery plugin: The value for current is no longer supplied unless the + battery provides this information. Thanks to Florian Forster. + * BIND plugin: Bind's XML v3 API is now supported; Thanks to Victor + Berger, Bruno Prémont and Michal Humpula. #742, #847 + * Ceph plugin: This new plugin collects statistics from the Ceph + distributed storage system. Thanks to Dan Ryder, Dennis Zou, Colin + McCabe, Sage Weil. #522, #598 + * ConnTrack plugin: Support for reporting values as percentages as well + as legacy conntrack files in "/proc" has been added. Thanks to + Pierre-Yves Ritschard. #497, #680 + * CPU plugin: The plugin is now able to report values as percentages and + aggregate values per-state and per-CPU. Thanks to Pierre-Yves + Ritschard, Florian Forster, Fabien Wernli, Nicholas Humfrey and + Wilfried Goesgens. #499, #516, #639 #734, #812, #802 + * cURL-JSON plugin: Extracting values from complex JSON structures has + been enhanced. Thanks to Jim Radford. #408, #411 + * cURL-JSON plugin: Intervals can now be configured on a per-URL basis. + Thanks to Stan Sawa. #685 + * cURL-JSON, cURL-XML, Write HTTP plugins: These plugins now also follow + HTTP redirects. Thanks to Marc Fournier. + * cURL, cURL-JSON, cURL-XML plugins: HTTP Digest authentication has been + implemented. Thanks to Frank Cornelis. #482 + * DBI, Oracle, PostgreSQL plugins: A "MetadataFrom" parameter has been + added which allows to set metadata from database columns. Thanks to + Mark Wong. #317, #321 + * DBI plugin: Querying several databases in parallel is now possible. + Thanks to Vincent Bernat. #453 + * Disk plugin: On the Linux platform, disk names can now get looked up + in udev with the "UdevNameAttr" option. Thanks to Patrick Mooney. #537 + * Disk plugin: This plugin now collects several additional I/O-related + metrics on the Linux platform. Thanks to Florian Forster and Michael + Schenck. #705, #759 + * DRBD plugin: This new plugin reads Linux's Distributed Replicated + Block Device (DRBD) statistics. Thanks to Tim Laszlo. #566, #700 + * Exec, UnixSock plugins: The "PUTNOTIF" command now allows to set + metadata on notifications. Thanks to John-John Tedro. #416 + * fhcount plugin: This new plugin reports the number of used file + handles. Thanks to Jiri Tyr. #1009 + * GenericJMX plugin: A Class Loader for "JMXConnectorFactory" has been + added, allowing the plugin to work with JBOSS > 7. Thanks to Alexandre + Moutot. #452 + * IPC plugin: This new plugin collects information related to shared + memory. Thanks to Andrés J. Díaz. #925 + * Java plugin: Now uses the hostname defined in the configuration file. + Thanks to Pierre-Yves Ritschard. #530, #681 + * Load plugin: The plugin is now able to report values as percentages. + Thanks to Vedran Bartonicek and Pierre-Yves Ritschard. #344, #498 + * Log Logstash plugin: This new plugin writes collectd logs and events + as Logstash JSON formatted events. Thanks to Pierre-Yves Ritschard. + #360 + * LVM plugin: The plugin collects thin pool data volumes size, and no + longer reports virtual volumes. Thanks to Benjamin Gilbert. #603 + * memcached plugin: "listen_disabled_num" are now also reported. Thanks + to Matt Cottingham. #622 + * Memory plugin: Slab memory reporting on the Linux platform has been + added. Thanks to Manuel CISSÉ and Marc Fournier. #560, #697 + * Memory plugin: The plugin is now able to report values as percentages. + Thanks to Jeremy Katz, Florian Forster and Manuel CISSÉ. #501, #511, + #559 + * Modbus plugin: Selecting between holding and input registers is now + possible. Thanks to Jan Vitek. #338 + * Modbus plugin: Support for accessing devices through an RS-485 serial + port has been added. Thanks to Eric Sandeen. + * Multimeter plugin: This plugin isn't built by default on the AIX + platform anymore. Thanks to Manuel Luis Sanmartin Rozada. #549, #684 + * MySQL and PostgreSQL plugins: Passing "127.0.0.1" as a host will now + result in the global Hostname being used in metric names. Thanks to + Jeremy Katz. #441 + * MySQL plugin: InnoDB, Select and Sort statistics collection has been + added. Thanks to Wilson Felipe, Marek Becka and Pierre-Yves Ritschard. + #248, #621, #699, #824 + * MySQL plugin: The "Alias" and "ConnectTimeout" options have been + added. Thanks to William Tisäter. + * Netlink plugin: Support for 64bit netlink counters has been added. + Thanks to Marek Becka. #435 + * Network plugin: The "ReconnectInterval" configuration option has been + added. Thanks to John Ferlito. #732 + * NFS plugin: Support for NFSv4.0 has been implemented. Thanks to Marek + Becka. #550 + * OneWire plugin: Support for more temperature-providing sensor families + has been added. Thanks to Tomasz Torcz. #672 + * OneWire plugin: Support for full OWFS path and more device families + has been implemented. Thanks to Tomas Menzl. #68 + * OpenLDAP plugin: This new plugin reads monitoring information from + OpenLDAP's "cn=Monitor" subtree. Thanks to Kimo Rosenbaum, Marc + Fournier and Nicholas Humfrey. #719 + * OpenVPN plugin: Support for OpenVPN 2.3.0 has been implemented. Thanks + to Ed Okerson. #252 + * OpenVZ plugin: Various improvements have been made, making the plugin + report values like the other collectd plugins do. Thanks to Chris + Lundquist. #264 + * Perl plugin: A new "listval_filter" method has been added, various + internal cleanups and improvements have been made and a test suite has + been added. Thanks to Matthias Bethke. #728 + * PostgreSQL plugin: The new "ExpireDelay" option allows skipping older + values pending write when the database slows down. Thanks to Stephen + O'Dor. #593 + * PowerDNS plugin: The plugin was updated for stats from pdns 3.4.3. + Thanks to Ruben Kerkhof. #965 + * Processes plugin: A memory-usage related optimization for low-profile + systems has been added. Thanks to Florian Forster. #652 + * Python plugin: Support for Python3 has been improved, "ModulePath" is + now prepended to "sys.path", and the "get_dataset()" function has been + added to the Python API. Thanks to Sven Trenkel and Patrick Browne. + #890, #751, #771 + * Redis and Write_Redis plugins: The support library has been switched + from credis to hiredis. Thanks to Andrés J. Díaz, Victor Seva, Marc + Fournier, Johan Bergström, Michael Spiegle and brianpkelly. #296, + #464, #475, #799, #1030 + * Redis plugin: Custom commands can now be used to fetch values stored + in Redis. Thanks to Pierre-Yves Ritschard. #816 + * Redis plugin: Support for passwords up to 512 characters long has been + added. Thanks to Jeremy Katz. #532 + * Sensors plugin: Support for lm_sensors' power sensors has been added. + Thanks to Jan Kundrát. #571 + * SMART plugin: This new plugin collects SMART statistics from disk + drives. Thanks to Vincent Bernat. #797 + * SNMP plugin: A blacklist/whitelist feature can now be used to filter + which OIDs to collect. Thanks to Christophe Courtaut. #414 + * SNMP plugin: SNMPv3 authentication and encryption support has been + implemented. Thanks to Michael Pilat. #362 + * SNMP plugin: Two error messages have been disambiguated. Thanks to + Sergey. #939, #952 + * Swap plugin: The plugin is now able to report values as percentages. + Thanks to Jeremy Katz and Florian Forster. #500, #510 + * Swap plugin: The plugin no longer fails on Linux systems where + "SwapCached" isn't exposed by the kernel. Thanks to Florian Forster. + #733 + * Tail plugin: "GaugeInc" and "GaugeAdd" options have been implemented. + Thanks to Andre Ferraz. #673 + * Tail plugin: Intervals can now be configured on a per-File basis. + Thanks to Tom Leaman. #446 + * TCPConns plugin: The "AllPortsSummary" option, allowing to summarize + all connections, has been added. Thanks to Marek Becka. #488 + * TCPConns plugin: Three metrics were renamed on the AIX platform, for + the sake of consistency. Thanks to Manuel Luis Sanmartín Rozada. #546 + * Turbostat plugin: This new plugin reads CPU frequency and C-state + residency on modern Intel turbo-capable processors. Thanks to Vincent + Brillault, Jean Delvare and Nicolas Iooss. #651 + * UnixSock plugin: The "GETTHRESHOLD" command has been re-added. Thanks + to Manuel Luis Sanmartín Rozada. #674 + * Varnish plugin: Varnish 4 support has been added, as well as as + monitoring metrics only available in Varnish 4. Thanks to Marc + Fournier. #618, #783 + * virt plugin: Guests memory usage is now also collected. Thanks to + Tiago Carvalho, jazzmes and Zollner Robert. + * virt plugin: It is now possible to chose between using guests' name or + UUID as plugin_instance. Thanks to Remi Ferrand. #385 + * virt plugin: The libvirt plugin has been renamed to virt. Thanks to + Florian Forster. + * Write Graphite plugin: When the connection to graphite fails, + reconnection attempts are now limited to once per second. Thanks to + Florian Forster. #625 + * Write HTTP plugin: Multi-instance support of this plugin has been + improved. The "" block has been deprecated in favor of + "". Thanks to Marc Fournier. #902 + * Write HTTP plugin: Several TLS-related configuration options have been + added. Thanks to Ingmar Runge. #666 + * Write HTTP plugin: The "LowSpeedLimit" and "Timeout" options allow to + reset slow/stalled network connections. Thanks to loginator17 and Marc + Fournier. #752, #985 + * Write HTTP plugin: The size of the payload posted to the HTTP server + can now be controlled with the "BufferSize" option. Thanks to Florian + Forster. #722 + * Write Kafka plugin: This new plugin sends data to Apache Kafka, a + distributed messaging queue. Thanks to Pierre-Yves Ritschard, + ciomaire, Vincent Bernat, Marc Fournier. #670, #694, #794, #853, #014 + * Write Log plugin: This new plugin dispatches collected values to the + configured log destination(s). Thanks to Pierre-Yves Ritschard. #886 + * Write Riemann plugin: Extra meta strings are now added as attributes + in notifications. Thanks to John-John Tedro. #417 + * Write Riemann plugin: Notification message are now sent to the Riemann + server via the description field. Thanks to Adrian Miron. #575 + * Write Riemann plugin: Support for custom attributes has been added. + Thanks to Pierre-Yves Ritschard. #459 + * Write Riemann plugin: Support had been implemented for sending events + to Riemann in batches (when using TCP), and is enabled by default. + Thanks to Pierre-Yves Ritschard. #800 + * Write Riemann plugin: The "EventServicePrefix" option has been added, + which adds a prefix to event service names. Thanks to Moshe Zada. #706 + * Write Riemann plugin: Threshold checks can now be passed down to the + Riemann server. Thanks to Pierre-Yves Ritschard. #518 + * Write Sensu plugin: This new plugin submits values to Sensu, a stream + processing and monitoring system. Thanks to Fabrice A. Marie and Marc + Fournier. #912, #1001, #1016 + * Write TSDB plugin: This new plugin sends data to OpenTSDB, a scalable + time series database. Thanks to Kevin Bowling, Florian Forster, Dallin + Young, Michael Schenck and Pierre-Yves Ritschard. #703, #772, #945 + * ZFS ARC plugin: Support for ZFS-on-Linux has been added. Thanks to + Marc Fournier and Wilfried Goesgens. #552 + * Zookeeper plugin: This new plugin reads data from the Apache Zookeeper + "MNTR" command. Thanks to Jeremy Katz. #826 + 2015-02-26, Version 5.4.2 * Build system: Numerous fixes. Thanks to Bjørn Nordbø, Jim Radford, KOMEDA Shinji, Lauri Tirkkonen, Manuel Luis Sanmartin Rozada, Marc diff --git a/README b/README index 9604fda3..6f2fb724 100644 --- a/README +++ b/README @@ -385,6 +385,10 @@ Features - zfs_arc Statistics for ZFS' “Adaptive Replacement Cache” (ARC). + - zone + Measures the percentage of cpu load per container (zone) under Solaris 10 + and higher + - zookeeper Read data from Zookeeper's MNTR command. diff --git a/bindings/java/Makefile.am b/bindings/java/Makefile.am index f8e936a8..8d2e49d7 100644 --- a/bindings/java/Makefile.am +++ b/bindings/java/Makefile.am @@ -24,7 +24,7 @@ EXTRA_DIST = org/collectd/api/CollectdConfigInterface.java \ org/collectd/java/GenericJMX.java \ org/collectd/java/JMXMemory.java -java-build-stamp: org/collectd/api/*.java org/collectd/java/*.java +java-build-stamp: $(srcdir)/org/collectd/api/*.java $(srcdir)/org/collectd/java/*.java $(JAVAC) -d "." "$(srcdir)/org/collectd/api"/*.java $(JAVAC) -d "." "$(srcdir)/org/collectd/java"/*.java mkdir -p .libs @@ -41,6 +41,11 @@ install-exec-local: java-build-stamp $(INSTALL) -m 644 .libs/generic-jmx.jar \ "$(DESTDIR)$(pkgdatadir)/java" +uninstall-local: + rm -f "$(DESTDIR)$(pkgdatadir)/java/collectd-api.jar" + rm -f "$(DESTDIR)$(pkgdatadir)/java/generic-jmx.jar" + rmdir "$(DESTDIR)$(pkgdatadir)/java" || true + clean-local: rm -f "org/collectd/api"/*.class rm -f "org/collectd/java"/*.class diff --git a/configure.ac b/configure.ac index 87d1502b..f713ce13 100644 --- a/configure.ac +++ b/configure.ac @@ -5194,6 +5194,7 @@ plugin_vmem="no" plugin_vserver="no" plugin_wireless="no" plugin_zfs_arc="no" +plugin_zone="no" plugin_zookeeper="no" # Linux @@ -5291,6 +5292,7 @@ then plugin_processes="yes" plugin_uptime="yes" plugin_zfs_arc="yes" + plugin_zone="yes" fi if test "x$with_devinfo$with_kstat" = "xyesyes" @@ -5656,6 +5658,7 @@ AC_PLUGIN([write_sensu], [yes], [Sensu output plugin]) AC_PLUGIN([write_tsdb], [yes], [TSDB output plugin]) AC_PLUGIN([xmms], [$with_libxmms], [XMMS statistics]) AC_PLUGIN([zfs_arc], [$plugin_zfs_arc], [ZFS ARC statistics]) +AC_PLUGIN([zone], [$plugin_zone], [Solaris container statistics]) AC_PLUGIN([zookeeper], [yes], [Zookeeper statistics]) dnl Default configuration file @@ -6033,6 +6036,7 @@ Configuration: write_tsdb . . . . . $enable_write_tsdb xmms . . . . . . . . $enable_xmms zfs_arc . . . . . . . $enable_zfs_arc + zone . . . . . . . . $enable_zone zookeeper . . . . . . $enable_zookeeper EOF diff --git a/contrib/collectd.service b/contrib/collectd.service deleted file mode 100644 index ee4d596d..00000000 --- a/contrib/collectd.service +++ /dev/null @@ -1,15 +0,0 @@ -[Unit] -Description=statistics collection daemon -Documentation=man:collectd(1) -After=local-fs.target network.target -Requires=local-fs.target network.target - -[Service] -ExecStart=/usr/sbin/collectd -C /etc/collectd/collectd.conf -f -Restart=always -RestartSec=10 -StandardOutput=syslog -StandardError=syslog - -[Install] -WantedBy=multi-user.target diff --git a/contrib/redhat/collectd.spec b/contrib/redhat/collectd.spec index 5315870f..5e83b0f4 100644 --- a/contrib/redhat/collectd.spec +++ b/contrib/redhat/collectd.spec @@ -214,10 +214,12 @@ %define with_write_mongodb 0%{!?_without_write_mongodb:0} # plugin xmms disabled, requires xmms %define with_xmms 0%{!?_without_xmms:0} +# plugin zone disabled, requires Solaris +%define with_zone 0%{!?_without_zone:0} Summary: statistics collection and monitoring daemon Name: collectd -Version: 5.4.2 +Version: 5.5.0 Release: 1%{?dist} URL: http://collectd.org Source: http://collectd.org/files/%{name}-%{version}.tar.bz2 @@ -1571,6 +1573,12 @@ Collectd utilities %define _with_zfs_arc --disable-zfs_arc %endif +%if %{with_zone} +%define _with_zone --enable-zone +%else +%define _with_zone --disable-zone +%endif + %if %{with_zookeeper} %define _with_zookeeper --enable-zookeeper %else @@ -1672,6 +1680,7 @@ Collectd utilities %{?_with_write_redis} \ %{?_with_xmms} \ %{?_with_zfs_arc} \ + %{?_with_zone} \ %{?_with_zookeeper} \ %{?_with_irq} \ %{?_with_load} \ @@ -2335,15 +2344,21 @@ fi %doc contrib/ %changelog -# * TODO 5.5.0-1 -# - New upstream version -# - New plugins enabled by default: ceph, drbd, log_logstash, write_tsdb, smart, openldap, redis, write_redis, zookeeper, write_log, write_sensu, ipc, turbostat -# - New plugins disabled by default: barometer, write_kafka -# - Enable zfs_arc, now supported on Linux -# - Install disk plugin in a dedicated package, as it depends on libudev -# - use systemd on EL7, sysvinit on EL6 & EL5 -# - Install collectdctl, collectd-tg and collectd-nagios in collectd-utils.rpm -# - Add build-dependency on libcap-devel +#* TODO: next feature release changelog +#- New upstream version +#- New plugins disabled by default: zone +# +* Wed May 27 2015 Marc Fournier 5.5.0-1 +- New upstream version +- New plugins enabled by default: ceph, drbd, log_logstash, write_tsdb, smart, + openldap, redis, write_redis, zookeeper, write_log, write_sensu, ipc, + turbostat, fhcount +- New plugins disabled by default: barometer, write_kafka +- Enable zfs_arc, now supported on Linux +- Install disk plugin in a dedicated package, as it depends on libudev +- use systemd on EL7, sysvinit on EL6 & EL5 +- Install collectdctl, collectd-tg and collectd-nagios in collectd-utils.rpm +- Add build-dependency on libcap-devel * Mon Aug 19 2013 Marc Fournier 5.4.0-1 - New upstream version diff --git a/contrib/wiki2changelog.pl b/contrib/wiki2changelog.pl new file mode 100755 index 00000000..b8fc965b --- /dev/null +++ b/contrib/wiki2changelog.pl @@ -0,0 +1,75 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +=head1 NAME + +wiki2changelog.pl + +=head1 DESCRIPTION + +This script takes the change log from one of the "Version x.y" pages in +collectd's wiki and converts it to the format used by the "ChangeLog" file. +This is usually done as part of the release process. + +=cut + +our $TextWidth = 80; + +sub format_entry +{ + my $in = shift; + my $out = ''; + + my $line = "\t*"; + my $line_len = 9; + + for (split (' ', $in)) { + my $word = $_; + my $word_len = 1 + length $word; + + if (($line_len + $word_len) > $TextWidth) { + $out .= "$line\n"; + $line = "\t "; + $line_len = 9; + } + + $line .= " $word"; + $line_len += $word_len; + } + + if ($line_len != 9) { + $out .= "$line\n"; + } + + return $out; +} + +while (<>) +{ + chomp; + my $line = $_; + + if ($line =~ m#^\* (.*)#) { + $line = $1; + } else { + next; + } + + $line =~ s#<#<#g; + $line =~ s#>#>#g; + $line =~ s# # #g; + $line =~ s#"#"#g; + + $line =~ s#\{\{Plugin\|([^}]+)\}\}#$1 plugin#g; + $line =~ s@\{\{Issue\|([^}]+)\}\}@#$1@g; + $line =~ s#\[\[[^|]+\|([^\]]+)\]\]#$1#g; + $line =~ s#\[\[([^|]+)\]\]#$1#g; + + $line =~ s#'''(.*?)'''#*$1*#g; + $line =~ s#''(.*?)''#$1#g; + $line =~ s#(.*?)#"$1"#gi; + + print format_entry($line); +} diff --git a/src/Makefile.am b/src/Makefile.am index 08b8d525..1282f225 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -23,6 +23,14 @@ AM_CPPFLAGS += -DPKGDATADIR='"${pkgdatadir}"' AUTOMAKE_OPTIONS = subdir-objects +noinst_LTLIBRARIES = libmount.la liblookup.la + +libmount_la_SOURCES = utils_mount.c utils_mount.h +libmount_la_LIBADD = daemon/libcommon.la + +liblookup_la_SOURCES = utils_vl_lookup.c utils_vl_lookup.h +liblookup_la_LIBADD = daemon/libavltree.la daemon/libcommon.la + sbin_PROGRAMS = collectdmon bin_PROGRAMS = collectd-nagios collectdctl collectd-tg @@ -55,10 +63,9 @@ endif collectdctl_LDADD += libcollectdclient/libcollectdclient.la collectdctl_DEPENDENCIES = libcollectdclient/libcollectdclient.la -collectd_tg_SOURCES = collectd-tg.c \ - daemon/utils_heap.c daemon/utils_heap.h +collectd_tg_SOURCES = collectd-tg.c collectd_tg_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/src/libcollectdclient/collectd -I$(top_builddir)/src/libcollectdclient/collectd -collectd_tg_LDADD = +collectd_tg_LDADD = daemon/libheap.la if BUILD_WITH_LIBSOCKET collectd_tg_LDADD += -lsocket endif @@ -183,9 +190,9 @@ endif if BUILD_PLUGIN_CGROUPS pkglib_LTLIBRARIES += cgroups.la cgroups_la_SOURCES = cgroups.c \ - utils_ignorelist.c utils_ignorelist.h \ - utils_mount.c utils_mount.h + utils_ignorelist.c utils_ignorelist.h cgroups_la_LDFLAGS = $(PLUGIN_LDFLAGS) +cgroups_la_LIBADD = libmount.la endif if BUILD_PLUGIN_CONNTRACK @@ -283,9 +290,9 @@ endif if BUILD_PLUGIN_DF pkglib_LTLIBRARIES += df.la df_la_SOURCES = df.c \ - utils_ignorelist.c utils_ignorelist.h \ - utils_mount.c utils_mount.h + utils_ignorelist.c utils_ignorelist.h df_la_LDFLAGS = $(PLUGIN_LDFLAGS) +df_la_LIBADD = libmount.la endif if BUILD_PLUGIN_DISK @@ -1281,6 +1288,13 @@ endif BUILT_SOURCES += $(dist_man_MANS) +if BUILD_PLUGIN_ZONE +pkglib_LTLIBRARIES += zone.la +zone_la_SOURCES = zone.c +zone_la_CFLAGS = $(AM_CFLAGS) +zone_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + dist_man_MANS = collectd.1 \ collectd.conf.5 \ collectd-email.5 \ @@ -1373,49 +1387,12 @@ uninstall-hook: rm -f $(DESTDIR)$(sysconfdir)/collectd.conf rm -f $(DESTDIR)$(pkgdatadir)/postgresql_default.conf; -check_PROGRAMS = test_common test_utils_avltree test_utils_heap test_utils_mount test_utils_vl_lookup - -test_common_SOURCES = tests/test_common.c \ - daemon/common.h daemon/common.c \ - tests/macros.h \ - tests/mock/plugin.c \ - tests/mock/utils_cache.c \ - tests/mock/utils_time.c -test_common_CPPFLAGS = $(AM_CPPFLAGS) $(LTDLINCL) -test_common_LDFLAGS = -export-dynamic -test_common_LDADD = - -test_utils_avltree_SOURCES = tests/test_utils_avltree.c \ - daemon/utils_avltree.c daemon/utils_avltree.h -test_utils_avltree_CPPFLAGS = $(AM_CPPFLAGS) $(LTDLINCL) -test_utils_avltree_LDFLAGS = -export-dynamic -test_utils_avltree_LDADD = - -test_utils_heap_SOURCES = tests/test_utils_heap.c \ - daemon/utils_heap.c daemon/utils_heap.h -test_utils_heap_CPPFLAGS = $(AM_CPPFLAGS) $(LTDLINCL) -test_utils_heap_LDFLAGS = -export-dynamic -test_utils_heap_LDADD = - -test_utils_mount_SOURCES = tests/test_utils_mount.c \ - utils_mount.c utils_mount.h \ - daemon/common.c daemon/common.h \ - tests/mock/plugin.c \ - tests/mock/utils_cache.c \ - tests/mock/utils_time.c -test_utils_mount_CPPFLAGS = $(AM_CPPFLAGS) $(LTDLINCL) -test_utils_mount_LDFLAGS = -export-dynamic -test_utils_mount_LDADD = - -test_utils_vl_lookup_SOURCES = tests/test_utils_vl_lookup.c \ - utils_vl_lookup.h utils_vl_lookup.c \ - daemon/utils_avltree.c daemon/utils_avltree.h \ - daemon/common.c daemon/common.h \ - tests/mock/plugin.c \ - tests/mock/utils_cache.c \ - tests/mock/utils_time.c -test_utils_vl_lookup_CPPFLAGS = $(AM_CPPFLAGS) $(LTDLINCL) -test_utils_vl_lookup_LDFLAGS = -export-dynamic -test_utils_vl_lookup_LDADD = - -TESTS = test_common test_utils_avltree test_utils_heap test_utils_mount test_utils_vl_lookup +check_PROGRAMS = test_utils_mount test_utils_vl_lookup + +test_utils_mount_SOURCES = utils_mount_test.c testing.h +test_utils_mount_LDADD = libmount.la daemon/libplugin_mock.la + +test_utils_vl_lookup_SOURCES = utils_vl_lookup_test.c testing.h +test_utils_vl_lookup_LDADD = liblookup.la daemon/libplugin_mock.la + +TESTS = test_utils_mount test_utils_vl_lookup diff --git a/src/collectd.conf.in b/src/collectd.conf.in index 5132cb4a..99f879cc 100644 --- a/src/collectd.conf.in +++ b/src/collectd.conf.in @@ -206,6 +206,7 @@ #@BUILD_PLUGIN_WRITE_TSDB_TRUE@LoadPlugin write_tsdb #@BUILD_PLUGIN_XMMS_TRUE@LoadPlugin xmms #@BUILD_PLUGIN_ZFS_ARC_TRUE@LoadPlugin zfs_arc +#@BUILD_PLUGIN_ZONE_TRUE@LoadPlugin zone #@BUILD_PLUGIN_ZOOKEEPER_TRUE@LoadPlugin zookeeper ############################################################################## diff --git a/src/daemon/Makefile.am b/src/daemon/Makefile.am index fc815543..7f826e34 100644 --- a/src/daemon/Makefile.am +++ b/src/daemon/Makefile.am @@ -17,16 +17,23 @@ AUTOMAKE_OPTIONS = subdir-objects sbin_PROGRAMS = collectd +noinst_LTLIBRARIES = libavltree.la libcommon.la libheap.la libplugin_mock.la + +libavltree_la_SOURCES = utils_avltree.c utils_avltree.h + +libcommon_la_SOURCES = common.c common.h + +libheap_la_SOURCES = utils_heap.c utils_heap.h + +libplugin_mock_la_SOURCES = plugin_mock.c utils_cache_mock.c utils_time_mock.c + collectd_SOURCES = collectd.c collectd.h \ - common.c common.h \ configfile.c configfile.h \ filter_chain.c filter_chain.h \ meta_data.c meta_data.h \ plugin.c plugin.h \ - utils_avltree.c utils_avltree.h \ utils_cache.c utils_cache.h \ utils_complain.c utils_complain.h \ - utils_heap.c utils_heap.h \ utils_llist.c utils_llist.h \ utils_random.c utils_random.h \ utils_tail_match.c utils_tail_match.h \ @@ -41,7 +48,7 @@ collectd_SOURCES = collectd.c collectd.h \ collectd_CPPFLAGS = $(AM_CPPFLAGS) $(LTDLINCL) collectd_CFLAGS = $(AM_CFLAGS) collectd_LDFLAGS = -export-dynamic -collectd_LDADD = -lm +collectd_LDADD = libavltree.la libcommon.la libheap.la -lm collectd_DEPENDENCIES = # Link to these libraries.. @@ -83,3 +90,15 @@ collectd_DEPENDENCIES += $(top_builddir)/src/liboconfig/liboconfig.la else collectd_LDADD += -loconfig endif + +check_PROGRAMS = test_common test_utils_avltree test_utils_heap +TESTS = test_common test_utils_avltree test_utils_heap + +test_common_SOURCES = common_test.c ../testing.h +test_common_LDADD = libcommon.la libplugin_mock.la + +test_utils_avltree_SOURCES = utils_avltree_test.c ../testing.h +test_utils_avltree_LDADD = libavltree.la + +test_utils_heap_SOURCES = utils_heap_test.c ../testing.h +test_utils_heap_LDADD = libheap.la diff --git a/src/daemon/collectd.h b/src/daemon/collectd.h index 6886c123..80b753c8 100644 --- a/src/daemon/collectd.h +++ b/src/daemon/collectd.h @@ -304,6 +304,10 @@ typedef int _Bool; # endif #endif +#ifndef GAUGE_FORMAT +# define GAUGE_FORMAT "%.15g" +#endif + /* Type for time as used by "utils_time.h" */ typedef uint64_t cdtime_t; diff --git a/src/daemon/common.c b/src/daemon/common.c index e2b618fb..e396b79d 100644 --- a/src/daemon/common.c +++ b/src/daemon/common.c @@ -968,18 +968,17 @@ int format_values (char *ret, size_t ret_len, /* {{{ */ for (i = 0; i < ds->ds_num; i++) { if (ds->ds[i].type == DS_TYPE_GAUGE) - BUFFER_ADD (":%f", vl->values[i].gauge); + BUFFER_ADD (":"GAUGE_FORMAT, vl->values[i].gauge); else if (store_rates) { if (rates == NULL) rates = uc_get_rate (ds, vl); if (rates == NULL) { - WARNING ("format_values: " - "uc_get_rate failed."); + WARNING ("format_values: uc_get_rate failed."); return (-1); } - BUFFER_ADD (":%g", rates[i]); + BUFFER_ADD (":"GAUGE_FORMAT, rates[i]); } else if (ds->ds[i].type == DS_TYPE_COUNTER) BUFFER_ADD (":%llu", vl->values[i].counter); @@ -989,7 +988,7 @@ int format_values (char *ret, size_t ret_len, /* {{{ */ BUFFER_ADD (":%"PRIu64, vl->values[i].absolute); else { - ERROR ("format_values plugin: Unknown data source type: %i", + ERROR ("format_values: Unknown data source type: %i", ds->ds[i].type); sfree (rates); return (-1); diff --git a/src/daemon/common_test.c b/src/daemon/common_test.c new file mode 100644 index 00000000..1fa8f324 --- /dev/null +++ b/src/daemon/common_test.c @@ -0,0 +1,246 @@ +/** + * collectd - src/tests/test_common.c + * Copyright (C) 2013 Florian octo Forster + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + * Florian octo Forster + */ + +#include "testing.h" +#include "common.h" + +DEF_TEST(sstrncpy) +{ + char buffer[16] = ""; + char *ptr = &buffer[4]; + char *ret; + + buffer[0] = buffer[1] = buffer[2] = buffer[3] = 0xff; + buffer[12] = buffer[13] = buffer[14] = buffer[15] = 0xff; + + ret = sstrncpy (ptr, "foobar", 8); + OK(ret == ptr); + STREQ ("foobar", ptr); + OK(buffer[3] == buffer[12]); + + ret = sstrncpy (ptr, "abc", 8); + OK(ret == ptr); + STREQ ("abc", ptr); + OK(buffer[3] == buffer[12]); + + ret = sstrncpy (ptr, "collectd", 8); + OK(ret == ptr); + OK(ptr[7] == 0); + STREQ ("collect", ptr); + OK(buffer[3] == buffer[12]); + + return (0); +} + +DEF_TEST(ssnprintf) +{ + char buffer[16] = ""; + char *ptr = &buffer[4]; + int status; + + buffer[0] = buffer[1] = buffer[2] = buffer[3] = 0xff; + buffer[12] = buffer[13] = buffer[14] = buffer[15] = 0xff; + + status = ssnprintf (ptr, 8, "%i", 1337); + OK(status == 4); + STREQ ("1337", ptr); + + status = ssnprintf (ptr, 8, "%s", "collectd"); + OK(status == 8); + OK(ptr[7] == 0); + STREQ ("collect", ptr); + OK(buffer[3] == buffer[12]); + + return (0); +} + +DEF_TEST(sstrdup) +{ + char *ptr; + + ptr = sstrdup ("collectd"); + OK(ptr != NULL); + STREQ ("collectd", ptr); + + sfree(ptr); + OK(ptr == NULL); + + ptr = sstrdup (NULL); + OK(ptr == NULL); + + return (0); +} + +DEF_TEST(strsplit) +{ + char buffer[32]; + char *fields[8]; + int status; + + strncpy (buffer, "foo bar", sizeof (buffer)); + status = strsplit (buffer, fields, 8); + OK(status == 2); + STREQ ("foo", fields[0]); + STREQ ("bar", fields[1]); + + strncpy (buffer, "foo \t bar", sizeof (buffer)); + status = strsplit (buffer, fields, 8); + OK(status == 2); + STREQ ("foo", fields[0]); + STREQ ("bar", fields[1]); + + strncpy (buffer, "one two\tthree\rfour\nfive", sizeof (buffer)); + status = strsplit (buffer, fields, 8); + OK(status == 5); + STREQ ("one", fields[0]); + STREQ ("two", fields[1]); + STREQ ("three", fields[2]); + STREQ ("four", fields[3]); + STREQ ("five", fields[4]); + + strncpy (buffer, "\twith trailing\n", sizeof (buffer)); + status = strsplit (buffer, fields, 8); + OK(status == 2); + STREQ ("with", fields[0]); + STREQ ("trailing", fields[1]); + + strncpy (buffer, "1 2 3 4 5 6 7 8 9 10 11 12 13", sizeof (buffer)); + status = strsplit (buffer, fields, 8); + OK(status == 8); + STREQ ("7", fields[6]); + STREQ ("8", fields[7]); + + strncpy (buffer, "single", sizeof (buffer)); + status = strsplit (buffer, fields, 8); + OK(status == 1); + STREQ ("single", fields[0]); + + strncpy (buffer, "", sizeof (buffer)); + status = strsplit (buffer, fields, 8); + OK(status == 0); + + return (0); +} + +DEF_TEST(strjoin) +{ + char buffer[16]; + char *fields[4]; + int status; + + fields[0] = "foo"; + fields[1] = "bar"; + fields[2] = "baz"; + fields[3] = "qux"; + + status = strjoin (buffer, sizeof (buffer), fields, 2, "!"); + OK(status == 7); + STREQ ("foo!bar", buffer); + + status = strjoin (buffer, sizeof (buffer), fields, 1, "!"); + OK(status == 3); + STREQ ("foo", buffer); + + status = strjoin (buffer, sizeof (buffer), fields, 0, "!"); + OK(status < 0); + + status = strjoin (buffer, sizeof (buffer), fields, 2, "rcht"); + OK(status == 10); + STREQ ("foorchtbar", buffer); + + status = strjoin (buffer, sizeof (buffer), fields, 4, ""); + OK(status == 12); + STREQ ("foobarbazqux", buffer); + + status = strjoin (buffer, sizeof (buffer), fields, 4, "!"); + OK(status == 15); + STREQ ("foo!bar!baz!qux", buffer); + + fields[0] = "0123"; + fields[1] = "4567"; + fields[2] = "8901"; + fields[3] = "2345"; + status = strjoin (buffer, sizeof (buffer), fields, 4, "-"); + OK(status < 0); + + return (0); +} + +DEF_TEST(strunescape) +{ + char buffer[16]; + int status; + + strncpy (buffer, "foo\\tbar", sizeof (buffer)); + status = strunescape (buffer, sizeof (buffer)); + OK(status == 0); + STREQ ("foo\tbar", buffer); + + strncpy (buffer, "\\tfoo\\r\\n", sizeof (buffer)); + status = strunescape (buffer, sizeof (buffer)); + OK(status == 0); + STREQ ("\tfoo\r\n", buffer); + + strncpy (buffer, "With \\\"quotes\\\"", sizeof (buffer)); + status = strunescape (buffer, sizeof (buffer)); + OK(status == 0); + STREQ ("With \"quotes\"", buffer); + + /* Backslash before null byte */ + strncpy (buffer, "\\tbackslash end\\", sizeof (buffer)); + status = strunescape (buffer, sizeof (buffer)); + OK(status != 0); + STREQ ("\tbackslash end", buffer); + return (0); + + /* Backslash at buffer end */ + strncpy (buffer, "\\t3\\56", sizeof (buffer)); + status = strunescape (buffer, 4); + OK(status != 0); + OK(buffer[0] == '\t'); + OK(buffer[1] == '3'); + OK(buffer[2] == 0); + OK(buffer[3] == 0); + OK(buffer[4] == '5'); + OK(buffer[5] == '6'); + OK(buffer[6] == '7'); + + return (0); +} + +int main (void) +{ + RUN_TEST(sstrncpy); + RUN_TEST(ssnprintf); + RUN_TEST(sstrdup); + RUN_TEST(strsplit); + RUN_TEST(strjoin); + RUN_TEST(strunescape); + + END_TEST; +} + +/* vim: set sw=2 sts=2 et : */ diff --git a/src/daemon/filter_chain.c b/src/daemon/filter_chain.c index b93435fd..0fd4a73e 100644 --- a/src/daemon/filter_chain.c +++ b/src/daemon/filter_chain.c @@ -733,6 +733,8 @@ static int fc_bit_write_invoke (const data_set_t *ds, /* {{{ */ "all write plugins failed with status %i (ENOENT). " "Most likely this means you didn't load any write plugins.", status); + + plugin_log_available_writers (); } else if (status != 0) { @@ -763,6 +765,8 @@ static int fc_bit_write_invoke (const data_set_t *ds, /* {{{ */ "Filter subsystem: Built-in target `write': Dispatching value to " "the `%s' plugin failed with status %i.", plugin_list[i].plugin, status); + + plugin_log_available_writers (); } else { diff --git a/src/daemon/plugin.c b/src/daemon/plugin.c index 25bd37b8..3d364458 100644 --- a/src/daemon/plugin.c +++ b/src/daemon/plugin.c @@ -307,6 +307,56 @@ static int register_callback (llist_t **list, /* {{{ */ return (0); } /* }}} int register_callback */ +static void log_list_callbacks (llist_t **list, /* {{{ */ + const char *comment) +{ + char *str; + int len; + llentry_t *le; + int i; + int n; + char **keys; + + n = llist_size(*list); + if (n == 0) + { + INFO("%s [none]", comment); + return; + } + + keys = calloc(n, sizeof(char*)); + + if (keys == NULL) + { + ERROR("%s: failed to allocate memory for list of callbacks", + comment); + + return; + } + + for (le = llist_head (*list), i = 0, len = 0; + le != NULL; + le = le->next, i++) + { + keys[i] = le->key; + len += strlen(le->key) + 6; + } + str = malloc(len + 10); + if (str == NULL) + { + ERROR("%s: failed to allocate memory for list of callbacks", + comment); + } + else + { + *str = '\0'; + strjoin(str, len, keys, n, "', '"); + INFO("%s ['%s']", comment, str); + free(str); + } + free(keys); +} /* }}} void log_list_callbacks */ + static int create_register_callback (llist_t **list, /* {{{ */ const char *name, void *callback, user_data_t *ud) { @@ -1398,6 +1448,11 @@ int plugin_unregister_read (const char *name) /* {{{ */ return (0); } /* }}} int plugin_unregister_read */ +void plugin_log_available_writers (void) +{ + log_list_callbacks (&list_write, "Available write targets:"); +} + static int compare_read_func_group (llentry_t *e, void *ud) /* {{{ */ { read_func_t *rf = e->value; diff --git a/src/daemon/plugin.h b/src/daemon/plugin.h index 86a2d662..70a22326 100644 --- a/src/daemon/plugin.h +++ b/src/daemon/plugin.h @@ -322,6 +322,17 @@ int plugin_unregister_data_set (const char *name); int plugin_unregister_log (const char *name); int plugin_unregister_notification (const char *name); +/* + * NAME + * plugin_log_available_writers + * + * DESCRIPTION + * This function can be called to output a list of _all_ registered + * writers to the logfacility. + * Since some writers dynamically build their name it can be hard for + * the configuring person to know it. This function will fill this gap. + */ +void plugin_log_available_writers (); /* * NAME diff --git a/src/daemon/plugin_mock.c b/src/daemon/plugin_mock.c new file mode 100644 index 00000000..86528809 --- /dev/null +++ b/src/daemon/plugin_mock.c @@ -0,0 +1,41 @@ +/** + * collectd - src/tests/mock/plugin.c + * Copyright (C) 2013 Florian octo Forster + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + * Florian octo Forster + */ + +#include "plugin.h" + +void plugin_log (int level, char const *format, ...) +{ + char buffer[1024]; + va_list ap; + + va_start (ap, format); + vsnprintf (buffer, sizeof (buffer), format, ap); + va_end (ap); + + printf ("plugin_log (%i, \"%s\");\n", level, buffer); +} + +/* vim: set sw=2 sts=2 et : */ diff --git a/src/daemon/utils_avltree_test.c b/src/daemon/utils_avltree_test.c new file mode 100644 index 00000000..2a8244c9 --- /dev/null +++ b/src/daemon/utils_avltree_test.c @@ -0,0 +1,82 @@ +/** + * collectd - src/tests/test_utils_avltree.c + * Copyright (C) 2013 Florian octo Forster + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + * Florian octo Forster + */ + +#include "testing.h" +#include "collectd.h" +#include "utils_avltree.h" + +static int compare_total_count = 0; +#define RESET_COUNTS() do { compare_total_count = 0; } while (0) + +static int compare_callback (void const *v0, void const *v1) +{ + assert (v0 != NULL); + assert (v1 != NULL); + + compare_total_count++; + return (strcmp (v0, v1)); +} + +DEF_TEST(success) +{ + c_avl_tree_t *t; + char key_orig[] = "foo"; + char value_orig[] = "bar"; + char *key_ret = NULL; + char *value_ret = NULL; + + RESET_COUNTS (); + t = c_avl_create (compare_callback); + OK (t != NULL); + + OK (c_avl_insert (t, key_orig, value_orig) == 0); + OK (c_avl_size (t) == 1); + + /* Key already exists. */ + OK (c_avl_insert (t, "foo", "qux") > 0); + + OK (c_avl_get (t, "foo", (void *) &value_ret) == 0); + OK (value_ret == &value_orig[0]); + + key_ret = value_ret = NULL; + OK (c_avl_remove (t, "foo", (void *) &key_ret, (void *) &value_ret) == 0); + OK (key_ret == &key_orig[0]); + OK (value_ret == &value_orig[0]); + OK (c_avl_size (t) == 0); + + c_avl_destroy (t); + + return (0); +} + +int main (void) +{ + RUN_TEST(success); + + END_TEST; +} + +/* vim: set sw=2 sts=2 et : */ diff --git a/src/daemon/utils_cache_mock.c b/src/daemon/utils_cache_mock.c new file mode 100644 index 00000000..6c78d64d --- /dev/null +++ b/src/daemon/utils_cache_mock.c @@ -0,0 +1,32 @@ +/** + * collectd - src/tests/mock/utils_cache.c + * Copyright (C) 2013 Florian octo Forster + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + * Florian octo Forster + */ + +#include "utils_cache.h" + +gauge_t *uc_get_rate (const data_set_t *ds, const value_list_t *vl) +{ + return (NULL); +} diff --git a/src/daemon/utils_heap_test.c b/src/daemon/utils_heap_test.c new file mode 100644 index 00000000..53d0fba8 --- /dev/null +++ b/src/daemon/utils_heap_test.c @@ -0,0 +1,85 @@ +/** + * collectd - src/tests/test_utils_heap.c + * Copyright (C) 2013 Florian octo Forster + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + * Florian octo Forster + */ + +#include "testing.h" +#include "collectd.h" +#include "utils_heap.h" + +static int compare (void const *v0, void const *v1) +{ + int const *i0 = v0; + int const *i1 = v1; + + if ((*i0) < (*i1)) + return -1; + else if ((*i0) > (*i1)) + return 1; + else + return 0; +} + +DEF_TEST(simple) +{ + int values[] = { 9, 5, 6, 1, 3, 4, 0, 8, 2, 7 }; + int i; + c_heap_t *h; + + CHECK_NOT_NULL(h = c_heap_create (compare)); + for (i = 0; i < 10; i++) + CHECK_ZERO(c_heap_insert (h, &values[i])); + + for (i = 0; i < 5; i++) + { + int *ret = NULL; + CHECK_NOT_NULL(ret = c_heap_get_root(h)); + OK(*ret == i); + } + + CHECK_ZERO(c_heap_insert (h, &values[6] /* = 0 */)); + CHECK_ZERO(c_heap_insert (h, &values[3] /* = 1 */)); + CHECK_ZERO(c_heap_insert (h, &values[8] /* = 2 */)); + CHECK_ZERO(c_heap_insert (h, &values[4] /* = 3 */)); + CHECK_ZERO(c_heap_insert (h, &values[5] /* = 4 */)); + + for (i = 0; i < 10; i++) + { + int *ret = NULL; + CHECK_NOT_NULL(ret = c_heap_get_root(h)); + OK(*ret == i); + } + + c_heap_destroy(h); + return (0); +} + +int main (void) +{ + RUN_TEST(simple); + + END_TEST; +} + +/* vim: set sw=2 sts=2 et : */ diff --git a/src/daemon/utils_time_mock.c b/src/daemon/utils_time_mock.c new file mode 100644 index 00000000..5edfe6f9 --- /dev/null +++ b/src/daemon/utils_time_mock.c @@ -0,0 +1,33 @@ +/** + * collectd - src/tests/mock/utils_time.c + * Copyright (C) 2013 Florian octo Forster + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + * Florian octo Forster + */ + +#include "utils_time.h" + +cdtime_t cdtime (void) +{ + return (0); +} + diff --git a/src/ipc.c b/src/ipc.c index 2d2db2ab..3763f248 100644 --- a/src/ipc.c +++ b/src/ipc.c @@ -111,7 +111,80 @@ static void ipc_submit_g (const char *plugin_instance, plugin_dispatch_values (&vl); } /* }}} */ -#if KERNEL_AIX +#if KERNEL_LINUX +static int ipc_read_sem (void) /* {{{ */ +{ + struct seminfo seminfo; + union semun arg; + int status; + + arg.array = (void *) &seminfo; + + status = semctl (/* id = */ 0, /* num = */ 0, SEM_INFO, arg); + if (status == -1) + { + char errbuf[1024]; + ERROR("ipc plugin: semctl(2) failed: %s. " + "Maybe the kernel is not configured for semaphores?", + sstrerror (errno, errbuf, sizeof (errbuf))); + return (-1); + } + + ipc_submit_g("sem", "count", "arrays", seminfo.semusz); + ipc_submit_g("sem", "count", "total", seminfo.semaem); + + return (0); +} /* }}} int ipc_read_sem */ + +static int ipc_read_shm (void) /* {{{ */ +{ + struct shm_info shm_info; + int status; + + status = shmctl (/* id = */ 0, SHM_INFO, (void *) &shm_info); + if (status == -1) + { + char errbuf[1024]; + ERROR("ipc plugin: shmctl(2) failed: %s. " + "Maybe the kernel is not configured for shared memory?", + sstrerror (errno, errbuf, sizeof (errbuf))); + return (-1); + } + + ipc_submit_g("shm", "segments", NULL, shm_info.used_ids); + ipc_submit_g("shm", "bytes", "total", shm_info.shm_tot * pagesize_g); + ipc_submit_g("shm", "bytes", "rss", shm_info.shm_rss * pagesize_g); + ipc_submit_g("shm", "bytes", "swapped", shm_info.shm_swp * pagesize_g); + return (0); +} +/* }}} int ipc_read_shm */ + +static int ipc_read_msg (void) /* {{{ */ +{ + struct msginfo msginfo; + + if ( msgctl(0, MSG_INFO, (struct msqid_ds *) (void *) &msginfo) < 0 ) + { + ERROR("Kernel is not configured for message queues"); + return (-1); + } + ipc_submit_g("msg", "count", "queues", msginfo.msgmni); + ipc_submit_g("msg", "count", "headers", msginfo.msgmap); + ipc_submit_g("msg", "count", "space", msginfo.msgtql); + + return (0); +} +/* }}} int ipc_read_msg */ + +static int ipc_init (void) /* {{{ */ +{ + pagesize_g = sysconf(_SC_PAGESIZE); + return (0); +} +/* }}} */ +/* #endif KERNEL_LINUX */ + +#elif KERNEL_AIX static caddr_t ipc_get_info (cid_t cid, int cmd, int version, int stsize, int *nmemb) /* {{{ */ { int size = 0; @@ -154,27 +227,9 @@ static caddr_t ipc_get_info (cid_t cid, int cmd, int version, int stsize, int *n return buff; } /* }}} */ -#endif /* KERNEL_AIX */ static int ipc_read_sem (void) /* {{{ */ { -#if KERNEL_LINUX - struct seminfo seminfo; - union semun arg; - - arg.array = (ushort *) (void *) &seminfo; - - if ( semctl(0, 0, SEM_INFO, arg) < 0 ) - { - ERROR("Kernel is not configured for semaphores"); - return (-1); - } - - ipc_submit_g("sem", "count", "arrays", seminfo.semusz); - ipc_submit_g("sem", "count", "total", seminfo.semaem); - -/* #endif KERNEL_LINUX */ -#elif KERNEL_AIX ipcinfo_sem_t *ipcinfo_sem; unsigned short sem_nsems=0; unsigned short sems=0; @@ -193,28 +248,12 @@ static int ipc_read_sem (void) /* {{{ */ ipc_submit_g("sem", "count", "arrays", sem_nsems); ipc_submit_g("sem", "count", "total", sems); -#endif /* KERNEL_AIX */ return (0); -} -/* }}} */ +} /* }}} int ipc_read_sem */ static int ipc_read_shm (void) /* {{{ */ { -#if KERNEL_LINUX - struct shm_info shm_info; - - if ( shmctl(0, SHM_INFO, (struct shmid_ds *) (void *) &shm_info) < 0 ) - { - ERROR("Kernel is not configured for shared memory"); - return (-1); - } - ipc_submit_g("shm", "segments", NULL, shm_info.used_ids); - ipc_submit_g("shm", "bytes", "total", shm_info.shm_tot * pagesize_g); - ipc_submit_g("shm", "bytes", "rss", shm_info.shm_rss * pagesize_g); - ipc_submit_g("shm", "bytes", "swapped", shm_info.shm_swp * pagesize_g); -/* #endif KERNEL_LINUX */ -#elif KERNEL_AIX ipcinfo_shm_t *ipcinfo_shm; ipcinfo_shm_t *pshm; unsigned int shm_segments=0; @@ -235,26 +274,12 @@ static int ipc_read_shm (void) /* {{{ */ ipc_submit_g("shm", "segments", NULL, shm_segments); ipc_submit_g("shm", "bytes", "total", shm_bytes); -#endif /* KERNEL_AIX */ return (0); } -/* }}} */ +/* }}} int ipc_read_shm */ static int ipc_read_msg (void) /* {{{ */ { -#if KERNEL_LINUX - struct msginfo msginfo; - - if ( msgctl(0, MSG_INFO, (struct msqid_ds *) (void *) &msginfo) < 0 ) - { - ERROR("Kernel is not configured for message queues"); - return (-1); - } - ipc_submit_g("msg", "count", "queues", msginfo.msgmni); - ipc_submit_g("msg", "count", "headers", msginfo.msgmap); - ipc_submit_g("msg", "count", "space", msginfo.msgtql); -/* #endif KERNEL_LINUX */ -#elif KERNEL_AIX ipcinfo_msg_t *ipcinfo_msg; uint32_t msg_used_space=0; uint32_t msg_alloc_queues=0; @@ -270,16 +295,17 @@ static int ipc_read_msg (void) /* {{{ */ msg_alloc_queues++; msg_used_space += ipcinfo_msg[i].msg_cbytes; msg_qnum += ipcinfo_msg[i].msg_qnum; - } + free(ipcinfo_msg); ipc_submit_g("msg", "count", "queues", msg_alloc_queues); ipc_submit_g("msg", "count", "headers", msg_qnum); ipc_submit_g("msg", "count", "space", msg_used_space); -#endif /* KERNEL_AIX */ + return (0); } /* }}} */ +#endif /* KERNEL_AIX */ static int ipc_read (void) /* {{{ */ { @@ -292,15 +318,6 @@ static int ipc_read (void) /* {{{ */ } /* }}} */ -#ifdef KERNEL_LINUX -static int ipc_init (void) /* {{{ */ -{ - pagesize_g = sysconf(_SC_PAGESIZE); - return (0); -} -/* }}} */ -#endif /* KERNEL_LINUX */ - void module_register (void) /* {{{ */ { #ifdef KERNEL_LINUX diff --git a/src/network.c b/src/network.c index 551bd5cc..e58d1dc5 100644 --- a/src/network.c +++ b/src/network.c @@ -310,6 +310,7 @@ static pthread_t dispatch_thread_id; static char *send_buffer; static char *send_buffer_ptr; static int send_buffer_fill; +static cdtime_t send_buffer_last_update; static value_list_t send_buffer_vl = VALUE_LIST_STATIC; static pthread_mutex_t send_buffer_lock = PTHREAD_MUTEX_INITIALIZER; @@ -2577,6 +2578,7 @@ static void network_init_buffer (void) memset (send_buffer, 0, network_config_packet_size); send_buffer_ptr = send_buffer; send_buffer_fill = 0; + send_buffer_last_update = 0; memset (&send_buffer_vl, 0, sizeof (send_buffer_vl)); } /* int network_init_buffer */ @@ -2916,6 +2918,7 @@ static int network_write (const data_set_t *ds, const value_list_t *vl, /* status == bytes added to the buffer */ send_buffer_fill += status; send_buffer_ptr += status; + send_buffer_last_update = cdtime(); stats_values_sent++; } @@ -3605,15 +3608,25 @@ static int network_init (void) * just send the buffer if `flush' is called - if the requested value was in * there, good. If not, well, then there is nothing to flush.. -octo */ -static int network_flush (__attribute__((unused)) cdtime_t timeout, +static int network_flush (cdtime_t timeout, __attribute__((unused)) const char *identifier, __attribute__((unused)) user_data_t *user_data) { pthread_mutex_lock (&send_buffer_lock); if (send_buffer_fill > 0) - flush_buffer (); - + { + if (timeout > 0) + { + cdtime_t now = cdtime (); + if ((send_buffer_last_update + timeout) > now) + { + pthread_mutex_unlock (&send_buffer_lock); + return (0); + } + } + flush_buffer (); + } pthread_mutex_unlock (&send_buffer_lock); return (0); diff --git a/src/postgresql.c b/src/postgresql.c index 47c9c5c2..54c856d6 100644 --- a/src/postgresql.c +++ b/src/postgresql.c @@ -772,7 +772,7 @@ static char *values_to_sqlarray (const data_set_t *ds, const value_list_t *vl, if (ds->ds[i].type == DS_TYPE_GAUGE) status = ssnprintf (str_ptr, str_len, - ",%f", vl->values[i].gauge); + ","GAUGE_FORMAT, vl->values[i].gauge); else if (store_rates) { if (rates == NULL) rates = uc_get_rate (ds, vl); diff --git a/src/rrdtool.c b/src/rrdtool.c index c795e265..bebf468c 100644 --- a/src/rrdtool.c +++ b/src/rrdtool.c @@ -227,7 +227,7 @@ static int value_list_to_string_multiple (char *buffer, int buffer_len, ":%llu", vl->values[i].counter); else if (ds->ds[i].type == DS_TYPE_GAUGE) status = ssnprintf (buffer + offset, buffer_len - offset, - ":%lf", vl->values[i].gauge); + ":"GAUGE_FORMAT, vl->values[i].gauge); else if (ds->ds[i].type == DS_TYPE_DERIVE) status = ssnprintf (buffer + offset, buffer_len - offset, ":%"PRIi64, vl->values[i].derive); @@ -262,7 +262,7 @@ static int value_list_to_string (char *buffer, int buffer_len, (unsigned) tt, vl->values[0].derive); break; case DS_TYPE_GAUGE: - status = ssnprintf (buffer, buffer_len, "%u:%lf", + status = ssnprintf (buffer, buffer_len, "%u:"GAUGE_FORMAT, (unsigned) tt, vl->values[0].gauge); break; case DS_TYPE_COUNTER: diff --git a/src/target_notification.c b/src/target_notification.c index 5eaa4275..2e5ab3b2 100644 --- a/src/target_notification.c +++ b/src/target_notification.c @@ -256,12 +256,12 @@ static int tn_invoke (const data_set_t *ds, value_list_t *vl, /* {{{ */ /* If this is a gauge value, use the current value. */ if (ds->ds[i].type == DS_TYPE_GAUGE) ssnprintf (value_str, sizeof (value_str), - "%g", (double) vl->values[i].gauge); + GAUGE_FORMAT, (double) vl->values[i].gauge); /* If it's a counter, try to use the current rate. This may fail, if the * value has been renamed. */ else if (rates != NULL) ssnprintf (value_str, sizeof (value_str), - "%g", (double) rates[i]); + GAUGE_FORMAT, (double) rates[i]); /* Since we don't know any better, use the string `unknown'. */ else sstrncpy (value_str, "unknown", sizeof (value_str)); diff --git a/src/testing.h b/src/testing.h new file mode 100644 index 00000000..5df1b83a --- /dev/null +++ b/src/testing.h @@ -0,0 +1,67 @@ +/** + * collectd - src/tests/macros.h + * Copyright (C) 2013 Florian octo Forster + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + * Florian octo Forster + */ + +static int fail_count__ = 0; +static int check_count__ = 0; + +#define DEF_TEST(func) static int test_##func () + +#define RUN_TEST(func) do { \ + int status; \ + printf ("Testing %s ...\n", #func); \ + status = test_ ## func (); \ + printf ("%s.\n", (status == 0) ? "Success" : "FAILURE"); \ + if (status != 0) { fail_count__++; } \ +} while (0) + +#define END_TEST exit ((fail_count__ == 0) ? 0 : 1); + +#define OK1(cond, text) do { \ + _Bool result = (cond); \ + printf ("%s %i - %s\n", result ? "ok" : "not ok", ++check_count__, text); \ +} while (0) +#define OK(cond) OK1(cond, #cond) + +#define STREQ(expect, actual) do { \ + if (strcmp (expect, actual) != 0) { \ + printf ("not ok %i - %s incorrect: expected \"%s\", got \"%s\"\n", \ + ++check_count__, #actual, expect, actual); \ + return (-1); \ + } \ + printf ("ok %i - %s evaluates to \"%s\"\n", ++check_count__, #actual, expect); \ +} while (0) + +#define CHECK_NOT_NULL(expr) do { \ + void *ptr_; \ + ptr_ = (expr); \ + OK1(ptr_ != NULL, #expr); \ +} while (0) + +#define CHECK_ZERO(expr) do { \ + long status_; \ + status_ = (long) (expr); \ + OK1(status_ == 0L, #expr); \ +} while (0) diff --git a/src/tests/common_test.c b/src/tests/common_test.c deleted file mode 100644 index f65fcab3..00000000 --- a/src/tests/common_test.c +++ /dev/null @@ -1,246 +0,0 @@ -/** - * collectd - src/tests/common_test.c - * Copyright (C) 2013 Florian octo Forster - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Florian octo Forster - */ - -#include "tests/macros.h" -#include "common.h" - -DEF_TEST(sstrncpy) -{ - char buffer[16] = ""; - char *ptr = &buffer[4]; - char *ret; - - buffer[0] = buffer[1] = buffer[2] = buffer[3] = 0xff; - buffer[12] = buffer[13] = buffer[14] = buffer[15] = 0xff; - - ret = sstrncpy (ptr, "foobar", 8); - OK(ret == ptr); - STREQ ("foobar", ptr); - OK(buffer[3] == buffer[12]); - - ret = sstrncpy (ptr, "abc", 8); - OK(ret == ptr); - STREQ ("abc", ptr); - OK(buffer[3] == buffer[12]); - - ret = sstrncpy (ptr, "collectd", 8); - OK(ret == ptr); - OK(ptr[7] == 0); - STREQ ("collect", ptr); - OK(buffer[3] == buffer[12]); - - return (0); -} - -DEF_TEST(ssnprintf) -{ - char buffer[16] = ""; - char *ptr = &buffer[4]; - int status; - - buffer[0] = buffer[1] = buffer[2] = buffer[3] = 0xff; - buffer[12] = buffer[13] = buffer[14] = buffer[15] = 0xff; - - status = ssnprintf (ptr, 8, "%i", 1337); - OK(status == 4); - STREQ ("1337", ptr); - - status = ssnprintf (ptr, 8, "%s", "collectd"); - OK(status == 8); - OK(ptr[7] == 0); - STREQ ("collect", ptr); - OK(buffer[3] == buffer[12]); - - return (0); -} - -DEF_TEST(sstrdup) -{ - char *ptr; - - ptr = sstrdup ("collectd"); - OK(ptr != NULL); - STREQ ("collectd", ptr); - - sfree(ptr); - OK(ptr == NULL); - - ptr = sstrdup (NULL); - OK(ptr == NULL); - - return (0); -} - -DEF_TEST(strsplit) -{ - char buffer[32]; - char *fields[8]; - int status; - - strncpy (buffer, "foo bar", sizeof (buffer)); - status = strsplit (buffer, fields, 8); - OK(status == 2); - STREQ ("foo", fields[0]); - STREQ ("bar", fields[1]); - - strncpy (buffer, "foo \t bar", sizeof (buffer)); - status = strsplit (buffer, fields, 8); - OK(status == 2); - STREQ ("foo", fields[0]); - STREQ ("bar", fields[1]); - - strncpy (buffer, "one two\tthree\rfour\nfive", sizeof (buffer)); - status = strsplit (buffer, fields, 8); - OK(status == 5); - STREQ ("one", fields[0]); - STREQ ("two", fields[1]); - STREQ ("three", fields[2]); - STREQ ("four", fields[3]); - STREQ ("five", fields[4]); - - strncpy (buffer, "\twith trailing\n", sizeof (buffer)); - status = strsplit (buffer, fields, 8); - OK(status == 2); - STREQ ("with", fields[0]); - STREQ ("trailing", fields[1]); - - strncpy (buffer, "1 2 3 4 5 6 7 8 9 10 11 12 13", sizeof (buffer)); - status = strsplit (buffer, fields, 8); - OK(status == 8); - STREQ ("7", fields[6]); - STREQ ("8", fields[7]); - - strncpy (buffer, "single", sizeof (buffer)); - status = strsplit (buffer, fields, 8); - OK(status == 1); - STREQ ("single", fields[0]); - - strncpy (buffer, "", sizeof (buffer)); - status = strsplit (buffer, fields, 8); - OK(status == 0); - - return (0); -} - -DEF_TEST(strjoin) -{ - char buffer[16]; - char *fields[4]; - int status; - - fields[0] = "foo"; - fields[1] = "bar"; - fields[2] = "baz"; - fields[3] = "qux"; - - status = strjoin (buffer, sizeof (buffer), fields, 2, "!"); - OK(status == 7); - STREQ ("foo!bar", buffer); - - status = strjoin (buffer, sizeof (buffer), fields, 1, "!"); - OK(status == 3); - STREQ ("foo", buffer); - - status = strjoin (buffer, sizeof (buffer), fields, 0, "!"); - OK(status < 0); - - status = strjoin (buffer, sizeof (buffer), fields, 2, "rcht"); - OK(status == 10); - STREQ ("foorchtbar", buffer); - - status = strjoin (buffer, sizeof (buffer), fields, 4, ""); - OK(status == 12); - STREQ ("foobarbazqux", buffer); - - status = strjoin (buffer, sizeof (buffer), fields, 4, "!"); - OK(status == 15); - STREQ ("foo!bar!baz!qux", buffer); - - fields[0] = "0123"; - fields[1] = "4567"; - fields[2] = "8901"; - fields[3] = "2345"; - status = strjoin (buffer, sizeof (buffer), fields, 4, "-"); - OK(status < 0); - - return (0); -} - -DEF_TEST(strunescape) -{ - char buffer[16]; - int status; - - strncpy (buffer, "foo\\tbar", sizeof (buffer)); - status = strunescape (buffer, sizeof (buffer)); - OK(status == 0); - STREQ ("foo\tbar", buffer); - - strncpy (buffer, "\\tfoo\\r\\n", sizeof (buffer)); - status = strunescape (buffer, sizeof (buffer)); - OK(status == 0); - STREQ ("\tfoo\r\n", buffer); - - strncpy (buffer, "With \\\"quotes\\\"", sizeof (buffer)); - status = strunescape (buffer, sizeof (buffer)); - OK(status == 0); - STREQ ("With \"quotes\"", buffer); - - /* Backslash before null byte */ - strncpy (buffer, "\\tbackslash end\\", sizeof (buffer)); - status = strunescape (buffer, sizeof (buffer)); - OK(status != 0); - STREQ ("\tbackslash end", buffer); - return (0); - - /* Backslash at buffer end */ - strncpy (buffer, "\\t3\\56", sizeof (buffer)); - status = strunescape (buffer, 4); - OK(status != 0); - OK(buffer[0] == '\t'); - OK(buffer[1] == '3'); - OK(buffer[2] == 0); - OK(buffer[3] == 0); - OK(buffer[4] == '5'); - OK(buffer[5] == '6'); - OK(buffer[6] == '7'); - - return (0); -} - -int main (void) -{ - RUN_TEST(sstrncpy); - RUN_TEST(ssnprintf); - RUN_TEST(sstrdup); - RUN_TEST(strsplit); - RUN_TEST(strjoin); - RUN_TEST(strunescape); - - END_TEST; -} - -/* vim: set sw=2 sts=2 et : */ diff --git a/src/tests/macros.h b/src/tests/macros.h deleted file mode 100644 index 5df1b83a..00000000 --- a/src/tests/macros.h +++ /dev/null @@ -1,67 +0,0 @@ -/** - * collectd - src/tests/macros.h - * Copyright (C) 2013 Florian octo Forster - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Florian octo Forster - */ - -static int fail_count__ = 0; -static int check_count__ = 0; - -#define DEF_TEST(func) static int test_##func () - -#define RUN_TEST(func) do { \ - int status; \ - printf ("Testing %s ...\n", #func); \ - status = test_ ## func (); \ - printf ("%s.\n", (status == 0) ? "Success" : "FAILURE"); \ - if (status != 0) { fail_count__++; } \ -} while (0) - -#define END_TEST exit ((fail_count__ == 0) ? 0 : 1); - -#define OK1(cond, text) do { \ - _Bool result = (cond); \ - printf ("%s %i - %s\n", result ? "ok" : "not ok", ++check_count__, text); \ -} while (0) -#define OK(cond) OK1(cond, #cond) - -#define STREQ(expect, actual) do { \ - if (strcmp (expect, actual) != 0) { \ - printf ("not ok %i - %s incorrect: expected \"%s\", got \"%s\"\n", \ - ++check_count__, #actual, expect, actual); \ - return (-1); \ - } \ - printf ("ok %i - %s evaluates to \"%s\"\n", ++check_count__, #actual, expect); \ -} while (0) - -#define CHECK_NOT_NULL(expr) do { \ - void *ptr_; \ - ptr_ = (expr); \ - OK1(ptr_ != NULL, #expr); \ -} while (0) - -#define CHECK_ZERO(expr) do { \ - long status_; \ - status_ = (long) (expr); \ - OK1(status_ == 0L, #expr); \ -} while (0) diff --git a/src/tests/mock/plugin.c b/src/tests/mock/plugin.c deleted file mode 100644 index 86528809..00000000 --- a/src/tests/mock/plugin.c +++ /dev/null @@ -1,41 +0,0 @@ -/** - * collectd - src/tests/mock/plugin.c - * Copyright (C) 2013 Florian octo Forster - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Florian octo Forster - */ - -#include "plugin.h" - -void plugin_log (int level, char const *format, ...) -{ - char buffer[1024]; - va_list ap; - - va_start (ap, format); - vsnprintf (buffer, sizeof (buffer), format, ap); - va_end (ap); - - printf ("plugin_log (%i, \"%s\");\n", level, buffer); -} - -/* vim: set sw=2 sts=2 et : */ diff --git a/src/tests/mock/utils_cache.c b/src/tests/mock/utils_cache.c deleted file mode 100644 index 6c78d64d..00000000 --- a/src/tests/mock/utils_cache.c +++ /dev/null @@ -1,32 +0,0 @@ -/** - * collectd - src/tests/mock/utils_cache.c - * Copyright (C) 2013 Florian octo Forster - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Florian octo Forster - */ - -#include "utils_cache.h" - -gauge_t *uc_get_rate (const data_set_t *ds, const value_list_t *vl) -{ - return (NULL); -} diff --git a/src/tests/mock/utils_time.c b/src/tests/mock/utils_time.c deleted file mode 100644 index 5edfe6f9..00000000 --- a/src/tests/mock/utils_time.c +++ /dev/null @@ -1,33 +0,0 @@ -/** - * collectd - src/tests/mock/utils_time.c - * Copyright (C) 2013 Florian octo Forster - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Florian octo Forster - */ - -#include "utils_time.h" - -cdtime_t cdtime (void) -{ - return (0); -} - diff --git a/src/tests/test_common.c b/src/tests/test_common.c deleted file mode 100644 index c2eec953..00000000 --- a/src/tests/test_common.c +++ /dev/null @@ -1,246 +0,0 @@ -/** - * collectd - src/tests/test_common.c - * Copyright (C) 2013 Florian octo Forster - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Florian octo Forster - */ - -#include "tests/macros.h" -#include "common.h" - -DEF_TEST(sstrncpy) -{ - char buffer[16] = ""; - char *ptr = &buffer[4]; - char *ret; - - buffer[0] = buffer[1] = buffer[2] = buffer[3] = 0xff; - buffer[12] = buffer[13] = buffer[14] = buffer[15] = 0xff; - - ret = sstrncpy (ptr, "foobar", 8); - OK(ret == ptr); - STREQ ("foobar", ptr); - OK(buffer[3] == buffer[12]); - - ret = sstrncpy (ptr, "abc", 8); - OK(ret == ptr); - STREQ ("abc", ptr); - OK(buffer[3] == buffer[12]); - - ret = sstrncpy (ptr, "collectd", 8); - OK(ret == ptr); - OK(ptr[7] == 0); - STREQ ("collect", ptr); - OK(buffer[3] == buffer[12]); - - return (0); -} - -DEF_TEST(ssnprintf) -{ - char buffer[16] = ""; - char *ptr = &buffer[4]; - int status; - - buffer[0] = buffer[1] = buffer[2] = buffer[3] = 0xff; - buffer[12] = buffer[13] = buffer[14] = buffer[15] = 0xff; - - status = ssnprintf (ptr, 8, "%i", 1337); - OK(status == 4); - STREQ ("1337", ptr); - - status = ssnprintf (ptr, 8, "%s", "collectd"); - OK(status == 8); - OK(ptr[7] == 0); - STREQ ("collect", ptr); - OK(buffer[3] == buffer[12]); - - return (0); -} - -DEF_TEST(sstrdup) -{ - char *ptr; - - ptr = sstrdup ("collectd"); - OK(ptr != NULL); - STREQ ("collectd", ptr); - - sfree(ptr); - OK(ptr == NULL); - - ptr = sstrdup (NULL); - OK(ptr == NULL); - - return (0); -} - -DEF_TEST(strsplit) -{ - char buffer[32]; - char *fields[8]; - int status; - - strncpy (buffer, "foo bar", sizeof (buffer)); - status = strsplit (buffer, fields, 8); - OK(status == 2); - STREQ ("foo", fields[0]); - STREQ ("bar", fields[1]); - - strncpy (buffer, "foo \t bar", sizeof (buffer)); - status = strsplit (buffer, fields, 8); - OK(status == 2); - STREQ ("foo", fields[0]); - STREQ ("bar", fields[1]); - - strncpy (buffer, "one two\tthree\rfour\nfive", sizeof (buffer)); - status = strsplit (buffer, fields, 8); - OK(status == 5); - STREQ ("one", fields[0]); - STREQ ("two", fields[1]); - STREQ ("three", fields[2]); - STREQ ("four", fields[3]); - STREQ ("five", fields[4]); - - strncpy (buffer, "\twith trailing\n", sizeof (buffer)); - status = strsplit (buffer, fields, 8); - OK(status == 2); - STREQ ("with", fields[0]); - STREQ ("trailing", fields[1]); - - strncpy (buffer, "1 2 3 4 5 6 7 8 9 10 11 12 13", sizeof (buffer)); - status = strsplit (buffer, fields, 8); - OK(status == 8); - STREQ ("7", fields[6]); - STREQ ("8", fields[7]); - - strncpy (buffer, "single", sizeof (buffer)); - status = strsplit (buffer, fields, 8); - OK(status == 1); - STREQ ("single", fields[0]); - - strncpy (buffer, "", sizeof (buffer)); - status = strsplit (buffer, fields, 8); - OK(status == 0); - - return (0); -} - -DEF_TEST(strjoin) -{ - char buffer[16]; - char *fields[4]; - int status; - - fields[0] = "foo"; - fields[1] = "bar"; - fields[2] = "baz"; - fields[3] = "qux"; - - status = strjoin (buffer, sizeof (buffer), fields, 2, "!"); - OK(status == 7); - STREQ ("foo!bar", buffer); - - status = strjoin (buffer, sizeof (buffer), fields, 1, "!"); - OK(status == 3); - STREQ ("foo", buffer); - - status = strjoin (buffer, sizeof (buffer), fields, 0, "!"); - OK(status < 0); - - status = strjoin (buffer, sizeof (buffer), fields, 2, "rcht"); - OK(status == 10); - STREQ ("foorchtbar", buffer); - - status = strjoin (buffer, sizeof (buffer), fields, 4, ""); - OK(status == 12); - STREQ ("foobarbazqux", buffer); - - status = strjoin (buffer, sizeof (buffer), fields, 4, "!"); - OK(status == 15); - STREQ ("foo!bar!baz!qux", buffer); - - fields[0] = "0123"; - fields[1] = "4567"; - fields[2] = "8901"; - fields[3] = "2345"; - status = strjoin (buffer, sizeof (buffer), fields, 4, "-"); - OK(status < 0); - - return (0); -} - -DEF_TEST(strunescape) -{ - char buffer[16]; - int status; - - strncpy (buffer, "foo\\tbar", sizeof (buffer)); - status = strunescape (buffer, sizeof (buffer)); - OK(status == 0); - STREQ ("foo\tbar", buffer); - - strncpy (buffer, "\\tfoo\\r\\n", sizeof (buffer)); - status = strunescape (buffer, sizeof (buffer)); - OK(status == 0); - STREQ ("\tfoo\r\n", buffer); - - strncpy (buffer, "With \\\"quotes\\\"", sizeof (buffer)); - status = strunescape (buffer, sizeof (buffer)); - OK(status == 0); - STREQ ("With \"quotes\"", buffer); - - /* Backslash before null byte */ - strncpy (buffer, "\\tbackslash end\\", sizeof (buffer)); - status = strunescape (buffer, sizeof (buffer)); - OK(status != 0); - STREQ ("\tbackslash end", buffer); - return (0); - - /* Backslash at buffer end */ - strncpy (buffer, "\\t3\\56", sizeof (buffer)); - status = strunescape (buffer, 4); - OK(status != 0); - OK(buffer[0] == '\t'); - OK(buffer[1] == '3'); - OK(buffer[2] == 0); - OK(buffer[3] == 0); - OK(buffer[4] == '5'); - OK(buffer[5] == '6'); - OK(buffer[6] == '7'); - - return (0); -} - -int main (void) -{ - RUN_TEST(sstrncpy); - RUN_TEST(ssnprintf); - RUN_TEST(sstrdup); - RUN_TEST(strsplit); - RUN_TEST(strjoin); - RUN_TEST(strunescape); - - END_TEST; -} - -/* vim: set sw=2 sts=2 et : */ diff --git a/src/tests/test_utils_avltree.c b/src/tests/test_utils_avltree.c deleted file mode 100644 index 00d14e16..00000000 --- a/src/tests/test_utils_avltree.c +++ /dev/null @@ -1,82 +0,0 @@ -/** - * collectd - src/tests/test_utils_avltree.c - * Copyright (C) 2013 Florian octo Forster - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Florian octo Forster - */ - -#include "tests/macros.h" -#include "collectd.h" -#include "utils_avltree.h" - -static int compare_total_count = 0; -#define RESET_COUNTS() do { compare_total_count = 0; } while (0) - -static int compare_callback (void const *v0, void const *v1) -{ - assert (v0 != NULL); - assert (v1 != NULL); - - compare_total_count++; - return (strcmp (v0, v1)); -} - -DEF_TEST(success) -{ - c_avl_tree_t *t; - char key_orig[] = "foo"; - char value_orig[] = "bar"; - char *key_ret = NULL; - char *value_ret = NULL; - - RESET_COUNTS (); - t = c_avl_create (compare_callback); - OK (t != NULL); - - OK (c_avl_insert (t, key_orig, value_orig) == 0); - OK (c_avl_size (t) == 1); - - /* Key already exists. */ - OK (c_avl_insert (t, "foo", "qux") > 0); - - OK (c_avl_get (t, "foo", (void *) &value_ret) == 0); - OK (value_ret == &value_orig[0]); - - key_ret = value_ret = NULL; - OK (c_avl_remove (t, "foo", (void *) &key_ret, (void *) &value_ret) == 0); - OK (key_ret == &key_orig[0]); - OK (value_ret == &value_orig[0]); - OK (c_avl_size (t) == 0); - - c_avl_destroy (t); - - return (0); -} - -int main (void) -{ - RUN_TEST(success); - - END_TEST; -} - -/* vim: set sw=2 sts=2 et : */ diff --git a/src/tests/test_utils_heap.c b/src/tests/test_utils_heap.c deleted file mode 100644 index 91c90e5d..00000000 --- a/src/tests/test_utils_heap.c +++ /dev/null @@ -1,85 +0,0 @@ -/** - * collectd - src/tests/test_utils_heap.c - * Copyright (C) 2013 Florian octo Forster - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Florian octo Forster - */ - -#include "collectd.h" -#include "tests/macros.h" -#include "utils_heap.h" - -static int compare (void const *v0, void const *v1) -{ - int const *i0 = v0; - int const *i1 = v1; - - if ((*i0) < (*i1)) - return -1; - else if ((*i0) > (*i1)) - return 1; - else - return 0; -} - -DEF_TEST(simple) -{ - int values[] = { 9, 5, 6, 1, 3, 4, 0, 8, 2, 7 }; - int i; - c_heap_t *h; - - CHECK_NOT_NULL(h = c_heap_create (compare)); - for (i = 0; i < 10; i++) - CHECK_ZERO(c_heap_insert (h, &values[i])); - - for (i = 0; i < 5; i++) - { - int *ret = NULL; - CHECK_NOT_NULL(ret = c_heap_get_root(h)); - OK(*ret == i); - } - - CHECK_ZERO(c_heap_insert (h, &values[6] /* = 0 */)); - CHECK_ZERO(c_heap_insert (h, &values[3] /* = 1 */)); - CHECK_ZERO(c_heap_insert (h, &values[8] /* = 2 */)); - CHECK_ZERO(c_heap_insert (h, &values[4] /* = 3 */)); - CHECK_ZERO(c_heap_insert (h, &values[5] /* = 4 */)); - - for (i = 0; i < 10; i++) - { - int *ret = NULL; - CHECK_NOT_NULL(ret = c_heap_get_root(h)); - OK(*ret == i); - } - - c_heap_destroy(h); - return (0); -} - -int main (void) -{ - RUN_TEST(simple); - - END_TEST; -} - -/* vim: set sw=2 sts=2 et : */ diff --git a/src/tests/test_utils_mount.c b/src/tests/test_utils_mount.c deleted file mode 100644 index ba6b99bb..00000000 --- a/src/tests/test_utils_mount.c +++ /dev/null @@ -1,101 +0,0 @@ -/** - * collectd - src/tests/test_utils_mount.c - * Copyright (C) 2013 Florian octo Forster - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Florian octo Forster - */ - -#include "tests/macros.h" -#include "collectd.h" -#include "utils_mount.h" - -DEF_TEST(cu_mount_checkoption) -{ - char line_opts[] = "foo=one,bar=two,qux=three"; - char *foo = strstr (line_opts, "foo"); - char *bar = strstr (line_opts, "bar"); - char *qux = strstr (line_opts, "qux"); - - char line_bool[] = "one,two,three"; - char *one = strstr (line_bool, "one"); - char *two = strstr (line_bool, "two"); - char *three = strstr (line_bool, "three"); - - /* Normal operation */ - OK (foo == cu_mount_checkoption (line_opts, "foo", 0)); - OK (bar == cu_mount_checkoption (line_opts, "bar", 0)); - OK (qux == cu_mount_checkoption (line_opts, "qux", 0)); - OK (NULL == cu_mount_checkoption (line_opts, "unknown", 0)); - - OK (one == cu_mount_checkoption (line_bool, "one", 0)); - OK (two == cu_mount_checkoption (line_bool, "two", 0)); - OK (three == cu_mount_checkoption (line_bool, "three", 0)); - OK (NULL == cu_mount_checkoption (line_bool, "four", 0)); - - /* Shorter and longer parts */ - OK (foo == cu_mount_checkoption (line_opts, "fo", 0)); - OK (bar == cu_mount_checkoption (line_opts, "bar=", 0)); - OK (qux == cu_mount_checkoption (line_opts, "qux=thr", 0)); - - OK (one == cu_mount_checkoption (line_bool, "o", 0)); - OK (two == cu_mount_checkoption (line_bool, "tw", 0)); - OK (three == cu_mount_checkoption (line_bool, "thr", 0)); - - /* "full" flag */ - OK (one == cu_mount_checkoption (line_bool, "one", 1)); - OK (two == cu_mount_checkoption (line_bool, "two", 1)); - OK (three == cu_mount_checkoption (line_bool, "three", 1)); - OK (NULL == cu_mount_checkoption (line_bool, "four", 1)); - - OK (NULL == cu_mount_checkoption (line_bool, "o", 1)); - OK (NULL == cu_mount_checkoption (line_bool, "tw", 1)); - OK (NULL == cu_mount_checkoption (line_bool, "thr", 1)); - - return (0); -} -DEF_TEST(cu_mount_getoptionvalue) -{ - char line_opts[] = "foo=one,bar=two,qux=three"; - char line_bool[] = "one,two,three"; - - STREQ ("one", cu_mount_getoptionvalue (line_opts, "foo=")); - STREQ ("two", cu_mount_getoptionvalue (line_opts, "bar=")); - STREQ ("three", cu_mount_getoptionvalue (line_opts, "qux=")); - OK (NULL == cu_mount_getoptionvalue (line_opts, "unknown=")); - - STREQ ("", cu_mount_getoptionvalue (line_bool, "one")); - STREQ ("", cu_mount_getoptionvalue (line_bool, "two")); - STREQ ("", cu_mount_getoptionvalue (line_bool, "three")); - OK (NULL == cu_mount_getoptionvalue (line_bool, "four")); - - return (0); -} - -int main (void) -{ - RUN_TEST(cu_mount_checkoption); - RUN_TEST(cu_mount_getoptionvalue); - - END_TEST; -} - -/* vim: set sw=2 sts=2 et : */ diff --git a/src/tests/test_utils_vl_lookup.c b/src/tests/test_utils_vl_lookup.c deleted file mode 100644 index 842f3fd3..00000000 --- a/src/tests/test_utils_vl_lookup.c +++ /dev/null @@ -1,249 +0,0 @@ -/** - * collectd - src/tests/test_utils_vl_lookup.c - * Copyright (C) 2012 Florian Forster - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Florian Forster - **/ - -#include "tests/macros.h" -#include "collectd.h" -#include "utils_vl_lookup.h" - -static _Bool expect_new_obj = 0; -static _Bool have_new_obj = 0; - -static identifier_t last_class_ident; -static identifier_t last_obj_ident; - -static data_source_t dsrc_test = { "value", DS_TYPE_DERIVE, 0.0, NAN }; -static data_set_t const ds_test = { "test", 1, &dsrc_test }; - -static data_source_t dsrc_unknown = { "value", DS_TYPE_DERIVE, 0.0, NAN }; -static data_set_t const ds_unknown = { "unknown", 1, &dsrc_unknown }; - -static int lookup_obj_callback (data_set_t const *ds, - value_list_t const *vl, - void *user_class, void *user_obj) -{ - identifier_t *class = user_class; - identifier_t *obj = user_obj; - - OK1(expect_new_obj == have_new_obj, - (expect_new_obj ? "New obj is created." : "Updating existing obj.")); - - memcpy (&last_class_ident, class, sizeof (last_class_ident)); - memcpy (&last_obj_ident, obj, sizeof (last_obj_ident)); - - if (strcmp (obj->plugin_instance, "failure") == 0) - return (-1); - - return (0); -} - -static void *lookup_class_callback (data_set_t const *ds, - value_list_t const *vl, void *user_class) -{ - identifier_t *class = user_class; - identifier_t *obj; - - OK(expect_new_obj); - - memcpy (&last_class_ident, class, sizeof (last_class_ident)); - - obj = malloc (sizeof (*obj)); - strncpy (obj->host, vl->host, sizeof (obj->host)); - strncpy (obj->plugin, vl->plugin, sizeof (obj->plugin)); - strncpy (obj->plugin_instance, vl->plugin_instance, sizeof (obj->plugin_instance)); - strncpy (obj->type, vl->type, sizeof (obj->type)); - strncpy (obj->type_instance, vl->type_instance, sizeof (obj->type_instance)); - - have_new_obj = 1; - - return ((void *) obj); -} - -static void checked_lookup_add (lookup_t *obj, /* {{{ */ - char const *host, - char const *plugin, char const *plugin_instance, - char const *type, char const *type_instance, - unsigned int group_by) -{ - identifier_t ident; - void *user_class; - - memset (&ident, 0, sizeof (ident)); - strncpy (ident.host, host, sizeof (ident.host)); - strncpy (ident.plugin, plugin, sizeof (ident.plugin)); - strncpy (ident.plugin_instance, plugin_instance, sizeof (ident.plugin_instance)); - strncpy (ident.type, type, sizeof (ident.type)); - strncpy (ident.type_instance, type_instance, sizeof (ident.type_instance)); - - user_class = malloc (sizeof (ident)); - memmove (user_class, &ident, sizeof (ident)); - - OK(lookup_add (obj, &ident, group_by, user_class) == 0); -} /* }}} void test_add */ - -static int checked_lookup_search (lookup_t *obj, - char const *host, - char const *plugin, char const *plugin_instance, - char const *type, char const *type_instance, - _Bool expect_new) -{ - int status; - value_list_t vl = VALUE_LIST_STATIC; - data_set_t const *ds = &ds_unknown; - - strncpy (vl.host, host, sizeof (vl.host)); - strncpy (vl.plugin, plugin, sizeof (vl.plugin)); - strncpy (vl.plugin_instance, plugin_instance, sizeof (vl.plugin_instance)); - strncpy (vl.type, type, sizeof (vl.type)); - strncpy (vl.type_instance, type_instance, sizeof (vl.type_instance)); - - if (strcmp (vl.type, "test") == 0) - ds = &ds_test; - - expect_new_obj = expect_new; - have_new_obj = 0; - - status = lookup_search (obj, ds, &vl); - return (status); -} - -static lookup_t *checked_lookup_create (void) -{ - lookup_t *obj = lookup_create ( - lookup_class_callback, - lookup_obj_callback, - (void *) free, - (void *) free); - OK(obj != NULL); - return (obj); -} - -DEF_TEST(group_by_specific_host) -{ - lookup_t *obj = checked_lookup_create (); - - checked_lookup_add (obj, "/.*/", "test", "", "test", "/.*/", LU_GROUP_BY_HOST); - checked_lookup_search (obj, "host0", "test", "", "test", "0", - /* expect new = */ 1); - checked_lookup_search (obj, "host0", "test", "", "test", "1", - /* expect new = */ 0); - checked_lookup_search (obj, "host1", "test", "", "test", "0", - /* expect new = */ 1); - checked_lookup_search (obj, "host1", "test", "", "test", "1", - /* expect new = */ 0); - - lookup_destroy (obj); - return (0); -} - -DEF_TEST(group_by_any_host) -{ - lookup_t *obj = checked_lookup_create (); - - checked_lookup_add (obj, "/.*/", "/.*/", "/.*/", "test", "/.*/", LU_GROUP_BY_HOST); - checked_lookup_search (obj, "host0", "plugin0", "", "test", "0", - /* expect new = */ 1); - checked_lookup_search (obj, "host0", "plugin0", "", "test", "1", - /* expect new = */ 0); - checked_lookup_search (obj, "host0", "plugin1", "", "test", "0", - /* expect new = */ 0); - checked_lookup_search (obj, "host0", "plugin1", "", "test", "1", - /* expect new = */ 0); - checked_lookup_search (obj, "host1", "plugin0", "", "test", "0", - /* expect new = */ 1); - checked_lookup_search (obj, "host1", "plugin0", "", "test", "1", - /* expect new = */ 0); - checked_lookup_search (obj, "host1", "plugin1", "", "test", "0", - /* expect new = */ 0); - checked_lookup_search (obj, "host1", "plugin1", "", "test", "1", - /* expect new = */ 0); - - lookup_destroy (obj); - return (0); -} - -DEF_TEST(multiple_lookups) -{ - lookup_t *obj = checked_lookup_create (); - int status; - - checked_lookup_add (obj, "/.*/", "plugin0", "", "test", "/.*/", LU_GROUP_BY_HOST); - checked_lookup_add (obj, "/.*/", "/.*/", "", "test", "ti0", LU_GROUP_BY_HOST); - - status = checked_lookup_search (obj, "host0", "plugin1", "", "test", "", - /* expect new = */ 0); - assert (status == 0); - status = checked_lookup_search (obj, "host0", "plugin0", "", "test", "", - /* expect new = */ 1); - assert (status == 1); - status = checked_lookup_search (obj, "host0", "plugin1", "", "test", "ti0", - /* expect new = */ 1); - assert (status == 1); - status = checked_lookup_search (obj, "host0", "plugin0", "", "test", "ti0", - /* expect new = */ 0); - assert (status == 2); - - lookup_destroy (obj); - return (0); -} - -DEF_TEST(regex) -{ - lookup_t *obj = checked_lookup_create (); - - checked_lookup_add (obj, "/^db[0-9]\\./", "cpu", "/.*/", "cpu", "/.*/", - LU_GROUP_BY_TYPE_INSTANCE); - checked_lookup_search (obj, "db0.example.com", "cpu", "0", "cpu", "user", - /* expect new = */ 1); - checked_lookup_search (obj, "db0.example.com", "cpu", "0", "cpu", "idle", - /* expect new = */ 1); - checked_lookup_search (obj, "db0.example.com", "cpu", "1", "cpu", "user", - /* expect new = */ 0); - checked_lookup_search (obj, "db0.example.com", "cpu", "1", "cpu", "idle", - /* expect new = */ 0); - checked_lookup_search (obj, "app0.example.com", "cpu", "0", "cpu", "user", - /* expect new = */ 0); - checked_lookup_search (obj, "app0.example.com", "cpu", "0", "cpu", "idle", - /* expect new = */ 0); - checked_lookup_search (obj, "db1.example.com", "cpu", "0", "cpu", "user", - /* expect new = */ 0); - checked_lookup_search (obj, "db1.example.com", "cpu", "0", "cpu", "idle", - /* expect new = */ 0); - checked_lookup_search (obj, "db1.example.com", "cpu", "0", "cpu", "system", - /* expect new = */ 1); - - lookup_destroy (obj); - return (0); -} - -int main (int argc, char **argv) /* {{{ */ -{ - RUN_TEST(group_by_specific_host); - RUN_TEST(group_by_any_host); - RUN_TEST(multiple_lookups); - RUN_TEST(regex); - - END_TEST; -} /* }}} int main */ diff --git a/src/utils_format_graphite.c b/src/utils_format_graphite.c index 220258f4..023f7a46 100644 --- a/src/utils_format_graphite.c +++ b/src/utils_format_graphite.c @@ -60,7 +60,7 @@ static int gr_format_values (char *ret, size_t ret_len, } while (0) if (ds->ds[ds_num].type == DS_TYPE_GAUGE) - BUFFER_ADD ("%f", vl->values[ds_num].gauge); + BUFFER_ADD (GAUGE_FORMAT, vl->values[ds_num].gauge); else if (rates != NULL) BUFFER_ADD ("%f", rates[ds_num]); else if (ds->ds[ds_num].type == DS_TYPE_COUNTER) diff --git a/src/utils_format_json.c b/src/utils_format_json.c index 699c74e2..10a5343f 100644 --- a/src/utils_format_json.c +++ b/src/utils_format_json.c @@ -113,7 +113,7 @@ static int values_to_json (char *buffer, size_t buffer_size, /* {{{ */ if (ds->ds[i].type == DS_TYPE_GAUGE) { if(isfinite (vl->values[i].gauge)) - BUFFER_ADD ("%g", vl->values[i].gauge); + BUFFER_ADD (JSON_GAUGE_FORMAT, vl->values[i].gauge); else BUFFER_ADD ("null"); } @@ -129,7 +129,7 @@ static int values_to_json (char *buffer, size_t buffer_size, /* {{{ */ } if(isfinite (rates[i])) - BUFFER_ADD ("%g", rates[i]); + BUFFER_ADD (JSON_GAUGE_FORMAT, rates[i]); else BUFFER_ADD ("null"); } diff --git a/src/utils_format_json.h b/src/utils_format_json.h index a56913d5..f1fbb6e7 100644 --- a/src/utils_format_json.h +++ b/src/utils_format_json.h @@ -30,6 +30,10 @@ #include "collectd.h" #include "plugin.h" +#ifndef JSON_GAUGE_FORMAT +# define JSON_GAUGE_FORMAT GAUGE_FORMAT +#endif + int format_json_initialize (char *buffer, size_t *ret_buffer_fill, size_t *ret_buffer_free); int format_json_value_list (char *buffer, diff --git a/src/utils_mount.c b/src/utils_mount.c index 3cede018..b63a81ad 100644 --- a/src/utils_mount.c +++ b/src/utils_mount.c @@ -21,20 +21,18 @@ * Niki W. Waibel **/ -#if HAVE_CONFIG_H -# include "config.h" -#endif +#include "collectd.h" +#include "utils_mount.h" + +#include "common.h" /* sstrncpy() et alii */ +#include "plugin.h" /* ERROR() macro */ -#include "common.h" #if HAVE_XFS_XQM_H # include #define XFS_SUPER_MAGIC_STR "XFSB" #define XFS_SUPER_MAGIC2_STR "BSFX" #endif -#include "plugin.h" -#include "utils_mount.h" - #if HAVE_GETVFSSTAT # if HAVE_SYS_TYPES_H # include diff --git a/src/utils_mount_test.c b/src/utils_mount_test.c new file mode 100644 index 00000000..c5ffbfbc --- /dev/null +++ b/src/utils_mount_test.c @@ -0,0 +1,101 @@ +/** + * collectd - src/tests/test_utils_mount.c + * Copyright (C) 2013 Florian octo Forster + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + * Florian octo Forster + */ + +#include "testing.h" +#include "collectd.h" +#include "utils_mount.h" + +DEF_TEST(cu_mount_checkoption) +{ + char line_opts[] = "foo=one,bar=two,qux=three"; + char *foo = strstr (line_opts, "foo"); + char *bar = strstr (line_opts, "bar"); + char *qux = strstr (line_opts, "qux"); + + char line_bool[] = "one,two,three"; + char *one = strstr (line_bool, "one"); + char *two = strstr (line_bool, "two"); + char *three = strstr (line_bool, "three"); + + /* Normal operation */ + OK (foo == cu_mount_checkoption (line_opts, "foo", 0)); + OK (bar == cu_mount_checkoption (line_opts, "bar", 0)); + OK (qux == cu_mount_checkoption (line_opts, "qux", 0)); + OK (NULL == cu_mount_checkoption (line_opts, "unknown", 0)); + + OK (one == cu_mount_checkoption (line_bool, "one", 0)); + OK (two == cu_mount_checkoption (line_bool, "two", 0)); + OK (three == cu_mount_checkoption (line_bool, "three", 0)); + OK (NULL == cu_mount_checkoption (line_bool, "four", 0)); + + /* Shorter and longer parts */ + OK (foo == cu_mount_checkoption (line_opts, "fo", 0)); + OK (bar == cu_mount_checkoption (line_opts, "bar=", 0)); + OK (qux == cu_mount_checkoption (line_opts, "qux=thr", 0)); + + OK (one == cu_mount_checkoption (line_bool, "o", 0)); + OK (two == cu_mount_checkoption (line_bool, "tw", 0)); + OK (three == cu_mount_checkoption (line_bool, "thr", 0)); + + /* "full" flag */ + OK (one == cu_mount_checkoption (line_bool, "one", 1)); + OK (two == cu_mount_checkoption (line_bool, "two", 1)); + OK (three == cu_mount_checkoption (line_bool, "three", 1)); + OK (NULL == cu_mount_checkoption (line_bool, "four", 1)); + + OK (NULL == cu_mount_checkoption (line_bool, "o", 1)); + OK (NULL == cu_mount_checkoption (line_bool, "tw", 1)); + OK (NULL == cu_mount_checkoption (line_bool, "thr", 1)); + + return (0); +} +DEF_TEST(cu_mount_getoptionvalue) +{ + char line_opts[] = "foo=one,bar=two,qux=three"; + char line_bool[] = "one,two,three"; + + STREQ ("one", cu_mount_getoptionvalue (line_opts, "foo=")); + STREQ ("two", cu_mount_getoptionvalue (line_opts, "bar=")); + STREQ ("three", cu_mount_getoptionvalue (line_opts, "qux=")); + OK (NULL == cu_mount_getoptionvalue (line_opts, "unknown=")); + + STREQ ("", cu_mount_getoptionvalue (line_bool, "one")); + STREQ ("", cu_mount_getoptionvalue (line_bool, "two")); + STREQ ("", cu_mount_getoptionvalue (line_bool, "three")); + OK (NULL == cu_mount_getoptionvalue (line_bool, "four")); + + return (0); +} + +int main (void) +{ + RUN_TEST(cu_mount_checkoption); + RUN_TEST(cu_mount_getoptionvalue); + + END_TEST; +} + +/* vim: set sw=2 sts=2 et : */ diff --git a/src/utils_vl_lookup_test.c b/src/utils_vl_lookup_test.c new file mode 100644 index 00000000..6a2676a8 --- /dev/null +++ b/src/utils_vl_lookup_test.c @@ -0,0 +1,249 @@ +/** + * collectd - src/tests/test_utils_vl_lookup.c + * Copyright (C) 2012 Florian Forster + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + * Florian Forster + **/ + +#include "testing.h" +#include "collectd.h" +#include "utils_vl_lookup.h" + +static _Bool expect_new_obj = 0; +static _Bool have_new_obj = 0; + +static identifier_t last_class_ident; +static identifier_t last_obj_ident; + +static data_source_t dsrc_test = { "value", DS_TYPE_DERIVE, 0.0, NAN }; +static data_set_t const ds_test = { "test", 1, &dsrc_test }; + +static data_source_t dsrc_unknown = { "value", DS_TYPE_DERIVE, 0.0, NAN }; +static data_set_t const ds_unknown = { "unknown", 1, &dsrc_unknown }; + +static int lookup_obj_callback (data_set_t const *ds, + value_list_t const *vl, + void *user_class, void *user_obj) +{ + identifier_t *class = user_class; + identifier_t *obj = user_obj; + + OK1(expect_new_obj == have_new_obj, + (expect_new_obj ? "New obj is created." : "Updating existing obj.")); + + memcpy (&last_class_ident, class, sizeof (last_class_ident)); + memcpy (&last_obj_ident, obj, sizeof (last_obj_ident)); + + if (strcmp (obj->plugin_instance, "failure") == 0) + return (-1); + + return (0); +} + +static void *lookup_class_callback (data_set_t const *ds, + value_list_t const *vl, void *user_class) +{ + identifier_t *class = user_class; + identifier_t *obj; + + OK(expect_new_obj); + + memcpy (&last_class_ident, class, sizeof (last_class_ident)); + + obj = malloc (sizeof (*obj)); + strncpy (obj->host, vl->host, sizeof (obj->host)); + strncpy (obj->plugin, vl->plugin, sizeof (obj->plugin)); + strncpy (obj->plugin_instance, vl->plugin_instance, sizeof (obj->plugin_instance)); + strncpy (obj->type, vl->type, sizeof (obj->type)); + strncpy (obj->type_instance, vl->type_instance, sizeof (obj->type_instance)); + + have_new_obj = 1; + + return ((void *) obj); +} + +static void checked_lookup_add (lookup_t *obj, /* {{{ */ + char const *host, + char const *plugin, char const *plugin_instance, + char const *type, char const *type_instance, + unsigned int group_by) +{ + identifier_t ident; + void *user_class; + + memset (&ident, 0, sizeof (ident)); + strncpy (ident.host, host, sizeof (ident.host)); + strncpy (ident.plugin, plugin, sizeof (ident.plugin)); + strncpy (ident.plugin_instance, plugin_instance, sizeof (ident.plugin_instance)); + strncpy (ident.type, type, sizeof (ident.type)); + strncpy (ident.type_instance, type_instance, sizeof (ident.type_instance)); + + user_class = malloc (sizeof (ident)); + memmove (user_class, &ident, sizeof (ident)); + + OK(lookup_add (obj, &ident, group_by, user_class) == 0); +} /* }}} void test_add */ + +static int checked_lookup_search (lookup_t *obj, + char const *host, + char const *plugin, char const *plugin_instance, + char const *type, char const *type_instance, + _Bool expect_new) +{ + int status; + value_list_t vl = VALUE_LIST_STATIC; + data_set_t const *ds = &ds_unknown; + + strncpy (vl.host, host, sizeof (vl.host)); + strncpy (vl.plugin, plugin, sizeof (vl.plugin)); + strncpy (vl.plugin_instance, plugin_instance, sizeof (vl.plugin_instance)); + strncpy (vl.type, type, sizeof (vl.type)); + strncpy (vl.type_instance, type_instance, sizeof (vl.type_instance)); + + if (strcmp (vl.type, "test") == 0) + ds = &ds_test; + + expect_new_obj = expect_new; + have_new_obj = 0; + + status = lookup_search (obj, ds, &vl); + return (status); +} + +static lookup_t *checked_lookup_create (void) +{ + lookup_t *obj = lookup_create ( + lookup_class_callback, + lookup_obj_callback, + (void *) free, + (void *) free); + OK(obj != NULL); + return (obj); +} + +DEF_TEST(group_by_specific_host) +{ + lookup_t *obj = checked_lookup_create (); + + checked_lookup_add (obj, "/.*/", "test", "", "test", "/.*/", LU_GROUP_BY_HOST); + checked_lookup_search (obj, "host0", "test", "", "test", "0", + /* expect new = */ 1); + checked_lookup_search (obj, "host0", "test", "", "test", "1", + /* expect new = */ 0); + checked_lookup_search (obj, "host1", "test", "", "test", "0", + /* expect new = */ 1); + checked_lookup_search (obj, "host1", "test", "", "test", "1", + /* expect new = */ 0); + + lookup_destroy (obj); + return (0); +} + +DEF_TEST(group_by_any_host) +{ + lookup_t *obj = checked_lookup_create (); + + checked_lookup_add (obj, "/.*/", "/.*/", "/.*/", "test", "/.*/", LU_GROUP_BY_HOST); + checked_lookup_search (obj, "host0", "plugin0", "", "test", "0", + /* expect new = */ 1); + checked_lookup_search (obj, "host0", "plugin0", "", "test", "1", + /* expect new = */ 0); + checked_lookup_search (obj, "host0", "plugin1", "", "test", "0", + /* expect new = */ 0); + checked_lookup_search (obj, "host0", "plugin1", "", "test", "1", + /* expect new = */ 0); + checked_lookup_search (obj, "host1", "plugin0", "", "test", "0", + /* expect new = */ 1); + checked_lookup_search (obj, "host1", "plugin0", "", "test", "1", + /* expect new = */ 0); + checked_lookup_search (obj, "host1", "plugin1", "", "test", "0", + /* expect new = */ 0); + checked_lookup_search (obj, "host1", "plugin1", "", "test", "1", + /* expect new = */ 0); + + lookup_destroy (obj); + return (0); +} + +DEF_TEST(multiple_lookups) +{ + lookup_t *obj = checked_lookup_create (); + int status; + + checked_lookup_add (obj, "/.*/", "plugin0", "", "test", "/.*/", LU_GROUP_BY_HOST); + checked_lookup_add (obj, "/.*/", "/.*/", "", "test", "ti0", LU_GROUP_BY_HOST); + + status = checked_lookup_search (obj, "host0", "plugin1", "", "test", "", + /* expect new = */ 0); + assert (status == 0); + status = checked_lookup_search (obj, "host0", "plugin0", "", "test", "", + /* expect new = */ 1); + assert (status == 1); + status = checked_lookup_search (obj, "host0", "plugin1", "", "test", "ti0", + /* expect new = */ 1); + assert (status == 1); + status = checked_lookup_search (obj, "host0", "plugin0", "", "test", "ti0", + /* expect new = */ 0); + assert (status == 2); + + lookup_destroy (obj); + return (0); +} + +DEF_TEST(regex) +{ + lookup_t *obj = checked_lookup_create (); + + checked_lookup_add (obj, "/^db[0-9]\\./", "cpu", "/.*/", "cpu", "/.*/", + LU_GROUP_BY_TYPE_INSTANCE); + checked_lookup_search (obj, "db0.example.com", "cpu", "0", "cpu", "user", + /* expect new = */ 1); + checked_lookup_search (obj, "db0.example.com", "cpu", "0", "cpu", "idle", + /* expect new = */ 1); + checked_lookup_search (obj, "db0.example.com", "cpu", "1", "cpu", "user", + /* expect new = */ 0); + checked_lookup_search (obj, "db0.example.com", "cpu", "1", "cpu", "idle", + /* expect new = */ 0); + checked_lookup_search (obj, "app0.example.com", "cpu", "0", "cpu", "user", + /* expect new = */ 0); + checked_lookup_search (obj, "app0.example.com", "cpu", "0", "cpu", "idle", + /* expect new = */ 0); + checked_lookup_search (obj, "db1.example.com", "cpu", "0", "cpu", "user", + /* expect new = */ 0); + checked_lookup_search (obj, "db1.example.com", "cpu", "0", "cpu", "idle", + /* expect new = */ 0); + checked_lookup_search (obj, "db1.example.com", "cpu", "0", "cpu", "system", + /* expect new = */ 1); + + lookup_destroy (obj); + return (0); +} + +int main (int argc, char **argv) /* {{{ */ +{ + RUN_TEST(group_by_specific_host); + RUN_TEST(group_by_any_host); + RUN_TEST(multiple_lookups); + RUN_TEST(regex); + + END_TEST; +} /* }}} int main */ diff --git a/src/write_redis.c b/src/write_redis.c index b4c5e212..22e30abb 100644 --- a/src/write_redis.c +++ b/src/write_redis.c @@ -95,7 +95,7 @@ static int wr_write (const data_set_t *ds, /* {{{ */ if (ds->ds[i].type == DS_TYPE_COUNTER) APPEND ("%llu", vl->values[i].counter); else if (ds->ds[i].type == DS_TYPE_GAUGE) - APPEND ("%g", vl->values[i].gauge); + APPEND (GAUGE_FORMAT, vl->values[i].gauge); else if (ds->ds[i].type == DS_TYPE_DERIVE) APPEND ("%"PRIi64, vl->values[i].derive); else if (ds->ds[i].type == DS_TYPE_ABSOLUTE) @@ -113,22 +113,30 @@ static int wr_write (const data_set_t *ds, /* {{{ */ node->conn = redisConnectWithTimeout ((char *)node->host, node->port, node->timeout); if (node->conn == NULL) { - ERROR ("write_redis plugin: Connecting to host \"%s\" (port %i) failed.", + ERROR ("write_redis plugin: Connecting to host \"%s\" (port %i) failed: Unkown reason", (node->host != NULL) ? node->host : "localhost", (node->port != 0) ? node->port : 6379); pthread_mutex_unlock (&node->lock); return (-1); } + else if (node->conn->err) + { + ERROR ("write_redis plugin: Connecting to host \"%s\" (port %i) failed: %s", + (node->host != NULL) ? node->host : "localhost", + (node->port != 0) ? node->port : 6379, + node->conn->errstr); + pthread_mutex_unlock (&node->lock); + return (-1); + } } - assert (node->conn != NULL); rr = redisCommand (node->conn, "ZADD %s %s %s", key, time, value); if (rr==NULL) - WARNING("ZADD command error. key:%s", key); + WARNING("ZADD command error. key:%s message:%s", key, node->conn->errstr); rr = redisCommand (node->conn, "SADD collectd/values %s", ident); if (rr==NULL) - WARNING("SADD command error. ident:%s", ident); + WARNING("SADD command error. ident:%s message:%s", ident, node->conn->errstr); pthread_mutex_unlock (&node->lock); diff --git a/src/write_sensu.c b/src/write_sensu.c index cb0c2fe2..7a3e4f40 100644 --- a/src/write_sensu.c +++ b/src/write_sensu.c @@ -468,16 +468,14 @@ static char *sensu_value_to_json(struct sensu_host const *host, /* {{{ */ // calculate the value and set to a string if (ds->ds[index].type == DS_TYPE_GAUGE) { - double tmp_v = (double) vl->values[index].gauge; - res = asprintf(&value_str, "%.8f", tmp_v); + res = asprintf(&value_str, GAUGE_FORMAT, vl->values[index].gauge); if (res == -1) { free(ret_str); ERROR("write_sensu plugin: Unable to alloc memory"); return NULL; } } else if (rates != NULL) { - double tmp_v = (double) rates[index]; - res = asprintf(&value_str, "%.8f", tmp_v); + res = asprintf(&value_str, GAUGE_FORMAT, rates[index]); if (res == -1) { free(ret_str); ERROR("write_sensu plugin: Unable to alloc memory"); diff --git a/src/write_tsdb.c b/src/write_tsdb.c index 9008a67b..27ea4738 100644 --- a/src/write_tsdb.c +++ b/src/write_tsdb.c @@ -308,7 +308,7 @@ static int wt_format_values(char *ret, size_t ret_len, } while (0) if (ds->ds[ds_num].type == DS_TYPE_GAUGE) - BUFFER_ADD("%f", vl->values[ds_num].gauge); + BUFFER_ADD(GAUGE_FORMAT, vl->values[ds_num].gauge); else if (store_rates) { if (rates == NULL) @@ -319,7 +319,7 @@ static int wt_format_values(char *ret, size_t ret_len, "uc_get_rate failed."); return -1; } - BUFFER_ADD("%f", rates[ds_num]); + BUFFER_ADD(GAUGE_FORMAT, rates[ds_num]); } else if (ds->ds[ds_num].type == DS_TYPE_COUNTER) BUFFER_ADD("%llu", vl->values[ds_num].counter); diff --git a/src/zone.c b/src/zone.c new file mode 100644 index 00000000..cb3869d6 --- /dev/null +++ b/src/zone.c @@ -0,0 +1,202 @@ +/** + * collectd - src/zone.c + * Copyright (C) 2011 Mathijs Mohlmann + * + * 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; only version 2 of the License is applicable. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: + * Mathijs Mohlmann + * Dagobert Michelsen (forward-porting) + **/ + +#define _BSD_SOURCE + +#include "collectd.h" +#include "common.h" +#include "plugin.h" + +#include +#include +#include +#include + +#include "utils_avltree.h" + +#define MAX_PROCFS_PATH 40 +#define FRC2PCT(pp)(((float)(pp))/0x8000*100) + +typedef struct zone_stats { + ushort_t pctcpu; + ushort_t pctmem; +} zone_stats_t; + +static long pagesize; + +static int zone_init (void) +{ + pagesize = sysconf(_SC_PAGESIZE); + return (0); +} + +static int +zone_compare(const zoneid_t *a, const zoneid_t *b) +{ + if (*a == *b) + return(0); + if (*a < *b) + return(-1); + return(1); +} + +static int +zone_read_procfile(char *pidstr, char *file, void *buf, size_t bufsize) +{ + int fd; + + char procfile[MAX_PROCFS_PATH]; + (void)snprintf(procfile, sizeof(procfile), "/proc/%s/%s", pidstr, file); + if ((fd = open(procfile, O_RDONLY)) == -1) { + return (1); + } + + if (pread(fd, buf, bufsize, 0) != bufsize) { + close(fd); + return (1); + } + close(fd); + return (0); +} + +static int +zone_submit_value(char *zone, gauge_t value) +{ + value_list_t vl = VALUE_LIST_INIT; + value_t values[1]; + + values[0].gauge = value; + + vl.values = values; + vl.values_len = 1; /*STATIC_ARRAY_SIZE (values);*/ + sstrncpy (vl.host, hostname_g, sizeof (vl.host)); + sstrncpy (vl.plugin, "zone", sizeof (vl.plugin)); + sstrncpy (vl.type, "percent", sizeof (vl.type)); + sstrncpy (vl.type_instance, zone, sizeof (vl.type_instance)); + + return(plugin_dispatch_values (&vl)); +} + +static zone_stats_t * +zone_find_stats(c_avl_tree_t *tree, zoneid_t zoneid) +{ + zone_stats_t *ret = NULL; + zoneid_t *key = NULL; + + if (c_avl_get(tree, (void **)&zoneid, (void **)&ret)) { + if (!(ret = malloc(sizeof(zone_stats_t)))) { + WARNING("zone plugin: no memory"); + return(NULL); + } + if (!(key = malloc(sizeof(zoneid_t)))) { + WARNING("zone plugin: no memory"); + return(NULL); + } + *key = zoneid; + if (c_avl_insert(tree, key, ret)) { + WARNING("zone plugin: error inserting into tree"); + return(NULL); + } + } + return(ret); +} + +static void +zone_submit_values(c_avl_tree_t *tree) +{ + char zonename[ZONENAME_MAX]; + zoneid_t *zoneid = NULL; + zone_stats_t *stats = NULL; + + while (c_avl_pick (tree, (void **)&zoneid, (void **)&stats) == 0) + { + if (getzonenamebyid(*zoneid, zonename, sizeof( zonename )) == -1) { + WARNING("zone plugin: error retreiving zonename"); + } else { + zone_submit_value(zonename, (gauge_t)FRC2PCT(stats->pctcpu)); + } + free(stats); + free(zoneid); + } + c_avl_destroy(tree); +} + +static c_avl_tree_t * +zone_scandir(DIR *procdir) +{ + char *pidstr; + pid_t pid; + dirent_t *direntp; + psinfo_t psinfo; + c_avl_tree_t *tree; + zone_stats_t *stats; + + if (!(tree=c_avl_create((void *) zone_compare))) { + WARNING("zone plugin: Failed to create tree"); + return(NULL); + } + + rewinddir(procdir); + while ((direntp = readdir(procdir))) { + pidstr = direntp->d_name; + if (pidstr[0] == '.') /* skip "." and ".." */ + continue; + pid = atoi(pidstr); + if (pid == 0 || pid == 2 || pid == 3) + continue; /* skip sched, pageout and fsflush */ + if (zone_read_procfile(pidstr, "psinfo", &psinfo, + sizeof(psinfo_t)) != 0) + continue; + stats = zone_find_stats(tree, psinfo.pr_zoneid); + if( stats ) { + stats->pctcpu += psinfo.pr_pctcpu; + stats->pctmem += psinfo.pr_pctmem; + } + } + return(tree); +} + + +static int zone_read (void) +{ + DIR *procdir; + c_avl_tree_t *tree; + + if ((procdir = opendir("/proc")) == NULL) { + ERROR("zone plugin: cannot open /proc directory\n"); + return (-1); + } + + tree=zone_scandir(procdir); + closedir(procdir); + if (tree == NULL) { + return (-1); + } + zone_submit_values(tree); /* this also frees tree */ + return (0); +} + +void module_register (void) +{ + plugin_register_init ("zone", zone_init); + plugin_register_read ("zone", zone_read); +} /* void module_register */ diff --git a/version-gen.sh b/version-gen.sh index 460c6e9d..b09be8e7 100755 --- a/version-gen.sh +++ b/version-gen.sh @@ -1,6 +1,6 @@ #!/bin/sh -DEFAULT_VERSION="5.4.2.git" +DEFAULT_VERSION="5.5.0.git" VERSION="`git describe 2> /dev/null | grep collectd | sed -e 's/^collectd-//'`"