Skip to content

Commit

Permalink
Pytest, Existing GitLfs garnet-data repo connection and Code Coverage…
Browse files Browse the repository at this point in the history
… Initialization (#4)

Updates in tests, pytest, codecoverage and garnet-data existing repository configurations
  • Loading branch information
mpatrou authored Jun 4, 2024
1 parent b6ec278 commit 082a603
Show file tree
Hide file tree
Showing 21 changed files with 303 additions and 182 deletions.
34 changes: 34 additions & 0 deletions .github/workflows/garnetreduction.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: CI

on:
workflow_dispatch:
pull_request:
push:
branches: [next, qa, main]
tags: ['v*']

jobs:
tests:
runs-on: ubuntu-latest
defaults:
run:
shell: bash -l {0}
steps:
- uses: actions/checkout@v4
- uses: mamba-org/setup-micromamba@v1
with:
environment-file: environment.yml
cache-environment-key: ${{ runner.os }}-env-${{ hashFiles('**/environment.yml') }}
cache-downloads-key: ${{ runner.os }}-downloads-${{ hashFiles('**/environment.yml') }}
- name: install garnet_reduction
run: |
python -m pip install -e .
- name: run unit tests
run: |
echo "running unit tests"
xvfb-run --server-args="-screen 0 1920x1080x24" -a python -m pytest --cov=src --cov-report=xml --cov-report=term-missing
- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v4.0.1
with:
token: ${{ secrets.CODECOV_TOKEN }}
slug: neutrons/garnet_reduction
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ share/python-wheels/
.installed.cfg
*.egg
MANIFEST
src/garnet/_version.py

# PyInstaller
# Usually these files are written by a python script from a template
Expand Down
6 changes: 6 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[submodule "tests/data/garnet-data"]
path = tests/data/garnet-data
url = https://code.ornl.gov/sns-hfir-scse/infrastructure/test-data/garnet-data.git
branch = main
[submodule "garnet-data"]
update = merge
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1 +1,23 @@
# ![](garnet.svg)


### Getting started

Create conda environment
```bash
conda env create -f environment.yml
```

Activate garnet environment
```bash
conda activate garnet_reduction
```

Install in editable mode for developlment
```bash
python -m pip install -e .
```


[![CI](https://github.com/neutrons/garnet_reduction/actions/workflows/garnetreduction.yml/badge.svg?branch=next)](https://github.com/neutrons/garnet_reduction/actions/workflows/garnetreduction.yml/)
[![codecov](https://codecov.io/gh/neutrons/garnet_reduction/graph/badge.svg?token=SV1HMY1XPW)](https://codecov.io/gh/neutrons/garnet_reduction)
10 changes: 10 additions & 0 deletions codecov.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Configuration file for codecov reporting code coverage

# Percentage drop allowed
coverage:
status:
project:
default:
# base on last build, but allow drop of upto this percent
target: 80.0
threshold: 2.0
4 changes: 3 additions & 1 deletion environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ dependencies:
- matplotlib
- pycifrw
- pre-commit
- pytest
- pytest-qt
- pytest-cov
- h5py
- lmfit
- mantidworkbench
- pytest
8 changes: 8 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,11 @@ ignore = ["D203", # conflict with D211
"ANN201", "D400", "D401", "D415", # Unnecessary
"ARG002", "N802", "N803","N806", "D100","D101","D102","D103", "D104","D107","D417" # put it back in the future
]

[tool.pytest.ini_options]
markers = [
"resources_intensive: mark test as using a lot of computing resources: CPU, memory, etc.",
"mount_sns: mark a test as using /SNS/ data mount",
"mount_hfir: mark a test as using /HFIR/ data mount",
"datarepo: Tests that require the garnet_data submodule"
]
5 changes: 3 additions & 2 deletions src/garnet/reduction/normalization.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ def normalize(self):
data.update_raw_path(self.plan)

runs = self.plan["Runs"]

grouping_file = ""
if data.laue:
grouping_file = diag_file.replace(".nxs", ".xml")

Expand Down Expand Up @@ -152,7 +152,8 @@ def normalize(self):

mtd.clear()

os.remove(grouping_file)
if grouping_file and os.path.exists(grouping_file):
os.remove(grouping_file)

return output_file

Expand Down
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
47 changes: 47 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
"""pytest config"""

import os

import pytest


def pytest_addoption(parser):
parser.addoption("--all", action="store_true", default=False, help="run slow tests")


def pytest_collection_modifyitems(config, items):
if config.getoption("--all"):
# --all: do not skip slow tests
return
skip_slow = pytest.mark.skip(reason="need --all option to run")
for item in items:
if "resources_intensive" in item.keywords:
item.add_marker(skip_slow)


@pytest.fixture(scope="session")
def has_sns_mount():
"""Fixture that returns True if the SNS data mount (e.g CORELLI shared) is available"""
sns_dir = "/SNS/CORELLI/shared/"
return os.path.exists(sns_dir)


@pytest.fixture(scope="session")
def has_hfir_mount():
"""Fixture that returns True if the HFIR data mount (e.g HB3A shared) is available"""
hfir_dir = "/HFIR/HB3A/shared/"
return os.path.exists(hfir_dir)


@pytest.fixture(scope="session")
def has_datarepo():
"""Fixture that returns True if the datarepo_dir is available"""
readme_data = os.path.join(os.path.dirname(os.path.abspath(__file__)), "data", "garnet-data", "README.md")
return os.path.exists(readme_data)


@pytest.fixture(scope="session")
def datarepo_dir():
"""Return the directory **absolute** paths for test data."""
root_data = os.path.join(os.path.dirname(os.path.abspath(__file__)), "data", "garnet-data")
return root_data
1 change: 1 addition & 0 deletions tests/data/garnet-data
Submodule garnet-data added at 74cdac
97 changes: 36 additions & 61 deletions tests/test_integration.py
Original file line number Diff line number Diff line change
@@ -1,96 +1,71 @@
import os
import shutil
import subprocess
import tempfile

import numpy as np
import pytest
from garnet.config.instruments import beamlines
from garnet.reduction.integration import PeakEllipsoid, PeakSphere
from garnet.reduction.plan import ReductionPlan

benchmark = "shared/benchmark/int"


@pytest.mark.skipif(not os.path.exists("/SNS/CORELLI/"), reason="file mount")
def test_corelli():
@pytest.mark.resources_intensive
@pytest.mark.mount_sns
def test_corelli(tmpdir, has_sns_mount):
if not has_sns_mount:
pytest.skip("Test is skipped. SNS mount is not available.")

config_file = "corelli_reduction_plan.yaml"
reduction_plan = os.path.abspath(os.path.join("./tests/data", config_file))
script = os.path.abspath("./src/garnet/workflow.py")
command = ["python", script, config_file, "int", "16"]

with tempfile.TemporaryDirectory() as tmpdir:
os.chdir(tmpdir)

rp = ReductionPlan()
rp.load_plan(reduction_plan)
rp.save_plan(os.path.join(tmpdir, config_file))

instrument_config = beamlines[rp.plan["Instrument"]]
facility = instrument_config["Facility"]
name = instrument_config["Name"]
baseline_path = os.path.join("/", facility, name, benchmark)
rp = ReductionPlan()
rp.load_plan(reduction_plan)
saved_plan = os.path.join(tmpdir, config_file)
rp.set_output(saved_plan)
rp.save_plan(saved_plan)

subprocess.run(command, check=False)
command = ["python", script, saved_plan, "int", "16"]
subprocess.run(command, check=False)

if os.path.exists(baseline_path):
shutil.rmtree(baseline_path)

shutil.copytree(tmpdir, baseline_path)
@pytest.mark.mount_hfir
def test_wand2(tmpdir, has_hfir_mount):
if not has_hfir_mount:
pytest.skip("Test is skipped. HFIR mount is not available.")


@pytest.mark.skipif(not os.path.exists("/HFIR/HB2C/"), reason="file mount")
def test_wand2():
config_file = "wand2_reduction_plan.yaml"
reduction_plan = os.path.abspath(os.path.join("./tests/data", config_file))
script = os.path.abspath("./src/garnet/workflow.py")
command = ["python", script, config_file, "int", "4"]

with tempfile.TemporaryDirectory() as tmpdir:
os.chdir(tmpdir)

rp = ReductionPlan()
rp.load_plan(reduction_plan)
rp.save_plan(os.path.join(tmpdir, config_file))

instrument_config = beamlines[rp.plan["Instrument"]]
facility = instrument_config["Facility"]
name = instrument_config["Name"]
baseline_path = os.path.join("/", facility, name, benchmark)
rp = ReductionPlan()
rp.load_plan(reduction_plan)
saved_plan = os.path.join(tmpdir, config_file)
rp.set_output(saved_plan)
rp.save_plan(saved_plan)

subprocess.run(command, check=False)
command = ["python", script, saved_plan, "int", "4"]
subprocess.run(command, check=False)

if os.path.exists(baseline_path):
shutil.rmtree(baseline_path)

shutil.copytree(tmpdir, baseline_path)
@pytest.mark.mount_hfir
def test_demand(tmpdir, has_hfir_mount):
if not has_hfir_mount:
pytest.skip("Test is skipped. HFIR mount is not available.")


@pytest.mark.skipif(not os.path.exists("/HFIR/HB3A/"), reason="file mount")
def test_demand():
config_file = "demand_reduction_plan.yaml"
reduction_plan = os.path.abspath(os.path.join("./tests/data", config_file))
script = os.path.abspath("./src/garnet/workflow.py")
command = ["python", script, config_file, "int", "4"]

with tempfile.TemporaryDirectory() as tmpdir:
os.chdir(tmpdir)

rp = ReductionPlan()
rp.load_plan(reduction_plan)
rp.save_plan(os.path.join(tmpdir, config_file))

instrument_config = beamlines[rp.plan["Instrument"]]
facility = instrument_config["Facility"]
name = instrument_config["Name"]
baseline_path = os.path.join("/", facility, name, benchmark)

subprocess.run(command, check=False)

if os.path.exists(baseline_path):
shutil.rmtree(baseline_path)
rp = ReductionPlan()
rp.load_plan(reduction_plan)
saved_plan = os.path.join(tmpdir, config_file)
rp.set_output(saved_plan)
rp.save_plan(saved_plan)

shutil.copytree(tmpdir, baseline_path)
command = ["python", script, saved_plan, "int", "4"]
subprocess.run(command, check=False)


def test_sphere():
Expand Down Expand Up @@ -176,7 +151,7 @@ def test_ellipsoid():
radii = params[3:6]
vectors = params[6:9]

S = ellipsoid.S_matrix(*ellipsoid.scale(*radii, s=0.25), *ellipsoid.angles(*vectors))
S = ellipsoid.S_matrix(*ellipsoid.scale(*radii), *ellipsoid.angles(*vectors))

s = np.sqrt(np.linalg.det(S))
sigma = np.sqrt(np.linalg.det(cov))
Expand Down
Loading

0 comments on commit 082a603

Please sign in to comment.