adding "Hal" implementation and testsuite
authorKlaus Kaempf <kkaempf@suse.de>
Fri, 13 Jan 2006 15:11:21 +0000 (15:11 +0000)
committerKlaus Kaempf <kkaempf@suse.de>
Fri, 13 Jan 2006 15:11:21 +0000 (15:11 +0000)
14 files changed:
configure.ac
doc/autodoc/Makefile.am
zypp/solver/testsuite/Makefile.am
zypp/target/Makefile.am
zypp/target/hal/Hal.cc
zypp/target/hal/Makefile.am
zypp/target/testsuite/Makefile.am [new file with mode: 0644]
zypp/target/testsuite/config/default.exp [new file with mode: 0644]
zypp/target/testsuite/config/unix.exp [new file with mode: 0644]
zypp/target/testsuite/config/unknown.exp [new file with mode: 0644]
zypp/target/testsuite/lib/target_init.exp [new file with mode: 0644]
zypp/target/testsuite/target.test/Hal.exp [new file with mode: 0644]
zypp/target/testsuite/tests/Makefile.am [new file with mode: 0644]
zypp/target/testsuite/tests/hal.cc [new file with mode: 0644]

index 5b6593c..60bcfc0 100644 (file)
@@ -124,6 +124,16 @@ AC_CHECK_LIB([xml2], [xmlNewTextReader],
         [:],
         AC_MSG_ERROR([libxml2 not found. please install libxml2-devel]))
 dnl ==================================================
+dnl checks for pkgconfig modules
+hal_module="hal >= 0.5.4"
+dbus_module="dbus-1 >= 0.33"
+hal_modules="glib-2.0 >= 2.6.0, gobject-2.0 >= 2.6.0, dbus-glib-1 >= 0.33, $dbus_module, $hal_module"
+PKG_CHECK_MODULES(HAL, [$hal_modules])
+AC_SUBST(HAL_CFLAGS)
+AC_SUBST(HAL_LDADD)
+AC_SUBST(HAL_LIBS)
+
+dnl ==================================================
 dnl checks for header files
 AC_CHECK_HEADERS([boost/scoped_ptr.hpp],
         [],
@@ -181,7 +191,9 @@ AC_OUTPUT(  \
        zypp/url/Makefile               \
        zypp/target/Makefile            \
        zypp/target/rpm/Makefile        \
-       zypp/target/hal/Makefile
+       zypp/target/hal/Makefile        \
+       zypp/target/testsuite/Makefile  \
+       zypp/target/testsuite/tests/Makefile
 
 )
 dnl ==================================================
index 62a50d7..3c3f508 100644 (file)
@@ -7,9 +7,7 @@ html_DATA =     @PACKAGE@.doxytag $(wildcard html/*)
 
 ## ##################################################
 
-.PHONY:        always
-
-@PACKAGE@.doxytag: Doxyfile always
+@PACKAGE@.doxytag: Doxyfile
        @DOCGEN@
 
 ## ##################################################
index 54c3183..86d5840 100644 (file)
@@ -10,6 +10,12 @@ INCLUDES=                                            \
        -I$(includedir)                                 \
        -I/usr/include/YaST2                            \
        -I/usr/include/libxml2 -I/usr/include/rpm       \
+        -DDBUS_API_SUBJECT_TO_CHANGE                   \
+       -I/usr/include/dbus-1.0                         \
+       -I/usr/lib64/dbus-1.0/include                   \
+       -I/opt/gnome/include/glib-2.0                   \
+       -I/opt/gnome/lib64/glib-2.0/include             \
+       -I/usr/include/hal                              \
        -DG_LOG_DOMAIN=\"testsuite\"                    \
        -Wall
 
@@ -49,4 +55,4 @@ deptestomatic_multi_LDADD =                           \
 clean-local:
        rm -rf data.deptestomatic/*/out
        rm -rf data.deptestomatic/*/out
-       rm -rf single.out/out
\ No newline at end of file
+       rm -rf single.out/out
index 6102a9d..a849386 100644 (file)
@@ -1,7 +1,7 @@
 ## Process this file with automake to produce Makefile.in
 ## ##################################################
 
-SUBDIRS = hal rpm
+SUBDIRS = hal rpm testsuite
 
 ## ##################################################
 
index 3ebb401..0de8a6d 100644 (file)
  *
 */
 #include <iostream>
-//#include "zypp/base/Logger.h"
+
+#define ZYPP_BASE_LOGGER_LOGGROUP "HAL"
+#include "zypp/base/Logger.h"
 
 #include "zypp/target/hal/Hal.h"
 
+#include <glib.h>
+
+#include <dbus/dbus-glib-lowlevel.h>
+#include <dbus/dbus-glib.h>
+#include <hal/libhal.h>
+
 using std::endl;
+using std::string;
 
 ///////////////////////////////////////////////////////////////////
 namespace zypp
@@ -26,102 +35,235 @@ namespace zypp
     namespace hal
     { /////////////////////////////////////////////////////////////////
 
-      ///////////////////////////////////////////////////////////////////
-      //
-      //       CLASS NAME : Hal::Impl
-      //
-      /** Hal implementation. */
-      struct Hal::Impl
-      {
-        /** Ctor. */
-        Impl()
-        {}
-
-        bool query( const std::string & cap_r ) const
-        { return query( cap_r, Rel::ANY, std::string() ); }
-
-        /** \todo Implement it.
-         * And maybee std::ostream & operator<< Hal::Impl below too.
-         * return libhal vetsion ore something like that.
-        */
-        bool  query( const std::string & cap_r,
-                     Rel op_r,
-                     const std::string & val_r ) const
-        { return false; }
-
-      public:
-        /** Offer default Impl. */
-        static shared_ptr<Impl> nullimpl()
-        {
-          static shared_ptr<Impl> _nullimpl( new Impl );
-          return _nullimpl;
-        }
-      };
-      ///////////////////////////////////////////////////////////////////
-
-      /** \relates Hal::Impl Stream output */
-      inline std::ostream & operator<<( std::ostream & str, const Hal::Impl & obj )
-      {
-        return str << "Hal::Impl";
-      }
-
-      ///////////////////////////////////////////////////////////////////
-      //
-      //       CLASS NAME : Hal
-      //
-      ///////////////////////////////////////////////////////////////////
-
-      ///////////////////////////////////////////////////////////////////
-      //
-      //       METHOD NAME : Hal::Hal
-      //       METHOD TYPE : Ctor
-      //
-      Hal::Hal()
-      : _pimpl( Impl::nullimpl() )
-      {}
-
-      ///////////////////////////////////////////////////////////////////
-      //
-      //       METHOD NAME : Hal::~Hal
-      //       METHOD TYPE : Dtor
-      //
-      Hal::~Hal()
-      {}
-
-      ///////////////////////////////////////////////////////////////////
-      //
-      //       METHOD NAME : Hal::instance
-      //       METHOD TYPE : Hal &
-      //
-      Hal & Hal::instance()
-      {
-        static Hal _singleton;
-        return _singleton;
-      }
-
-      ///////////////////////////////////////////////////////////////////
-      // Foreward to implenemtation
-      ///////////////////////////////////////////////////////////////////
-
-      bool Hal::query( const std::string & cap_r ) const
-      { return _pimpl->query( cap_r ); }
-
-      bool Hal::query( const std::string & cap_r,
-                       Rel op_r,
-                       const std::string & val_r ) const
-      { return _pimpl->query( cap_r, op_r, val_r ); }
-
-      /******************************************************************
-      **
-      **       FUNCTION NAME : operator<<
-      **       FUNCTION TYPE : std::ostream &
-      */
-      std::ostream & operator<<( std::ostream & str, const Hal & obj )
-      {
-        return str << *obj._pimpl;
-      }
-
-      /////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////
+//
+//     CLASS NAME : Hal::Impl
+//
+/** Hal implementation. */
+struct Hal::Impl
+{
+    /**
+     * pointer to dbus connection
+     */
+    DBusConnection *_connection;
+
+    /**
+     * pointer to complete hal context
+     */
+    LibHalContext *_context;
+
+    /**
+     * report HAL error and reset the error condition
+     */
+    void
+    report_error (const std::string & reason, DBusError & error) const
+    {
+       ERR << reason << ": " << string (error.name) << ": " << string(error.message);
+       dbus_error_init(&error);
+       return;
+    }
+
+    /** Ctor. */
+    Impl()
+    {
+       DBusError error;
+       dbus_error_init (&error);
+
+       _connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error);                   // get DBUS 'socket'
+       if (_connection) {
+           _context = libhal_ctx_new ();                                       // create empty HAL context
+           if (_context) {
+               if (libhal_ctx_set_dbus_connection (_context, _connection)) {   // connect to HAL daemon via DBUS
+                   if (libhal_ctx_init (_context, &error)) {                   // fill HAL context
+                       return;
+                   } else {
+                       report_error ("libhal_ctx_init", error);
+                   }
+               } else {
+                   report_error ("libhal_ctx_set_dbus_connection", error);
+               }
+               libhal_ctx_free (_context);                                     // clean up
+               _context = NULL;
+           } else {
+               report_error ("libhal_ctx_new: Can't create libhal context", error);
+           }
+           dbus_connection_disconnect (_connection);
+           dbus_connection_unref (_connection);
+           _connection = NULL;
+       } else {
+           report_error ("dbus_bus_get", error);
+       }
+    }
+
+
+    /** Dtor. */
+    ~Impl()
+    {
+       if (_context) {
+           libhal_ctx_free (_context);
+       }
+       if (_connection) {
+           dbus_connection_disconnect (_connection);
+           dbus_connection_unref (_connection);
+       }
+    }
+
+    /**
+     * query for HAL capability present
+     */
+
+    bool query( const std::string & cap_r ) const
+    { return query( cap_r, Rel::ANY, std::string() ); }
+
+    /**
+     * query for HAL capability having a specific value
+     */
+    bool  query( const std::string & cap_r,
+              Rel op_r,
+              const std::string & val_r ) const
+    {
+       DBusError error;
+
+       // ask HAL which devices provide the needed capability
+
+       bool result = false;
+
+       int device_count;
+       char **device_names = libhal_find_device_by_capability (_context, cap_r.c_str(), &device_count, &error);
+
+       if (device_names == NULL) {
+           report_error ("libhal_find_device_by_capability", error);
+           result = false;
+       }
+       else if (device_count > 0) {
+
+#if 0          // once we get a capabilities value from HAL, we can compare it ...
+           if (value) {
+               string lhs (value);
+               int cmp = (lhs != rhs) ? ((lhs < rhs) ? -1 : 1) : 0;
+
+               switch ( relation.inSwitch() )
+               {
+                   case Rel::EQ_e:
+                       res = (cmp == 0);
+                       break;
+                   case Rel::NE_e:
+                       res = (cmp != 0);
+                       break;
+                   case Rel::LT_e:
+                       res = (cmp == -1);
+                       break;
+                   case Rel::LE_e:
+                       res = (cmp != 1);
+                       break;
+                   case Rel::GT_e:
+                       res = (cmp == 1);
+                       break;
+                   case Rel::GE_e:
+                       res = (cmp != -1);
+                       break;
+                   case Rel::ANY_e:
+                       res = true;
+                       break;
+                   case Rel::NONE_e:
+                       res = false;
+                       break;
+                   default:
+                       // We shouldn't get here.
+                       INT << "Unknown relational opertor '" << relation << "' treated as  'NONE'" << endl;
+                       break;
+               }
+           }
+#endif
+
+           result = true;
+
+       }
+
+       if (device_names != NULL)
+           libhal_free_string_array (device_names);
+
+       return result;
+    }
+
+  public:
+     /** Offer default Impl. */
+    static shared_ptr<Impl> nullimpl()
+    {
+       static shared_ptr<Impl> _nullimpl( new Impl );
+       return _nullimpl;
+    }
+
+};  // struct Hal::Impl
+
+///////////////////////////////////////////////////////////////////
+
+/** \relates Hal::Impl Stream output
+     * And maybe std::ostream & operator<< Hal::Impl below too.
+     * return libhal version or something like that.
+ */
+inline std::ostream & operator<<( std::ostream & str, const Hal::Impl & obj )
+{
+  return str << "Hal::Impl";
+}
+
+///////////////////////////////////////////////////////////////////
+//
+//     CLASS NAME : Hal
+//
+///////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////
+//
+//     METHOD NAME : Hal::Hal
+//     METHOD TYPE : Ctor
+//
+Hal::Hal()
+: _pimpl( Impl::nullimpl() )
+{}
+
+///////////////////////////////////////////////////////////////////
+//
+//     METHOD NAME : Hal::~Hal
+//     METHOD TYPE : Dtor
+//
+Hal::~Hal()
+{}
+
+///////////////////////////////////////////////////////////////////
+//
+//     METHOD NAME : Hal::instance
+//     METHOD TYPE : Hal &
+//
+Hal & Hal::instance()
+{
+  static Hal _singleton;
+  return _singleton;
+}
+
+///////////////////////////////////////////////////////////////////
+// Foreward to implenemtation
+///////////////////////////////////////////////////////////////////
+
+bool Hal::query( const std::string & cap_r ) const
+{ return _pimpl->query( cap_r ); }
+
+bool Hal::query( const std::string & cap_r,
+                Rel op_r,
+                const std::string & val_r ) const
+{ return _pimpl->query( cap_r, op_r, val_r ); }
+
+/******************************************************************
+**
+**     FUNCTION NAME : operator<<
+**     FUNCTION TYPE : std::ostream &
+*/
+std::ostream & operator<<( std::ostream & str, const Hal & obj )
+{
+  return str << *obj._pimpl;
+}
+
+/////////////////////////////////////////////////////////////////
     } // namespace hal
     ///////////////////////////////////////////////////////////////////
     /////////////////////////////////////////////////////////////////
index c8d6950..ad887e5 100644 (file)
@@ -3,6 +3,16 @@
 
 SUBDIRS =
 
+INCLUDES = \
+        -DDBUS_API_SUBJECT_TO_CHANGE           \
+       @HAL_CFLAGS@
+
+#      -I/usr/include/dbus-1.0         
+#      -I/usr/lib64/dbus-1.0/include           
+#      -I/opt/gnome/include/glib-2.0           
+#      -I/opt/gnome/lib64/glib-2.0/include     
+#      -I/usr/include/hal
+
 ## ##################################################
 
 include_HEADERS =      \
@@ -16,6 +26,7 @@ noinst_LTLIBRARIES =  lib@PACKAGE@_target_hal.la
 lib@PACKAGE@_target_hal_la_SOURCES =   \
        Hal.cc
 
-#lib@PACKAGE@_target_hal_la_LIBADD =
+lib@PACKAGE@_target_hal_la_LIBADD =    \
+       @HAL_LIBS@
 
 ## ##################################################
diff --git a/zypp/target/testsuite/Makefile.am b/zypp/target/testsuite/Makefile.am
new file mode 100644 (file)
index 0000000..1f58dc8
--- /dev/null
@@ -0,0 +1,12 @@
+#
+# Makefile.am for zypp/target/testsuite
+#
+SUBDIRS = tests
+AUTOMAKE_OPTIONS = dejagnu
+PACKAGE = target
+
+EXTRA_DIST = lib/target_init.exp config/*.exp target.test/*.exp
+
+clean-local:
+       rm -rf *.log
+       rm -rf *.exp
diff --git a/zypp/target/testsuite/config/default.exp b/zypp/target/testsuite/config/default.exp
new file mode 100644 (file)
index 0000000..fe1e08a
--- /dev/null
@@ -0,0 +1,2 @@
+# default.exp -- empty
+
diff --git a/zypp/target/testsuite/config/unix.exp b/zypp/target/testsuite/config/unix.exp
new file mode 100644 (file)
index 0000000..f2a7a39
--- /dev/null
@@ -0,0 +1,4 @@
+load_lib "solver_init.exp"
+proc solver_exit {} {}
+proc solver_version {} {}
+
diff --git a/zypp/target/testsuite/config/unknown.exp b/zypp/target/testsuite/config/unknown.exp
new file mode 100644 (file)
index 0000000..fe48c2f
--- /dev/null
@@ -0,0 +1,2 @@
+perror "No setup for current configuration"
+exit 1
diff --git a/zypp/target/testsuite/lib/target_init.exp b/zypp/target/testsuite/lib/target_init.exp
new file mode 100644 (file)
index 0000000..d5f3653
--- /dev/null
@@ -0,0 +1,53 @@
+# target_init.exp
+
+#
+# run binary $path/$prog
+# and expect $expected_result as a result
+#  (expected_result == 0  ==> program should pass)
+#  (expected_result == 1  ==> program should fail)
+#
+
+proc runBinary { prog {path ""} {expected_result 0} } {
+
+  if { $path == "" } { set path "tests" }
+
+  set result 0
+  set oops [catch { set result [exec "$path/$prog" ">" "/dev/null" "2>/dev/null"] } catched]
+
+  # check if the program crashed
+
+  if {$oops != 0 && $result != 0} {
+    puts ""
+    fail "$prog crashed ($oops) with: $catched"
+    return -1
+  }
+
+  # check return code from $prog
+
+  if {$result != ""} {
+    if {$expected_result != 0} {
+      xfail $prog                      # expected failure
+      return 0
+    }
+    puts ""
+    warning "Running of $prog results in '$result'"
+    return -1
+  }
+
+  pass $prog
+
+  return 0
+}
+
+# expect prog to pass
+
+proc shouldPass { prog {path ""} } {
+  return [runBinary $prog $path 0]
+}
+
+# expect prog to fail
+
+proc shouldFail { prog {path ""} } {
+  return [runBinary $prog $path 1]
+}
+
diff --git a/zypp/target/testsuite/target.test/Hal.exp b/zypp/target/testsuite/target.test/Hal.exp
new file mode 100644 (file)
index 0000000..fcdc12a
--- /dev/null
@@ -0,0 +1,4 @@
+# Hal.exp
+# run tests for Hal
+
+  shouldPass "hal"
diff --git a/zypp/target/testsuite/tests/Makefile.am b/zypp/target/testsuite/tests/Makefile.am
new file mode 100644 (file)
index 0000000..f16273a
--- /dev/null
@@ -0,0 +1,28 @@
+#
+# Makefile.am for zypp/target/testsuite/tests
+#
+
+INCLUDES=                                              \
+       -I$(top_srcdir)/src                             \
+       -I$(includedir)                                 \
+       -I/usr/include/libxml2 -I/usr/include/rpm       \
+        -DDBUS_API_SUBJECT_TO_CHANGE                   \
+       @HAL_CFLAGS@                                    \
+       -DG_LOG_DOMAIN=\"testsuite\"                    \
+       -Wall
+
+LIBZYPP_LIBS = -lxml2 -lz -lm -ly2util -lpthread -lrt -lz -lbz2 -lzypp
+
+noinst_PROGRAMS = hal
+
+hal_SOURCES =                                  \
+       hal.cc
+
+hal_LDFLAGS =                                  \
+       -L$(top_srcdir)/zypp/target/hal/.libs   \
+       -L$(top_srcdir)/zypp
+
+hal_LDADD =                                    \
+       -lzypp_target_hal                       \
+       @HAL_LIBS@                              \
+       $(LIBZYPP_LIBS)
diff --git a/zypp/target/testsuite/tests/hal.cc b/zypp/target/testsuite/tests/hal.cc
new file mode 100644 (file)
index 0000000..90c6c91
--- /dev/null
@@ -0,0 +1,18 @@
+#include <string.h>
+#include "zypp/target/hal/Hal.h"
+
+using namespace zypp::target::hal;
+
+int
+main (int argc, char *argv[])
+{
+  Hal hal = Hal::instance();
+
+  if (!hal.query ("processor"))
+       return 1;
+
+  if (hal.query ("processor", zypp::Rel::LT, "1"))
+       return 1;
+
+  return 0;
+}