diff options
Diffstat (limited to 'bindings/rust/tests')
-rw-r--r-- | bindings/rust/tests/Cargo.toml.in | 36 | ||||
-rw-r--r-- | bindings/rust/tests/Makefile.am | 26 | ||||
-rw-r--r-- | bindings/rust/tests/Makefile.in | 625 | ||||
-rw-r--r-- | bindings/rust/tests/build.rs.in | 22 | ||||
-rw-r--r-- | bindings/rust/tests/src/bin/cfg-test.rs | 135 | ||||
-rw-r--r-- | bindings/rust/tests/src/bin/cmap-test.rs | 195 | ||||
-rw-r--r-- | bindings/rust/tests/src/bin/cpg-test.rs | 142 | ||||
-rw-r--r-- | bindings/rust/tests/src/bin/quorum-test.rs | 83 | ||||
-rw-r--r-- | bindings/rust/tests/src/bin/votequorum-test.rs | 117 |
9 files changed, 1381 insertions, 0 deletions
diff --git a/bindings/rust/tests/Cargo.toml.in b/bindings/rust/tests/Cargo.toml.in new file mode 100644 index 0000000..1d8fabf --- /dev/null +++ b/bindings/rust/tests/Cargo.toml.in @@ -0,0 +1,36 @@ +[package] +name = "rust-corosync-tests" +version = "@corosyncrustver@" +authors = ["Christine Caulfield <ccaulfie@redhat.com>"] +edition = "2021" + +[dependencies] +rust-corosync = { path = ".." } + +[build-dependencies] +pkg-config = "0.3" + +[[bin]] +name = "cpg-test" +test = false +bench = false + +[[bin]] +name = "quorum-test" +test = false +bench = false + +[[bin]] +name = "votequorum-test" +test = false +bench = false + +[[bin]] +name = "cfg-test" +test = false +bench = false + +[[bin]] +name = "cmap-test" +test = false +bench = false diff --git a/bindings/rust/tests/Makefile.am b/bindings/rust/tests/Makefile.am new file mode 100644 index 0000000..a8ac087 --- /dev/null +++ b/bindings/rust/tests/Makefile.am @@ -0,0 +1,26 @@ +# +# Copyright (C) 2022-2023 Red Hat, Inc. All rights reserved. +# +# Author: Christine Caulfield <ccaulfie@redhat.com> +# +# This software licensed under GPL-2.0+ +# + +MAINTAINERCLEANFILES = Makefile.in + +include $(top_srcdir)/build-aux/rust.mk + +EXTRA_DIST = \ + $(RUST_COMMON) \ + $(RUST_SHIP_SRCS) + +RUST_SHIP_SRCS = src/bin/cpg-test.rs \ + src/bin/cfg-test.rs \ + src/bin/cmap-test.rs \ + src/bin/quorum-test.rs \ + src/bin/votequorum-test.rs + +# This will build all of the tests +noinst_SCRIPTS = target/$(RUST_TARGET_DIR)/cpg-test + +clean-local: cargo-clean diff --git a/bindings/rust/tests/Makefile.in b/bindings/rust/tests/Makefile.in new file mode 100644 index 0000000..36cc52a --- /dev/null +++ b/bindings/rust/tests/Makefile.in @@ -0,0 +1,625 @@ +# Makefile.in generated by automake 1.13.4 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# +# Copyright (C) 2022-2023 Red Hat, Inc. All rights reserved. +# +# Author: Christine Caulfield <ccaulfie@redhat.com> +# +# This software licensed under GPL-2.0+ +# + +# +# Copyright (C) 2021-2022 Red Hat, Inc. All rights reserved. +# +# Author: Fabio M. Di Nitto <fabbione@kronosnet.org> +# +# This software licensed under GPL-2.0+ +# + +VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +DIST_COMMON = $(top_srcdir)/build-aux/rust.mk $(srcdir)/Makefile.in \ + $(srcdir)/Makefile.am $(srcdir)/Cargo.toml.in +subdir = bindings/rust/tests +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/lib/libcfg.verso $(top_srcdir)/lib/libcpg.verso \ + $(top_srcdir)/lib/libquorum.verso \ + $(top_srcdir)/lib/libsam.verso \ + $(top_srcdir)/lib/libvotequorum.verso \ + $(top_srcdir)/lib/libcmap.verso $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/include/corosync/config.h +CONFIG_CLEAN_FILES = Cargo.toml +CONFIG_CLEAN_VPATH_FILES = +SCRIPTS = $(noinst_SCRIPTS) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUGTOOL = @AUGTOOL@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BASHPATH = @BASHPATH@ +BINDGEN = @BINDGEN@ +CARGO = @CARGO@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFG_SONAME = @CFG_SONAME@ +CFLAGS = @CFLAGS@ +CLIPPY = @CLIPPY@ +CMAP_SONAME = @CMAP_SONAME@ +COROSYSCONFDIR = @COROSYSCONFDIR@ +CPG_SONAME = @CPG_SONAME@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DBUS_CFLAGS = @DBUS_CFLAGS@ +DBUS_LIBS = @DBUS_LIBS@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOT = @DOT@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +GROFF = @GROFF@ +INITCONFIGDIR = @INITCONFIGDIR@ +INITDDIR = @INITDDIR@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBQB_CFLAGS = @LIBQB_CFLAGS@ +LIBQB_LIBS = @LIBQB_LIBS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LINT_FLAGS = @LINT_FLAGS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LOGDIR = @LOGDIR@ +LOGROTATEDIR = @LOGROTATEDIR@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +QUORUM_SONAME = @QUORUM_SONAME@ +RANLIB = @RANLIB@ +RUSTC = @RUSTC@ +RUSTDOC = @RUSTDOC@ +RUSTFMT = @RUSTFMT@ +RUST_FLAGS = @RUST_FLAGS@ +RUST_TARGET_DIR = @RUST_TARGET_DIR@ +SAM_SONAME = @SAM_SONAME@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SNMPCONFIG = @SNMPCONFIG@ +SNMP_LIBS = @SNMP_LIBS@ +SOMAJOR = @SOMAJOR@ +SOMICRO = @SOMICRO@ +SOMINOR = @SOMINOR@ +SONAME = @SONAME@ +STRIP = @STRIP@ +SYSTEMDDIR = @SYSTEMDDIR@ +VERSCRIPT_LDFLAGS = @VERSCRIPT_LDFLAGS@ +VERSION = @VERSION@ +VOTEQUORUM_SONAME = @VOTEQUORUM_SONAME@ +WITH_LIST = @WITH_LIST@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +corosyncrustver = @corosyncrustver@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +knet_CFLAGS = @knet_CFLAGS@ +knet_LIBS = @knet_LIBS@ +libdir = @libdir@ +libexecdir = @libexecdir@ +libsystemd_CFLAGS = @libsystemd_CFLAGS@ +libsystemd_LIBS = @libsystemd_LIBS@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +nozzle_CFLAGS = @nozzle_CFLAGS@ +nozzle_LIBS = @nozzle_LIBS@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +statgrab_CFLAGS = @statgrab_CFLAGS@ +statgrab_LIBS = @statgrab_LIBS@ +statgrabge090_CFLAGS = @statgrabge090_CFLAGS@ +statgrabge090_LIBS = @statgrabge090_LIBS@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +MAINTAINERCLEANFILES = Makefile.in +RUST_COMMON = \ + build.rs.in + +RUST_SRCS = $(RUST_SHIP_SRCS) $(RUST_BUILT_SRCS) +EXTRA_DIST = \ + $(RUST_COMMON) \ + $(RUST_SHIP_SRCS) + +RUST_SHIP_SRCS = src/bin/cpg-test.rs \ + src/bin/cfg-test.rs \ + src/bin/cmap-test.rs \ + src/bin/quorum-test.rs \ + src/bin/votequorum-test.rs + + +# This will build all of the tests +noinst_SCRIPTS = target/$(RUST_TARGET_DIR)/cpg-test +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(top_srcdir)/build-aux/rust.mk $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign bindings/rust/tests/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign bindings/rust/tests/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; +$(top_srcdir)/build-aux/rust.mk: + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +Cargo.toml: $(top_builddir)/config.status $(srcdir)/Cargo.toml.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +tags TAGS: + +ctags CTAGS: + +cscope cscopelist: + + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) check-local +check: check-am +all-am: Makefile $(SCRIPTS) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-am + +clean-am: clean-generic clean-libtool clean-local mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: check-am install-am install-strip + +.PHONY: all all-am check check-am check-local clean clean-generic \ + clean-libtool clean-local cscopelist-am ctags-am distclean \ + distclean-generic distclean-libtool distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \ + uninstall-am + + +%.rlib: $(RUST_SRCS) Cargo.toml build.rs + PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(CARGO) build $(RUST_FLAGS) + +%-test: $(RUST_SRCS) Cargo.toml build.rs + PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(CARGO) build $(RUST_FLAGS) + +build.rs: build.rs.in + rm -f $@ $@-t + cat $^ | sed \ + -e 's#@ABSTOPLEVELSRC@#$(abs_top_srcdir)#g' \ + -e 's#@ABSTOPLEVELBUILD@#$(abs_top_builddir)#g' \ + -e 's#@LIBQBLIBS@#$(LIBQB_LIBS)#g' \ + > $@-t + chmod a-w $@-t + mv $@-t $@ + rm -f $@-t + +cargo-tree-prep: + if [ "${abs_builddir}" != "${abs_srcdir}" ]; then \ + echo "Generating builddir out-of-tree rust symlinks"; \ + src_realpath=$(shell realpath ${abs_srcdir}); \ + for i in `find "$$src_realpath/" -type d | \ + grep -v "${abs_builddir}" | \ + sed -e 's#^'$$src_realpath'/##g'`; do \ + $(MKDIR_P) ${abs_builddir}/$${i}; \ + done; \ + find "$$src_realpath/" -type f | { while read src; do \ + process=no; \ + copy=no; \ + case $$src in \ + ${abs_builddir}*) \ + ;; \ + *Makefile.*|*.in) \ + ;; \ + *) \ + process=yes; \ + ;; \ + esac ; \ + dst=`echo $$src | sed -e 's#^'$$src_realpath'/##g'`; \ + if [ $${process} == yes ]; then \ + rm -f ${abs_builddir}/$$dst; \ + $(LN_S) $$src ${abs_builddir}/$$dst; \ + fi; \ + if [ $${copy} == yes ]; then \ + rm -f ${abs_builddir}/$$dst; \ + cp $$src ${abs_builddir}/$$dst; \ + chmod u+w ${abs_builddir}/$$dst; \ + fi; \ + done; }; \ + fi + +cargo-clean: + -$(CARGO) clean + rm -rf Cargo.lock $(RUST_BUILT_SRCS) build.rs target/ + if [ "${abs_builddir}" != "${abs_srcdir}" ]; then \ + echo "Cleaning out-of-tree rust symlinks" ; \ + find "${abs_builddir}/" -type l -delete; \ + find "${abs_builddir}/" -type d -empty -delete; \ + fi + +clippy-check: + $(CARGO) clippy --verbose --all-features -- -D warnings + +format-check: + if [ "${abs_builddir}" = "${abs_srcdir}" ]; then \ + $(CARGO) fmt --all --check; \ + else \ + echo "!!!!! WARNING: skipping format check !!!!!"; \ + fi + +doc-check: + $(CARGO) doc --verbose --all-features + +publish-check: + if [ -f "${abs_srcdir}/README.md" ]; then \ + $(CARGO) publish --dry-run; \ + fi + +crates-publish: + if [ -f "${abs_srcdir}/README.md" ]; then \ + bindingname=`cat Cargo.toml | grep ^name | sed -e 's#.*= ##g' -e 's#"##g'` && \ + cratesver=`cargo search $$bindingname | grep "^$$bindingname " | sed -e 's#.*= ##g' -e 's#"##g' -e 's/\+.*//g'` && \ + testver=`echo $(localver) | sed -e 's/\+.*//g'` && \ + if [ "$$cratesver" != "$$testver" ]; then \ + $(CARGO) publish; \ + fi; \ + fi + +crates-check: + if [ -f "${abs_srcdir}/README.md" ]; then \ + bindingname=`cat Cargo.toml | grep ^name | sed -e 's#.*= ##g' -e 's#"##g'` && \ + cratesver=`cargo search $$bindingname | grep "^$$bindingname " | sed -e 's#.*= ##g' -e 's#"##g' -e 's/\+.*//g'` && \ + testver=`echo $(localver) | sed -e 's/\+.*//g'` && \ + if [ "$$cratesver" != "$$testver" ]; then \ + echo "!!!!! WARNING !!!!!"; \ + echo "!!!!! WARNING: $$bindingname local version ($$testver) is higher than the current published one on crates.io ($$cratesver)"; \ + echo "!!!!! WARNING !!!!!"; \ + fi; \ + fi + +check-local: clippy-check format-check doc-check crates-check publish-check + +clean-local: cargo-clean + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/bindings/rust/tests/build.rs.in b/bindings/rust/tests/build.rs.in new file mode 100644 index 0000000..39a97ba --- /dev/null +++ b/bindings/rust/tests/build.rs.in @@ -0,0 +1,22 @@ +// Copyright (C) 2021-2023 Red Hat, Inc. +// +// All rights reserved. +// +// Author: Christine Caulfield (ccaulfi@redhat.com) +// + +extern crate pkg_config; + +fn main() { + // Tell the compiler to use the build-tree libs & headers for compiling + println!("cargo:rustc-link-search=native=../../../lib/.libs/"); + println!("cargo:rustc-link-search=native=../../../common_lib/.libs/"); + println!("cargo:rustc-flags=@LIBQBLIBS@"); + println!("cargo:rustc-link-lib=cpg"); + println!("cargo:rustc-link-lib=cfg"); + println!("cargo:rustc-link-lib=cmap"); + println!("cargo:rustc-link-lib=quorum"); + println!("cargo:rustc-link-lib=votequorum"); + println!("cargo:rustc-link-lib=corosync_common"); + println!("cargo:rustc-link-lib=qb"); +} diff --git a/bindings/rust/tests/src/bin/cfg-test.rs b/bindings/rust/tests/src/bin/cfg-test.rs new file mode 100644 index 0000000..cd70d38 --- /dev/null +++ b/bindings/rust/tests/src/bin/cfg-test.rs @@ -0,0 +1,135 @@ +// Test the CFG library. Requires that corosync is running and that we are root. + +extern crate rust_corosync as corosync; +use corosync::{cfg, NodeId}; + +use std::thread::spawn; + +fn dispatch_thread(handle: cfg::Handle) { + loop { + if cfg::dispatch(handle, corosync::DispatchFlags::One).is_err() { + return; + } + } +} + +// Test the shutdown callback +fn shutdown_check_fn(handle: &cfg::Handle, _flags: u32) { + println!("in shutdown callback"); + + // DON'T shutdown corosync - we're just testing + if let Err(e) = cfg::reply_to_shutdown(*handle, cfg::ShutdownReply::No) { + println!("Error in CFG replyto_shutdown: {e}"); + } +} + +fn main() { + // Initialise the callbacks data + let cb = cfg::Callbacks { + corosync_cfg_shutdown_callback_fn: Some(shutdown_check_fn), + }; + + let handle = match cfg::initialize(&cb) { + Ok(h) => { + println!("cfg initialized."); + h + } + Err(e) => { + println!("Error in CFG init: {e}"); + return; + } + }; + + // Open two handles to CFG so that the second one can refuse shutdown + let handle2 = match cfg::initialize(&cb) { + Ok(h) => { + println!("cfg2 initialized."); + h + } + Err(e) => { + println!("Error in CFG init: {e}"); + return; + } + }; + + match cfg::track_start(handle2, cfg::TrackFlags::None) { + Ok(_) => { + // Run handle2 dispatch in its own thread + spawn(move || dispatch_thread(handle2)); + } + Err(e) => { + println!("Error in CFG track_start: {e}"); + } + }; + + let local_nodeid = { + match cfg::local_get(handle) { + Ok(n) => { + println!("Local nodeid is {n}"); + Some(n) + } + Err(e) => { + println!("Error in CFG local_get: {e}"); + None + } + } + }; + + // Test node_status_get. + // node status for the local node looks odd (cos it's the loopback connection), so + // we try for a node ID one less or more than us just to get output that looks + // sensible to the user. + if let Some(our_nodeid) = local_nodeid { + let us_plus1 = NodeId::from(u32::from(our_nodeid) + 1); + let us_less1 = NodeId::from(u32::from(our_nodeid) - 1); + let mut res = cfg::node_status_get(handle, us_plus1, cfg::NodeStatusVersion::V1); + if let Err(e) = res { + println!("Error from node_status_get on nodeid {us_plus1}: {e}"); + res = cfg::node_status_get(handle, us_less1, cfg::NodeStatusVersion::V1); + }; + match res { + Ok(ns) => { + println!("Node Status for nodeid {}", ns.nodeid); + println!(" reachable: {}", ns.reachable); + println!(" remote: {}", ns.remote); + println!(" onwire_min: {}", ns.onwire_min); + println!(" onwire_max: {}", ns.onwire_max); + println!(" onwire_ver: {}", ns.onwire_ver); + for (ls_num, ls) in ns.link_status.iter().enumerate() { + if ls.enabled { + println!(" Link {ls_num}"); + println!(" connected: {}", ls.connected); + println!(" mtu: {}", ls.mtu); + println!(" src: {}", ls.src_ipaddr); + println!(" dst: {}", ls.dst_ipaddr); + } + } + } + Err(e) => { + println!( + "Error in CFG node_status get: {e} (tried nodeids {us_plus1} & {us_less1})" + ); + } + } + } + + // This should not shutdown corosync because the callback on handle2 will refuse it. + match cfg::try_shutdown(handle, cfg::ShutdownFlags::Request) { + Ok(_) => { + println!("CFG try_shutdown suceeded, should return busy"); + } + Err(e) => { + if e != corosync::CsError::CsErrBusy { + println!("Error in CFG try_shutdown: {e}"); + } + } + } + + // Wait for events + loop { + if cfg::dispatch(handle, corosync::DispatchFlags::One).is_err() { + break; + } + } + println!("ERROR: Corosync quit"); +} diff --git a/bindings/rust/tests/src/bin/cmap-test.rs b/bindings/rust/tests/src/bin/cmap-test.rs new file mode 100644 index 0000000..f435653 --- /dev/null +++ b/bindings/rust/tests/src/bin/cmap-test.rs @@ -0,0 +1,195 @@ +// Test the CMAP library. Requires that corosync is running and that we are root. + +extern crate rust_corosync as corosync; +use corosync::cmap; + +fn track_notify_fn( + _handle: &cmap::Handle, + _track_handle: &cmap::TrackHandle, + event: cmap::TrackType, + key_name: &str, + old_value: &cmap::Data, + new_value: &cmap::Data, + user_data: u64, +) { + println!("Track notify callback"); + println!("Key: {key_name}, event: {event}, user_data: {user_data}"); + println!(" Old value: {old_value}"); + println!(" New value: {new_value}"); +} + +fn main() { + let handle = match cmap::initialize(cmap::Map::Icmap) { + Ok(h) => { + println!("cmap initialized."); + h + } + Err(e) => { + println!("Error in CMAP (Icmap) init: {e}"); + return; + } + }; + + // Test some SETs + if let Err(e) = cmap::set_u32(handle, "test.test_uint32", 456) { + println!("Error in CMAP set_u32: {e}"); + return; + }; + + if let Err(e) = cmap::set_i16(handle, "test.test_int16", -789) { + println!("Error in CMAP set_i16: {e}"); + return; + }; + + if let Err(e) = cmap::set_number(handle, "test.test_num_1", 6809u32) { + println!("Error in CMAP set_number(u32): {e}"); + return; + }; + + // NOT PI (just to avoid clippy whingeing) + if let Err(e) = cmap::set_number(handle, "test.test_num_2", 3.24159265) { + println!("Error in CMAP set_number(f32): {e}"); + return; + }; + + if let Err(e) = cmap::set_string(handle, "test.test_string", "Hello from Rust") { + println!("Error in CMAP set_string: {e}"); + return; + }; + + let test_d = cmap::Data::UInt64(0xdeadbeefbacecafe); + if let Err(e) = cmap::set(handle, "test.test_data", &test_d) { + println!("Error in CMAP set_data: {e}"); + return; + }; + + // let test_d2 = cmap::Data::UInt32(6809); + let test_d2 = cmap::Data::String("Test string in data 12345".to_string()); + if let Err(e) = cmap::set(handle, "test.test_again", &test_d2) { + println!("Error in CMAP set_data2: {e}"); + return; + }; + + // get them back again + match cmap::get(handle, "test.test_uint32") { + Ok(v) => { + println!("GOT uint32 {v}"); + } + + Err(e) => { + println!("Error in CMAP get: {e}"); + return; + } + }; + match cmap::get(handle, "test.test_int16") { + Ok(v) => { + println!("GOT uint16 {v}"); + } + + Err(e) => { + println!("Error in CMAP get: {e}"); + return; + } + }; + + match cmap::get(handle, "test.test_num_1") { + Ok(v) => { + println!("GOT num {v}"); + } + + Err(e) => { + println!("Error in CMAP get: {e}"); + return; + } + }; + match cmap::get(handle, "test.test_num_2") { + Ok(v) => { + println!("GOT num {v}"); + } + + Err(e) => { + println!("Error in CMAP get: {e}"); + return; + } + }; + match cmap::get(handle, "test.test_string") { + Ok(v) => { + println!("GOT string {v}"); + } + + Err(e) => { + println!("Error in CMAP get: {e}"); + return; + } + }; + + match cmap::get(handle, "test.test_data") { + Ok(v) => match v { + cmap::Data::UInt64(u) => println!("GOT data value {u:x}"), + _ => println!("ERROR type was not UInt64, got {v}"), + }, + + Err(e) => { + println!("Error in CMAP get: {e}"); + return; + } + }; + + // Test an iterator + match cmap::CmapIterStart::new(handle, "totem.") { + Ok(cmap_iter) => { + for i in cmap_iter { + println!("ITER: {i:?}"); + } + println!(); + } + Err(e) => { + println!("Error in CMAP iter start: {e}"); + } + } + + // Close this handle + if let Err(e) = cmap::finalize(handle) { + println!("Error in CMAP get: {e}"); + return; + }; + + // Test notifications on the stats map + let handle = match cmap::initialize(cmap::Map::Stats) { + Ok(h) => h, + Err(e) => { + println!("Error in CMAP (Stats) init: {e}"); + return; + } + }; + + let cb = cmap::NotifyCallback { + notify_fn: Some(track_notify_fn), + }; + let _track_handle = match cmap::track_add( + handle, + "stats.srp.memb_merge_detect_tx", + cmap::TrackType::MODIFY | cmap::TrackType::ADD | cmap::TrackType::DELETE, + &cb, + 997u64, + ) { + Ok(th) => th, + Err(e) => { + println!("Error in CMAP track_add {e}"); + return; + } + }; + + // Wait for events + let mut event_num = 0; + loop { + if let Err(e) = cmap::dispatch(handle, corosync::DispatchFlags::One) { + println!("Error from CMAP dispatch: {e}"); + } + // Just do 5 + event_num += 1; + if event_num > 5 { + break; + } + } +} diff --git a/bindings/rust/tests/src/bin/cpg-test.rs b/bindings/rust/tests/src/bin/cpg-test.rs new file mode 100644 index 0000000..df83c2d --- /dev/null +++ b/bindings/rust/tests/src/bin/cpg-test.rs @@ -0,0 +1,142 @@ +// Test the CPG library. Requires that corosync is running and that we are root. + +extern crate rust_corosync as corosync; +use corosync::{cpg, NodeId}; +use std::str; + +fn deliver_fn( + _handle: &cpg::Handle, + group_name: String, + nodeid: NodeId, + pid: u32, + msg: &[u8], + msg_len: usize, +) { + println!( + "TEST deliver_fn called for {group_name}, from nodeid/pid {nodeid}/{pid}. len={msg_len}" + ); + + // Print as text if it's valid UTF8 + match str::from_utf8(msg) { + Ok(s) => println!(" {s}"), + Err(_) => { + for i in msg { + print!("{i:02x} "); + } + println!(); + } + } +} + +fn confchg_fn( + _handle: &cpg::Handle, + group_name: &str, + member_list: Vec<cpg::Address>, + left_list: Vec<cpg::Address>, + joined_list: Vec<cpg::Address>, +) { + println!("TEST confchg_fn called for {group_name}"); + println!(" members: {member_list:?}"); + println!(" left: {left_list:?}"); + println!(" joined: {joined_list:?}"); +} + +fn totem_confchg_fn(_handle: &cpg::Handle, ring_id: cpg::RingId, member_list: Vec<NodeId>) { + println!( + "TEST totem_confchg_fn called for {}/{}", + ring_id.nodeid, ring_id.seq + ); + println!(" members: {member_list:?}"); +} + +fn main() { + // Initialise the model data + let md = cpg::ModelData::ModelV1(cpg::Model1Data { + flags: cpg::Model1Flags::None, + deliver_fn: Some(deliver_fn), + confchg_fn: Some(confchg_fn), + totem_confchg_fn: Some(totem_confchg_fn), + }); + + let handle = match cpg::initialize(&md, 99_u64) { + Ok(h) => h, + Err(e) => { + println!("Error in CPG init: {e}"); + return; + } + }; + + if let Err(e) = cpg::join(handle, "TEST") { + println!("Error in CPG join: {e}"); + return; + } + + match cpg::local_get(handle) { + Ok(n) => { + println!("Local nodeid is {n}"); + } + Err(e) => { + println!("Error in CPG local_get: {e}"); + } + } + + // Test membership_get() + match cpg::membership_get(handle, "TEST") { + Ok(m) => { + println!(" members: {m:?}"); + println!(); + } + Err(e) => { + println!("Error in CPG membership_get: {e}"); + } + } + + // Test context APIs + let set_context: u64 = 0xabcdbeefcafe; + if let Err(e) = cpg::context_set(handle, set_context) { + println!("Error in CPG context_set: {e}"); + return; + } + + // NOTE This will fail on 32 bit systems because void* is not u64 + match cpg::context_get(handle) { + Ok(c) => { + if c != set_context { + println!("Error: context_get() returned {c:x}, context should be {set_context:x}"); + } + } + Err(e) => { + println!("Error in CPG context_get: {e}"); + } + } + + // Test iterator + match cpg::CpgIterStart::new(handle, "", cpg::CpgIterType::All) { + Ok(cpg_iter) => { + for i in cpg_iter { + println!("ITER: {i:?}"); + } + println!(); + } + Err(e) => { + println!("Error in CPG iter start: {e}"); + } + } + + // We should receive our own message (at least) in the event loop + if let Err(e) = cpg::mcast_joined( + handle, + cpg::Guarantee::TypeAgreed, + &"This is a test".to_string().into_bytes(), + ) { + println!("Error in CPG mcast_joined: {e}"); + } + + // Wait for events + loop { + if cpg::dispatch(handle, corosync::DispatchFlags::One).is_err() { + break; + } + } + println!("ERROR: Corosync quit"); +} diff --git a/bindings/rust/tests/src/bin/quorum-test.rs b/bindings/rust/tests/src/bin/quorum-test.rs new file mode 100644 index 0000000..5797b7d --- /dev/null +++ b/bindings/rust/tests/src/bin/quorum-test.rs @@ -0,0 +1,83 @@ +// Test the QUORUM library. Requires that corosync is running and that we are root. + +extern crate rust_corosync as corosync; +use corosync::{quorum, NodeId}; + +fn quorum_fn( + _handle: &quorum::Handle, + quorate: bool, + ring_id: quorum::RingId, + member_list: Vec<NodeId>, +) { + println!("TEST quorum_fn called. quorate = {quorate}"); + println!(" ring_id: {}/{}", ring_id.nodeid, ring_id.seq); + println!(" members: {member_list:?}"); +} + +fn nodelist_fn( + _handle: &quorum::Handle, + ring_id: quorum::RingId, + member_list: Vec<NodeId>, + joined_list: Vec<NodeId>, + left_list: Vec<NodeId>, +) { + println!( + "TEST nodelist_fn called for {}/{}", + ring_id.nodeid, ring_id.seq + ); + println!(" members: {member_list:?}"); + println!(" joined: {joined_list:?}"); + println!(" left: {left_list:?}"); +} + +fn main() { + // Initialise the model data + let md = quorum::ModelData::ModelV1(quorum::Model1Data { + flags: quorum::Model1Flags::None, + quorum_notification_fn: Some(quorum_fn), + nodelist_notification_fn: Some(nodelist_fn), + }); + + let handle = match quorum::initialize(&md, 99_u64) { + Ok((h, t)) => { + println!("Quorum initialized; type = {}", t as u32); + h + } + Err(e) => { + println!("Error in QUORUM init: {e}"); + return; + } + }; + + // Test context APIs + let set_context: u64 = 0xabcdbeefcafe; + if let Err(e) = quorum::context_set(handle, set_context) { + println!("Error in QUORUM context_set: {e}"); + return; + } + + // NOTE This will fail on 32 bit systems because void* is not u64 + match quorum::context_get(handle) { + Ok(c) => { + if c != set_context { + println!("Error: context_get() returned {c:x}, context should be {set_context:x}"); + } + } + Err(e) => { + println!("Error in QUORUM context_get: {e}"); + } + } + + if let Err(e) = quorum::trackstart(handle, corosync::TrackFlags::Changes) { + println!("Error in QUORUM trackstart: {e}"); + return; + } + + // Wait for events + loop { + if quorum::dispatch(handle, corosync::DispatchFlags::One).is_err() { + break; + } + } + println!("ERROR: Corosync quit"); +} diff --git a/bindings/rust/tests/src/bin/votequorum-test.rs b/bindings/rust/tests/src/bin/votequorum-test.rs new file mode 100644 index 0000000..cf9746b --- /dev/null +++ b/bindings/rust/tests/src/bin/votequorum-test.rs @@ -0,0 +1,117 @@ +// Test the VOTEQUORUM library. Requires that corosync is running and that we are root. + +extern crate rust_corosync as corosync; +use corosync::votequorum; + +fn quorum_fn( + _handle: &votequorum::Handle, + _context: u64, + quorate: bool, + member_list: Vec<votequorum::Node>, +) { + println!("TEST votequorum_quorum_fn called. quorate = {quorate}"); + println!(" members: {member_list:?}"); +} + +fn nodelist_fn( + _handle: &votequorum::Handle, + _context: u64, + ring_id: votequorum::RingId, + member_list: Vec<corosync::NodeId>, +) { + println!( + "TEST nodelist_fn called for {}/{}", + ring_id.nodeid, ring_id.seq + ); + println!(" members: {member_list:?}"); +} + +fn expectedvotes_fn(_handle: &votequorum::Handle, _context: u64, expected_votes: u32) { + println!("TEST expected_votes_fn called: value is {expected_votes}"); +} + +fn main() { + // Initialise the model data + let cb = votequorum::Callbacks { + quorum_notification_fn: Some(quorum_fn), + nodelist_notification_fn: Some(nodelist_fn), + expectedvotes_notification_fn: Some(expectedvotes_fn), + }; + + let handle = match votequorum::initialize(&cb) { + Ok(h) => { + println!("Votequorum initialized."); + h + } + Err(e) => { + println!("Error in VOTEQUORUM init: {e}"); + return; + } + }; + + // Test context APIs + let set_context: u64 = 0xabcdbeefcafe; + if let Err(e) = votequorum::context_set(handle, set_context) { + println!("Error in VOTEQUORUM context_set: {e}"); + } + + // NOTE This will fail on 32 bit systems because void* is not u64 + match votequorum::context_get(handle) { + Ok(c) => { + if c != set_context { + println!("Error: context_get() returned {c:x}, context should be {set_context:x}"); + } + } + Err(e) => { + println!("Error in VOTEQUORUM context_get: {e}"); + } + } + + const QDEVICE_NAME: &str = "RustQdevice"; + + if let Err(e) = votequorum::qdevice_register(handle, QDEVICE_NAME) { + println!("Error in VOTEQUORUM qdevice_register: {e}"); + } + + match votequorum::get_info(handle, corosync::NodeId::from(1u32)) { + Ok(i) => { + println!("Node info for nodeid 1"); + println!(" nodeid: {}", i.node_id); + println!(" node_state: {:?}", i.node_state); + println!(" node_votes: {}", i.node_votes); + println!(" node_expected: {}", i.node_expected_votes); + println!(" highest_expected: {}", i.highest_expected); + println!(" quorum: {}", i.quorum); + println!(" flags: {:x}", i.flags); + println!(" qdevice_votes: {}", i.qdevice_votes); + println!(" qdevice_name: {}", i.qdevice_name); + + if i.qdevice_name != QDEVICE_NAME { + println!( + "qdevice names do not match: s/b: \"{}\" is: \"{}\"", + QDEVICE_NAME, i.qdevice_name + ); + } + } + Err(e) => { + println!("Error in VOTEQUORUM get_info: {e} (check nodeid 1 has been online)"); + } + } + + if let Err(e) = votequorum::qdevice_unregister(handle, QDEVICE_NAME) { + println!("Error in VOTEQUORUM qdevice_unregister: {e}"); + } + + if let Err(e) = votequorum::trackstart(handle, 99_u64, corosync::TrackFlags::Changes) { + println!("Error in VOTEQUORUM trackstart: {e}"); + return; + } + + // Wait for events + loop { + if votequorum::dispatch(handle, corosync::DispatchFlags::One).is_err() { + break; + } + } + println!("ERROR: Corosync quit"); +} |