Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 49 additions & 41 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,36 @@ name: GitHub Actions
on: [ pull_request, push ]

jobs:
build-test:
name: Build and Test

build:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- uses: actions/setup-dotnet@v1
- uses: actions/setup-python@v2

- name: Build wheel
run: |
pip install --quiet wheel
python setup.py bdist_wheel

- uses: actions/upload-artifact@v2
with:
name: wheel
path: dist/*.whl

- run: |
dotnet publish -f netstandard2.0 -o tests/binaries/netstandard/ src/testing/
dotnet publish -f net5.0 -o tests/binaries/netcore/ src/testing/

- uses: actions/upload-artifact@v2
with:
name: python-tests
path: tests/

python-test:
needs: build
runs-on: ${{ matrix.os }}-latest
timeout-minutes: 15

Expand All @@ -13,22 +41,25 @@ jobs:
matrix:
os: [windows, ubuntu, macos]
python: ["3.6", "3.7", "3.8", "3.9", "3.10"]
platform: [x64]
shutdown_mode: [Normal, Soft]

env:
PYTHONNET_SHUTDOWN_MODE: ${{ matrix.SHUTDOWN_MODE }}
platform: [x86, x64]

steps:
- uses: actions/download-artifact@v2
with:
name: wheel
path: wheel

- uses: actions/download-artifact@v2
with:
name: python-tests
path: python_tests

- name: Set Environment on macOS
uses: maxim-lobanov/setup-xamarin@v1
if: ${{ matrix.os == 'macos' }}
with:
mono-version: latest

- name: Checkout code
uses: actions/checkout@v2

- name: Setup .NET
uses: actions/setup-dotnet@v1

Expand All @@ -37,42 +68,19 @@ jobs:
with:
python-version: ${{ matrix.python }}
architecture: ${{ matrix.platform }}

- name: Install dependencies
run: |
pip install --upgrade -r requirements.txt
pip install numpy # for tests

- name: Build and Install
run: |
pip install -v .

- name: Set Python DLL path (non Windows)
if: ${{ matrix.os != 'windows' }}
run: |
python -m pythonnet.find_libpython --export >> $GITHUB_ENV

- name: Set Python DLL path (Windows)
if: ${{ matrix.os == 'windows' }}
run: |
python -m pythonnet.find_libpython --export | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append

- name: Embedding tests
run: dotnet test --runtime any-${{ matrix.platform }} --logger "console;verbosity=detailed" src/embed_tests/

- run: |
pip install wheel
pip install psutil pytest clr-loader
pip install --no-index --find-links=wheel pythonnet

- name: Python Tests (Mono)
if: ${{ matrix.os != 'windows' }}
run: pytest --runtime mono
run: pytest --runtime mono ./python_tests --precompiled

- name: Python Tests (.NET Core)
run: pytest --runtime netcore
run: pytest --runtime netcore ./python_tests --precompiled

- name: Python Tests (.NET Framework)
if: ${{ matrix.os == 'windows' }}
run: pytest --runtime netfx

- name: Python tests run from .NET
run: dotnet test --runtime any-${{ matrix.platform }} src/python_tests_runner/

# TODO: Run perf tests
# TODO: Run mono tests on Windows?
run: pytest --runtime netfx ./python_tests --precompiled
68 changes: 40 additions & 28 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,30 +29,45 @@ def pytest_addoption(parser):
help="Must be one of default, netcore, netfx and mono"
)

parser.addoption(
"--precompiled",
action="store_true",
)

collect_ignore = []

def pytest_configure(config):
global bin_path
global precompiled

if "clr" in sys.modules:
# Already loaded (e.g. by the C# test runner), skip build
import clr
clr.AddReference("Python.Test")
precompiled = True
return


precompiled_opt = config.getoption("precompiled")
runtime_opt = config.getoption("runtime")

test_proj_path = os.path.join(cwd, "..", "src", "testing")

if runtime_opt not in ["netcore", "netfx", "mono", "default"]:
raise RuntimeError(f"Invalid runtime: {runtime_opt}")

bin_path = mkdtemp()

# tmpdir_factory.mktemp(f"pythonnet-{runtime_opt}")
if precompiled_opt:
precompiled = True

fw = "net5.0" if runtime_opt == "netcore" else "netstandard2.0"
bin_path = os.path.join(
cwd, "binaries",
"netcore" if runtime_opt == "netcore" else "netstandard"
)
else:
precompiled = False

check_call(["dotnet", "publish", "-f", fw, "-o", bin_path, test_proj_path])
fw = "net5.0" if runtime_opt == "netcore" else "netstandard2.0"
bin_path = mkdtemp()
test_proj_path = os.path.join(cwd, "..", "src", "testing")
check_call(["dotnet", "publish", "-f", fw, "-o", bin_path, test_proj_path])

sys.path.append(bin_path)

Expand All @@ -75,28 +90,27 @@ def pytest_configure(config):
import clr
clr.AddReference("Python.Test")

soft_mode = False
try:
os.environ['PYTHONNET_SHUTDOWN_MODE'] == 'Soft'
except: pass

if config.getoption("--runtime") == "netcore" or soft_mode\
:
collect_ignore.append("domain_tests/test_domain_reload.py")
else:
domain_tests_dir = os.path.join(os.path.dirname(__file__), "domain_tests")
bin_path = os.path.join(domain_tests_dir, "bin")
check_call(["dotnet", "build", domain_tests_dir, "-o", bin_path])

collect_ignore.append("domain_tests/test_domain_reload.py")
# Disable for now
# if config.getoption("--runtime") == "netcore":
# collect_ignore.append("domain_tests/test_domain_reload.py")
# else:
# os.environ['PYTHONNET_SHUTDOWN_MODE'] == 'Soft'
# domain_tests_dir = os.path.join(os.path.dirname(__file__), "domain_tests")
# bin_path = os.path.join(domain_tests_dir, "bin")
# check_call(["dotnet", "build", domain_tests_dir, "-o", bin_path])
#



def pytest_unconfigure(config):
global bin_path
try:
shutil.rmtree(bin_path)
except Exception:
pass
global bin_path, precompiled
if not precompiled:
try:
shutil.rmtree(bin_path)
except Exception:
pass


def pytest_report_header(config):
"""Generate extra report headers"""
Expand All @@ -105,10 +119,8 @@ def pytest_report_header(config):
arch = "x64" if is_64bits else "x86"
ucs = ctypes.sizeof(ctypes.c_wchar)
libdir = sysconfig.get_config_var("LIBDIR")
shared = bool(sysconfig.get_config_var("Py_ENABLE_SHARED"))

header = ("Arch: {arch}, UCS: {ucs}, LIBDIR: {libdir}, "
"Py_ENABLE_SHARED: {shared}".format(**locals()))
header = "Arch: {arch}, UCS: {ucs}, LIBDIR: {libdir}".format(**locals())
return header


Expand Down