Skip to content

Commit

Permalink
Add Python bindings for testing local DBs
Browse files Browse the repository at this point in the history
We just need to `dlopen("libpromises.so")` and then call the new
DB testing API functions with appropriate arguments.

Ticket: CFE-4281
Changelog: None
  • Loading branch information
vpodzime committed Jan 30, 2024
1 parent 1d6f8a6 commit 1ee9089
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ stamp-h1
/libpromises/Makefile
/misc/Makefile
/misc/selinux/Makefile
/python/Makefile
/tests/Makefile
/tests/acceptance/25_cf-execd/Makefile
/tests/acceptance/Makefile
Expand Down
1 change: 1 addition & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ SUBDIRS = \
cf-net \
cf-secret \
misc \
python \
ext \
examples \
tests \
Expand Down
1 change: 1 addition & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -1872,6 +1872,7 @@ AC_CONFIG_FILES([Makefile
contrib/vagrant-ci/centos-7-x64/Makefile
misc/Makefile
misc/selinux/Makefile
python/Makefile
ext/Makefile
examples/Makefile
tests/Makefile
Expand Down
33 changes: 33 additions & 0 deletions python/Makefile.am
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#
# Copyright 2024 Northern.tech AS
#
# This file is part of CFEngine 3 - written and maintained by Northern.tech AS.
#
# 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; version 3.
#
# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
#
# To the extent this program is licensed as part of the Enterprise
# versions of CFEngine, the applicable Commercial Open Source License
# (COSL) may apply to this file if you as a licensee so wish it. See
# included file COSL.txt.
#

pythonbindingsdir = $(libdir)/python
dist_pythonbindings_DATA = README

if !NDEBUG
if LINUX
# The dbm_test_api is only compile in on Linux in debug builds.
dist_pythonbindings_DATA += test_cfe_db.py
endif
endif
10 changes: 10 additions & 0 deletions python/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
This directory contains Python packages and modules for working with CFEngine
and its libraries.

If you want to use one of these, PYTHONPATH and LD_LIBRARY_PATH variables can
make things easier when used like this:

PYTHONPATH=/var/cfengine/lib/python LD_LIBRARY_PATH=/var/cfengine/lib python3

That will make sure that the bindings are found by Python and that CFEngine's
libraries are found by dlopen() (used by ctypes.CDLL() etc.).
76 changes: 76 additions & 0 deletions python/test_cfe_db.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import ctypes

# Based on the dbid enum from libpromises/dbm_api.h
dbs = (
"classes", # Deprecated
"variables", # Deprecated
"performance",
"checksums", # Deprecated
"filestats", # Deprecated
"changes",
"observations",
"state",
"lastseen",
"audit",
"locks",
"history",
"measure",
"static",
"scalars",
"windows_registry",
"cache",
"license",
"value",
"agent_execution",
"bundles", # Deprecated
"packages_installed", # new package promise installed packages list
"packages_updates", # new package promise list of available updates
"cookies", # Enterprise reporting cookies for duplicate host detection
)

def get_db_id(db_name):
return dbs.index(db_name)


class _SimulationStruct(ctypes.Structure):
pass

class _FilamentStruct(ctypes.Structure):
pass

_promises = ctypes.CDLL("libpromises.so.3.0.6")

_promises.SimulateDBLoad.restype = ctypes.POINTER(_SimulationStruct)
_promises.SimulateDBLoad.argtypes = [ctypes.c_int, ctypes.c_int, ctypes.c_long, ctypes.c_long,
ctypes.c_int, ctypes.c_int, ctypes.c_long, ctypes.c_long,
ctypes.c_long, ctypes.c_long]
def SimulateDBLoad(db_id,
read_keys_refresh_s=5,
read_min_interval_ms=100,
read_max_interval_ms=200,
write_sample_size_pct=50,
write_prune_interval_s=10,
write_min_interval_ms=200,
write_max_interval_ms=400,
iter_min_interval_ms=1000,
iter_max_interval_ms=2000):
return _promises.SimulateDBLoad(db_id,
read_keys_refresh_s, read_min_interval_ms, read_max_interval_ms,
write_sample_size_pct,
write_prune_interval_s, write_min_interval_ms, write_max_interval_ms,
iter_min_interval_ms, iter_max_interval_ms)

_promises.StopSimulation.restype = None # void
_promises.StopSimulation.argtypes = [ctypes.POINTER(_SimulationStruct)]
def StopSimulation(simulation):
_promises.StopSimulation(simulation)

_promises.FillUpDB.restype = ctypes.POINTER(_FilamentStruct)
_promises.FillUpDB.argtypes = [ctypes.c_int, ctypes.c_int]
def FillUpDB(db_id, usage):
return _promises.FillUpDB(db_id, usage)

_promises.RemoveFilament.restype = None # void
_promises.RemoveFilament.argtypes = [ctypes.POINTER(_FilamentStruct)]
def RemoveFilament(filament):
_promises.RemoveFilament(filament)

0 comments on commit 1ee9089

Please sign in to comment.