Skip to content

Commit

Permalink
Added python testing ready for development
Browse files Browse the repository at this point in the history
  • Loading branch information
toastedcrumpets committed Apr 13, 2021
1 parent 23ed1a4 commit bbd714f
Show file tree
Hide file tree
Showing 23 changed files with 201 additions and 57 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,6 @@
path = extern/eigen
url = https://gitlab.com/libeigen/eigen.git
branch = branches/3.4
[submodule "extern/pybind11"]
path = extern/pybind11
url = https://github.com/pybind/pybind11.git
20 changes: 11 additions & 9 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
cmake_minimum_required (VERSION 2.6 FATAL_ERROR)
cmake_minimum_required (VERSION 3.0)
if (NOT CMAKE_BUILD_TYPE)
message(STATUS "No build type selected, default to Release")
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo" FORCE)
endif()

project(stator) #Project name
project(stator VERSION 1.0) #Project name

enable_testing() #Enable build of test executables and 'make test' command
include(CTest)


IF(WIN32)
ENDIF(WIN32)

########## RELEASE MODE
if(MSVC)
#MSVC has crazy warnings for -Wall, we'll build up support to the higher warning levels
Expand All @@ -32,7 +28,7 @@ if(MSVC)
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /bigobj")
SET(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} /bigobj")
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /bigobj")
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /bigobj")
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /bigobj")
else()
add_compile_options(-Wall)
endif()
Expand Down Expand Up @@ -133,13 +129,12 @@ endif(DOXYGEN_FOUND)
######### TEST TARGETS
######################################################################
function(stator_test name) #Registers a unit-test
add_executable(${name} ${CMAKE_CURRENT_SOURCE_DIR}/testing/${name}.cpp)
add_executable(${name} ${CMAKE_CURRENT_SOURCE_DIR}/tests/${name}.cpp)
add_test(${name} ${name})
endfunction(stator_test)

add_executable(symbolic_example ${CMAKE_CURRENT_SOURCE_DIR}/examples/symbolic_example.cpp)


#stator_test(orphan_static_list)
stator_test(stack_vector)

Expand All @@ -155,3 +150,10 @@ if(CXX11_TEMPLATE_TYPEDEFS)
stator_test(symbolic_ad)
#stator_test(symbolic_integration)
endif()

######################################################################
########## PYTHON INTERFACE
######################################################################
add_subdirectory(extern/pybind11)
pybind11_add_module(core pysrc/stator/core.cpp)
target_include_directories(core PRIVATE ${PROJECT_SOURCE_DIR})
129 changes: 81 additions & 48 deletions Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ spec:
containers:
- name: dind
image: docker:dind
args: ["--registry-mirror=https://registry.bansci.com"]
args: ["--registry-mirror","https://registry.bansci.com"]
tty: true
securityContext:
privileged: true
Expand Down Expand Up @@ -39,66 +39,99 @@ spec:
}
}
}
stage('CMake configure') {
steps{
container('dind') {
script {
dockerBuildImage.inside {
dir('build') {
sh "cmake .."
parallel {
stage('C++/CMake build and test') {
stage('CMake configure') {
steps{
container('dind') {
script {
dockerBuildImage.inside {
dir('build') {
sh "cmake .."
}
}
}
}
}
}
}
}
stage('Make the C++ library') {
steps{
container('dind') {
script {
dockerBuildImage.inside {
dir('build') {
sh "make -j2"
stage('Make the C++ library') {
steps{
container('dind') {
script {
dockerBuildImage.inside {
dir('build') {
sh "make -j2"
}
}
}
}
}
}
}
}
stage('Test the C++ library') {
steps{
container('dind') {
script {
dockerBuildImage.inside {
dir('build') {
sh 'ctest -j2 --no-compress-output -T Test'
stage('Test the C++ library') {
steps{
container('dind') {
script {
dockerBuildImage.inside {
dir('build') {
sh 'ctest -j2 --no-compress-output -T Test'
}
}
}
}
}
post {
always {
archiveArtifacts (
artifacts: 'build/Testing/**/*.xml',
fingerprint: true,
)
// Process the CTest xml output with the xUnit plugin
xunit (
testTimeMargin: '3000',
thresholdMode: 1,
thresholds: [
skipped(failureThreshold: '0'),
failed(failureThreshold: '0')
],
tools: [CTest(
pattern: 'build/Testing/**/*.xml',
deleteOutputFiles: true,
failIfNotNew: false,
skipNoTestFiles: true,
stopProcessingIfError: true
)]
)
}
}
}
}
post {
always {
archiveArtifacts (
artifacts: 'build/Testing/**/*.xml',
fingerprint: true,
)
// Process the CTest xml output with the xUnit plugin
xunit (
testTimeMargin: '3000',
thresholdMode: 1,
thresholds: [
skipped(failureThreshold: '0'),
failed(failureThreshold: '0')
],
tools: [CTest(
pattern: 'build/Testing/**/*.xml',
deleteOutputFiles: true,
failIfNotNew: false,
skipNoTestFiles: true,
stopProcessingIfError: true
)]
)
stage('Python build and test') {
stage('setuptools build') {
steps{
container('dind') {
script {
dockerBuildImage.inside {
sh "python3 setup.py build"
}
}
}
}
}
stage('Unit Tests') {
steps {
container('dind') {
script {
dockerBuildImage.inside {
sh 'PYTHONUNBUFFERED=1 py.test --junitxml test_results.xml'
}
}
}
}
post {
always {
junit 'test_results.xml'
}
}
}
}
}
Expand Down
1 change: 1 addition & 0 deletions extern/pybind11
Submodule pybind11 added at 8de777
8 changes: 8 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[build-system]
requires = [
"setuptools>=42",
"wheel",
"pybind11>=2.6.0",
]

build-backend = "setuptools.build_meta"
1 change: 1 addition & 0 deletions pysrc/stator/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from stator.core import *
32 changes: 32 additions & 0 deletions pysrc/stator/core.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#include <stator/string.hpp>
#include <stator/symbolic/ad.hpp>
#include <pybind11/pybind11.h>
#include <pybind11/stl_bind.h>

namespace py = pybind11;
using namespace pybind11::literals;

PYBIND11_MODULE(core, m)
{
py::class_<sym::Expr>(m, "Expr")
.def(py::init<std::string>())
.def(py::init<int>())
.def(py::init<double>())
.def("__repr__", +[](const sym::Expr& self) { return stator::repr(self); })
.def("__str__", +[](const sym::Expr& self) { return stator::repr(self); })
.def("latex", +[](const sym::Expr& self) { return stator::repr<stator::ReprConfig<stator::Latex_output> >(self); })
.def("simplify", +[](const sym::Expr& self) { return sym::simplify(self); })
.def("__add__", +[](const sym::Expr& l, const sym::Expr& r) { return sym::Expr(l+r); })
.def("__radd__", +[](const sym::Expr& l, const sym::Expr& r) { return sym::Expr(l+r); })
.def("__sub__", +[](const sym::Expr& l, const sym::Expr& r) { return sym::Expr(l-r); })
.def("__rsub__", +[](const sym::Expr& l, const sym::Expr& r) { return sym::Expr(l-r); })
.def("__mul__", +[](const sym::Expr& l, const sym::Expr& r) { return sym::Expr(l*r); })
.def("__rmul__", +[](const sym::Expr& l, const sym::Expr& r) { return sym::Expr(l*r); })
.def("__div__", +[](const sym::Expr& l, const sym::Expr& r) { return sym::Expr(l/r); })
.def("__rdiv__", +[](const sym::Expr& l, const sym::Expr& r) { return sym::Expr(l/r); })
.def(py::self / py::self)
;

py::implicitly_convertible<int, sym::Expr>();
py::implicitly_convertible<double, sym::Expr>();
}
2 changes: 2 additions & 0 deletions pytest.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[pytest]
norecursedirs = extern build
2 changes: 2 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[aliases]
test=pytest
50 changes: 50 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
from setuptools import setup, find_packages
import sys,os

# Track down the pybind11 directory, add it to path, import
# requirements, then remove it again.
DIR = os.path.abspath(os.path.dirname(__file__))
sys.path.append(os.path.join(DIR, "extern", "pybind11"))
from pybind11.setup_helpers import Pybind11Extension, build_ext
from pybind11 import get_cmake_dir
del sys.path[-1]


__version__ = "0.0.1"

# The main interface is through Pybind11Extension.
# * You can add cxx_std=11/14/17, and then build_ext can be removed.
# * You can set include_pybind11=false to add the include directory yourself,
# say from a submodule.
#
# Note:
# Sort input source files if you glob sources to ensure bit-for-bit
# reproducible builds (https://github.com/pybind/python_example/pull/53)

ext_modules = [
Pybind11Extension("stator.core",
["pysrc/stator/core.cpp"],
# Example: passing in the version to the compiled code
define_macros = [('VERSION_INFO', __version__)],
include_dirs=['.', 'extern/eigen']
),
]

setup(
name="stator",
version=__version__,
author="Marcus Bannerman",
author_email="[email protected]",
url="https://github.com/toastedcrumpets/stator",
description="The python stator interface.",
long_description="",
packages=find_packages('pysrc'),
ext_modules=ext_modules,
extras_require={"test": "pytest"},
# Currently, build_ext only provides an optional "highest supported C++
# level" feature, but in the future it may provide more features.
cmdclass={"build_ext": build_ext},
setup_requires=['pytest-runner'],
tests_require=['pytest'],
zip_safe=False,
)
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
10 changes: 10 additions & 0 deletions tests/test_stator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import unittest
import stator
import stator.core

class Testfit(unittest.TestCase):
def test_interface(self):
e = stator.core.Expr("1+1")

if __name__ == "__main__":
unittest.main()

0 comments on commit bbd714f

Please sign in to comment.