diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 61920bd34..f17799d7c 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -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 @@ -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 @@ -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 \ No newline at end of file diff --git a/tests/conftest.py b/tests/conftest.py index 0361830d6..c50aeb3c7 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -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) @@ -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""" @@ -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